2017-07-20 06:08:49 +02:00
|
|
|
/*
|
|
|
|
* Catapult.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 "Catapult.h"
|
|
|
|
|
|
|
|
#include "Registry.h"
|
|
|
|
#include "../ISpellMechanics.h"
|
|
|
|
|
|
|
|
#include "../../NetPacks.h"
|
|
|
|
#include "../../battle/IBattleState.h"
|
|
|
|
#include "../../battle/CBattleInfoCallback.h"
|
|
|
|
#include "../../battle/Unit.h"
|
|
|
|
#include "../../mapObjects/CGTownInstance.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
|
|
|
static const std::string EFFECT_NAME = "core:catapult";
|
|
|
|
|
|
|
|
namespace spells
|
|
|
|
{
|
|
|
|
namespace effects
|
|
|
|
{
|
|
|
|
|
|
|
|
VCMI_REGISTER_SPELL_EFFECT(Catapult, EFFECT_NAME);
|
|
|
|
|
|
|
|
Catapult::Catapult()
|
|
|
|
: LocationEffect(),
|
|
|
|
targetsToAttack(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Catapult::~Catapult() = default;
|
|
|
|
|
|
|
|
bool Catapult::applicable(Problem & problem, const Mechanics * m) const
|
|
|
|
{
|
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 town = m->battle()->battleGetDefendedTown();
|
2017-07-20 06:08:49 +02:00
|
|
|
|
|
|
|
if(nullptr == town)
|
|
|
|
{
|
|
|
|
return m->adaptProblem(ESpellCastProblem::NO_APPROPRIATE_TARGET, problem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(CGTownInstance::NONE == town->fortLevel())
|
|
|
|
{
|
|
|
|
return m->adaptProblem(ESpellCastProblem::NO_APPROPRIATE_TARGET, problem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(m->isSmart() && m->casterSide != BattleSide::ATTACKER)
|
|
|
|
{
|
|
|
|
//if spell targeting is smart, then only attacker can use it
|
|
|
|
return m->adaptProblem(ESpellCastProblem::NO_APPROPRIATE_TARGET, problem);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
const auto attackableBattleHexes = m->battle()->getAttackableBattleHexes();
|
|
|
|
|
2019-03-20 21:58:15 +02:00
|
|
|
return !attackableBattleHexes.empty() || m->adaptProblem(ESpellCastProblem::NO_APPROPRIATE_TARGET, problem);
|
2017-07-20 06:08:49 +02:00
|
|
|
}
|
|
|
|
|
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 Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & /* eTarget */) const
|
2017-07-20 06:08:49 +02:00
|
|
|
{
|
|
|
|
//start with all destructible parts
|
|
|
|
static const std::set<EWallPart::EWallPart> possibleTargets =
|
|
|
|
{
|
|
|
|
EWallPart::KEEP,
|
|
|
|
EWallPart::BOTTOM_TOWER,
|
|
|
|
EWallPart::BOTTOM_WALL,
|
|
|
|
EWallPart::BELOW_GATE,
|
|
|
|
EWallPart::OVER_GATE,
|
|
|
|
EWallPart::UPPER_WALL,
|
|
|
|
EWallPart::UPPER_TOWER,
|
|
|
|
EWallPart::GATE
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(possibleTargets.size() == EWallPart::PARTS_COUNT);
|
|
|
|
|
|
|
|
CatapultAttack ca;
|
|
|
|
ca.attacker = -1;
|
|
|
|
|
2018-03-05 13:55:44 +02:00
|
|
|
BattleUnitsChanged removeUnits;
|
|
|
|
|
2017-07-20 06:08:49 +02:00
|
|
|
for(int i = 0; i < targetsToAttack; i++)
|
|
|
|
{
|
|
|
|
//Any destructible part can be hit regardless of its HP. Multiple hit on same target is allowed.
|
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
|
|
|
EWallPart::EWallPart target = *RandomGeneratorUtil::nextItem(possibleTargets, *server->getRNG());
|
2017-07-20 06:08:49 +02:00
|
|
|
|
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 state = m->battle()->battleGetWallState(target);
|
2017-07-20 06:08:49 +02:00
|
|
|
|
|
|
|
if(state == EWallState::DESTROYED || state == EWallState::NONE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
CatapultAttack::AttackInfo attackInfo;
|
|
|
|
|
|
|
|
attackInfo.damageDealt = 1;
|
|
|
|
attackInfo.attackedPart = target;
|
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
|
|
|
attackInfo.destinationTile = m->battle()->wallPartToBattleHex(target);
|
2017-07-20 06:08:49 +02:00
|
|
|
|
|
|
|
ca.attackedParts.push_back(attackInfo);
|
|
|
|
|
|
|
|
//removing creatures in turrets / keep if one is destroyed
|
|
|
|
BattleHex posRemove;
|
|
|
|
|
|
|
|
switch(target)
|
|
|
|
{
|
|
|
|
case EWallPart::KEEP:
|
|
|
|
posRemove = -2;
|
|
|
|
break;
|
|
|
|
case EWallPart::BOTTOM_TOWER:
|
|
|
|
posRemove = -3;
|
|
|
|
break;
|
|
|
|
case EWallPart::UPPER_TOWER:
|
|
|
|
posRemove = -4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-03-05 13:55:44 +02:00
|
|
|
if(posRemove != BattleHex::INVALID && state - attackInfo.damageDealt <= 0) //HP enum subtraction not intuitive, consider using SiegeInfo::applyDamage
|
2017-07-20 06:08:49 +02:00
|
|
|
{
|
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 all = m->battle()->battleGetUnitsIf([=](const battle::Unit * unit)
|
2017-07-20 06:08:49 +02:00
|
|
|
{
|
|
|
|
return !unit->isGhost();
|
|
|
|
});
|
|
|
|
|
|
|
|
for(auto & elem : all)
|
|
|
|
{
|
|
|
|
if(elem->getPosition() == posRemove)
|
|
|
|
{
|
|
|
|
removeUnits.changedStacks.emplace_back(elem->unitId(), UnitChanges::EOperation::REMOVE);
|
|
|
|
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
|
|
|
server->apply(&ca);
|
2018-03-05 13:55:44 +02:00
|
|
|
|
|
|
|
if(!removeUnits.changedStacks.empty())
|
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(&removeUnits);
|
2017-07-20 06:08:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Catapult::serializeJsonEffect(JsonSerializeFormat & handler)
|
|
|
|
{
|
|
|
|
//TODO: add configuration unifying with Catapult ability
|
|
|
|
handler.serializeInt("targetsToAttack", targetsToAttack);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2022-07-26 15:07:42 +02:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|