mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* fixed compilation error
* added frenzy spell * repaired order in stack queue in case a unit has waited (it should work correctly now) * added spell positiveness info, positive spells cannot be cast on hostile stacks and vice versa
This commit is contained in:
parent
dbd6f2bc82
commit
99691b0f11
@ -765,7 +765,7 @@ void CResDataBar::deactivate()
|
||||
{
|
||||
ClickableR::deactivate();
|
||||
}
|
||||
CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int datedist)
|
||||
CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist)
|
||||
{
|
||||
bg = BitmapHandler::loadBitmap(defname);
|
||||
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
|
||||
|
@ -435,12 +435,13 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
int yPos = 10;
|
||||
|
||||
std::vector<CStack> stacksSorted;
|
||||
for(int v=0; v<stacks.size(); ++v)
|
||||
{
|
||||
if(stacks[v].alive()) //we don't want dead stacks to be there
|
||||
stacksSorted.push_back(stacks[v]);
|
||||
}
|
||||
std::stable_sort(stacksSorted.begin(), stacksSorted.end(), cmpst2);
|
||||
stacksSorted = LOCPLINT->cb->battleGetStackQueue();
|
||||
//for(int v=0; v<stacks.size(); ++v)
|
||||
//{
|
||||
// if(stacks[v].alive()) //we don't want dead stacks to be there
|
||||
// stacksSorted.push_back(stacks[v]);
|
||||
//}
|
||||
//std::stable_sort(stacksSorted.begin(), stacksSorted.end(), cmpst2);
|
||||
int startFrom = -1;
|
||||
for(int n=0; n<stacksSorted.size(); ++n)
|
||||
{
|
||||
@ -1446,6 +1447,11 @@ void CBattleInterface::spellCasted(SpellCasted * sc)
|
||||
displayEffect(19, sc->tile);
|
||||
break;
|
||||
}
|
||||
case 56: //frenzy
|
||||
{
|
||||
displayEffect(17, sc->tile);
|
||||
break;
|
||||
}
|
||||
case 61: //forgetfulness
|
||||
{
|
||||
displayEffect(42, sc->tile);
|
||||
@ -1470,14 +1476,39 @@ void CBattleInterface::castThisSpell(int spellID)
|
||||
spellSelMode = 0;
|
||||
if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET") != std::string::npos)
|
||||
{
|
||||
switch(CGI->spellh->spells[spellID].positiveness)
|
||||
{
|
||||
case -1 :
|
||||
spellSelMode = 2;
|
||||
break;
|
||||
case 0:
|
||||
spellSelMode = 3;
|
||||
break;
|
||||
case 1:
|
||||
spellSelMode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET_2") != std::string::npos)
|
||||
{
|
||||
if(castingHero && castingHero->getSpellSecLevel(spellID) < 3)
|
||||
spellSelMode = 3;
|
||||
else //TODO: no destination chould apply in this case
|
||||
{
|
||||
switch(CGI->spellh->spells[spellID].positiveness)
|
||||
{
|
||||
case -1 :
|
||||
spellSelMode = 2;
|
||||
break;
|
||||
case 0:
|
||||
spellSelMode = 3;
|
||||
break;
|
||||
case 1:
|
||||
spellSelMode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spellSelMode = -1;
|
||||
}
|
||||
}
|
||||
CGI->curh->changeGraphic(3, 0);
|
||||
|
@ -137,7 +137,7 @@ private:
|
||||
float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
|
||||
|
||||
bool spellDestSelectMode; //if true, player is choosing destination for his spell
|
||||
int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle
|
||||
int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location
|
||||
BattleAction * spellToCast; //spell for which player is choosing destination
|
||||
|
||||
class CAttHelper
|
||||
|
@ -491,6 +491,11 @@ std::map<int, CStack> CCallback::battleGetStacks()
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<CStack> CCallback::battleGetStackQueue()
|
||||
{
|
||||
return gs->curB->getStackQueue();
|
||||
}
|
||||
|
||||
CCreature CCallback::battleGetCreature(int number)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
virtual int battleGetPos(int stack)=0; //returns position (tile ID) of stack
|
||||
virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
virtual std::map<int, CStack> battleGetStacks()=0; //returns stacks on battlefield
|
||||
virtual std::vector<CStack> battleGetStackQueue()=0; //returns vector of stack in order of their move sequence
|
||||
virtual CCreature battleGetCreature(int number)=0; //returns type of creature by given number of stack
|
||||
//virtual bool battleMoveCreature(int ID, int dest)=0; //moves creature with id ID to dest if possible
|
||||
virtual std::vector<int> battleGetAvailableHexes(int ID)=0; //reutrns numbers of hexes reachable by creature with id ID
|
||||
@ -167,6 +168,7 @@ public:
|
||||
int battleGetPos(int stack); //returns position (tile ID) of stack
|
||||
int battleMakeAction(BattleAction* action);//for casting spells by hero - DO NOT use it for moving active stack
|
||||
std::map<int, CStack> battleGetStacks(); //returns stacks on battlefield
|
||||
std::vector<CStack> battleGetStackQueue(); //returns vector of stack in order of their move sequence
|
||||
CCreature battleGetCreature(int number); //returns type of creature by given number of stack
|
||||
std::vector<int> battleGetAvailableHexes(int ID); //reutrns numbers of hexes reachable by creature with id ID
|
||||
bool battleIsStackMine(int ID); //returns true if stack with id ID belongs to caller
|
||||
|
115
CGameState.cpp
115
CGameState.cpp
@ -1500,58 +1500,47 @@ void CGameState::loadTownDInfos()
|
||||
}
|
||||
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
|
||||
{
|
||||
int attackDefenseBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0) - (defender->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0));
|
||||
int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0);
|
||||
if(attacker->getEffect(56)) //frenzy for attacker
|
||||
{
|
||||
attackerAttackBonus += (VLC->spellh->spells[attacker->getEffect(56)->id].powers[attacker->getEffect(56)->level]/100.0) *(attacker->creature->defence + (attackerHero ? attackerHero->getPrimSkillLevel(1) : 0));
|
||||
}
|
||||
int defenderDefenseBonus = defender->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0);
|
||||
if(defender->getEffect(56)) //frenzy for defender
|
||||
{
|
||||
defenderDefenseBonus = 0;
|
||||
}
|
||||
int attackDefenseBonus = attackerAttackBonus - defenderDefenseBonus;
|
||||
if(defender->getEffect(48)) //defender's prayer handling
|
||||
{
|
||||
if(defender->getEffect(48)->level<=1) //none or basic
|
||||
attackDefenseBonus -= 2;
|
||||
else //adv or expert
|
||||
attackDefenseBonus -= 4;
|
||||
attackDefenseBonus -= VLC->spellh->spells[defender->getEffect(48)->id].powers[defender->getEffect(48)->level];
|
||||
}
|
||||
if(attacker->getEffect(48)) //attacker's prayer handling
|
||||
{
|
||||
if(attacker->getEffect(48)->level<=1) //none or basic
|
||||
attackDefenseBonus += 2;
|
||||
else //adv or expert
|
||||
attackDefenseBonus += 4;
|
||||
attackDefenseBonus += VLC->spellh->spells[attacker->getEffect(48)->id].powers[attacker->getEffect(48)->level];
|
||||
}
|
||||
if(defender->getEffect(46)) //stone skin handling
|
||||
{
|
||||
if(defender->getEffect(46)->level<=1) //none or basic
|
||||
attackDefenseBonus -= 3;
|
||||
else //adv or expert
|
||||
attackDefenseBonus -= 6;
|
||||
attackDefenseBonus -= VLC->spellh->spells[defender->getEffect(46)->id].powers[defender->getEffect(46)->level];
|
||||
}
|
||||
if(attacker->getEffect(45)) //weakness handling
|
||||
{
|
||||
if(attacker->getEffect(45)->level<=1) //none or basic
|
||||
attackDefenseBonus -= 3;
|
||||
else //adv or expert
|
||||
attackDefenseBonus -= 6;
|
||||
attackDefenseBonus -= VLC->spellh->spells[attacker->getEffect(45)->id].powers[attacker->getEffect(45)->level];
|
||||
}
|
||||
if(!shooting && attacker->getEffect(43)) //bloodlust handling
|
||||
{
|
||||
if(attacker->getEffect(43)->level<=1) //none or basic
|
||||
attackDefenseBonus += 3;
|
||||
else //adv or expert
|
||||
attackDefenseBonus += 6;
|
||||
attackDefenseBonus += VLC->spellh->spells[attacker->getEffect(43)->id].powers[attacker->getEffect(43)->level];
|
||||
}
|
||||
int damageBase = 0;
|
||||
if(attacker->getEffect(42)) //curse handling (partial, the rest is below)
|
||||
{
|
||||
damageBase = attacker->creature->damageMin;
|
||||
if(attacker->getEffect(42)->level >= 2) //adv or expert
|
||||
{
|
||||
damageBase -= 1;
|
||||
}
|
||||
damageBase -= VLC->spellh->spells[attacker->getEffect(42)->id].powers[attacker->getEffect(42)->level];
|
||||
}
|
||||
else if(attacker->getEffect(41)) //bless handling
|
||||
{
|
||||
damageBase = attacker->creature->damageMax;
|
||||
if(attacker->getEffect(41)->level >= 2) //adv or expert
|
||||
{
|
||||
damageBase += 1;
|
||||
}
|
||||
damageBase += VLC->spellh->spells[attacker->getEffect(41)->id].powers[attacker->getEffect(41)->level];
|
||||
}
|
||||
else if(attacker->creature->damageMax == attacker->creature->damageMin) //constant damage
|
||||
{
|
||||
@ -1699,3 +1688,71 @@ CStack * BattleInfo::getNextStack()
|
||||
}
|
||||
return NULL; //all stacks moved or defending!
|
||||
}
|
||||
|
||||
std::vector<CStack> BattleInfo::getStackQueue()
|
||||
{
|
||||
std::vector<CStack> ret;
|
||||
std::vector<int> taken; //if non-zero value, corresponding stack has been placed in ret
|
||||
taken.resize(stacks.size());
|
||||
for(int g=0; g<taken.size(); ++g)
|
||||
{
|
||||
taken[g] = 0;
|
||||
}
|
||||
|
||||
for(int moved=0; moved<2; ++moved) //in first cycle we add stacks that can act in current turn, in second one the rest of them
|
||||
{
|
||||
for(int gc=0; gc<stacks.size(); ++gc)
|
||||
{
|
||||
int id = -1, speed = -1;
|
||||
for(int i=0; i<stacks.size(); ++i) //find not waited stacks only
|
||||
{
|
||||
if((moved == 1 ||!vstd::contains(stacks[i]->state,DEFENDING))
|
||||
&& stacks[i]->alive()
|
||||
&& (moved == 1 || !vstd::contains(stacks[i]->state,MOVED))
|
||||
&& !vstd::contains(stacks[i]->state,WAITING)
|
||||
&& taken[i]==0)
|
||||
{
|
||||
if(speed == -1 || stacks[i]->speed() > speed)
|
||||
{
|
||||
id = i;
|
||||
speed = stacks[i]->speed();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(id != -1)
|
||||
{
|
||||
ret.push_back(*stacks[id]);
|
||||
taken[id] = 1;
|
||||
}
|
||||
else //choose something from not moved stacks
|
||||
{
|
||||
int id = -1, speed = 10000; //infinite speed
|
||||
for(int i=0; i<stacks.size(); ++i) //find waited stacks only
|
||||
{
|
||||
if((moved == 1 ||!vstd::contains(stacks[i]->state,DEFENDING))
|
||||
&& stacks[i]->alive()
|
||||
&& (moved == 1 || !vstd::contains(stacks[i]->state,MOVED))
|
||||
&& vstd::contains(stacks[i]->state,WAITING)
|
||||
&& taken[i]==0)
|
||||
{
|
||||
if(stacks[i]->speed() < speed) //slowest one
|
||||
{
|
||||
id = i;
|
||||
speed = stacks[i]->speed();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(id != -1)
|
||||
{
|
||||
ret.push_back(*stacks[id]);
|
||||
taken[id] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; //no stacks have been found, so none of them will be found in next iterations
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ struct DLL_EXPORT BattleInfo
|
||||
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
|
||||
}
|
||||
CStack * getNextStack(); //which stack will have turn after current one
|
||||
std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
|
||||
CStack * getStack(int stackID);
|
||||
CStack * getStackT(int tileID);
|
||||
void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
|
||||
|
73
config/spell_info.txt
Normal file
73
config/spell_info.txt
Normal file
@ -0,0 +1,73 @@
|
||||
//additional spell info, not included in original heroes III files
|
||||
//[spellID - -1 is the end of data in file] [-1 -> spell is negative for influenced creatures; 0 - spell is indifferent for them; 1 - spell is poitive for them]
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
8 0
|
||||
9 0
|
||||
10 0
|
||||
11 0
|
||||
12 0
|
||||
13 0
|
||||
14 0
|
||||
15 -1
|
||||
16 -1
|
||||
17 -1
|
||||
18 -1
|
||||
19 -1
|
||||
20 -1
|
||||
21 -1
|
||||
22 -1
|
||||
23 -1
|
||||
24 -1
|
||||
25 -1
|
||||
26 -1
|
||||
27 1
|
||||
28 1
|
||||
29 1
|
||||
30 1
|
||||
31 1
|
||||
32 1
|
||||
33 1
|
||||
34 1
|
||||
35 1
|
||||
36 1
|
||||
37 1
|
||||
38 1
|
||||
39 1
|
||||
40 1
|
||||
41 1
|
||||
42 -1
|
||||
43 1
|
||||
44 1
|
||||
45 -1
|
||||
46 1
|
||||
47 -1
|
||||
48 1
|
||||
49 1
|
||||
50 -1
|
||||
51 1
|
||||
52 -1
|
||||
53 1
|
||||
54 -1
|
||||
55 1
|
||||
56 1
|
||||
57 -1
|
||||
58 1
|
||||
59 -1
|
||||
60 -1
|
||||
61 -1
|
||||
62 -1
|
||||
63 1
|
||||
64 0
|
||||
65 1
|
||||
66 0
|
||||
67 0
|
||||
68 0
|
||||
69 0
|
||||
-1
|
@ -79,4 +79,27 @@ void CSpellHandler::loadSpells()
|
||||
nsp.creatureAbility = creatureAbility;
|
||||
spells.push_back(nsp);
|
||||
}
|
||||
//loading of additional spell traits
|
||||
std::ifstream ast;
|
||||
ast.open("config/spell_info.txt", std::ios::binary);
|
||||
if(!ast.is_open())
|
||||
{
|
||||
tlog1<<"lack of config/spell_info.txt file!"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
//reading header
|
||||
std::string dump;
|
||||
for(int i=0; i<42; ++i) ast>>dump;
|
||||
//reading exact info
|
||||
int spellID;
|
||||
ast>>spellID;
|
||||
while(spellID != -1)
|
||||
{
|
||||
int buf;
|
||||
ast>>buf;
|
||||
spells[spellID].positiveness = buf;
|
||||
ast>>spellID;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ public:
|
||||
std::string attributes; //reference only attributes
|
||||
bool combatSpell; //is this spell combat (true) or adventure (false)
|
||||
bool creatureAbility; //if true, only creatures can use this spell
|
||||
si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative
|
||||
};
|
||||
|
||||
class DLL_EXPORT CSpellHandler
|
||||
|
@ -1400,6 +1400,16 @@ upgend:
|
||||
sendAndApply(&sse);
|
||||
break;
|
||||
}
|
||||
case 56: //frenzy
|
||||
{
|
||||
SetStackEffect sse;
|
||||
sse.stack = gs->curB->getStackT(ba.destinationTile)->ID;
|
||||
sse.effect.id = 56;
|
||||
sse.effect.level = getSchoolLevel(h,s);
|
||||
sse.effect.turnsRemain = 1; //! - different duration
|
||||
sendAndApply(&sse);
|
||||
break;
|
||||
}
|
||||
case 61: //forgetfulness
|
||||
{
|
||||
SetStackEffect sse;
|
||||
|
Loading…
Reference in New Issue
Block a user