mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* new spell: remove obstacle
* minor changes
This commit is contained in:
parent
af1a55e063
commit
c4b0bd9d7e
@ -120,6 +120,7 @@ public:
|
||||
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning
|
||||
virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks){}; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp
|
||||
virtual void battleNewStackAppeared(int stackID){}; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||
virtual void battleObstaclesRemoved(const std::set<si32> & removedObstacles){}; //called when a certain set of obstacles is removed from batlefield; IDs of them are given
|
||||
};
|
||||
class CAIHandler
|
||||
{
|
||||
|
@ -848,7 +848,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
//get dead stack if we cast resurrection or animate dead
|
||||
const CStack * stackUnder = LOCPLINT->cb->battleGetStackByPos(myNumber, spellToCast->additionalInfo != 38 && spellToCast->additionalInfo != 39);
|
||||
|
||||
if(stackUnder && spellToCast->additionalInfo == 39 && !stackUnder->hasFeatureOfType(StackFeature::UNDEAD)) //animate dead can be cast only on living creatures
|
||||
if(stackUnder && spellToCast->additionalInfo == 39 && !stackUnder->hasFeatureOfType(StackFeature::UNDEAD)) //animate dead can be cast only on undead creatures
|
||||
stackUnder = NULL;
|
||||
|
||||
bool whichCase; //for cases 1, 2 and 3
|
||||
@ -896,6 +896,14 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
}
|
||||
break;
|
||||
case 4: //TODO: implement this case
|
||||
if( blockedByObstacle(myNumber) )
|
||||
{
|
||||
CGI->curh->changeGraphic(3, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGI->curh->changeGraphic(1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1520,6 +1528,19 @@ bool CBattleInterface::isTileAttackable(const int & number) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBattleInterface::blockedByObstacle(int hex) const
|
||||
{
|
||||
std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
|
||||
std::set<int> coveredHexes;
|
||||
for(int b = 0; b < obstacles.size(); ++b)
|
||||
{
|
||||
std::vector<int> blocked = CGI->heroh->obstacles[obstacles[b].ID].getBlocked(obstacles[b].pos);
|
||||
for(int w = 0; w < blocked.size(); ++w)
|
||||
coveredHexes.insert(blocked[w]);
|
||||
}
|
||||
return vstd::contains(coveredHexes, hex);
|
||||
}
|
||||
|
||||
void CBattleInterface::handleEndOfMove(int stackNumber, int destinationTile)
|
||||
{
|
||||
const CStack * movedStack = LOCPLINT->cb->battleGetStackByID(stackNumber);
|
||||
@ -1575,7 +1596,9 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
if(!LOCPLINT->cb->battleGetStackByPos(whichOne, onlyAlive))
|
||||
allowCasting = false;
|
||||
break;
|
||||
case 4: //TODO: implement this case
|
||||
case 4:
|
||||
if(!blockedByObstacle(whichOne))
|
||||
allowCasting = false;
|
||||
break;
|
||||
}
|
||||
//destination checked
|
||||
@ -1971,6 +1994,10 @@ void CBattleInterface::castThisSpell(int spellID)
|
||||
spellSelMode = -1;
|
||||
}
|
||||
}
|
||||
if(CGI->spellh->spells[spellID].attributes.find("OBSTACLE_TARGET") != std::string::npos) //spell to be cast on an obstacle
|
||||
{
|
||||
spellSelMode = 4;
|
||||
}
|
||||
if(spellSelMode == -1) //user does not have to select location
|
||||
{
|
||||
spellToCast->destinationTile = -1;
|
||||
|
@ -214,6 +214,7 @@ private:
|
||||
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
|
||||
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
|
||||
bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles
|
||||
bool blockedByObstacle(int hex) const;
|
||||
|
||||
void handleEndOfMove(int stackNumber, int destinationTile); //helper function
|
||||
|
||||
@ -237,7 +238,7 @@ public:
|
||||
int getAnimSpeed() const; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
|
||||
|
||||
CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each
|
||||
std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
|
||||
//std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
|
||||
SDL_Surface * cellBorder, * cellShade;
|
||||
CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
|
||||
bool myTurn; //if true, interface is active (commands can be ordered
|
||||
|
@ -981,6 +981,23 @@ void CPlayerInterface::battleNewStackAppeared(int stackID)
|
||||
battleInt->newStack(stackID);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
|
||||
{
|
||||
for(std::set<si32>::const_iterator it = removedObstacles.begin(); it != removedObstacles.end(); ++it)
|
||||
{
|
||||
for(std::map< int, CDefHandler * >::iterator itBat = battleInt->idToObstacle.begin(); itBat != battleInt->idToObstacle.end(); ++itBat)
|
||||
{
|
||||
if(itBat->first == *it) //remove this obstacle
|
||||
{
|
||||
battleInt->idToObstacle.erase(itBat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//update accessible hexes
|
||||
battleInt->redrawBackgroundWithHexes(battleInt->activeStack);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleNewRound(int round) //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
|
@ -179,6 +179,7 @@ public:
|
||||
void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
|
||||
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks); //called when stacks are healed / resurrected
|
||||
void battleNewStackAppeared(int stackID); //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||
void battleObstaclesRemoved(const std::set<si32> & removedObstacles); //called when a certain set of obstacles is removed from batlefield; IDs of them are given
|
||||
|
||||
//-------------//
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __FONTBASE_H__
|
||||
|
||||
/*
|
||||
* Graphics.h, part of VCMI engine
|
||||
* FontBase.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
|
@ -462,6 +462,13 @@ void StacksHealedOrResurrected::applyCl( CClient *cl )
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleStacksHealedRes, shiftedHealed);
|
||||
}
|
||||
|
||||
void ObstaclesRemoved::applyCl( CClient *cl )
|
||||
{
|
||||
//inform interfaces about removed obstacles
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, battleObstaclesRemoved, obstacles);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, battleObstaclesRemoved, obstacles);
|
||||
}
|
||||
|
||||
CGameState* CPackForClient::GS( CClient *cl )
|
||||
{
|
||||
return cl->gs;
|
||||
|
@ -4035,10 +4035,11 @@ void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if (!hasVisited (h->getOwner()) )
|
||||
if (!hasVisited (h->getOwner()) ) //if hero has not visited yet this cartographer
|
||||
{
|
||||
if (cb->getResource(h->tempOwner, 6) >= 1000)
|
||||
if (cb->getResource(h->tempOwner, 6) >= 1000) //if he can afford a map
|
||||
{
|
||||
//ask if he wants to buy one
|
||||
int text;
|
||||
if (cb->getTile(pos)->tertype == 8) //water
|
||||
text = 25;
|
||||
@ -4055,7 +4056,7 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
bd.text.addTxt (MetaString::ADVOB_TXT, text);
|
||||
cb->showBlockingDialog (&bd, boost::bind (&CCartographer::buyMap, this, h, _1));
|
||||
}
|
||||
else
|
||||
else //if he cannot afford
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
@ -4064,7 +4065,7 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
cb->showInfoDialog (&iw);
|
||||
}
|
||||
}
|
||||
else
|
||||
else //if he already visited carographer
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
@ -4073,9 +4074,10 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
cb->showInfoDialog (&iw);
|
||||
}
|
||||
}
|
||||
|
||||
void CCartographer::buyMap (const CGHeroInstance *h, ui32 accept) const
|
||||
{
|
||||
if (accept)
|
||||
if (accept) //if hero wants to buy map
|
||||
{
|
||||
cb->giveResource (h->tempOwner, 6, -1000);
|
||||
FoWChange fw;
|
||||
@ -4090,8 +4092,9 @@ void CCartographer::buyMap (const CGHeroInstance *h, ui32 accept) const
|
||||
else
|
||||
floor = 2;
|
||||
|
||||
//reveal apropriate tiles
|
||||
cb->getAllTiles (fw.tiles, h->tempOwner, floor, surface);
|
||||
cb->sendAndApply (&fw);
|
||||
cb->setObjProperty (id, 10, h->tempOwner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,11 +96,12 @@ public:
|
||||
|
||||
struct DLL_EXPORT CObstacleInstance
|
||||
{
|
||||
int ID; //ID of obstacle
|
||||
int uniqueID;
|
||||
int ID; //ID of obstacle (defines type of it)
|
||||
int pos; //position on battlefield
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ID & pos;
|
||||
h & ID & pos & uniqueID;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -977,6 +977,21 @@ struct StacksHealedOrResurrected : public CPackForClient //3013
|
||||
}
|
||||
};
|
||||
|
||||
struct ObstaclesRemoved : public CPackForClient //3014
|
||||
{
|
||||
ObstaclesRemoved(){type = 3014;}
|
||||
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
std::set<si32> obstacles; //uniqueIDs of removed obstacles
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & obstacles;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShowInInfobox : public CPackForClient //107
|
||||
{
|
||||
ShowInInfobox(){type = 107;};
|
||||
|
@ -1013,6 +1013,24 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void ObstaclesRemoved::applyGs( CGameState *gs )
|
||||
{
|
||||
if(gs->curB) //if there is a battle
|
||||
{
|
||||
for(std::set<si32>::const_iterator it = obstacles.begin(); it != obstacles.end(); ++it)
|
||||
{
|
||||
for(int i=0; i<gs->curB->obstacles.size(); ++i)
|
||||
{
|
||||
if(gs->curB->obstacles[i].uniqueID == *it) //remove this obstacle
|
||||
{
|
||||
gs->curB->obstacles.erase(gs->curB->obstacles.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->currentPlayer = player;
|
||||
|
@ -104,6 +104,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<StacksInjured>();
|
||||
s.template registerType<BattleResultsApplied>();
|
||||
s.template registerType<StacksHealedOrResurrected>();
|
||||
s.template registerType<ObstaclesRemoved>();
|
||||
s.template registerType<ShowInInfobox>();
|
||||
s.template registerType<OpenWindow>();
|
||||
s.template registerType<NewObject>();
|
||||
|
@ -1014,6 +1014,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
|
||||
while(toBlock>0)
|
||||
{
|
||||
CObstacleInstance coi;
|
||||
coi.uniqueID = curB->obstacles.size();
|
||||
coi.ID = possibleObstacles[rand()%possibleObstacles.size()];
|
||||
coi.pos = rand()%BFIELD_SIZE;
|
||||
std::vector<int> block = VLC->heroh->obstacles[coi.ID].getBlocked(coi.pos);
|
||||
@ -2869,6 +2870,23 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
sendAndApply(&shr);
|
||||
break;
|
||||
}
|
||||
case 64: //remove obstacle
|
||||
{
|
||||
ObstaclesRemoved obr;
|
||||
for(int g=0; g<gs->curB->obstacles.size(); ++g)
|
||||
{
|
||||
std::vector<int> blockedHexes = VLC->heroh->obstacles[gs->curB->obstacles[g].ID].getBlocked(gs->curB->obstacles[g].pos);
|
||||
|
||||
if(vstd::contains(blockedHexes, ba.destinationTile)) //this obstacle covers given hex
|
||||
{
|
||||
obr.obstacles.insert(gs->curB->obstacles[g].uniqueID);
|
||||
}
|
||||
}
|
||||
if(!obr.obstacles.empty())
|
||||
sendAndApply(&obr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
sendAndApply(&EndAction());
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user