2017-07-20 06:08:49 +02:00
/*
* Clone . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# include "StdInc.h"
# include "Clone.h"
# include "Registry.h"
# include "../ISpellMechanics.h"
# include "../../NetPacks.h"
# include "../../battle/CBattleInfoCallback.h"
2023-08-31 17:45:52 +02:00
# include "../../battle/IBattleState.h"
2017-07-20 06:08:49 +02:00
# include "../../battle/CUnitState.h"
# include "../../serializer/JsonSerializeFormat.h"
2022-07-26 15:07:42 +02:00
VCMI_LIB_NAMESPACE_BEGIN
2017-07-20 06:08:49 +02:00
namespace spells
{
namespace effects
{
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
void Clone : : apply ( ServerCallback * server , const Mechanics * m , const EffectTarget & target ) const
2017-07-20 06:08:49 +02:00
{
for ( const Destination & dest : target )
{
const battle : : Unit * clonedStack = dest . unitValue ;
//we shall have all targets to be stacks
if ( ! clonedStack )
{
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
server - > complain ( " No target stack to clone! Invalid effect target transformation. " ) ;
2017-07-20 06:08:49 +02:00
continue ;
}
//should not happen, but in theory we might have stack took damage from other effects
if ( clonedStack - > getCount ( ) < 1 )
continue ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
auto hex = m - > battle ( ) - > getAvaliableHex ( clonedStack - > creatureId ( ) , m - > casterSide , clonedStack - > getPosition ( ) ) ;
2017-07-20 06:08:49 +02:00
if ( ! hex . isValid ( ) )
{
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
server - > complain ( " No place to put new clone! " ) ;
2017-07-20 06:08:49 +02:00
break ;
}
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
auto unitId = m - > battle ( ) - > battleNextUnitId ( ) ;
2017-07-20 06:08:49 +02:00
battle : : UnitInfo info ;
info . id = unitId ;
info . count = clonedStack - > getCount ( ) ;
info . type = clonedStack - > creatureId ( ) ;
info . side = m - > casterSide ;
info . position = hex ;
info . summoned = true ;
BattleUnitsChanged pack ;
2023-08-31 17:45:52 +02:00
pack . battleID = m - > battle ( ) - > getBattle ( ) - > getBattleID ( ) ;
2017-07-20 06:08:49 +02:00
pack . changedStacks . emplace_back ( info . id , UnitChanges : : EOperation : : ADD ) ;
info . save ( pack . changedStacks . back ( ) . data ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
server - > apply ( & pack ) ;
2017-07-20 06:08:49 +02:00
//TODO: use BattleUnitsChanged with UPDATE operation
BattleUnitsChanged cloneFlags ;
2023-08-31 17:45:52 +02:00
cloneFlags . battleID = m - > battle ( ) - > getBattle ( ) - > getBattleID ( ) ;
2017-07-20 06:08:49 +02:00
2023-02-07 00:40:01 +02:00
const auto * cloneUnit = m - > battle ( ) - > battleGetUnitByID ( unitId ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
if ( ! cloneUnit )
{
server - > complain ( " [Internal error] Cloned unit missing. " ) ;
continue ;
}
2017-07-20 06:08:49 +02:00
auto cloneState = cloneUnit - > acquireState ( ) ;
cloneState - > cloned = true ;
cloneFlags . changedStacks . emplace_back ( cloneState - > unitId ( ) , UnitChanges : : EOperation : : RESET_STATE ) ;
cloneState - > save ( cloneFlags . changedStacks . back ( ) . data ) ;
auto originalState = clonedStack - > acquireState ( ) ;
originalState - > cloneID = unitId ;
cloneFlags . changedStacks . emplace_back ( originalState - > unitId ( ) , UnitChanges : : EOperation : : RESET_STATE ) ;
originalState - > save ( cloneFlags . changedStacks . back ( ) . data ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
server - > apply ( & cloneFlags ) ;
2017-07-20 06:08:49 +02:00
SetStackEffect sse ;
2023-08-31 17:45:52 +02:00
sse . battleID = m - > battle ( ) - > getBattle ( ) - > getBattleID ( ) ;
2023-10-21 13:50:42 +02:00
Bonus lifeTimeMarker ( BonusDuration : : N_TURNS , BonusType : : NONE , BonusSource : : SPELL_EFFECT , 0 , BonusSourceID ( SpellID ( SpellID : : CLONE ) ) ) ; //TODO: use special bonus type
2017-07-20 06:08:49 +02:00
lifeTimeMarker . turnsRemain = m - > getEffectDuration ( ) ;
std : : vector < Bonus > buffer ;
buffer . push_back ( lifeTimeMarker ) ;
2023-02-07 00:40:01 +02:00
sse . toAdd . emplace_back ( unitId , buffer ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
server - > apply ( & sse ) ;
2017-07-20 06:08:49 +02:00
}
}
bool Clone : : isReceptive ( const Mechanics * m , const battle : : Unit * s ) const
{
int creLevel = s - > creatureLevel ( ) ;
if ( creLevel > maxTier )
return false ;
//use default algorithm only if there is no mechanics-related problem
return UnitEffect : : isReceptive ( m , s ) ;
}
bool Clone : : isValidTarget ( const Mechanics * m , const battle : : Unit * s ) const
{
//can't clone already cloned creature
if ( s - > isClone ( ) )
return false ;
//can`t clone if old clone still alive
if ( s - > hasClone ( ) )
return false ;
return UnitEffect : : isValidTarget ( m , s ) ;
}
void Clone : : serializeJsonUnitEffect ( JsonSerializeFormat & handler )
{
handler . serializeInt ( " maxTier " , maxTier ) ;
}
}
}
2022-07-26 15:07:42 +02:00
VCMI_LIB_NAMESPACE_END