mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* added heroes pool for heroes available for hiring
* better handling disposed/predefined heroes * blocked scrolling adventure map with mouse when left ctrl is pressed * scholar will be accessible from the top * partially done tavern and hero recruitment * fixed bug with formation button in hero window * unified hero initialization code * minor changes For 0.63c dev release
This commit is contained in:
parent
45204d8beb
commit
3a66dc2b7c
@ -1132,12 +1132,12 @@ void CAdvMapInt::activate()
|
||||
}
|
||||
void CAdvMapInt::deactivate()
|
||||
{
|
||||
KeyInterested::deactivate();
|
||||
if(subInt == heroWindow)
|
||||
{
|
||||
heroWindow->deactivate();
|
||||
return;
|
||||
}
|
||||
KeyInterested::deactivate();
|
||||
hide();
|
||||
}
|
||||
void CAdvMapInt::show(SDL_Surface *to)
|
||||
|
@ -627,4 +627,21 @@ void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
|
||||
void CCallback::setSelection(const CArmedInstance * obj)
|
||||
{
|
||||
*cl->serv << ui16(514) << obj->id;
|
||||
}
|
||||
}
|
||||
|
||||
void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)
|
||||
{
|
||||
ui8 i=0;
|
||||
for(;i<gs->players[player].availableHeroes.size();i++)
|
||||
if(gs->players[player].availableHeroes[i] == hero)
|
||||
break;
|
||||
if(i>1) return;
|
||||
*cl->serv << ui16(515) << town->id << i;
|
||||
}
|
||||
|
||||
std::vector<const CGHeroInstance *> CCallback::getAvailableHeroes(const CGTownInstance * town) const
|
||||
{
|
||||
std::vector<const CGHeroInstance *> ret(gs->players[player].availableHeroes.size());
|
||||
std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin());
|
||||
return ret;
|
||||
}
|
@ -44,6 +44,7 @@ public:
|
||||
virtual void trade(int mode, int id1, int id2, int val1)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
||||
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
|
||||
virtual void setSelection(const CArmedInstance * obj)=0;
|
||||
virtual void recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)=0;
|
||||
|
||||
//get info
|
||||
virtual bool verifyPath(CPath * path, bool blockSea)const =0;
|
||||
@ -68,6 +69,7 @@ public:
|
||||
virtual void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0)const =0;
|
||||
virtual std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const =0;
|
||||
virtual int3 getMapSize() const =0; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
|
||||
|
||||
//battle
|
||||
virtual int battleGetBattlefieldType()=0; // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||
@ -127,6 +129,7 @@ public:
|
||||
void trade(int mode, int id1, int id2, int val1);
|
||||
void setFormation(const CGHeroInstance * hero, bool tight);
|
||||
void setSelection(const CArmedInstance * obj);
|
||||
void recruitHero(const CGTownInstance *town, const CGHeroInstance *hero);
|
||||
|
||||
//get info
|
||||
bool verifyPath(CPath * path, bool blockSea) const;
|
||||
@ -153,6 +156,7 @@ public:
|
||||
void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0) const;
|
||||
std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
|
||||
int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited
|
||||
|
||||
//battle
|
||||
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||
|
@ -478,7 +478,7 @@ void CCastleInterface::buildingClicked(int building)
|
||||
{
|
||||
switch(building)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4:
|
||||
case 0: case 1: case 2: case 3: case 4: //mage guild
|
||||
{
|
||||
if(town->visitingHero && !vstd::contains(town->visitingHero->artifWorn,ui16(17))) //visiting hero doesn't have spellboks
|
||||
{
|
||||
@ -500,11 +500,18 @@ void CCastleInterface::buildingClicked(int building)
|
||||
{
|
||||
deactivate();
|
||||
enterMageGuild();
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7: case 8: case 9:
|
||||
case 5: //tavern
|
||||
{
|
||||
std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town);
|
||||
CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
|
||||
deactivate();
|
||||
tv->activate();
|
||||
break;
|
||||
}
|
||||
case 7: case 8: case 9: //fort/citadel/castle
|
||||
{
|
||||
deactivate();
|
||||
CFortScreen *fs = new CFortScreen(this);
|
||||
@ -512,22 +519,22 @@ void CCastleInterface::buildingClicked(int building)
|
||||
fs->show();
|
||||
break;
|
||||
}
|
||||
case 10: case 11: case 12: case 13:
|
||||
case 10: case 11: case 12: case 13: //hall
|
||||
enterHall();
|
||||
break;
|
||||
case 14:
|
||||
case 14: //marketplace
|
||||
{
|
||||
deactivate();
|
||||
CMarketplaceWindow *cmw = new CMarketplaceWindow(0);
|
||||
cmw->activate();
|
||||
break;
|
||||
}
|
||||
case 15:
|
||||
case 15: //resource silo
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->buildh->buildings[town->subID][15]->description,std::vector<SComponent*>());
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
case 16: //blacksmith
|
||||
{
|
||||
const CGHeroInstance *hero = town->visitingHero;
|
||||
if(!hero)
|
||||
|
@ -88,10 +88,10 @@ void CConsoleHandler::setColor(int level)
|
||||
|
||||
int CConsoleHandler::run()
|
||||
{
|
||||
char buffer[500];
|
||||
char buffer[5000];
|
||||
while(true)
|
||||
{
|
||||
std::cin.getline(buffer, 500);
|
||||
std::cin.getline(buffer, 5000);
|
||||
if(cb && *cb)
|
||||
(*cb)(buffer);
|
||||
}
|
||||
|
172
CGameState.cpp
172
CGameState.cpp
@ -28,6 +28,7 @@ boost::rand48 ran;
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
|
||||
CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
|
||||
{
|
||||
CGObjectInstance * nobj;
|
||||
@ -35,39 +36,11 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
|
||||
{
|
||||
case 34: //hero
|
||||
{
|
||||
CGHeroInstance * nobj;
|
||||
nobj = new CGHeroInstance();
|
||||
CGHeroInstance * nobj = new CGHeroInstance();
|
||||
nobj->pos = pos;
|
||||
nobj->tempOwner = owner;
|
||||
nobj->defInfo = new CGDefInfo();
|
||||
nobj->defInfo->id = 34;
|
||||
nobj->defInfo->subid = subid;
|
||||
nobj->defInfo->printPriority = 0;
|
||||
nobj->defInfo->visitDir = 0xff;
|
||||
nobj->type = VLC->heroh->heroes[subid];
|
||||
for(int i=0;i<6;i++)
|
||||
{
|
||||
nobj->defInfo->blockMap[i]=255;
|
||||
nobj->defInfo->visitMap[i]=0;
|
||||
}
|
||||
nobj->ID = id;
|
||||
nobj->subID = subid;
|
||||
nobj->defInfo->handler=NULL;
|
||||
nobj->defInfo->blockMap[5] = 253;
|
||||
nobj->defInfo->visitMap[5] = 2;
|
||||
nobj->artifWorn[16] = 3;
|
||||
if(nobj->type->heroType % 2 == 1) //it's a magical hero
|
||||
{
|
||||
nobj->artifWorn[17] = 0; //give him spellbook
|
||||
}
|
||||
nobj->portrait = subid;
|
||||
nobj->primSkills.resize(4);
|
||||
nobj->primSkills[0] = nobj->type->heroClass->initialAttack;
|
||||
nobj->primSkills[1] = nobj->type->heroClass->initialDefence;
|
||||
nobj->primSkills[2] = nobj->type->heroClass->initialPower;
|
||||
nobj->primSkills[3] = nobj->type->heroClass->initialKnowledge;
|
||||
nobj->secSkills = nobj->type->secSkillsInit; //copying initial secondary skills
|
||||
nobj->mana = 10 * nobj->getPrimSkillLevel(3);
|
||||
//nobj->initHero(ran);
|
||||
return nobj;
|
||||
}
|
||||
case 98: //town
|
||||
@ -93,12 +66,6 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
|
||||
if(nobj->ID==34 || nobj->ID==98)
|
||||
return nobj;
|
||||
nobj->defInfo = VLC->dobjinfo->gobjs[id][subid];
|
||||
//if(!nobj->defInfo->handler)
|
||||
//{
|
||||
// nobj->defInfo->handler = CDefHandler::giveDef(nobj->defInfo->name);
|
||||
// nobj->defInfo->width = nobj->defInfo->handler->ourImages[0].bitmap->w/32;
|
||||
// nobj->defInfo->height = nobj->defInfo->handler->ourImages[0].bitmap->h/32;
|
||||
//}
|
||||
return nobj;
|
||||
}
|
||||
CStack * BattleInfo::getStack(int stackID)
|
||||
@ -428,6 +395,14 @@ void CGameState::applyNL(IPack * pack)
|
||||
players[rh->player].fogOfWarMap[t.x][t.y][t.z] = rh->mode;
|
||||
break;
|
||||
}
|
||||
case 113:
|
||||
{
|
||||
SetAvailableHeroes *rh = static_cast<SetAvailableHeroes*>(pack);
|
||||
players[rh->player].availableHeroes.clear();
|
||||
players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid1]);
|
||||
players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid2]);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject *rh = static_cast<RemoveObject*>(pack);
|
||||
@ -543,6 +518,31 @@ void CGameState::applyNL(IPack * pack)
|
||||
h->artifWorn = sha->artifWorn;
|
||||
break;
|
||||
}
|
||||
case 515:
|
||||
{
|
||||
HeroRecruited *sha = static_cast<HeroRecruited*>(pack);
|
||||
CGHeroInstance *h = hpool.heroesPool[sha->hid];
|
||||
CGTownInstance *t = getTown(sha->tid);
|
||||
h->setOwner(sha->player);
|
||||
h->pos = sha->tile;
|
||||
h->movement = h->maxMovePoints(true);
|
||||
|
||||
hpool.heroesPool.erase(sha->hid);
|
||||
if(h->id < 0)
|
||||
{
|
||||
h->id = map->objects.size();
|
||||
map->objects.push_back(h);
|
||||
}
|
||||
else
|
||||
map->objects[h->id] = h;
|
||||
map->heroes.push_back(h);
|
||||
players[h->tempOwner].heroes.push_back(h);
|
||||
map->addBlockVisTiles(h);
|
||||
t->visitingHero = h;
|
||||
h->visitedTown = t;
|
||||
h->inTownGarrison = false;
|
||||
break;
|
||||
}
|
||||
case 1001://set object property
|
||||
{
|
||||
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
|
||||
@ -987,6 +987,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
nnn->initHero();
|
||||
map->heroes.push_back(nnn);
|
||||
map->objects.push_back(nnn);
|
||||
map->addBlockVisTiles(nnn);
|
||||
@ -1037,82 +1038,41 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
}
|
||||
|
||||
/*************************HEROES************************************************/
|
||||
std::set<int> hids;
|
||||
for(int i=0; i<map->allowedHeroes.size(); i++) //add to hids all allowed heroes
|
||||
if(map->allowedHeroes[i])
|
||||
hids.insert(i);
|
||||
for (int i=0; i<map->heroes.size();i++) //heroes instances
|
||||
{
|
||||
if (map->heroes[i]->getOwner()<0)
|
||||
{
|
||||
tlog2 << "Warning - hero with uninitialized owner!\n";
|
||||
continue;
|
||||
}
|
||||
CGHeroInstance * vhi = (map->heroes[i]);
|
||||
if(!vhi->type)
|
||||
vhi->type = VLC->heroh->heroes[vhi->subID];
|
||||
|
||||
if (vhi->level<1)
|
||||
{
|
||||
vhi->exp=40+ran()%50;
|
||||
vhi->level = 1;
|
||||
}
|
||||
if(vhi->secSkills.size() == 1 && vhi->secSkills[0] == std::make_pair(-1, -1)) //set secondary skills to default
|
||||
{
|
||||
vhi->secSkills = vhi->type->secSkillsInit;
|
||||
}
|
||||
if ((!vhi->primSkills.size()) || (vhi->primSkills[0]<0))
|
||||
{
|
||||
if (vhi->primSkills.size()<PRIMARY_SKILLS)
|
||||
vhi->primSkills.resize(PRIMARY_SKILLS);
|
||||
vhi->primSkills[0] = vhi->type->heroClass->initialAttack;
|
||||
vhi->primSkills[1] = vhi->type->heroClass->initialDefence;
|
||||
vhi->primSkills[2] = vhi->type->heroClass->initialPower;
|
||||
vhi->primSkills[3] = vhi->type->heroClass->initialKnowledge;
|
||||
}
|
||||
vhi->mana = vhi->getPrimSkillLevel(3)*10;
|
||||
if (!vhi->name.length())
|
||||
{
|
||||
vhi->name = vhi->type->name;
|
||||
}
|
||||
if (!vhi->biography.length())
|
||||
{
|
||||
vhi->biography = vhi->type->biography;
|
||||
}
|
||||
if (vhi->portrait < 0)
|
||||
vhi->portrait = vhi->type->ID;
|
||||
|
||||
vhi->artifWorn[16] = 3;
|
||||
if(vhi->type->heroType % 2 == 1) //it's a magical hero
|
||||
{
|
||||
vhi->artifWorn[17] = 0; //give him spellbook
|
||||
}
|
||||
|
||||
//initial army
|
||||
if (!vhi->army.slots.size()) //standard army
|
||||
{
|
||||
int pom, pom2=0;
|
||||
for(int x=0;x<3;x++)
|
||||
{
|
||||
pom = (VLC->creh->nameToID[vhi->type->refTypeStack[x]]);
|
||||
if(pom>=145 && pom<=149) //war machine
|
||||
{
|
||||
pom2++;
|
||||
switch (pom)
|
||||
{
|
||||
case 145: //catapult
|
||||
vhi->artifWorn[16] = 3;
|
||||
break;
|
||||
default:
|
||||
vhi->artifWorn[9+CArtHandler::convertMachineID(pom,true)] = CArtHandler::convertMachineID(pom,true);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
vhi->army.slots[x-pom2].first = pom;
|
||||
if((pom = (vhi->type->highStack[x]-vhi->type->lowStack[x])) > 0)
|
||||
vhi->army.slots[x-pom2].second = (ran()%pom)+vhi->type->lowStack[x];
|
||||
else
|
||||
vhi->army.slots[x-pom2].second = +vhi->type->lowStack[x];
|
||||
vhi->army.formation = false;
|
||||
}
|
||||
}
|
||||
|
||||
vhi->initHero();
|
||||
players[vhi->getOwner()].heroes.push_back(vhi);
|
||||
|
||||
hids.erase(vhi->subID);
|
||||
}
|
||||
for(int i=0; i<map->predefinedHeroes.size(); i++)
|
||||
{
|
||||
if(!vstd::contains(hids,map->predefinedHeroes[i]->subID))
|
||||
continue;
|
||||
map->predefinedHeroes[i]->initHero();
|
||||
hpool.heroesPool[map->predefinedHeroes[i]->subID] = map->predefinedHeroes[i];
|
||||
hpool.pavailable[map->predefinedHeroes[i]->subID] = 0xff;
|
||||
hids.erase(map->predefinedHeroes[i]->subID);
|
||||
}
|
||||
BOOST_FOREACH(int hid, hids) //all not used allowed heroes go into the pool
|
||||
{
|
||||
CGHeroInstance * vhi = new CGHeroInstance();
|
||||
vhi->initHero(hid);
|
||||
hpool.heroesPool[hid] = vhi;
|
||||
hpool.pavailable[hid] = 0xff;
|
||||
}
|
||||
for(int i=0; i<map->disposedHeroes.size(); i++)
|
||||
{
|
||||
hpool.pavailable[map->disposedHeroes[i].ID] = map->disposedHeroes[i].players;
|
||||
}
|
||||
/*************************FOG**OF**WAR******************************************/
|
||||
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
std::vector<si32> resources;
|
||||
std::vector<CGHeroInstance *> heroes;
|
||||
std::vector<CGTownInstance *> towns;
|
||||
std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns
|
||||
PlayerState():color(-1),currentSelection(0xffffffff){};
|
||||
};
|
||||
|
||||
@ -142,7 +143,12 @@ private:
|
||||
std::map<ui8,PlayerState> players; //ID <-> playerstate
|
||||
std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
|
||||
std::vector<ui32> resVals;
|
||||
std::vector<CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
|
||||
|
||||
struct HeroesPool
|
||||
{
|
||||
std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
|
||||
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
|
||||
} hpool; //we have here all heroes available on this map that are not hired
|
||||
|
||||
boost::shared_mutex *mx;
|
||||
|
||||
|
@ -316,8 +316,9 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
gar2button->callback2 = vstd::assigno(hero->tacticFormationEnabled,false);
|
||||
}
|
||||
|
||||
formations->onChange = boost::bind(&CCallback::setFormation, LOCPLINT->cb, Hero, _1);
|
||||
formations->onChange = 0;
|
||||
formations->select(hero->army.formation,true);
|
||||
formations->onChange = boost::bind(&CCallback::setFormation, LOCPLINT->cb, Hero, _1);
|
||||
|
||||
redrawCurBack();
|
||||
}
|
||||
|
1
CMT.cpp
1
CMT.cpp
@ -225,6 +225,7 @@ int main(int argc, char** argv)
|
||||
#ifndef __unix__
|
||||
::console->killConsole(console->native_handle());
|
||||
#endif
|
||||
LOCPLINT->pim->lock();
|
||||
SDL_Delay(750);
|
||||
tlog0 << "Ending...\n";
|
||||
exit(0);
|
||||
|
@ -1608,8 +1608,10 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
}
|
||||
void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end())
|
||||
graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
|
||||
adventureInt->heroList.updateHList();
|
||||
}
|
||||
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
||||
{
|
||||
@ -1682,37 +1684,40 @@ void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
|
||||
(*i)->mouseMoved(sEvent->motion);
|
||||
}
|
||||
}
|
||||
if(sEvent->motion.x<15)
|
||||
if(!SDL_GetKeyState(NULL)[SDLK_LCTRL])
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingLeft = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingLeft = false;
|
||||
}
|
||||
if(sEvent->motion.x>screen->w-15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingRight = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingRight = false;
|
||||
}
|
||||
if(sEvent->motion.y<15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingUp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingUp = false;
|
||||
}
|
||||
if(sEvent->motion.y>screen->h-15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingDown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingDown = false;
|
||||
if(sEvent->motion.x<15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingLeft = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingLeft = false;
|
||||
}
|
||||
if(sEvent->motion.x>screen->w-15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingRight = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingRight = false;
|
||||
}
|
||||
if(sEvent->motion.y<15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingUp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingUp = false;
|
||||
}
|
||||
if(sEvent->motion.y>screen->h-15)
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingDown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->adventureInt->scrollingDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CPlayerInterface::handleEvent(SDL_Event *sEvent)
|
||||
@ -3842,3 +3847,138 @@ void CSystemOptionsWindow::show(SDL_Surface *to)
|
||||
backToMap->show(to);
|
||||
heroMoveSpeed->show(to);
|
||||
}
|
||||
|
||||
CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2, const std::string &gossip)
|
||||
:h1(selected,0,72,299,H1),h2(selected,1,162,299,H2)
|
||||
{
|
||||
selected = 0;
|
||||
bg = BitmapHandler::loadBitmap("TPTAVERN.bmp");
|
||||
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
|
||||
printAtMiddle(CGI->generaltexth->jktexts[37],200,35,GEOR16,tytulowy,bg);
|
||||
printAtMiddle("2500",320,328,GEOR13,zwykly,bg);
|
||||
printAtMiddle(CGI->generaltexth->jktexts[38],146,283,GEOR16,tytulowy,bg);
|
||||
printAtMiddleWB(gossip,200,220,GEOR13,50,zwykly,bg);
|
||||
pos.w = bg->w;
|
||||
pos.h = bg->h;
|
||||
pos.x = (screen->w-bg->w)/2;
|
||||
pos.y = (screen->h-bg->h)/2;
|
||||
h1.pos.x += pos.x;
|
||||
h2.pos.x += pos.x;
|
||||
h1.pos.y += pos.y;
|
||||
h2.pos.y += pos.y;
|
||||
cancel = new AdventureMapButton("","",boost::bind(&CTavernWindow::close,this),pos.x+310,pos.y+428,"ICANCEL.DEF",SDLK_ESCAPE);
|
||||
recruit = new AdventureMapButton("","",boost::bind(&CTavernWindow::recruitb,this),pos.x+272,pos.y+355,"TPTAV01.DEF",SDLK_RETURN);
|
||||
thiefGuild = new AdventureMapButton("","",0,pos.x+22,pos.y+428,"TPTAV02.DEF",SDLK_t);
|
||||
}
|
||||
|
||||
void CTavernWindow::recruitb()
|
||||
{
|
||||
const CGHeroInstance *toBuy = (selected ? h2 : h1).h;
|
||||
close();
|
||||
LOCPLINT->cb->recruitHero(LOCPLINT->castleInt->town,toBuy);
|
||||
}
|
||||
|
||||
CTavernWindow::~CTavernWindow()
|
||||
{
|
||||
SDL_FreeSurface(bg);
|
||||
delete cancel;
|
||||
delete thiefGuild;
|
||||
delete recruit;
|
||||
}
|
||||
|
||||
void CTavernWindow::activate()
|
||||
{
|
||||
LOCPLINT->objsToBlit += this;
|
||||
LOCPLINT->curint->subInt = this;
|
||||
thiefGuild->activate();
|
||||
cancel->activate();
|
||||
h1.activate();
|
||||
h2.activate();
|
||||
recruit->activate();
|
||||
}
|
||||
|
||||
void CTavernWindow::deactivate()
|
||||
{
|
||||
LOCPLINT->objsToBlit -= this;
|
||||
thiefGuild->deactivate();
|
||||
cancel->deactivate();
|
||||
h1.deactivate();
|
||||
h2.deactivate();
|
||||
recruit->deactivate();
|
||||
}
|
||||
|
||||
void CTavernWindow::close()
|
||||
{
|
||||
LOCPLINT->curint->subInt = NULL;
|
||||
deactivate();
|
||||
delete this;
|
||||
LOCPLINT->curint->activate();
|
||||
}
|
||||
|
||||
void CTavernWindow::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(bg,pos.x,pos.y,screen);
|
||||
h1.show();
|
||||
h2.show();
|
||||
thiefGuild->show();
|
||||
cancel->show();
|
||||
recruit->show();
|
||||
|
||||
|
||||
HeroPortrait *sel = selected ? &h2 : &h1;
|
||||
char descr[300];
|
||||
int artifs = sel->h->artifWorn.size()+sel->h->artifacts.size() - 1; //artifacts amount; - 1 is for catapult
|
||||
if(vstd::contains(sel->h->artifWorn,0)) artifs--; //spellbook doesn't count neither
|
||||
sprintf_s(descr,300,CGI->generaltexth->allTexts[215].c_str(),
|
||||
sel->h->name.c_str(),sel->h->level,sel->h->type->heroClass->name.c_str(),artifs);
|
||||
printAtMiddleWB(descr,pos.x+146,pos.y+389,GEOR13,40,zwykly,screen);
|
||||
CSDL_Ext::drawBorder(screen,sel->pos.x-2,sel->pos.y-2,sel->pos.w+4,sel->pos.h+4,int3(247,223,123));
|
||||
}
|
||||
|
||||
void CTavernWindow::HeroPortrait::clickLeft(boost::logic::tribool down)
|
||||
{
|
||||
if(pressedL && !down)
|
||||
as();
|
||||
ClickableL::clickLeft(down);
|
||||
}
|
||||
void CTavernWindow::HeroPortrait::activate()
|
||||
{
|
||||
ClickableL::activate();
|
||||
ClickableR::activate();
|
||||
}
|
||||
void CTavernWindow::HeroPortrait::deactivate()
|
||||
{
|
||||
ClickableL::deactivate();
|
||||
ClickableR::deactivate();
|
||||
}
|
||||
void CTavernWindow::HeroPortrait::clickRight(boost::logic::tribool down)
|
||||
{
|
||||
if(down)
|
||||
{
|
||||
LOCPLINT->adventureInt->heroWindow->setHero(h);
|
||||
LOCPLINT->objsToBlit += LOCPLINT->adventureInt->heroWindow;
|
||||
LOCPLINT->curint->deactivate();
|
||||
ClickableR::activate();
|
||||
}
|
||||
else if(vstd::contains(LOCPLINT->objsToBlit,LOCPLINT->adventureInt->heroWindow))
|
||||
{
|
||||
LOCPLINT->objsToBlit -= LOCPLINT->adventureInt->heroWindow;
|
||||
ClickableR::deactivate();
|
||||
LOCPLINT->castleInt->showAll(0,true);
|
||||
LOCPLINT->curint->subInt->activate();
|
||||
}
|
||||
}
|
||||
CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H)
|
||||
:as(sel,id)
|
||||
{
|
||||
h = H;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.w = 58;
|
||||
pos.h = 64;
|
||||
}
|
||||
|
||||
void CTavernWindow::HeroPortrait::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(graphics->portraitLarge[h->subID],pos);
|
||||
}
|
@ -109,8 +109,8 @@ public:
|
||||
ClickableL();
|
||||
virtual ~ClickableL(){};
|
||||
virtual void clickLeft (boost::logic::tribool down)=0;
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
virtual void activate();
|
||||
virtual void deactivate();
|
||||
};
|
||||
class ClickableR : public virtual CIntObject //for right-clicks
|
||||
{
|
||||
@ -663,6 +663,37 @@ public:
|
||||
void show(SDL_Surface * to = NULL);
|
||||
};
|
||||
|
||||
class CTavernWindow : public IShowActivable, public CIntObject
|
||||
{
|
||||
public:
|
||||
class HeroPortrait : public ClickableL, public ClickableR
|
||||
{
|
||||
public:
|
||||
vstd::assigner<int,int> as;
|
||||
const CGHeroInstance *h;
|
||||
void activate();
|
||||
void deactivate();
|
||||
void clickLeft(boost::logic::tribool down);
|
||||
void clickRight(boost::logic::tribool down);
|
||||
HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H);
|
||||
void show(SDL_Surface * to = NULL);
|
||||
} h1, h2;
|
||||
|
||||
SDL_Surface *bg;
|
||||
int selected;//0 (left) or 1 (right)
|
||||
|
||||
AdventureMapButton *thiefGuild, *cancel, *recruit;
|
||||
|
||||
CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2, const std::string &gossip); //c-tor
|
||||
~CTavernWindow(); //d-tor
|
||||
|
||||
void recruitb();
|
||||
void close();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to = NULL);
|
||||
};
|
||||
|
||||
extern CPlayerInterface * LOCPLINT;
|
||||
|
||||
#endif //CPLAYERINTERFACE_H
|
||||
|
30
ChangeLog
30
ChangeLog
@ -1,3 +1,33 @@
|
||||
0.63 -> 0.64 (Nov 01 2008 ?)
|
||||
* sprites from /Sprites folder are handled correctly now
|
||||
* several fixes for pathfinder and path arrows
|
||||
* clicking on a tile in advmap view when a path is shown will not only hide it but also calculate a new one
|
||||
* water elemental will really be treated as 2 hex creature
|
||||
* potential infinite loop in reverseCreature removed
|
||||
* better handling of battle cursor
|
||||
* better handling disposed/predefined heroes
|
||||
* fixed blocked shooter behavior
|
||||
* slowed map scrolling
|
||||
* blocked scrolling adventure map with mouse when left ctrl is pressed
|
||||
* blocked map scrolling when dialog window is opened
|
||||
* it's possible in battles to check remeaining HP of neutral stacks
|
||||
* heroes regain 1 mana point each turn
|
||||
* support for mistycisim and intelligence skills
|
||||
* partial support for Magic Arrow spell
|
||||
* fixed memory leak
|
||||
* fixed bug with dying unit
|
||||
* scholar will be accessible from the top
|
||||
* partially done tavern and hero recruitment
|
||||
* minor changes
|
||||
* Added some kind of simple chatting functionality through console. Implemented several WoG cheats equivalents:
|
||||
a) woggaladriel -> vcmiainur
|
||||
b) wogoliphaunt -> vcminoldor
|
||||
c) wogshadowfax -> vcminahar
|
||||
d) wogeyeofsauron -> vcmieagles
|
||||
e) wogisengard -> vcmiformenos
|
||||
f) wogsaruman -> vcmiistari
|
||||
g) wogpathofthedead -> vcmiangband
|
||||
|
||||
0.62 -> 0.63 (Oct 01 2008)
|
||||
GENERAL:
|
||||
* coloured console output, logging all info to txt files
|
||||
|
@ -42,11 +42,9 @@ struct StartInfo
|
||||
for(unsigned int i=0; i<playerInfos.size(); ++i)
|
||||
if(playerInfos[i].color == no)
|
||||
return playerInfos[i];
|
||||
#ifndef __GNUC__
|
||||
throw new std::exception("Cannot find info about player");
|
||||
#else
|
||||
throw new std::exception();
|
||||
#endif
|
||||
tlog1 << "Cannot find info about player " << no <<". Throwing...\n";
|
||||
throw std::string("Cannot find info about player");
|
||||
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -300,6 +300,14 @@ void CClient::process(int what)
|
||||
playerint[fc.player]->tileHidden(fc.tiles);
|
||||
break;
|
||||
}
|
||||
case 113:
|
||||
{
|
||||
SetAvailableHeroes sav;
|
||||
*serv >> sav;
|
||||
tlog5 << "Setting available heroes for player "<<(int)sav.player<<std::endl;
|
||||
gs->apply(&sav);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveObject rh;
|
||||
@ -438,6 +446,19 @@ void CClient::process(int what)
|
||||
tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl;
|
||||
break;
|
||||
}
|
||||
case 515:
|
||||
{
|
||||
HeroRecruited hr;
|
||||
*serv >> hr;
|
||||
tlog5 << "New hero bought\n";
|
||||
CGHeroInstance *h = gs->hpool.heroesPool[hr.hid];
|
||||
gs->apply(&hr);
|
||||
CGI->mh->initHeroDef(h);
|
||||
//CGI->mh->printObject(h);
|
||||
playerint[h->tempOwner]->heroCreated(h);
|
||||
playerint[h->tempOwner]->heroInGarrisonChange(gs->getTown(hr.tid));
|
||||
break;
|
||||
}
|
||||
case 1001:
|
||||
{
|
||||
SetObjectProperty sop;
|
||||
|
2
global.h
2
global.h
@ -18,7 +18,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
#define THC
|
||||
#endif
|
||||
|
||||
#define NAME_VER ("VCMI 0.63")
|
||||
#define NAME_VER ("VCMI 0.63c")
|
||||
#define CONSOLE_LOGGING_LEVEL 5
|
||||
#define FILE_LOGGING_LEVEL 6
|
||||
|
||||
|
@ -66,7 +66,7 @@ void CDefObjInfoHandler::load()
|
||||
inp>>nobj->id;
|
||||
inp>>nobj->subid;
|
||||
inp>>nobj->type;
|
||||
if(nobj->type == 2 || nobj->type == 3 || nobj->type == 4 || nobj->type == 5 || nobj->id == 111 || nobj->id == 33) //creature, hero, artifact, resource or whripool or garrison
|
||||
if(nobj->type == 2 || nobj->type == 3 || nobj->type == 4 || nobj->type == 5 || nobj->id == 111 || nobj->id == 33 || nobj->id == 81) //creature, hero, artifact, resource or whirlpool or garrison or scholar
|
||||
nobj->visitDir = 0xff;
|
||||
else
|
||||
nobj->visitDir = (8|16|32|64|128); //disabled visiting from the top
|
||||
|
@ -16,10 +16,12 @@ void CGeneralTextHandler::load()
|
||||
}
|
||||
|
||||
i+=2;
|
||||
std::string buflet;
|
||||
for(int jj=0; jj<764; ++jj)
|
||||
{
|
||||
std::string buflet;
|
||||
loadToIt(buflet, buf, i, 2);
|
||||
if(buflet[0] == '"' && buflet[buflet.size()-1] == '"')
|
||||
buflet = buflet.substr(1,buflet.size()-2);
|
||||
allTexts.push_back(buflet);
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,14 @@
|
||||
#include "CDefObjInfoHandler.h"
|
||||
#include "CHeroHandler.h"
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include "CTownHandler.h"
|
||||
#include "CArtHandler.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
|
||||
extern CLodHandler * bitmaph;
|
||||
extern boost::rand48 ran;
|
||||
|
||||
void CObjectHandler::loadObjects()
|
||||
{
|
||||
VLC->objh = this;
|
||||
@ -307,6 +310,57 @@ int CGHeroInstance::getSecSkillLevel(const int & ID) const
|
||||
return secSkills[i].second;
|
||||
return 0;
|
||||
}
|
||||
int lowestSpeed(const CGHeroInstance * chi)
|
||||
{
|
||||
std::map<si32,std::pair<ui32,si32> >::const_iterator i = chi->army.slots.begin();
|
||||
int ret = VLC->creh->creatures[(*i++).second.first].speed;
|
||||
for (;i!=chi->army.slots.end();i++)
|
||||
{
|
||||
ret = std::min(ret,VLC->creh->creatures[(*i).second.first].speed);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGHeroInstance::maxMovePoints(bool onLand) const
|
||||
{
|
||||
int ret = 1270+70*lowestSpeed(this);
|
||||
if (ret>2000)
|
||||
ret=2000;
|
||||
|
||||
if(onLand)
|
||||
{
|
||||
//logistics:
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.1f;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 1.2f;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 1.3f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//navigation:
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.5f;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 2.0f;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 2.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
|
||||
{
|
||||
if(pos<19)
|
||||
@ -348,7 +402,6 @@ const CArtifact * CGHeroInstance::getArt(int pos) const
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CGTownInstance::getSightDistance() const //returns sight distance
|
||||
{
|
||||
return 10;
|
||||
@ -442,7 +495,6 @@ bool CGTownInstance::hasCapitol() const
|
||||
}
|
||||
CGTownInstance::CGTownInstance()
|
||||
{
|
||||
pos = int3(-1,-1,-1);
|
||||
builded=-1;
|
||||
destroyed=-1;
|
||||
garrisonHero=NULL;
|
||||
@ -452,9 +504,13 @@ CGTownInstance::CGTownInstance()
|
||||
|
||||
CGObjectInstance::CGObjectInstance(): animPhaseShift(rand()%0xff)
|
||||
{
|
||||
pos = int3(-1,-1,-1);
|
||||
//std::cout << "Tworze obiekt "<<this<<std::endl;
|
||||
//state = new CLuaObjectScript();
|
||||
ID = subID = id = -1;
|
||||
defInfo = NULL;
|
||||
state = NULL;
|
||||
info = NULL;
|
||||
tempOwner = 254;
|
||||
blockVisit = false;
|
||||
}
|
||||
@ -467,13 +523,102 @@ CGObjectInstance::~CGObjectInstance()
|
||||
}
|
||||
CGHeroInstance::CGHeroInstance()
|
||||
{
|
||||
ID = 34;
|
||||
tacticFormationEnabled = inTownGarrison = false;
|
||||
portrait = level = exp = -1;
|
||||
mana = movement = portrait = level = -1;
|
||||
isStanding = true;
|
||||
moveDir = 4;
|
||||
mana = 0;
|
||||
exp = 0;
|
||||
visitedTown = NULL;
|
||||
type = NULL;
|
||||
secSkills.push_back(std::make_pair(-1, -1));
|
||||
}
|
||||
|
||||
void CGHeroInstance::initHero(int SUBID)
|
||||
{
|
||||
subID = SUBID;
|
||||
initHero();
|
||||
}
|
||||
|
||||
void CGHeroInstance::initHero()
|
||||
{
|
||||
if(!defInfo)
|
||||
{
|
||||
defInfo = new CGDefInfo();
|
||||
defInfo->id = 34;
|
||||
defInfo->subid = subID;
|
||||
defInfo->printPriority = 0;
|
||||
defInfo->visitDir = 0xff;
|
||||
}
|
||||
if(!type)
|
||||
type = VLC->heroh->heroes[subID];
|
||||
for(int i=0;i<6;i++)
|
||||
{
|
||||
defInfo->blockMap[i]=255;
|
||||
defInfo->visitMap[i]=0;
|
||||
}
|
||||
defInfo->handler=NULL;
|
||||
defInfo->blockMap[5] = 253;
|
||||
defInfo->visitMap[5] = 2;
|
||||
|
||||
artifWorn[16] = 3;
|
||||
if(type->heroType % 2 == 1) //it's a magical hero
|
||||
{
|
||||
artifWorn[17] = 0; //give him spellbook
|
||||
}
|
||||
|
||||
if(portrait < 0)
|
||||
portrait = subID;
|
||||
if((!primSkills.size()) || (primSkills[0]<0))
|
||||
{
|
||||
primSkills.resize(4);
|
||||
primSkills[0] = type->heroClass->initialAttack;
|
||||
primSkills[1] = type->heroClass->initialDefence;
|
||||
primSkills[2] = type->heroClass->initialPower;
|
||||
primSkills[3] = type->heroClass->initialKnowledge;
|
||||
}
|
||||
if(secSkills.size() == 1 && secSkills[0] == std::make_pair(-1, -1)) //set secondary skills to default
|
||||
secSkills = type->secSkillsInit;
|
||||
if(mana < 0)
|
||||
mana = manaLimit();
|
||||
if (!name.length())
|
||||
name = type->name;
|
||||
if (!biography.length())
|
||||
biography = type->biography;
|
||||
if (level<1)
|
||||
{
|
||||
exp=40+ (ran()) % 50;
|
||||
level = 1;
|
||||
}
|
||||
|
||||
if (!army.slots.size()) //standard army//initial army
|
||||
{
|
||||
int pom, pom2=0;
|
||||
for(int x=0;x<3;x++)
|
||||
{
|
||||
pom = (VLC->creh->nameToID[type->refTypeStack[x]]);
|
||||
if(pom>=145 && pom<=149) //war machine
|
||||
{
|
||||
pom2++;
|
||||
switch (pom)
|
||||
{
|
||||
case 145: //catapult
|
||||
artifWorn[16] = 3;
|
||||
break;
|
||||
default:
|
||||
artifWorn[9+CArtHandler::convertMachineID(pom,true)] = CArtHandler::convertMachineID(pom,true);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
army.slots[x-pom2].first = pom;
|
||||
if((pom = (type->highStack[x]-type->lowStack[x])) > 0)
|
||||
army.slots[x-pom2].second = (ran()%pom)+type->lowStack[x];
|
||||
else
|
||||
army.slots[x-pom2].second = +type->lowStack[x];
|
||||
army.formation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CGHeroInstance::~CGHeroInstance()
|
||||
|
@ -128,9 +128,12 @@ public:
|
||||
int getCurrentMorale() const;
|
||||
int getPrimSkillLevel(int id) const;
|
||||
int getSecSkillLevel(const int & ID) const; //0 - no skill
|
||||
int maxMovePoints(bool onLand) const;
|
||||
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
|
||||
void setArtAtPos(ui16 pos, int art);
|
||||
const CArtifact * getArt(int pos) const;
|
||||
void initHero();
|
||||
void initHero(int SUBID);
|
||||
CGHeroInstance();
|
||||
virtual ~CGHeroInstance();
|
||||
};
|
||||
|
@ -140,6 +140,18 @@ struct FoWChange : public CPack<FoWChange> //112
|
||||
h & tiles & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
|
||||
{
|
||||
SetAvailableHeroes(){type = 113;};
|
||||
ui8 player;
|
||||
ui32 hid1, hid2;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & hid1 & hid2;
|
||||
}
|
||||
};
|
||||
|
||||
struct RemoveObject : public CPack<RemoveObject> //500
|
||||
{
|
||||
RemoveObject(){type = 500;};
|
||||
@ -220,6 +232,19 @@ struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
|
||||
h & hid & artifacts & artifWorn;
|
||||
}
|
||||
};
|
||||
|
||||
struct HeroRecruited : public CPack<HeroRecruited> //515
|
||||
{
|
||||
HeroRecruited(){type = 515;};
|
||||
si32 hid, tid; //subID of hero
|
||||
int3 tile;
|
||||
ui8 player;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid & tid & tile & player;
|
||||
}
|
||||
};
|
||||
struct NewTurn : public CPack<NewTurn> //101
|
||||
{
|
||||
struct Hero
|
||||
|
59
map.cpp
59
map.cpp
@ -1015,15 +1015,38 @@ void Mapa::loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
|
||||
void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
|
||||
{
|
||||
CGHeroInstance * nhi = new CGHeroInstance;
|
||||
int identifier = 0;
|
||||
if(version>RoE)
|
||||
{
|
||||
identifier = readNormalNr(bufor,i, 4); i+=4;
|
||||
}
|
||||
nobj->setOwner(bufor[i]); ++i;
|
||||
nobj->subID = readNormalNr(bufor,i, 1); ++i;
|
||||
|
||||
for(int j=0; j<predefinedHeroes.size(); j++)
|
||||
{
|
||||
if(predefinedHeroes[j]->subID == nobj->subID)
|
||||
{
|
||||
*nhi = *predefinedHeroes[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(*(static_cast<CGObjectInstance*>(nhi))) = *nobj;
|
||||
delete nobj;
|
||||
nobj=nhi;
|
||||
if(version>RoE)
|
||||
nhi->portrait = nhi->subID;
|
||||
|
||||
for(int j=0; j<disposedHeroes.size(); j++)
|
||||
{
|
||||
nhi->identifier = readNormalNr(bufor,i, 4); i+=4;
|
||||
if(disposedHeroes[j].ID == nhi->subID)
|
||||
{
|
||||
nhi->name = disposedHeroes[j].name;
|
||||
nhi->portrait = disposedHeroes[j].portrait;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nhi->setOwner(bufor[i]); ++i;
|
||||
nhi->subID = readNormalNr(bufor,i, 1); ++i;
|
||||
nhi->identifier = identifier;
|
||||
if(readChar(bufor,i))//true if hero has nonstandard name
|
||||
nhi->name = readString(bufor,i);
|
||||
if(version>AB)
|
||||
@ -1038,10 +1061,7 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
|
||||
|
||||
bool portrait=bufor[i]; ++i;
|
||||
if (portrait)
|
||||
i++; //TODO read portrait nr, save, open
|
||||
else
|
||||
nhi->portrait = nhi->subID;
|
||||
|
||||
nhi->portrait = readChar(bufor,i);
|
||||
if(readChar(bufor,i))//true if hero has specified abilities
|
||||
{
|
||||
int howMany = readNormalNr(bufor,i); i+=4;
|
||||
@ -1052,10 +1072,6 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
|
||||
nhi->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
|
||||
}
|
||||
}
|
||||
else //set default secondary skils
|
||||
{
|
||||
nhi->secSkills.push_back(std::make_pair(-1, -1));
|
||||
}
|
||||
if(readChar(bufor,i))//true if hero has nonstandard garrison
|
||||
nhi->army = readCreatureSet(bufor,i,7,(version>RoE));
|
||||
nhi->army.formation =bufor[i]; ++i; //formation
|
||||
@ -1471,15 +1487,16 @@ void Mapa::readHeader( unsigned char * bufor, int &i)
|
||||
int lenbuf = readNormalNr(bufor,i); i+=4;
|
||||
for (int zz=0; zz<lenbuf; zz++)
|
||||
disposedHeroes[g].name+=bufor[i++];
|
||||
int players = bufor[i++];
|
||||
for(int zz=0;zz<8;zz++)
|
||||
{
|
||||
int por = (1<<zz);
|
||||
if(players & por)
|
||||
disposedHeroes[g].players[zz] = true;
|
||||
else
|
||||
disposedHeroes[g].players[zz] = false;
|
||||
}
|
||||
disposedHeroes[g].players = bufor[i++];
|
||||
//int players = bufor[i++];
|
||||
//for(int zz=0;zz<8;zz++)
|
||||
//{
|
||||
// int por = (1<<zz);
|
||||
// if(players & por)
|
||||
// disposedHeroes[g].players[zz] = true;
|
||||
// else
|
||||
// disposedHeroes[g].players[zz] = false;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
2
map.h
2
map.h
@ -356,7 +356,7 @@ struct DLL_EXPORT DisposedHero
|
||||
int ID;
|
||||
int portrait; //0xFF - default
|
||||
std::string name;
|
||||
bool players[8]; //who can hire this hero
|
||||
ui8 players; //who can hire this hero (bitfield)
|
||||
};
|
||||
|
||||
class DLL_EXPORT CMapEvent
|
||||
|
@ -481,6 +481,12 @@ void processDef (CGDefInfo* def)
|
||||
}
|
||||
}
|
||||
}
|
||||
void CMapHandler::initHeroDef(CGHeroInstance * h)
|
||||
{
|
||||
h->defInfo->handler = graphics->flags1[0];
|
||||
h->defInfo->width = h->defInfo->handler->ourImages[0].bitmap->w/32;
|
||||
h->defInfo->height = h->defInfo->handler->ourImages[0].bitmap->h/32;
|
||||
}
|
||||
void CMapHandler::init()
|
||||
{
|
||||
timeHandler th;
|
||||
@ -512,9 +518,7 @@ void CMapHandler::init()
|
||||
{
|
||||
if(!map->heroes[i]->defInfo->handler)
|
||||
{
|
||||
map->heroes[i]->defInfo->handler = graphics->flags1[0];
|
||||
map->heroes[i]->defInfo->width = map->heroes[i]->defInfo->handler->ourImages[0].bitmap->w/32;
|
||||
map->heroes[i]->defInfo->height = map->heroes[i]->defInfo->handler->ourImages[0].bitmap->h/32;
|
||||
initHeroDef(map->heroes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
bool printObject(const CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map
|
||||
bool hideObject(const CGObjectInstance * obj); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
|
||||
bool removeObject(CGObjectInstance * obj); //removes object from each place in VCMI (I hope)
|
||||
void initHeroDef(CGHeroInstance * h);
|
||||
void init();
|
||||
void calculateBlockedPos();
|
||||
void initObjectRects();
|
||||
|
@ -1005,6 +1005,28 @@ upgend:
|
||||
gs->players[*players.begin()].currentSelection = id;
|
||||
break;
|
||||
}
|
||||
case 515:
|
||||
{
|
||||
ui32 tid;
|
||||
ui8 hid;
|
||||
c >> tid >> hid;
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
if(!vstd::contains(players,t->tempOwner) //not our town
|
||||
|| !vstd::contains(t->builtBuildings,5) //no tavern in the town
|
||||
|| gs->players[t->tempOwner].resources[6]<2500 //not enough gold
|
||||
|| t->visitingHero //there is visiting hero - no place
|
||||
|| gs->players[t->tempOwner].heroes.size()>7 //8 hero limit
|
||||
)
|
||||
break;
|
||||
CGHeroInstance *nh = gs->players[t->tempOwner].availableHeroes[hid];
|
||||
HeroRecruited hr;
|
||||
hr.tid = tid;
|
||||
hr.hid = nh->subID;
|
||||
hr.player = t->tempOwner;
|
||||
hr.tile = t->pos - int3(1,0,0);
|
||||
sendAndApply(&hr);
|
||||
break;
|
||||
}
|
||||
case 2001:
|
||||
{
|
||||
ui32 qid, answer;
|
||||
@ -1303,67 +1325,36 @@ void CGameHandler::init(StartInfo *si, int Seed)
|
||||
|
||||
//delete lf;
|
||||
}
|
||||
int lowestSpeed(CGHeroInstance * chi)
|
||||
{
|
||||
std::map<si32,std::pair<ui32,si32> >::iterator i = chi->army.slots.begin();
|
||||
int ret = VLC->creh->creatures[(*i++).second.first].speed;
|
||||
for (;i!=chi->army.slots.end();i++)
|
||||
{
|
||||
ret = std::min(ret,VLC->creh->creatures[(*i).second.first].speed);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int valMovePoints(CGHeroInstance * chi, bool onLand)
|
||||
{
|
||||
int ret = 1270+70*lowestSpeed(chi);
|
||||
if (ret>2000)
|
||||
ret=2000;
|
||||
|
||||
if(onLand)
|
||||
{
|
||||
//logistics:
|
||||
switch(chi->getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.1f;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 1.2f;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 1.3f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//navigation:
|
||||
switch(chi->getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
ret *= 1.5f;
|
||||
break;
|
||||
case 2:
|
||||
ret *= 2.0f;
|
||||
break;
|
||||
case 3:
|
||||
ret *= 2.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: additional bonuses (but they aren't currently stored in chi)
|
||||
|
||||
return ret;
|
||||
}
|
||||
void CGameHandler::newTurn()
|
||||
{
|
||||
tlog5 << "Turn " << gs->day+1 << std::endl;
|
||||
NewTurn n;
|
||||
n.day = gs->day + 1;
|
||||
n.resetBuilded = true;
|
||||
|
||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
{
|
||||
if(gs->getDate(1)==7) //first day of week - new heroes in tavern
|
||||
{
|
||||
SetAvailableHeroes sah;
|
||||
sah.player = i->first;
|
||||
int r;
|
||||
if(!gs->hpool.heroesPool.size()) return;
|
||||
for(int a=0;a<2;a++)
|
||||
{
|
||||
r = rand() % gs->hpool.heroesPool.size();
|
||||
std::map<ui32,CGHeroInstance *>::iterator ch = gs->hpool.heroesPool.begin();
|
||||
while(r--) ch++;
|
||||
if(a) sah.hid2 = ch->first;
|
||||
else sah.hid1 = ch->first;
|
||||
}
|
||||
sendAndApply(&sah);
|
||||
//TODO: guarantee that heroes are different
|
||||
//TODO: first hero should be from initial player town
|
||||
//TODO: use selectionProbability from CHeroClass
|
||||
//int town = gs->scenarioOps->getIthPlayersSettings(i->first).castle;
|
||||
}
|
||||
if(i->first>=PLAYER_LIMIT) continue;
|
||||
SetResources r;
|
||||
r.player = i->first;
|
||||
@ -1374,7 +1365,7 @@ void CGameHandler::newTurn()
|
||||
{
|
||||
NewTurn::Hero hth;
|
||||
hth.id = h->id;
|
||||
hth.move = valMovePoints(h, true); //TODO: check if hero is really on the land
|
||||
hth.move = h->maxMovePoints(true); //TODO: check if hero is really on the land
|
||||
hth.mana = std::max(h->mana,std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit())); //hero regains 1 mana point + mysticism lvel
|
||||
n.heroes.insert(hth);
|
||||
|
||||
@ -1423,6 +1414,7 @@ void CGameHandler::newTurn()
|
||||
n.res.push_back(r);
|
||||
}
|
||||
sendAndApply(&n);
|
||||
tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
|
||||
for (std::set<CCPPObjectScript *>::iterator i=cppscripts.begin();i!=cppscripts.end();i++)
|
||||
{
|
||||
(*i)->newTurn();
|
||||
|
Loading…
Reference in New Issue
Block a user