mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
* teleportation implemented
This commit is contained in:
@ -976,6 +976,11 @@ si8 CCallback::battleHasWallPenalty( int stackID, int destHex )
|
|||||||
return gs->curB->hasWallPenalty(stackID, destHex);
|
return gs->curB->hasWallPenalty(stackID, destHex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
si8 CCallback::battleCanTeleportTo(int stackID, int destHex, int telportLevel)
|
||||||
|
{
|
||||||
|
return gs->curB->canTeleportTo(stackID, destHex, telportLevel);
|
||||||
|
}
|
||||||
|
|
||||||
InfoAboutTown::InfoAboutTown()
|
InfoAboutTown::InfoAboutTown()
|
||||||
{
|
{
|
||||||
tType = NULL;
|
tType = NULL;
|
||||||
|
@ -307,6 +307,7 @@ public:
|
|||||||
si8 battleGetStackLuck(int stackID); //returns luck of given stack
|
si8 battleGetStackLuck(int stackID); //returns luck of given stack
|
||||||
si8 battleHasDistancePenalty(int stackID, int destHex); //checks if given stack has distance penalty
|
si8 battleHasDistancePenalty(int stackID, int destHex); //checks if given stack has distance penalty
|
||||||
si8 battleHasWallPenalty(int stackID, int destHex); //checks if given stack has wall penalty
|
si8 battleHasWallPenalty(int stackID, int destHex); //checks if given stack has wall penalty
|
||||||
|
si8 battleCanTeleportTo(int stackID, int destHex, int telportLevel); //checks if teleportation of given stack to given position can take place
|
||||||
|
|
||||||
//XXX hmmm _tmain on _GNUC_ wtf?
|
//XXX hmmm _tmain on _GNUC_ wtf?
|
||||||
//friends
|
//friends
|
||||||
|
@ -2324,6 +2324,22 @@ bool CBattleInterface::isCatapultAttackable(int hex) const
|
|||||||
return curInt->cb->battleGetWallState(wallUnder) < 3;
|
return curInt->cb->battleGetWallState(wallUnder) < 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CGHeroInstance * CBattleInterface::getActiveHero()
|
||||||
|
{
|
||||||
|
const CStack * attacker = curInt->cb->battleGetStackByID(activeStack);
|
||||||
|
if (!attacker)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attacker->attackerOwned)
|
||||||
|
{
|
||||||
|
return attackingHeroInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defendingHeroInstance;
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleInterface::hexLclicked(int whichOne)
|
void CBattleInterface::hexLclicked(int whichOne)
|
||||||
{
|
{
|
||||||
const CStack * actSt = curInt->cb->battleGetStackByID(activeStack);
|
const CStack * actSt = curInt->cb->battleGetStackByID(activeStack);
|
||||||
@ -2355,6 +2371,13 @@ void CBattleInterface::hexLclicked(int whichOne)
|
|||||||
case 4:
|
case 4:
|
||||||
if(!blockedByObstacle(whichOne))
|
if(!blockedByObstacle(whichOne))
|
||||||
allowCasting = false;
|
allowCasting = false;
|
||||||
|
case 5: //teleport
|
||||||
|
const CSpell *s = &CGI->spellh->spells[spellToCast->additionalInfo];
|
||||||
|
ui8 skill = getActiveHero()->getSpellSchoolLevel(s); //skill level
|
||||||
|
if (!curInt->cb->battleCanTeleportTo(activeStack, whichOne, skill))
|
||||||
|
{
|
||||||
|
allowCasting = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//destination checked
|
//destination checked
|
||||||
@ -2750,10 +2773,11 @@ void CBattleInterface::castThisSpell(int spellID)
|
|||||||
|
|
||||||
//choosing possible tragets
|
//choosing possible tragets
|
||||||
const CGHeroInstance * castingHero = (attackingHeroInstance->tempOwner == curInt->playerID) ? attackingHeroInstance : attackingHeroInstance;
|
const CGHeroInstance * castingHero = (attackingHeroInstance->tempOwner == curInt->playerID) ? attackingHeroInstance : attackingHeroInstance;
|
||||||
|
const CSpell & spell = CGI->spellh->spells[spellID];
|
||||||
spellSelMode = 0;
|
spellSelMode = 0;
|
||||||
if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET") != std::string::npos) //spell to be cast on one specific creature
|
if(spell.attributes.find("CREATURE_TARGET") != std::string::npos) //spell to be cast on one specific creature
|
||||||
{
|
{
|
||||||
switch(CGI->spellh->spells[spellID].positiveness)
|
switch(spell.positiveness)
|
||||||
{
|
{
|
||||||
case -1 :
|
case -1 :
|
||||||
spellSelMode = 2;
|
spellSelMode = 2;
|
||||||
@ -2766,12 +2790,12 @@ void CBattleInterface::castThisSpell(int spellID)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET_1") != std::string::npos ||
|
if(spell.attributes.find("CREATURE_TARGET_1") != std::string::npos ||
|
||||||
CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET_2") != std::string::npos) //spell to be cast on a specific creature but massive on expert
|
spell.attributes.find("CREATURE_TARGET_2") != std::string::npos) //spell to be cast on a specific creature but massive on expert
|
||||||
{
|
{
|
||||||
if(castingHero && castingHero->getSpellSecLevel(spellID) < 3)
|
if(castingHero && castingHero->getSpellSecLevel(spellID) < 3)
|
||||||
{
|
{
|
||||||
switch(CGI->spellh->spells[spellID].positiveness)
|
switch(spell.positiveness)
|
||||||
{
|
{
|
||||||
case -1 :
|
case -1 :
|
||||||
spellSelMode = 2;
|
spellSelMode = 2;
|
||||||
@ -2789,14 +2813,20 @@ void CBattleInterface::castThisSpell(int spellID)
|
|||||||
spellSelMode = -1;
|
spellSelMode = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(CGI->spellh->spells[spellID].attributes.find("OBSTACLE_TARGET") != std::string::npos) //spell to be cast on an obstacle
|
if(spell.attributes.find("OBSTACLE_TARGET") != std::string::npos) //spell to be cast on an obstacle
|
||||||
{
|
{
|
||||||
spellSelMode = 4;
|
spellSelMode = 4;
|
||||||
}
|
}
|
||||||
if(CGI->spellh->spells[spellID].range[ castingHero->getSpellSchoolLevel(&CGI->spellh->spells[spellID]) ] == "X") //spell has no range
|
if(spell.range[ castingHero->getSpellSchoolLevel(&spell) ] == "X") //spell has no range
|
||||||
{
|
{
|
||||||
spellSelMode = -1;
|
spellSelMode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(spell.id == 63) //teleport
|
||||||
|
{
|
||||||
|
spellSelMode = 5;
|
||||||
|
}
|
||||||
|
|
||||||
if(spellSelMode == -1) //user does not have to select location
|
if(spellSelMode == -1) //user does not have to select location
|
||||||
{
|
{
|
||||||
spellToCast->destinationTile = -1;
|
spellToCast->destinationTile = -1;
|
||||||
|
@ -401,7 +401,8 @@ private:
|
|||||||
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
|
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
|
||||||
|
|
||||||
bool spellDestSelectMode; //if true, player is choosing destination for his spell
|
bool spellDestSelectMode; //if true, player is choosing destination for his spell
|
||||||
int spellSelMode; //0 - any location, 1 - any friendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle,z -1 - no location
|
int spellSelMode; //0 - any location, 1 - any friendly creature, 2 - any hostile creature, 3 - any creature,
|
||||||
|
//4 - obstacle, 5 - teleport -1 - no location
|
||||||
BattleAction * spellToCast; //spell for which player is choosing destination
|
BattleAction * spellToCast; //spell for which player is choosing destination
|
||||||
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
|
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
|
||||||
|
|
||||||
@ -439,6 +440,7 @@ private:
|
|||||||
} * siegeH;
|
} * siegeH;
|
||||||
|
|
||||||
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
|
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
|
||||||
|
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
|
||||||
public:
|
public:
|
||||||
CPlayerInterface * curInt; //current player interface
|
CPlayerInterface * curInt; //current player interface
|
||||||
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
|
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
|
||||||
|
@ -3521,6 +3521,17 @@ si8 BattleInfo::hasDistancePenalty( int stackID, int destHex )
|
|||||||
return distance > 8 && !stack->hasBonusOfType(Bonus::NO_DISTANCE_PENALTY);
|
return distance > 8 && !stack->hasBonusOfType(Bonus::NO_DISTANCE_PENALTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
si8 BattleInfo::sameSideOfWall(int pos1, int pos2)
|
||||||
|
{
|
||||||
|
int wallInStackLine = lineToWallHex(pos1/BFIELD_WIDTH);
|
||||||
|
int wallInDestLine = lineToWallHex(pos2/BFIELD_WIDTH);
|
||||||
|
|
||||||
|
bool stackLeft = pos1 < wallInStackLine;
|
||||||
|
bool destLeft = pos2 < wallInDestLine;
|
||||||
|
|
||||||
|
return stackLeft != destLeft;
|
||||||
|
}
|
||||||
|
|
||||||
si8 BattleInfo::hasWallPenalty( int stackID, int destHex )
|
si8 BattleInfo::hasWallPenalty( int stackID, int destHex )
|
||||||
{
|
{
|
||||||
if (siege == 0)
|
if (siege == 0)
|
||||||
@ -3532,13 +3543,28 @@ si8 BattleInfo::hasWallPenalty( int stackID, int destHex )
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int wallInStackLine = lineToWallHex(stack->position/BFIELD_WIDTH);
|
|
||||||
int wallInDestLine = lineToWallHex(destHex/BFIELD_WIDTH);
|
|
||||||
|
|
||||||
bool stackLeft = stack->position < wallInStackLine;
|
return !sameSideOfWall(stack->position, destHex);
|
||||||
bool destLeft = destHex < wallInDestLine;
|
}
|
||||||
|
|
||||||
|
si8 BattleInfo::canTeleportTo(int stackID, int destHex, int telportLevel)
|
||||||
|
{
|
||||||
|
bool ac[BFIELD_SIZE];
|
||||||
|
const CStack *s = getStack(stackID, false); //this function is called from healedOrResurrected, so our stack can be dead
|
||||||
|
|
||||||
|
std::set<int> occupyable;
|
||||||
|
|
||||||
|
getAccessibilityMap(ac, s->doubleWide(), s->attackerOwned, false, occupyable, s->hasBonusOfType(Bonus::FLYING), stackID);
|
||||||
|
|
||||||
|
if (siege && telportLevel < 2) //check for wall
|
||||||
|
{
|
||||||
|
return ac[destHex] && sameSideOfWall(s->position, destHex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ac[destHex];
|
||||||
|
}
|
||||||
|
|
||||||
return stackLeft != destLeft;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleInfo::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
void BattleInfo::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
||||||
|
@ -212,7 +212,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
|||||||
std::pair<const CStack *, int> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
|
std::pair<const CStack *, int> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
|
||||||
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
|
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
|
||||||
si8 hasDistancePenalty(int stackID, int destHex); //determines if given stack has distance penalty shooting given pos
|
si8 hasDistancePenalty(int stackID, int destHex); //determines if given stack has distance penalty shooting given pos
|
||||||
|
si8 sameSideOfWall(int pos1, int pos2); //determines if given positions are on the same side of wall
|
||||||
si8 hasWallPenalty(int stackID, int destHex); //determines if given stack has wall penalty shooting given pos
|
si8 hasWallPenalty(int stackID, int destHex); //determines if given stack has wall penalty shooting given pos
|
||||||
|
si8 canTeleportTo(int stackID, int destHex, int telportLevel); //determines if given stack can teleport to given place
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT CStack : public CStackInstance
|
class DLL_EXPORT CStack : public CStackInstance
|
||||||
|
@ -906,7 +906,7 @@ struct BattleResult : public CPackForClient//3003
|
|||||||
struct BattleStackMoved : public CPackForClient//3004
|
struct BattleStackMoved : public CPackForClient//3004
|
||||||
{
|
{
|
||||||
ui32 stack, tile;
|
ui32 stack, tile;
|
||||||
ui8 ending, distance;
|
ui8 ending, distance, teleporting;
|
||||||
BattleStackMoved(){type = 3004;};
|
BattleStackMoved(){type = 3004;};
|
||||||
void applyFirstCl(CClient *cl);
|
void applyFirstCl(CClient *cl);
|
||||||
void applyGs(CGameState *gs);
|
void applyGs(CGameState *gs);
|
||||||
|
@ -812,6 +812,7 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
sm.tile = path.first[0];
|
sm.tile = path.first[0];
|
||||||
sm.distance = path.second;
|
sm.distance = path.second;
|
||||||
sm.ending = true;
|
sm.ending = true;
|
||||||
|
sm.teleporting = false;
|
||||||
sendAndApply(&sm);
|
sendAndApply(&sm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,6 +827,7 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
sm.tile = path.first[v];
|
sm.tile = path.first[v];
|
||||||
sm.distance = path.second;
|
sm.distance = path.second;
|
||||||
sm.ending = v==tilesToMove;
|
sm.ending = v==tilesToMove;
|
||||||
|
sm.teleporting = false;
|
||||||
sendAndApply(&sm);
|
sendAndApply(&sm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3666,6 +3668,18 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
|||||||
sendAndApply(&sse);
|
sendAndApply(&sse);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 63: //teleport
|
||||||
|
{
|
||||||
|
BattleStackMoved bsm;
|
||||||
|
bsm.distance = -1;
|
||||||
|
bsm.stack = gs->curB->activeStack;
|
||||||
|
bsm.ending = true;
|
||||||
|
bsm.tile = destination;
|
||||||
|
bsm.teleporting = true;
|
||||||
|
sendAndApply(&bsm);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 37: //cure
|
case 37: //cure
|
||||||
case 38: //resurrection
|
case 38: //resurrection
|
||||||
case 39: //animate dead
|
case 39: //animate dead
|
||||||
@ -3728,7 +3742,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSpell *s = &VLC->spellh->spells[ba.additionalInfo];
|
const CSpell *s = &VLC->spellh->spells[ba.additionalInfo];
|
||||||
ui8 skill = h->getSpellSchoolLevel(s); //skill level
|
ui8 skill = h->getSpellSchoolLevel(s); //skill level
|
||||||
|
|
||||||
if( !(h->canCastThisSpell(s)) //hero cannot cast this spell at all
|
if( !(h->canCastThisSpell(s)) //hero cannot cast this spell at all
|
||||||
|
Reference in New Issue
Block a user