mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* fixed crash when AI attacked player before his first turn * fixed various crashes when mass-effect spells affected town turrets in sieges * some refactoring around spell positiveness
This commit is contained in:
parent
0c3e88226f
commit
4baf4e13ed
@ -949,7 +949,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
const CSpell * spell = CGI->spellh->spells[creatureSpellToCast];
|
||||
if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(myNumber)) == ESpellCastProblem::OK)
|
||||
{
|
||||
if ((spell->positiveness > -1 && ourStack) || (spell->positiveness < 1 && !ourStack))
|
||||
if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
|
||||
{
|
||||
CCS->curh->changeGraphic(3, 0);
|
||||
stackCastsSpell = true;
|
||||
@ -1788,7 +1788,7 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
const CSpell * spell = CGI->spellh->spells[creatureSpellToCast];
|
||||
if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(whichOne)) == ESpellCastProblem::OK)
|
||||
{
|
||||
if ((spell->positiveness > -1 && ourStack) || (spell->positiveness < 1 && !ourStack))
|
||||
if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
|
||||
{
|
||||
giveCommand(BattleAction::MONSTER_SPELL, whichOne, actSt->ID, creatureSpellToCast);
|
||||
spellCast = true;
|
||||
@ -2371,40 +2371,14 @@ void CBattleInterface::castThisSpell(int spellID)
|
||||
spellSelMode = ANY_LOCATION;
|
||||
if(spell.getTargetType() == CSpell::CREATURE)
|
||||
{
|
||||
switch(spell.positiveness)
|
||||
{
|
||||
case -1 :
|
||||
spellSelMode = HOSTILE_CREATURE;
|
||||
break;
|
||||
case 0:
|
||||
spellSelMode = ANY_CREATURE;
|
||||
break;
|
||||
case 1:
|
||||
spellSelMode = FRIENDLY_CREATURE;
|
||||
break;
|
||||
}
|
||||
spellSelMode = selectionTypeByPositiveness(spell);
|
||||
}
|
||||
if(spell.getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE)
|
||||
{
|
||||
if(castingHero && castingHero->getSpellSchoolLevel(&spell) < 3)
|
||||
{
|
||||
switch(spell.positiveness)
|
||||
{
|
||||
case -1 :
|
||||
spellSelMode = HOSTILE_CREATURE;
|
||||
break;
|
||||
case 0:
|
||||
spellSelMode = ANY_CREATURE;
|
||||
break;
|
||||
case 1:
|
||||
spellSelMode = FRIENDLY_CREATURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spellSelMode = selectionTypeByPositiveness(spell);
|
||||
else
|
||||
{
|
||||
spellSelMode = NO_LOCATION;
|
||||
}
|
||||
}
|
||||
if(spell.getTargetType() == CSpell::OBSTACLE)
|
||||
{
|
||||
@ -3088,6 +3062,19 @@ void CBattleInterface::bTacticNextStack()
|
||||
stackActivated(stacksOfMine.front());
|
||||
}
|
||||
|
||||
CBattleInterface::SpellSelectionType CBattleInterface::selectionTypeByPositiveness(const CSpell & spell)
|
||||
{
|
||||
switch(spell.positiveness)
|
||||
{
|
||||
case CSpell::NEGATIVE :
|
||||
return HOSTILE_CREATURE;
|
||||
case CSpell::NEUTRAL:
|
||||
return ANY_CREATURE;
|
||||
case CSpell::POSITIVE:
|
||||
return FRIENDLY_CREATURE;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CBattleInterface::SiegeHelper::townTypeInfixes[GameConstants::F_NUMBER] = {"CS", "RM", "TW", "IN", "NC", "DN", "ST", "FR", "EL"};
|
||||
|
||||
CBattleInterface::SiegeHelper::SiegeHelper(const CGTownInstance *siegeTown, const CBattleInterface * _owner)
|
||||
|
@ -246,7 +246,8 @@ public:
|
||||
void endAction(const BattleAction* action);
|
||||
void hideQueue();
|
||||
void showQueue();
|
||||
|
||||
SpellSelectionType selectionTypeByPositiveness(const CSpell & spell);
|
||||
|
||||
|
||||
friend class CPlayerInterface;
|
||||
friend class CAdventureMapButton;
|
||||
|
@ -157,12 +157,6 @@ void CPlayerInterface::yourTurn()
|
||||
|
||||
autosaveCount = getLastIndex("Autosave_");
|
||||
|
||||
if(!GH.listInt.size())
|
||||
{
|
||||
GH.pushInt(adventureInt);
|
||||
adventureInt->activateKeys();
|
||||
}
|
||||
|
||||
if(firstCall > 0) //new game, not loaded
|
||||
{
|
||||
int index = getLastIndex("Newgame_Autosave_");
|
||||
@ -224,6 +218,7 @@ STRONG_INLINE void delObjRect(const int & x, const int & y, const int & z, const
|
||||
}
|
||||
void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
{
|
||||
waitWhileDialog();
|
||||
if(LOCPLINT != this)
|
||||
return;
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
@ -2345,8 +2340,24 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
|
||||
|
||||
void CPlayerInterface::playerStartsTurn(ui8 player)
|
||||
{
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
if(!GH.listInt.size())
|
||||
{
|
||||
GH.pushInt(adventureInt);
|
||||
adventureInt->activateKeys();
|
||||
}
|
||||
if(howManyPeople == 1)
|
||||
{
|
||||
GH.curInt = this;
|
||||
adventureInt->startTurn();
|
||||
}
|
||||
}
|
||||
if(player != playerID && this == LOCPLINT)
|
||||
{
|
||||
waitWhileDialog();
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
|
||||
adventureInt->minimap.redraw();
|
||||
adventureInt->infoBar.enemyTurn(player, 0.5);
|
||||
|
||||
|
@ -1,136 +1,247 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CAdvmapInterface.cpp" />
|
||||
<ClCompile Include="CAnimation.cpp" />
|
||||
<ClCompile Include="..\CCallback.cpp" />
|
||||
<ClCompile Include="CBitmapHandler.cpp" />
|
||||
<ClCompile Include="CCastleInterface.cpp" />
|
||||
<ClCompile Include="CConfigHandler.cpp" />
|
||||
<ClCompile Include="CCreatureWindow.cpp" />
|
||||
<ClCompile Include="CDefHandler.cpp" />
|
||||
<ClCompile Include="CGameInfo.cpp" />
|
||||
<ClCompile Include="CHeroWindow.cpp" />
|
||||
<ClCompile Include="CKingdomInterface.cpp" />
|
||||
<ClCompile Include="Client.cpp" />
|
||||
<ClCompile Include="CMessage.cpp" />
|
||||
<ClCompile Include="CMT.cpp" />
|
||||
<ClCompile Include="CMusicHandler.cpp" />
|
||||
<ClCompile Include="CPlayerInterface.cpp" />
|
||||
<ClCompile Include="CPreGame.cpp" />
|
||||
<ClCompile Include="CSndHandler.cpp" />
|
||||
<ClCompile Include="CSpellWindow.cpp" />
|
||||
<ClCompile Include="CVideoHandler.cpp" />
|
||||
<ClCompile Include="Graphics.cpp" />
|
||||
<ClCompile Include="GUIClasses.cpp" />
|
||||
<ClCompile Include="mapHandler.cpp" />
|
||||
<ClCompile Include="NetPacksClient.cpp" />
|
||||
<ClCompile Include="StdInc.cpp" />
|
||||
<ClCompile Include="UIFramework\CCursorHandler.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CAdvmapInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CGuiHandler.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClCompile Include="CBitmapHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CIntObject.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClCompile Include="..\CCallback.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CIntObjectClasses.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClCompile Include="CCastleInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\Geometries.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClCompile Include="CConfigHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\SDL_Extensions.cpp">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClCompile Include="CGameInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CHeroWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CKingdomInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Client.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CMessage.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CMT.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CPlayerInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CPreGame.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CSpellWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Graphics.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GUIClasses.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NetPacksClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mapHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAnimation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDefHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CMusicHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CSndHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CVideoHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CCreatureWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BattleInterface\CBattleAnimations.cpp">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BattleInterface\CBattleInterface.cpp">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BattleInterface\CBattleInterfaceClasses.cpp">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BattleInterface\CCreatureAnimation.cpp">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StdInc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CCursorHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CGuiHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CIntObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\CIntObjectClasses.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\Geometries.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UIFramework\SDL_Extensions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CAdvmapInterface.h" />
|
||||
<ClInclude Include="CAnimation.h" />
|
||||
<ClInclude Include="CBitmapHandler.h" />
|
||||
<ClInclude Include="..\CCallback.h" />
|
||||
<ClInclude Include="CCastleInterface.h" />
|
||||
<ClInclude Include="CConfigHandler.h" />
|
||||
<ClInclude Include="CCreatureWindow.h" />
|
||||
<ClInclude Include="CDefHandler.h" />
|
||||
<ClInclude Include="CGameInfo.h" />
|
||||
<ClInclude Include="CHeroWindow.h" />
|
||||
<ClInclude Include="CKingdomInterface.h" />
|
||||
<ClInclude Include="Client.h" />
|
||||
<ClInclude Include="CMessage.h" />
|
||||
<ClInclude Include="CMusicBase.h" />
|
||||
<ClInclude Include="CMusicHandler.h" />
|
||||
<ClInclude Include="CPlayerInterface.h" />
|
||||
<ClInclude Include="CPreGame.h" />
|
||||
<ClInclude Include="CSndHandler.h" />
|
||||
<ClInclude Include="CSoundBase.h" />
|
||||
<ClInclude Include="CSpellWindow.h" />
|
||||
<ClInclude Include="CVideoHandler.h" />
|
||||
<ClInclude Include="FontBase.h" />
|
||||
<ClInclude Include="FunctionList.h" />
|
||||
<ClInclude Include="Graphics.h" />
|
||||
<ClInclude Include="GUIClasses.h" />
|
||||
<ClInclude Include="mapHandler.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="StdInc.h" />
|
||||
<ClInclude Include="..\Global.h" />
|
||||
<ClInclude Include="UIFramework\CCursorHandler.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="CAdvmapInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CGuiHandler.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="CBitmapHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CIntObject.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="..\CCallback.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CIntObjectClasses.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="CCastleInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\Geometries.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="CConfigHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\SDL_Extensions.h">
|
||||
<Filter>UIFramework</Filter>
|
||||
<ClInclude Include="CGameInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CHeroWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CKingdomInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Client.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CMessage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CPlayerInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CPreGame.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CSpellWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FontBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FunctionList.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\global.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Graphics.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GUIClasses.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mapHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CAnimation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CDefHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CMusicBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CMusicHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CSndHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CSoundBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CVideoHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CCreatureWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BattleInterface\CBattleAnimations.h">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BattleInterface\CBattleInterface.h">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BattleInterface\CBattleInterfaceClasses.h">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BattleInterface\CCreatureAnimation.h">
|
||||
<Filter>BattleInterface</Filter>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StdInc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CCursorHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CGuiHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CIntObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\CIntObjectClasses.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\Geometries.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UIFramework\SDL_Extensions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="VCMI_client.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\ChangeLog" />
|
||||
<None Include="vcmi.ico" />
|
||||
<None Include="ClassDiagram21.cd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="BattleInterface">
|
||||
<UniqueIdentifier>{3b4624b5-80f2-4bd8-b4c0-af29d3be4b58}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="UIFramework">
|
||||
<UniqueIdentifier>{918a73d4-7386-4d29-9515-a3579051d4ac}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<ResourceCompile Include="VCMI_client.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -728,16 +728,16 @@ std::set<CStack*> BattleInfo::getAttackedCreatures(const CSpell * s, int skillLe
|
||||
|
||||
bool onlyAlive = s->id != 38 && s->id != 39; //when casting resurrection or animate dead we should be allow to select dead stack
|
||||
|
||||
if(s->id == 24 || s->id == 25 || s->id == 26) //death ripple, destroy undead and Armageddon
|
||||
if(s->id == Spells::DEATH_RIPPLE || s->id == Spells::DESTROY_UNDEAD || s->id == Spells::ARMAGEDDON)
|
||||
{
|
||||
for(int it=0; it<stacks.size(); ++it)
|
||||
{
|
||||
if((s->id == 24 && !stacks[it]->getCreature()->isUndead()) //death ripple
|
||||
|| (s->id == 25 && stacks[it]->getCreature()->isUndead()) //destroy undead
|
||||
|| (s->id == 26) //Armageddon
|
||||
if((s->id == Spells::DEATH_RIPPLE && !stacks[it]->getCreature()->isUndead()) //death ripple
|
||||
|| (s->id == Spells::DESTROY_UNDEAD && stacks[it]->getCreature()->isUndead()) //destroy undead
|
||||
|| (s->id == Spells::ARMAGEDDON) //Armageddon
|
||||
)
|
||||
{
|
||||
if(stacks[it]->alive())
|
||||
if(stacks[it]->isValidTarget())
|
||||
attackedCres.insert(stacks[it]);
|
||||
}
|
||||
}
|
||||
@ -774,11 +774,11 @@ std::set<CStack*> BattleInfo::getAttackedCreatures(const CSpell * s, int skillLe
|
||||
for(int it=0; it<stacks.size(); ++it)
|
||||
{
|
||||
/*if it's non negative spell and our unit or non positive spell and hostile unit */
|
||||
if((s->positiveness >= 0 && stacks[it]->owner == attackerOwner)
|
||||
||(s->positiveness <= 0 && stacks[it]->owner != attackerOwner )
|
||||
if((!s->isNegative() && stacks[it]->owner == attackerOwner)
|
||||
||(!s->isPositive() && stacks[it]->owner != attackerOwner )
|
||||
)
|
||||
{
|
||||
if(!onlyAlive || stacks[it]->alive())
|
||||
if(stacks[it]->isValidTarget(!onlyAlive))
|
||||
attackedCres.insert(stacks[it]);
|
||||
}
|
||||
}
|
||||
@ -1889,7 +1889,7 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int pla
|
||||
{
|
||||
switch (spell->positiveness)
|
||||
{
|
||||
case 1:
|
||||
case CSpell::POSITIVE:
|
||||
if(stack->owner == caster->getOwner())
|
||||
{
|
||||
if(battleIsImmune(caster, spell, mode, stack->position) == ESpellCastProblem::OK)
|
||||
@ -1899,14 +1899,14 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int pla
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case CSpell::NEUTRAL:
|
||||
if(battleIsImmune(caster, spell, mode, stack->position) == ESpellCastProblem::OK)
|
||||
{
|
||||
targetExists = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
case CSpell::NEGATIVE:
|
||||
if(stack->owner != caster->getOwner())
|
||||
{
|
||||
if(battleIsImmune(caster, spell, mode, stack->position) == ESpellCastProblem::OK)
|
||||
@ -1950,7 +1950,7 @@ TSpell BattleInfo::getRandomBeneficialSpell(const CStack * subject) const
|
||||
for (int i = 0; i < GameConstants::SPELLS_QUANTITY; ++i) //should not use future spells added by mods
|
||||
{
|
||||
spell = VLC->spellh->spells[i];
|
||||
if (spell->positiveness == 1) //only positive
|
||||
if (spell->isPositive()) //only positive
|
||||
{
|
||||
if (subject->hasBonusFrom(Bonus::SPELL_EFFECT, i) ||
|
||||
battleCanCastThisSpellHere(subject->owner, spell, ECastingMode::CREATURE_ACTIVE_CASTING, subject->position) != ESpellCastProblem::OK)
|
||||
@ -2080,12 +2080,12 @@ bool NegateRemover(const Bonus* b)
|
||||
|
||||
bool BattleInfo::battleTestElementalImmunity(const CStack * subject, const CSpell * spell, Bonus::BonusType element, bool damageSpell) const //helper for battleisImmune
|
||||
{
|
||||
if (spell->positiveness < 1) //negative or indifferent
|
||||
if (!spell->isPositive()) //negative or indifferent
|
||||
{
|
||||
if ((damageSpell && subject->hasBonusOfType(element, 2)) || subject->hasBonusOfType(element, 1))
|
||||
return true;
|
||||
}
|
||||
else if (spell->positiveness == 1) //positive
|
||||
else if (spell->isPositive()) //positive
|
||||
{
|
||||
if (subject->hasBonusOfType(element, 0)) //must be immune to all spells
|
||||
return true;
|
||||
@ -2098,7 +2098,7 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInst
|
||||
const CStack * subject = getStackT(dest, false);
|
||||
if(subject)
|
||||
{
|
||||
if (spell->positiveness == 1 && subject->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells
|
||||
if (spell->isPositive() && subject->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells
|
||||
return ESpellCastProblem::OK;
|
||||
|
||||
switch (spell->id) //TODO: more general logic for new spells?
|
||||
@ -2132,7 +2132,7 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInst
|
||||
bool hasPositiveSpell = false;
|
||||
BOOST_FOREACH(const Bonus * b, *spellBon)
|
||||
{
|
||||
if(VLC->spellh->spells[b->sid]->positiveness > 0)
|
||||
if(VLC->spellh->spells[b->sid]->isPositive())
|
||||
{
|
||||
hasPositiveSpell = true;
|
||||
break;
|
||||
@ -2220,7 +2220,7 @@ std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const C
|
||||
}
|
||||
|
||||
//non-negative spells on friendly stacks should always succeed, unless immune
|
||||
if(sp->positiveness >= 0 && (*it)->owner == casterSideOwner)
|
||||
if(!sp->isNegative() && (*it)->owner == casterSideOwner)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -2811,6 +2811,11 @@ std::string CStack::getName() const
|
||||
return (count > 1) ? type->namePl : type->nameSing; //War machines can't use base
|
||||
}
|
||||
|
||||
bool CStack::isValidTarget(bool allowDead/* = false*/) const /*alive non-turret stacks (can be attacked or be object of magic effect) */
|
||||
{
|
||||
return (alive() || allowDead) && position.isValid();
|
||||
}
|
||||
|
||||
bool CMP_stack::operator()( const CStack* a, const CStack* b )
|
||||
{
|
||||
switch(phase)
|
||||
|
@ -250,6 +250,7 @@ public:
|
||||
{
|
||||
return vstd::contains(state,EBattleStackState::ALIVE);
|
||||
}
|
||||
bool isValidTarget(bool allowDead = false) const; //alive non-turret stacks (can be attacked or be object of magic effect)
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CMP_stack
|
||||
|
@ -205,6 +205,16 @@ CSpell::ETargetType CSpell::getTargetType() const
|
||||
return NO_TARGET;
|
||||
}
|
||||
|
||||
bool CSpell::isPositive() const
|
||||
{
|
||||
return positiveness == POSITIVE;
|
||||
}
|
||||
|
||||
bool CSpell::isNegative() const
|
||||
{
|
||||
return positiveness == NEGATIVE;
|
||||
}
|
||||
|
||||
static bool startsWithX(const std::string &s)
|
||||
{
|
||||
return s.size() && s[0] == 'x';
|
||||
|
@ -18,6 +18,7 @@ class DLL_LINKAGE CSpell
|
||||
{
|
||||
public:
|
||||
enum ETargetType {NO_TARGET, CREATURE, CREATURE_EXPERT_MASSIVE, OBSTACLE};
|
||||
enum ESpellPositiveness {NEGATIVE = -1, NEUTRAL = 0, POSITIVE = 1};
|
||||
ui32 id;
|
||||
std::string name;
|
||||
std::string abbName; //abbreviated name
|
||||
@ -41,6 +42,9 @@ public:
|
||||
si16 mainEffectAnim; //main spell effect animation, in AC format (or -1 when none)
|
||||
ETargetType getTargetType() const;
|
||||
|
||||
bool isPositive() const;
|
||||
bool isNegative() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs
|
||||
|
@ -1030,7 +1030,7 @@ namespace Selector
|
||||
if(b->source == Bonus::SPELL_EFFECT)
|
||||
{
|
||||
CSpell *sp = VLC->spellh->spells[b->sid];
|
||||
return sp->positiveness == 1;
|
||||
return sp->isPositive();
|
||||
}
|
||||
return false; //not a spell effect
|
||||
}
|
||||
|
@ -1209,7 +1209,7 @@ DLL_LINKAGE void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
BOOST_FOREACH(Bonus *b, tmpFeatures)
|
||||
{
|
||||
const CSpell *s = b->sourceSpell();
|
||||
if(s && s->positiveness < 0)
|
||||
if(s && s->isNegative())
|
||||
{
|
||||
changedStack->removeBonus(b);
|
||||
}
|
||||
|
@ -3579,10 +3579,10 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
BOOST_FOREACH (CStack * stack, gs->curB->stacks)
|
||||
{
|
||||
/*if it's non negative spell and our unit or non positive spell and hostile unit */
|
||||
if((spell->positiveness >= 0 && stack->owner == casterColor)
|
||||
||(spell->positiveness <= 0 && stack->owner != casterColor ))
|
||||
if((!spell->isNegative() && stack->owner == casterColor)
|
||||
|| (!spell->isPositive() && stack->owner != casterColor))
|
||||
{
|
||||
if(stack->alive()) //TODO: allow dead targets somewhere in the future
|
||||
if(stack->isValidTarget()) //TODO: allow dead targets somewhere in the future
|
||||
attackedCres.insert(stack);
|
||||
}
|
||||
}
|
||||
@ -3967,7 +3967,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
|
||||
}
|
||||
|
||||
//Magic Mirror effect
|
||||
if (spell->positiveness < 0 && mode != ECastingMode::MAGIC_MIRROR && spell->level && spell->range[0] == "0") //it is actual spell and can be reflected to single target, no recurrence
|
||||
if (spell->isNegative() && mode != ECastingMode::MAGIC_MIRROR && spell->level && spell->range[0] == "0") //it is actual spell and can be reflected to single target, no recurrence
|
||||
{
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
@ -5376,7 +5376,7 @@ void CGameHandler::runBattle()
|
||||
|
||||
for(int g=0; g<gs->curB->stacks.size(); ++g)
|
||||
{
|
||||
if(gs->curB->stacks[g]->owner != next->owner && gs->curB->stacks[g]->alive())
|
||||
if(gs->curB->stacks[g]->owner != next->owner && gs->curB->stacks[g]->isValidTarget())
|
||||
{
|
||||
attack.destinationTile = gs->curB->stacks[g]->position;
|
||||
break;
|
||||
@ -5412,7 +5412,7 @@ void CGameHandler::runBattle()
|
||||
for (int v=0; v<gs->curB->stacks.size(); ++v)
|
||||
{
|
||||
const CStack * cstack = gs->curB->stacks[v];
|
||||
if (cstack->owner == next->owner && cstack->firstHPleft < cstack->MaxHealth() && cstack->alive()) //it's friendly and not fully healthy
|
||||
if (cstack->owner == next->owner && cstack->firstHPleft < cstack->MaxHealth() && cstack->isValidTarget()) //it's friendly and not fully healthy
|
||||
{
|
||||
if (cstack->hasBonusOfType(Bonus::SIEGE_WEAPON))
|
||||
secondPriority.push_back(cstack);
|
||||
|
Loading…
Reference in New Issue
Block a user