mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
* started making morale/luck system
* basic calculation of hero/stack morale * displaying morale in hero window * redone checking if attack is possible (should fix some problems with attacking with 2-hex creatures, at least on server side) * std::list serialization * version set to 0.7b
This commit is contained in:
parent
124e768a99
commit
680993459a
@ -583,6 +583,13 @@ void CGameState::applyNL(IPack * pack)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 115:
|
||||
{
|
||||
GiveBonus *rh = static_cast<GiveBonus*>(pack);
|
||||
CGHeroInstance *h = getHero(rh->hid);
|
||||
h->bonuses.push_back(CGHeroInstance::Bonus(rh->bduration,rh->btype,rh->bval,rh->bid,toString(rh->bdescr)));
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject *rh = static_cast<RemoveObject*>(pack);
|
||||
|
@ -101,6 +101,12 @@ CHeroWindow::CHeroWindow(int playerColor):
|
||||
expArea->pos.h = 42;
|
||||
expArea->hoverText = CGI->generaltexth->heroscrn[9];
|
||||
|
||||
morale = new LRClickableAreaWTextComp();
|
||||
morale->pos = genRect(45,53,pos.x+240,pos.y+187);
|
||||
|
||||
luck = new LRClickableAreaWTextComp();
|
||||
luck->pos = genRect(45,53,pos.x+298,pos.y+187);
|
||||
|
||||
spellPointsArea = new LRClickableAreaWText();
|
||||
spellPointsArea->pos.x = pos.x+227;
|
||||
spellPointsArea->pos.y = pos.y + 236;
|
||||
@ -161,6 +167,8 @@ CHeroWindow::~CHeroWindow()
|
||||
|
||||
delete portraitArea;
|
||||
delete expArea;
|
||||
delete luck;
|
||||
delete morale;
|
||||
delete spellPointsArea;
|
||||
for(size_t v=0; v<primSkillAreas.size(); ++v)
|
||||
{
|
||||
@ -339,6 +347,18 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
formations->select(hero->army.formation,true);
|
||||
formations->onChange = boost::bind(&CCallback::setFormation, LOCPLINT->cb, Hero, _1);
|
||||
|
||||
std::vector<std::pair<int,std::string> > mrl = hero->getCurrentMoraleModifiers();
|
||||
int mrlv = hero->getCurrentMorale();
|
||||
int mrlt = (mrlv>0)-(mrlv<0); //signum: -1 - bad morale, 0 - neutral, 1 - good
|
||||
morale->hoverText = CGI->generaltexth->heroscrn[4 - mrlt];
|
||||
morale->baseType = SComponent::morale;
|
||||
morale->bonus = mrlv;
|
||||
morale->text = CGI->generaltexth->arraytxt[88];
|
||||
boost::algorithm::replace_first(morale->text,"%s",CGI->generaltexth->arraytxt[86-mrlt]);
|
||||
for(int it=0; it < mrl.size(); it++)
|
||||
morale->text += mrl[it].second;
|
||||
|
||||
|
||||
pos.x += 65;
|
||||
pos.y += 8;
|
||||
|
||||
@ -385,6 +405,8 @@ void CHeroWindow::activate()
|
||||
portraitArea->activate();
|
||||
expArea->activate();
|
||||
spellPointsArea->activate();
|
||||
morale->activate();
|
||||
luck->activate();
|
||||
|
||||
garInt->activate();
|
||||
LOCPLINT->statusbar = ourBar;
|
||||
@ -430,6 +452,8 @@ void CHeroWindow::deactivate()
|
||||
portraitArea->deactivate();
|
||||
expArea->deactivate();
|
||||
spellPointsArea->deactivate();
|
||||
morale->activate();
|
||||
luck->activate();
|
||||
|
||||
garInt->deactivate();
|
||||
|
||||
@ -830,10 +854,6 @@ void LClickableArea::clickLeft(boost::logic::tribool down)
|
||||
//{
|
||||
// LOCPLINT->showInfoDialog("TEST TEST AAA", std::vector<SComponent*>());
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RClickableArea::activate()
|
||||
@ -850,10 +870,6 @@ void RClickableArea::clickRight(boost::logic::tribool down)
|
||||
//{
|
||||
// LOCPLINT->showInfoDialog("TEST TEST AAA", std::vector<SComponent*>());
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LRClickableAreaWText::clickLeft(boost::logic::tribool down)
|
||||
|
@ -105,6 +105,8 @@ class CHeroWindow: public IShowActivable, public virtual CIntObject
|
||||
std::vector<LRClickableAreaWTextComp *> primSkillAreas;
|
||||
LRClickableAreaWText * expArea;
|
||||
LRClickableAreaWText * spellPointsArea;
|
||||
LRClickableAreaWTextComp * luck;
|
||||
LRClickableAreaWTextComp * morale;
|
||||
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
|
||||
public:
|
||||
AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
|
||||
|
@ -168,7 +168,7 @@ void CGarrisonSlot::clickRight (tribool down)
|
||||
pom->attackBonus = h->getPrimSkillLevel(0);
|
||||
pom->defenseBonus = h->getPrimSkillLevel(1);
|
||||
pom->luck = h->getCurrentLuck();
|
||||
pom->morale = h->getCurrentMorale();
|
||||
pom->morale = h->getCurrentMorale(ID);
|
||||
}
|
||||
(new CCreInfoWindow(creature->idNumber,0,count,pom,boost::function<void()>(),boost::function<void()>(),NULL))
|
||||
->activate();
|
||||
@ -723,6 +723,9 @@ SDL_Surface * SComponent::getImg()
|
||||
case experience:
|
||||
return graphics->pskillsb->ourImages[4].bitmap;
|
||||
break;
|
||||
case morale:
|
||||
return graphics->morale82->ourImages[val+3].bitmap;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1197,7 +1200,14 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
|
||||
adventureInt->centerOn(details.ho->pos); //centering screen on hero
|
||||
int3 buff = details.ho->pos;
|
||||
buff.x-=11;
|
||||
buff.y-=9;
|
||||
buff = repairScreenPos(buff);
|
||||
LOCPLINT->adventureInt->position = buff; //actualizing screen pos
|
||||
|
||||
if(adventureInt == curint)
|
||||
adventureInt->minimap.draw();
|
||||
|
||||
if(details.style>0)
|
||||
return;
|
||||
|
@ -224,7 +224,7 @@ class SComponent : public ClickableR
|
||||
public:
|
||||
enum Etype
|
||||
{
|
||||
primskill, secskill, resource, creature, artifact, experience, secskill44, spell
|
||||
primskill, secskill, resource, creature, artifact, experience, secskill44, spell, morale, luck
|
||||
} type;
|
||||
int subtype;
|
||||
int val;
|
||||
|
18
CPreGame.cpp
18
CPreGame.cpp
@ -839,6 +839,7 @@ int MapSel::countWL()
|
||||
void MapSel::printMaps(int from, int to, int at, bool abs)
|
||||
{
|
||||
if (!slid->positionsAmnt) return; //no maps to print
|
||||
slid->capacity = (CPG->fromnewgame == 2 ? 16 : 18);
|
||||
if(slid->positionsAmnt < slid->capacity)
|
||||
from = 0;
|
||||
int help=-1;
|
||||
@ -928,7 +929,7 @@ void MapSel::printMaps(int from, int to, int at, bool abs)
|
||||
else
|
||||
tlog2 << "Warning: " << curVector()[(i-at)+from].filename << " has wrong version!\n";
|
||||
|
||||
if(CPG->fromnewgame)
|
||||
if(CPG->fromnewgame == 1)
|
||||
{
|
||||
if (!(curVector()[(i-at)+from].name.length()))
|
||||
curVector()[(i-at)+from].name = "Unnamed";
|
||||
@ -998,7 +999,7 @@ void MapSel::show()
|
||||
//blit bg
|
||||
blitAt(bg,3,6);
|
||||
CSDL_Ext::printAt("Map Sizes",55,60,GEOR13);
|
||||
CSDL_Ext::printAt(CGI->generaltexth->arraytxt[CPG->fromnewgame ? 229 : 230],110,25,TNRB16); //Select a Scenario to Play : Load a Saved Game
|
||||
CSDL_Ext::printAt(CGI->generaltexth->arraytxt[CPG->fromnewgame==1 ? 229 : 230],110,25,TNRB16); //Select a Scenario to Play : Load a Saved Game
|
||||
//size buttons
|
||||
small.show();
|
||||
medium.show();
|
||||
@ -1318,7 +1319,7 @@ void MapSel::printSelectedInfo()
|
||||
|
||||
SDL_BlitSurface(CPG->ourScenSel->scenInf,&genRect(399,337,17,23),screen,&genRect(399,337,413,29));
|
||||
SDL_BlitSurface(CPG->ourScenSel->scenInf,&genRect(50,91,18,447),screen,&genRect(50,91,414,453));
|
||||
if(CPG->fromnewgame)
|
||||
if(CPG->fromnewgame==1)
|
||||
{
|
||||
SDL_BlitSurface(CPG->ourScenSel->bScens.imgs->ourImages[0].bitmap,NULL,screen,&CPG->ourScenSel->bScens.pos);
|
||||
SDL_BlitSurface(CPG->ourScenSel->bOptions.imgs->ourImages[0].bitmap,NULL,screen,&CPG->ourScenSel->bOptions.pos);
|
||||
@ -1471,7 +1472,7 @@ std::string MapSel::gdiff(std::string ss)
|
||||
|
||||
CMapInfo & MapSel::selectedMap()
|
||||
{
|
||||
if(CPG->fromnewgame)
|
||||
if(CPG->fromnewgame==1)
|
||||
return ourMaps[selected];
|
||||
else
|
||||
return ourGames[selected];
|
||||
@ -1480,7 +1481,7 @@ CMapInfo & MapSel::selectedMap()
|
||||
std::vector<CMapInfo> & MapSel::curVector()
|
||||
{
|
||||
|
||||
if (CPG->fromnewgame)
|
||||
if (CPG->fromnewgame==1)
|
||||
return ourMaps;
|
||||
else
|
||||
return ourGames;
|
||||
@ -1581,7 +1582,7 @@ void CPreGame::showScenSel()
|
||||
SDL_BlitSurface(ourScenSel->bHard.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bHard.pos);
|
||||
SDL_BlitSurface(ourScenSel->bExpert.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bExpert.pos);
|
||||
SDL_BlitSurface(ourScenSel->bImpossible.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bImpossible.pos);
|
||||
SDL_BlitSurface((fromnewgame ? ourScenSel->bBegin : ourScenSel->bLoad).imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBegin.pos);
|
||||
SDL_BlitSurface((fromnewgame==1 ? ourScenSel->bBegin : ourScenSel->bLoad).imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBegin.pos);
|
||||
SDL_BlitSurface(ourScenSel->bBack.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBack.pos);
|
||||
//blitAt(ourScenSel->bScens.imgs->ourImages[0].bitmap,ourScenSel->bScens.pos.x,ourScenSel->bScens.pos.y);
|
||||
//blitAt(ourScenSel->bRandom.imgs->ourImages[0].bitmap,414,105);
|
||||
@ -1592,7 +1593,7 @@ void CPreGame::showScenSel()
|
||||
//add buttons info
|
||||
if(first)
|
||||
{
|
||||
if(fromnewgame)
|
||||
if(fromnewgame==1)
|
||||
{
|
||||
btns.push_back(&ourScenSel->bEasy);
|
||||
btns.push_back(&ourScenSel->bNormal);
|
||||
@ -1605,7 +1606,7 @@ void CPreGame::showScenSel()
|
||||
}
|
||||
else
|
||||
ourScenSel->mapsel.show();
|
||||
btns.push_back(&(fromnewgame ? ourScenSel->bBegin : ourScenSel->bLoad));
|
||||
btns.push_back(&(fromnewgame==1 ? ourScenSel->bBegin : ourScenSel->bLoad));
|
||||
btns.push_back(&ourScenSel->bBack);
|
||||
|
||||
ourScenSel->selectedDiff=1;
|
||||
@ -2468,6 +2469,7 @@ ScenSel::ScenSel()
|
||||
else
|
||||
background = BitmapHandler::loadBitmap("ZPIC1001.bmp");
|
||||
|
||||
savenameStrip = BitmapHandler::loadBitmap("GSSTRIP.bmp");
|
||||
scenInf = BitmapHandler::loadBitmap("GSELPOP1.bmp");
|
||||
randMap = BitmapHandler::loadBitmap("RANMAPBK.bmp");
|
||||
options = BitmapHandler::loadBitmap("ADVOPTBK.bmp");
|
||||
|
@ -221,7 +221,7 @@ public:
|
||||
bool listShowed;
|
||||
//RanSel ransel;
|
||||
MapSel mapsel;
|
||||
SDL_Surface * background, *scenInf, *scenList, *randMap, *options ;
|
||||
SDL_Surface * background, *savenameStrip, *scenInf, *scenList, *randMap, *options ;
|
||||
Button bScens, bOptions, bRandom, bBegin, bLoad, bBack;
|
||||
IntSelBut bEasy, bNormal, bHard, bExpert, bImpossible;
|
||||
Button * pressed;
|
||||
@ -244,7 +244,7 @@ public:
|
||||
StartInfo ret;
|
||||
bool run;
|
||||
bool first; //hasn't we showed the scensel
|
||||
bool fromnewgame;
|
||||
int fromnewgame; //1 - new game; 0 - load game; 2 - save game
|
||||
std::vector<Slider *> interested;
|
||||
CMusicHandler * mush;
|
||||
std::vector<HighButton *> btns;
|
||||
|
@ -206,6 +206,14 @@ void CClient::process(int what)
|
||||
gs->apply(&sav);
|
||||
break;
|
||||
}
|
||||
case 115:
|
||||
{
|
||||
GiveBonus gb;
|
||||
*serv >> gb;
|
||||
tlog5 << "Hero receives bonus\n";
|
||||
gs->apply(&gb);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject rh;
|
||||
|
2
global.h
2
global.h
@ -19,7 +19,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
#define THC
|
||||
#endif
|
||||
|
||||
#define NAME_VER ("VCMI 0.7")
|
||||
#define NAME_VER ("VCMI 0.7b")
|
||||
#define CONSOLE_LOGGING_LEVEL 5
|
||||
#define FILE_LOGGING_LEVEL 6
|
||||
|
||||
|
@ -330,11 +330,6 @@ int CGHeroInstance::getCurrentLuck() const
|
||||
//TODO: write it
|
||||
return 0;
|
||||
}
|
||||
int CGHeroInstance::getCurrentMorale() const
|
||||
{
|
||||
//TODO: write it
|
||||
return 0;
|
||||
}
|
||||
int CGHeroInstance::getPrimSkillLevel(int id) const
|
||||
{
|
||||
return primSkills[id];
|
||||
@ -601,6 +596,60 @@ void CGHeroInstance::initObj()
|
||||
blockVisit = true;
|
||||
}
|
||||
|
||||
int CGHeroInstance::getCurrentMorale( int stack, bool town ) const
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<std::pair<int,std::string> > mods = getCurrentMoraleModifiers(stack,town);
|
||||
for(int i=0; i < mods.size(); i++)
|
||||
ret += mods[i].first;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentMoraleModifiers( int stack/*=-1*/, bool town/*=false*/ ) const
|
||||
{
|
||||
//TODO: check if stack is undead/mechanic/elemental => always neutrl morale
|
||||
std::vector<std::pair<int,std::string> > ret;
|
||||
|
||||
//various morale bonuses (from buildings, artifacts, etc)
|
||||
for(std::list<Bonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
|
||||
if(i->type == 2)
|
||||
ret.push_back(std::make_pair(i->val, i->description));
|
||||
|
||||
//leadership
|
||||
if(getSecSkillLevel(6))
|
||||
ret.push_back(std::make_pair(getSecSkillLevel(6),VLC->generaltexth->arraytxt[104+getSecSkillLevel(6)]));
|
||||
|
||||
|
||||
//number of alignments and presence of undead
|
||||
if(stack>=0)
|
||||
{
|
||||
std::set<si8> factions;
|
||||
for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=army.slots.begin(); i!=army.slots.end(); i++)
|
||||
factions.insert(VLC->creh->creatures[i->second.first].faction);
|
||||
|
||||
if(factions.size() == 1)
|
||||
ret.push_back(std::pair<int,std::string>(1,VLC->generaltexth->arraytxt[115])); //All troops of one alignment +1
|
||||
else
|
||||
{
|
||||
if(VLC->generaltexth->arraytxt[114].length() <= 100)
|
||||
{
|
||||
char buf[150];
|
||||
std::sprintf(buf,VLC->generaltexth->arraytxt[114].c_str(),factions.size(),2-factions.size());
|
||||
ret.push_back(std::pair<int,std::string>(2-factions.size(),buf)); //Troops of %d alignments %d
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.push_back(std::pair<int,std::string>(2-factions.size(),"")); //Troops of %d alignments %d
|
||||
}
|
||||
}
|
||||
|
||||
if(vstd::contains(factions,4))
|
||||
ret.push_back(std::pair<int,std::string>(-1,VLC->generaltexth->arraytxt[116])); //Undead in group -1
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGTownInstance::getSightDistance() const //returns sight distance
|
||||
{
|
||||
return 10;
|
||||
@ -1151,10 +1200,8 @@ void CGResource::collectRes( int player ) const
|
||||
|
||||
void CGResource::fightForRes(ui32 refusedFight, const CGHeroInstance *h) const
|
||||
{
|
||||
if(refusedFight)
|
||||
return;
|
||||
|
||||
cb->startBattleI(h->id,army,pos,boost::bind(&CGResource::endBattle,this,_1,h));
|
||||
if(!refusedFight)
|
||||
cb->startBattleI(h->id,army,pos,boost::bind(&CGResource::endBattle,this,_1,h));
|
||||
}
|
||||
|
||||
void CGResource::endBattle( BattleResult *result, const CGHeroInstance *h ) const
|
||||
@ -1308,15 +1355,51 @@ void CGArtifact::initObj()
|
||||
|
||||
void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
cb->giveHeroArtifact(subID,h->id,-2);
|
||||
cb->removeObject(id);
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.components.push_back(Component(4,subID,0,0));
|
||||
iw.text << std::pair<ui8,ui32>(12,subID);
|
||||
cb->showInfoDialog(&iw);
|
||||
if(!army.slots.size())
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.components.push_back(Component(4,subID,0,0));
|
||||
if(message.length())
|
||||
iw.text << message;
|
||||
else
|
||||
iw.text << std::pair<ui8,ui32>(12,subID);
|
||||
cb->showInfoDialog(&iw);
|
||||
pick(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(message.size())
|
||||
{
|
||||
YesNoDialog ynd;
|
||||
ynd.player = h->getOwner();
|
||||
ynd.text << message;
|
||||
cb->showYesNoDialog(&ynd,boost::bind(&CGArtifact::fightForArt,this,_1,h));
|
||||
}
|
||||
else
|
||||
{
|
||||
fightForArt(0,h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGArtifact::pick(const CGHeroInstance * h) const
|
||||
{
|
||||
cb->giveHeroArtifact(subID,h->id,-2);
|
||||
cb->removeObject(id);
|
||||
}
|
||||
|
||||
void CGArtifact::fightForArt( ui32 refusedFight, const CGHeroInstance *h ) const
|
||||
{
|
||||
if(!refusedFight)
|
||||
cb->startBattleI(h->id,army,pos,boost::bind(&CGArtifact::endBattle,this,_1,h));
|
||||
}
|
||||
|
||||
void CGArtifact::endBattle( BattleResult *result, const CGHeroInstance *h ) const
|
||||
{
|
||||
if(result->winner == 0) //attacker won
|
||||
pick(h);
|
||||
}
|
||||
void CGPickable::initObj()
|
||||
{
|
||||
blockVisit = true;
|
||||
@ -1453,4 +1536,14 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
|
||||
}
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGDwelling::initObj()
|
||||
{
|
||||
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include "CCreatureHandler.h"
|
||||
#ifndef _MSC_VER
|
||||
#include "CHeroHandler.h"
|
||||
@ -165,18 +166,41 @@ public:
|
||||
si32 movement; //remaining movement points
|
||||
si32 identifier; //from the map file
|
||||
ui8 sex;
|
||||
struct DLL_EXPORT Patrol
|
||||
{
|
||||
Patrol(){patrolling=false;patrolRadious=-1;};
|
||||
bool patrolling;
|
||||
int patrolRadious;
|
||||
} patrol;
|
||||
ui8 inTownGarrison; // if hero is in town garrison
|
||||
CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
|
||||
std::vector<ui32> artifacts; //hero's artifacts from bag
|
||||
std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
std::set<ui32> spells; //known spells (spell IDs)
|
||||
|
||||
struct DLL_EXPORT Patrol
|
||||
{
|
||||
Patrol(){patrolling=false;patrolRadious=-1;};
|
||||
ui8 patrolling;
|
||||
si32 patrolRadious;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & patrolling & patrolRadious;
|
||||
}
|
||||
} patrol;
|
||||
|
||||
struct DLL_EXPORT Bonus
|
||||
{
|
||||
ui8 duration; //0 - Permanent, 1 - OneBattle, 2 - OneDay, 3 - OneWeek
|
||||
ui8 type; //0 - none, 1 - movement; 2 - morale; 3 - luck
|
||||
si32 val;
|
||||
ui32 id;
|
||||
std::string description;
|
||||
|
||||
Bonus(ui8 Dur, ui8 Type, si32 Val, ui32 ID, std::string Desc)
|
||||
:duration(Dur), type(Type), val(Val), id(ID), description(Desc)
|
||||
{}
|
||||
Bonus(){};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & duration & type & val & id;
|
||||
}
|
||||
};
|
||||
std::list<Bonus> bonuses;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -184,7 +208,7 @@ public:
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
h & exp & level & name & biography & portrait & mana & primSkills & secSkills & movement
|
||||
& identifier & sex & inTownGarrison & artifacts & artifWorn & spells;
|
||||
& identifier & sex & inTownGarrison & artifacts & artifWorn & spells & patrol & bonuses;
|
||||
|
||||
ui8 standardType = (VLC->heroh->heroes[subID] == type);
|
||||
h & standardType;
|
||||
@ -207,7 +231,8 @@ public:
|
||||
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
|
||||
bool canWalkOnSea() const;
|
||||
int getCurrentLuck() const;
|
||||
int getCurrentMorale() const;
|
||||
int getCurrentMorale(int stack=-1, bool town=false) const; //if stack - position of creature, if -1 then morale for hero is calculated; town - if bonuses from town (tavern) should be considered
|
||||
std::vector<std::pair<int,std::string> > getCurrentMoraleModifiers(int stack=-1, bool town=false) const; //args as above
|
||||
int getPrimSkillLevel(int id) const;
|
||||
ui8 getSecSkillLevel(const int & ID) const; //0 - no skill
|
||||
int maxMovePoints(bool onLand) const;
|
||||
@ -217,6 +242,7 @@ public:
|
||||
int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
|
||||
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void initHero();
|
||||
@ -452,6 +478,9 @@ public:
|
||||
std::string message;
|
||||
ui32 spell; //if it's spell scroll
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void fightForArt(ui32 refusedFight, const CGHeroInstance *h) const;
|
||||
void endBattle(BattleResult *result, const CGHeroInstance *h) const;
|
||||
void pick( const CGHeroInstance * h ) const;
|
||||
void initObj();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -583,6 +612,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGDwelling : public CGObjectInstance //teleports and subterranean gates
|
||||
{
|
||||
public:
|
||||
static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void initObj();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DLL_EXPORT CObjectHandler
|
||||
{
|
||||
public:
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
@ -263,6 +264,15 @@ public:
|
||||
for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
|
||||
*this << *i;
|
||||
}
|
||||
template <typename T>
|
||||
void saveSerializable(const std::list<T> &data)
|
||||
{
|
||||
std::list<T> &d = const_cast<std::list<T> &>(data);
|
||||
boost::uint32_t length = d.size();
|
||||
*this << length;
|
||||
for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
|
||||
*this << *i;
|
||||
}
|
||||
void saveSerializable(const std::string &data)
|
||||
{
|
||||
*this << ui32(data.length());
|
||||
@ -383,6 +393,18 @@ public:
|
||||
data.insert(ins);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void loadSerializable(std::list<T> &data)
|
||||
{
|
||||
boost::uint32_t length;
|
||||
*this >> length;
|
||||
T ins;
|
||||
for(ui32 i=0;i<length;i++)
|
||||
{
|
||||
*this >> ins;
|
||||
data.push_back(ins);
|
||||
}
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
void loadSerializable(std::pair<T1,T2> &data)
|
||||
{
|
||||
|
@ -33,6 +33,41 @@ template <typename T> struct Query
|
||||
{
|
||||
ui32 id;
|
||||
};
|
||||
|
||||
struct MetaString : public CPack<MetaString> //2001 helper for object scrips
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt
|
||||
std::vector<si32> message;
|
||||
std::vector<std::string> replacements;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & strings & texts & message & replacements;
|
||||
}
|
||||
|
||||
MetaString& operator<<(const std::pair<ui8,ui32> &txt)
|
||||
{
|
||||
message.push_back(-((si32)texts.size())-1);
|
||||
texts.push_back(txt);
|
||||
return *this;
|
||||
}
|
||||
MetaString& operator<<(const std::string &txt)
|
||||
{
|
||||
message.push_back(strings.size()+1);
|
||||
strings.push_back(txt);
|
||||
return *this;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
strings.clear();
|
||||
texts.clear();
|
||||
message.clear();
|
||||
}
|
||||
|
||||
MetaString(){type = 2001;};
|
||||
};
|
||||
|
||||
struct SetResources : public CPack<SetResources> //104
|
||||
{
|
||||
SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;};
|
||||
@ -155,6 +190,23 @@ struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
|
||||
}
|
||||
};
|
||||
|
||||
struct GiveBonus : public CPack<GiveBonus> //115
|
||||
{
|
||||
GiveBonus(){type = 115;};
|
||||
|
||||
ui8 bduration;
|
||||
ui8 btype;
|
||||
si32 bval;
|
||||
ui32 bid;
|
||||
ui32 hid;
|
||||
MetaString bdescr;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & bduration & btype & bval & bid & hid & bdescr;
|
||||
}
|
||||
};
|
||||
|
||||
struct RemoveObject : public CPack<RemoveObject> //500
|
||||
{
|
||||
RemoveObject(){type = 500;};
|
||||
@ -295,39 +347,6 @@ struct NewTurn : public CPack<NewTurn> //101
|
||||
// h & sac;
|
||||
// }
|
||||
//};
|
||||
struct MetaString : public CPack<MetaString> //2001 helper for object scrips
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt
|
||||
std::vector<si32> message;
|
||||
std::vector<std::string> replacements;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & strings & texts & message & replacements;
|
||||
}
|
||||
|
||||
MetaString& operator<<(const std::pair<ui8,ui32> &txt)
|
||||
{
|
||||
message.push_back(-((si32)texts.size())-1);
|
||||
texts.push_back(txt);
|
||||
return *this;
|
||||
}
|
||||
MetaString& operator<<(const std::string &txt)
|
||||
{
|
||||
message.push_back(strings.size()+1);
|
||||
strings.push_back(txt);
|
||||
return *this;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
strings.clear();
|
||||
texts.clear();
|
||||
message.clear();
|
||||
}
|
||||
|
||||
MetaString(){type = 2001;};
|
||||
};
|
||||
struct Component : public CPack<Component> //2002 helper for object scrips informations
|
||||
{
|
||||
ui16 id, subtype; //ids: 0 - primskill; 1 - secskill; 2 - resource; 3 - creature; 4 - artifact; 5 - experience (sub==0 exp points; sub==1 levels)
|
||||
|
@ -1136,20 +1136,37 @@ upgend:
|
||||
tlog3<<"We cannot move this stack to its destination "<<curStack->creature->namePl<<std::endl;
|
||||
}
|
||||
|
||||
if( (BattleInfo::mutualPosition(ba.destinationTile, ba.additionalInfo) < 0 //destination tile is not neighbouring with enemy stack
|
||||
&& !curStack->creature->isDoubleWide())
|
||||
|| (curStack->creature->isDoubleWide()
|
||||
&& (BattleInfo::mutualPosition(ba.destinationTile, ba.additionalInfo) < 0)
|
||||
&& (BattleInfo::mutualPosition(ba.destinationTile + (curStack->attackerOwned ? -1 : 1), ba.additionalInfo) < 0))
|
||||
)
|
||||
if(!stackAtEnd)
|
||||
{
|
||||
tlog3 << "There is no stack on " << ba.additionalInfo << " tile (no attack)!";
|
||||
break;
|
||||
}
|
||||
|
||||
ui16 curpos = curStack->position,
|
||||
enemypos = stackAtEnd->position;
|
||||
|
||||
|
||||
if( !(
|
||||
(BattleInfo::mutualPosition(curpos, enemypos) >= 0) //front <=> front
|
||||
|| (curStack->creature->isDoubleWide() //back <=> front
|
||||
&& BattleInfo::mutualPosition(curpos + (curStack->attackerOwned ? -1 : 1), enemypos) >= 0)
|
||||
|| (stackAtEnd->creature->isDoubleWide() //front <=> back
|
||||
&& BattleInfo::mutualPosition(curpos, enemypos + (stackAtEnd->attackerOwned ? -1 : 1)) >= 0)
|
||||
|| (stackAtEnd->creature->isDoubleWide() && curStack->creature->isDoubleWide()//back <=> back
|
||||
&& BattleInfo::mutualPosition(curpos + (curStack->attackerOwned ? -1 : 1), enemypos + (stackAtEnd->attackerOwned ? -1 : 1)) >= 0)
|
||||
)
|
||||
)
|
||||
{
|
||||
tlog3 << "Attack cannot be performed!";
|
||||
sendDataToClients(ui16(3008)); //end movement and attack
|
||||
break;
|
||||
}
|
||||
|
||||
//attack
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,stackAtEnd);
|
||||
sendAndApply(&bat);
|
||||
|
||||
//counterattack
|
||||
if(!vstd::contains(curStack->abilities,NO_ENEMY_RETALIATION)
|
||||
&& stackAtEnd->alive()
|
||||
@ -1161,6 +1178,7 @@ upgend:
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
|
||||
//second attack
|
||||
if(vstd::contains(curStack->abilities,TWICE_ATTACK)
|
||||
&& curStack->alive()
|
||||
&& stackAtEnd->alive() )
|
||||
|
Loading…
x
Reference in New Issue
Block a user