From 57328bdc83983346b3f46e84dfe25bc68d949136 Mon Sep 17 00:00:00 2001 From: Arseniy Shestakov Date: Fri, 29 Jan 2016 22:43:35 +0300 Subject: [PATCH] Battles: implement basic drawbridge mechanics Movement to blocking hex 94 not yet properly handled as stack movement code need to be rewritten first. Also gate destruction not immidiately affect drawbridge state. --- lib/CBattleCallback.cpp | 24 ++++++++++++++++++++++-- lib/CBattleCallback.h | 1 + server/CGameHandler.cpp | 35 +++++++++++++++++++++++++++++++++++ server/CGameHandler.h | 1 + 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/lib/CBattleCallback.cpp b/lib/CBattleCallback.cpp index bdfb2580e..c5556d4c0 100644 --- a/lib/CBattleCallback.cpp +++ b/lib/CBattleCallback.cpp @@ -442,6 +442,15 @@ si8 CBattleInfoEssentials::battleGetWallState(int partOfWall) const return getBattle()->si.wallState[partOfWall]; } +EDrawbridgeState CBattleInfoEssentials::battleGetDrawbridgeState() const +{ + RETURN_IF_NOT_BATTLE(EDrawbridgeState::NONE); + if(getBattle()->town == nullptr || getBattle()->town->fortLevel() == CGTownInstance::NONE) + return EDrawbridgeState::NONE; + + return getBattle()->si.drawbridgeState; +} + si8 CBattleInfoCallback::battleHasWallPenalty( const CStack * stack, BattleHex destHex ) const { return battleHasWallPenalty(stack, stack->position, destHex); @@ -1129,9 +1138,20 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const } //gate -> should be before stacks - if(battleGetSiegeLevel() > 0 && battleGetWallState(EWallPart::GATE) != EWallState::DESTROYED) + if(battleGetSiegeLevel() > 0) { - ret[95] = ret[96] = EAccessibility::GATE; //block gate's hexes + EAccessibility::EAccessibility accessability = EAccessibility::ACCESSIBLE; + switch(battleGetDrawbridgeState()) + { + case EDrawbridgeState::RAISED: + accessability = EAccessibility::GATE; + break; + + case EDrawbridgeState::RAISED_BLOCKED: + accessability = EAccessibility::UNAVAILABLE; + break; + } + ret[95] = ret[96] = accessability; } //tiles occupied by standing stacks diff --git a/lib/CBattleCallback.h b/lib/CBattleCallback.h index 0c7323706..8d2fe69c0 100644 --- a/lib/CBattleCallback.h +++ b/lib/CBattleCallback.h @@ -199,6 +199,7 @@ public: // for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, // [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle si8 battleGetWallState(int partOfWall) const; + EDrawbridgeState battleGetDrawbridgeState() const; //helpers ///returns all stacks, alive or dead or undead or mechanical :) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 368201a81..6f657ab80 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1148,6 +1148,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest) handleDamageFromObstacle(*theLastObstacle, curStack); } } + updateDrawbridgeState(); return ret; } @@ -3449,6 +3450,40 @@ bool CGameHandler::queryReply(QueryID qid, ui32 answer, PlayerColor player) static EndAction end_action; +void CGameHandler::updateDrawbridgeState() +{ + BattleDrawbridgeStateChanged db; + db.state = gs->curB->si.drawbridgeState; + if(gs->curB->si.wallState[EWallPart::GATE] == EWallState::DESTROYED) + { + db.state = EDrawbridgeState::LOWERED_BORKED; + } + else if(db.state == EDrawbridgeState::LOWERED) + { + if(gs->curB->battleGetStackByPos(BattleHex(94), false) || + gs->curB->battleGetStackByPos(BattleHex(95), false) || + gs->curB->battleGetStackByPos(BattleHex(96), false)) + { + db.state = EDrawbridgeState::LOWERED; + } + else + db.state = EDrawbridgeState::RAISED; + } + else if(db.state == EDrawbridgeState::RAISED || db.state == EDrawbridgeState::RAISED_BLOCKED) + { + if(gs->curB->battleGetStackByPos(BattleHex(94), false)) + db.state = EDrawbridgeState::RAISED_BLOCKED; + else if(gs->curB->battleGetStackByPos(BattleHex(95), false) || + gs->curB->battleGetStackByPos(BattleHex(96), false)) + { + db.state = EDrawbridgeState::LOWERED; + } + else + db.state = EDrawbridgeState::RAISED; + } + sendAndApply(&db); +} + bool CGameHandler::makeBattleAction( BattleAction &ba ) { bool ok = true; diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 104979140..7eacccf77 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -200,6 +200,7 @@ public: PlayerColor getPlayerAt(CConnection *c) const; void playerMessage( PlayerColor player, const std::string &message, ObjectInstanceID currObj); + void updateDrawbridgeState(); bool makeBattleAction(BattleAction &ba); bool makeAutomaticAction(const CStack *stack, BattleAction &ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack) bool makeCustomAction(BattleAction &ba);