mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-30 08:57:00 +02:00
Rewrote hero moving code. Seems to be working.
This commit is contained in:
parent
001868652a
commit
3247a9a4dd
337
CCallback.cpp
337
CCallback.cpp
@ -17,8 +17,16 @@
|
||||
#include "lib/Connection.h"
|
||||
#include "client/Client.h"
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "lib/NetPacks.h"
|
||||
//LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
extern CSharedCond<std::set<IPack*> > mess;
|
||||
|
||||
HeroMoveDetails::HeroMoveDetails(int3 Src, int3 Dst, CGHeroInstance*Ho)
|
||||
:src(Src),dst(Dst),ho(Ho)
|
||||
{
|
||||
owner = ho->getOwner();
|
||||
};
|
||||
bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
{
|
||||
CGHeroInstance * hero = NULL;
|
||||
@ -69,120 +77,123 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
return false;
|
||||
for(int i=ourPath->nodes.size()-1; i>0; i--)
|
||||
{
|
||||
int3 stpos, endpos;
|
||||
stpos = int3(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, hero->pos.z);
|
||||
endpos = int3(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, hero->pos.z);
|
||||
HeroMoveDetails curd;
|
||||
curd.src = stpos;
|
||||
curd.dst = endpos;
|
||||
curd.ho = hero;
|
||||
curd.owner = hero->getOwner();
|
||||
/*if(player!=-1)
|
||||
{
|
||||
hero->pos = endpos;
|
||||
}*/
|
||||
if(hero->movement >= (ourPath->nodes.size()>=2 ? (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist || player==-1)
|
||||
{ //performing move
|
||||
hero->movement -= (ourPath->nodes.size()>=2 ? (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist;
|
||||
ourPath->nodes.pop_back();
|
||||
int3 stpos(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, hero->pos.z),
|
||||
endpos(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, hero->pos.z);
|
||||
HeroMoveDetails curd(stpos,endpos,hero);
|
||||
|
||||
std::vector< CGObjectInstance * > vis = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.dst,false));
|
||||
bool blockvis = false;
|
||||
for (int pit = 0; pit<vis.size();pit++)
|
||||
if (vis[pit]->blockVisit)
|
||||
blockvis = true;
|
||||
|
||||
if (!blockvis)
|
||||
{
|
||||
curd.successful = true;
|
||||
hero->pos = curd.dst;
|
||||
|
||||
//inform leaved objects
|
||||
std::vector< CGObjectInstance * > leave = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.src,false));
|
||||
for (int iii=0; iii<leave.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
{
|
||||
//TODO: allow to handle this in LUA
|
||||
if(leave[iii]->state) //hard-coded function
|
||||
leave[iii]->state->onHeroLeave(leave[iii],curd.ho->subID);
|
||||
}
|
||||
|
||||
|
||||
//reveal fog of war
|
||||
int heroSight = hero->getSightDistance();
|
||||
int xbeg = stpos.x - heroSight - 2;
|
||||
if(xbeg < 0)
|
||||
xbeg = 0;
|
||||
int xend = stpos.x + heroSight + 2;
|
||||
if(xend >= CGI->mh->map->width)
|
||||
xend = CGI->mh->map->width;
|
||||
int ybeg = stpos.y - heroSight - 2;
|
||||
if(ybeg < 0)
|
||||
ybeg = 0;
|
||||
int yend = stpos.y + heroSight + 2;
|
||||
if(yend >= CGI->mh->map->height)
|
||||
yend = CGI->mh->map->height;
|
||||
for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
|
||||
{
|
||||
for(int yd=ybeg; yd<yend; ++yd)
|
||||
{
|
||||
int deltaX = (hero->getPosition(false).x-xd)*(hero->getPosition(false).x-xd);
|
||||
int deltaY = (hero->getPosition(false).y-yd)*(hero->getPosition(false).y-yd);
|
||||
if(deltaX+deltaY<hero->getSightDistance()*hero->getSightDistance())
|
||||
{
|
||||
if(gs->players[player].fogOfWarMap[xd][yd][hero->getPosition(false).z] == 0)
|
||||
{
|
||||
CGI->playerint[gs->players[player].serial]->tileRevealed(int3(xd, yd, hero->getPosition(false).z));
|
||||
}
|
||||
gs->players[player].fogOfWarMap[xd][yd][hero->getPosition(false).z] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//notify interfacesabout move
|
||||
int nn=0; //number of interfece of currently browsed player
|
||||
for(std::map<ui8, PlayerState>::iterator j=CGI->state->players.begin(); j!=CGI->state->players.end(); ++j)//CGI->state->players.size(); ++j) //for testing
|
||||
{
|
||||
if (j->first > PLAYER_LIMIT)
|
||||
break;
|
||||
if(j->second.fogOfWarMap[stpos.x-1][stpos.y][stpos.z] || j->second.fogOfWarMap[endpos.x-1][endpos.y][endpos.z])
|
||||
{ //player should be notified
|
||||
CGI->playerint[j->second.serial]->heroMoved(curd);
|
||||
}
|
||||
++nn;
|
||||
}
|
||||
|
||||
|
||||
//call objects if they arevisited
|
||||
for (int iii=0; iii<vis.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
{
|
||||
if(gs->checkFunc(vis[iii]->ID,"heroVisit")) //script function
|
||||
gs->objscr[vis[iii]->ID]["heroVisit"]->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
if(vis[iii]->state) //hard-coded function
|
||||
vis[iii]->state->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
}
|
||||
}
|
||||
else //interaction with blocking object (like resources)
|
||||
{
|
||||
curd.successful = false;
|
||||
CGI->playerint[gs->players[hero->getOwner()].serial]->heroMoved(curd);
|
||||
for (int iii=0; iii<vis.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
{
|
||||
if (vis[iii]->blockVisit)
|
||||
{
|
||||
if(gs->checkFunc(vis[iii]->ID,"heroVisit")) //script function
|
||||
gs->objscr[vis[iii]->ID]["heroVisit"]->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
if(vis[iii]->state) //hard-coded function
|
||||
vis[iii]->state->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
}
|
||||
}
|
||||
*cl->serv << ui16(501) << hero->id << stpos << endpos;
|
||||
{//wait till there is server answer
|
||||
boost::unique_lock<boost::mutex> lock(*mess.mx);
|
||||
while(std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>) == mess.res->end())
|
||||
mess.cv->wait(lock);
|
||||
std::set<IPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>);
|
||||
TryMoveHero tmh = *static_cast<TryMoveHero*>(*itr);
|
||||
mess.res->erase(itr);
|
||||
if(!tmh.result)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
return true; //move ended - no more movement points
|
||||
}
|
||||
// if(hero->movement >= (ourPath->nodes.size()>=2 ? (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist || player==-1)
|
||||
// { //performing move
|
||||
// hero->movement -= (ourPath->nodes.size()>=2 ? (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist;
|
||||
// ourPath->nodes.pop_back();
|
||||
//
|
||||
// std::vector< CGObjectInstance * > vis = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.dst,false));
|
||||
// bool blockvis = false;
|
||||
// for (int pit = 0; pit<vis.size();pit++)
|
||||
// if (vis[pit]->blockVisit)
|
||||
// blockvis = true;
|
||||
|
||||
// if (!blockvis)
|
||||
// {
|
||||
// curd.successful = true;
|
||||
// hero->pos = curd.dst;
|
||||
|
||||
// //inform leaved objects
|
||||
// std::vector< CGObjectInstance * > leave = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.src,false));
|
||||
// for (int iii=0; iii<leave.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
// {
|
||||
// //TODO: allow to handle this in LUA
|
||||
// if(leave[iii]->state) //hard-coded function
|
||||
// leave[iii]->state->onHeroLeave(leave[iii],curd.ho->subID);
|
||||
// }
|
||||
|
||||
|
||||
// //reveal fog of war
|
||||
// int heroSight = hero->getSightDistance();
|
||||
// int xbeg = stpos.x - heroSight - 2;
|
||||
// if(xbeg < 0)
|
||||
// xbeg = 0;
|
||||
// int xend = stpos.x + heroSight + 2;
|
||||
// if(xend >= CGI->mh->map->width)
|
||||
// xend = CGI->mh->map->width;
|
||||
// int ybeg = stpos.y - heroSight - 2;
|
||||
// if(ybeg < 0)
|
||||
// ybeg = 0;
|
||||
// int yend = stpos.y + heroSight + 2;
|
||||
// if(yend >= CGI->mh->map->height)
|
||||
// yend = CGI->mh->map->height;
|
||||
// for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
|
||||
// {
|
||||
// for(int yd=ybeg; yd<yend; ++yd)
|
||||
// {
|
||||
// int deltaX = (hero->getPosition(false).x-xd)*(hero->getPosition(false).x-xd);
|
||||
// int deltaY = (hero->getPosition(false).y-yd)*(hero->getPosition(false).y-yd);
|
||||
// if(deltaX+deltaY<hero->getSightDistance()*hero->getSightDistance())
|
||||
// {
|
||||
// if(gs->players[player].fogOfWarMap[xd][yd][hero->getPosition(false).z] == 0)
|
||||
// {
|
||||
// cl->playerint[player]->tileRevealed(int3(xd, yd, hero->getPosition(false).z));
|
||||
// }
|
||||
// gs->players[player].fogOfWarMap[xd][yd][hero->getPosition(false).z] = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// //notify interfacesabout move
|
||||
// int nn=0; //number of interfece of currently browsed player
|
||||
// for(std::map<ui8, PlayerState>::iterator j=CGI->state->players.begin(); j!=CGI->state->players.end(); ++j)//CGI->state->players.size(); ++j) //for testing
|
||||
// {
|
||||
// if (j->first > PLAYER_LIMIT)
|
||||
// break;
|
||||
// if(j->second.fogOfWarMap[stpos.x-1][stpos.y][stpos.z] || j->second.fogOfWarMap[endpos.x-1][endpos.y][endpos.z])
|
||||
// { //player should be notified
|
||||
// cl->playerint[j->second.color]->heroMoved(curd);
|
||||
// }
|
||||
// ++nn;
|
||||
// }
|
||||
|
||||
|
||||
// //call objects if they arevisited
|
||||
// for (int iii=0; iii<vis.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
// {
|
||||
// if(gs->checkFunc(vis[iii]->ID,"heroVisit")) //script function
|
||||
// gs->objscr[vis[iii]->ID]["heroVisit"]->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
// if(vis[iii]->state) //hard-coded function
|
||||
// vis[iii]->state->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
// }
|
||||
// }
|
||||
// else //interaction with blocking object (like resources)
|
||||
// {
|
||||
// curd.successful = false;
|
||||
// cl->playerint[gs->players[hero->getOwner()].color]->heroMoved(curd);
|
||||
// for (int iii=0; iii<vis.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
// {
|
||||
// if (vis[iii]->blockVisit)
|
||||
// {
|
||||
// if(gs->checkFunc(vis[iii]->ID,"heroVisit")) //script function
|
||||
// gs->objscr[vis[iii]->ID]["heroVisit"]->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
// if(vis[iii]->state) //hard-coded function
|
||||
// vis[iii]->state->onHeroVisit(vis[iii],curd.ho->subID);
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// }
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -254,7 +265,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount
|
||||
t->army.slots[slot].first = &CGI->creh->creatures[ID];
|
||||
t->army.slots[slot].second = amount;
|
||||
}
|
||||
CGI->playerint[gs->players[player].serial]->garrisonChanged(obj);
|
||||
cl->playerint[player]->garrisonChanged(obj);
|
||||
|
||||
}
|
||||
//TODO: recruit from dwellings on the adventure map
|
||||
@ -267,7 +278,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
|
||||
return false;
|
||||
CArmedInstance *ob = const_cast<CArmedInstance*>(obj);
|
||||
ob->army.slots.erase(stackPos);
|
||||
CGI->playerint[gs->players[player].serial]->garrisonChanged(obj);
|
||||
cl->playerint[player]->garrisonChanged(obj);
|
||||
return true;
|
||||
}
|
||||
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
|
||||
@ -515,27 +526,9 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
|
||||
S2->slots.erase(p2);
|
||||
|
||||
if(s1->tempOwner<PLAYER_LIMIT)
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -555,27 +548,10 @@ int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s
|
||||
S1->slots.erase(p1);
|
||||
|
||||
if(s1->tempOwner<PLAYER_LIMIT)
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||
|
||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||
return 0;
|
||||
}
|
||||
int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
|
||||
@ -597,25 +573,11 @@ int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2
|
||||
|
||||
if(s1->tempOwner<PLAYER_LIMIT)
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||
}
|
||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||
{
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
||||
{
|
||||
CGI->playerint[b]->garrisonChanged(s2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -686,7 +648,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, int buildingID)
|
||||
for(int i=0;i<7;i++)
|
||||
gs->players[player].resources[i]-=b->resources[i];
|
||||
t->builded++;
|
||||
CGI->playerint[CGI->state->players[player].serial]->buildChanged(town,buildingID,1);
|
||||
cl->playerint[player]->buildChanged(town,buildingID,1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -782,18 +744,11 @@ int3 CScriptCallback::getPos(CGObjectInstance * ob)
|
||||
}
|
||||
void CScriptCallback::changePrimSkill(int ID, int which, int val)
|
||||
{
|
||||
CGHeroInstance * hero = CGI->state->map->getHero(ID,0);
|
||||
CGHeroInstance * hero = gs->map->getHero(ID,0);
|
||||
if (which<PRIMARY_SKILLS)
|
||||
{
|
||||
hero->primSkills[which]+=val;
|
||||
for (int i=0; i<CGI->playerint.size(); i++)
|
||||
{
|
||||
if (CGI->playerint[i]->playerID == hero->getOwner())
|
||||
{
|
||||
CGI->playerint[i]->heroPrimarySkillChanged(hero, which, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cl->playerint[hero->getOwner()]->heroPrimarySkillChanged(hero, which, val);
|
||||
}
|
||||
else if (which==4)
|
||||
{
|
||||
@ -830,24 +785,25 @@ void CScriptCallback::showInfoDialog(int player, std::string text, std::vector<S
|
||||
//TODO: upewniac sie ze mozemy to zrzutowac (przy customowych interfejsach cos moze sie kopnac)
|
||||
if (player>=0)
|
||||
{
|
||||
CGameInterface * temp = CGI->playerint[CGI->state->players[player].serial];
|
||||
CGameInterface * temp = cl->playerint[player];
|
||||
if (temp->human)
|
||||
((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<CGI->playerint.size();i++)
|
||||
typedef std::pair<const ui8, CGameInterface*> intf;
|
||||
BOOST_FOREACH(intf & i, cl->playerint)
|
||||
{
|
||||
if (CGI->playerint[i]->human)
|
||||
((CPlayerInterface*)(CGI->playerint[i]))->showInfoDialog(text,*components);
|
||||
if (i.second->human)
|
||||
((CPlayerInterface*)(i.second))->showInfoDialog(text,*components);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
|
||||
{
|
||||
CGameInterface * temp = CGI->playerint[CGI->state->players[player].serial];
|
||||
CGameInterface * temp = cl->playerint[player];
|
||||
if (temp->human)
|
||||
((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
|
||||
return;
|
||||
@ -891,11 +847,11 @@ int CScriptCallback::getDate(int mode)
|
||||
void CScriptCallback::giveResource(int player, int which, int val)
|
||||
{
|
||||
gs->players[player].resources[which]+=val;
|
||||
CGI->playerint[gs->players[player].serial]->receivedResource(which,val);
|
||||
cl->playerint[player]->receivedResource(which,val);
|
||||
}
|
||||
void CScriptCallback::showCompInfo(int player, SComponent * comp)
|
||||
{
|
||||
CPlayerInterface * i = dynamic_cast<CPlayerInterface*>(CGI->playerint[gs->players[player].serial]);
|
||||
CPlayerInterface * i = dynamic_cast<CPlayerInterface*>(cl->playerint[player]);
|
||||
if(i)
|
||||
i->showComp(*comp);
|
||||
}
|
||||
@ -905,15 +861,8 @@ void CScriptCallback::heroVisitCastle(CGObjectInstance * ob, int heroID)
|
||||
if(n = dynamic_cast<CGTownInstance*>(ob))
|
||||
{
|
||||
n->visitingHero = CGI->state->map->getHero(heroID,0);
|
||||
CGI->state->map->getHero(heroID,0)->visitedTown = n;
|
||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
||||
{
|
||||
if(CGI->playerint[b]->playerID == getHeroOwner(heroID))
|
||||
{
|
||||
CGI->playerint[b]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
gs->map->getHero(heroID,0)->visitedTown = n;
|
||||
cl->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
@ -78,6 +78,8 @@ public:
|
||||
|
||||
struct HeroMoveDetails
|
||||
{
|
||||
HeroMoveDetails(){};
|
||||
HeroMoveDetails(int3 Src, int3 Dst, CGHeroInstance*Ho);
|
||||
int3 src, dst; //source and destination points
|
||||
CGHeroInstance * ho; //object instance of this hero
|
||||
int owner;
|
||||
@ -152,8 +154,10 @@ public:
|
||||
};
|
||||
class CScriptCallback
|
||||
{
|
||||
CScriptCallback(){};
|
||||
public:
|
||||
CGameState * gs;
|
||||
CClient *cl;
|
||||
|
||||
//get info
|
||||
static int3 getPos(CGObjectInstance * ob);
|
||||
@ -162,7 +166,7 @@ public:
|
||||
int getDate(int mode=0);
|
||||
|
||||
//do sth
|
||||
static void changePrimSkill(int ID, int which, int val);
|
||||
void changePrimSkill(int ID, int which, int val);
|
||||
void showInfoDialog(int player, std::string text, std::vector<SComponent*> * components); //TODO: obslugiwac nulle
|
||||
void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
|
||||
void giveResource(int player, int which, int val);
|
||||
|
@ -58,8 +58,6 @@ public:
|
||||
CPathfinder * pathf;
|
||||
CCursorHandler * curh;
|
||||
CScreenHandler * screenh;
|
||||
int localPlayer;
|
||||
std::vector<CGameInterface *> playerint;
|
||||
};
|
||||
|
||||
#endif //CGAMEINFO_H
|
@ -128,6 +128,20 @@ void CGameState::apply(IPack * pack)
|
||||
if(n->resetBuilded) //reset amount of structures set in this turn in towns
|
||||
BOOST_FOREACH(CGTownInstance* t, map->towns)
|
||||
t->builded = 0;
|
||||
break;
|
||||
}
|
||||
case 501://hero try-move
|
||||
{
|
||||
TryMoveHero * n = static_cast<TryMoveHero*>(pack);
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(map->objects[n->id]);
|
||||
h->movement = n->movePoints;
|
||||
if(n->result)
|
||||
h->pos = n->end;
|
||||
else
|
||||
h->pos = n->start;
|
||||
BOOST_FOREACH(int3 t, n->fowRevealed)
|
||||
players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mx->unlock();
|
||||
|
@ -340,7 +340,7 @@ void CGarrisonInt::createSlots()
|
||||
{
|
||||
sup = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
||||
for
|
||||
(std::map<int,std::pair<CCreature*,int> >::const_iterator i=set1->slots.begin();
|
||||
(std::map<si32,std::pair<CCreature*,si32> >::const_iterator i=set1->slots.begin();
|
||||
i!=set1->slots.end(); i++)
|
||||
{
|
||||
(*sup)[i->first] =
|
||||
@ -354,7 +354,7 @@ void CGarrisonInt::createSlots()
|
||||
{
|
||||
sdown = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
||||
for
|
||||
(std::map<int,std::pair<CCreature*,int> >::const_iterator i=set2->slots.begin();
|
||||
(std::map<si32,std::pair<CCreature*,si32> >::const_iterator i=set2->slots.begin();
|
||||
i!=set2->slots.end(); i++)
|
||||
{
|
||||
(*sdown)[i->first] =
|
||||
@ -902,13 +902,11 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
|
||||
LOCPLINT = this;
|
||||
playerID=Player;
|
||||
serialID=serial;
|
||||
CGI->localPlayer = playerID;
|
||||
human=true;
|
||||
}
|
||||
void CPlayerInterface::init(ICallback * CB)
|
||||
{
|
||||
cb = dynamic_cast<CCallback*>(CB);
|
||||
CGI->localPlayer = serialID;
|
||||
adventureInt = new CAdvMapInt(playerID);
|
||||
castleInt = NULL;
|
||||
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
|
||||
@ -928,7 +926,6 @@ void CPlayerInterface::yourTurn()
|
||||
{
|
||||
LOCPLINT = this;
|
||||
makingTurn = true;
|
||||
CGI->localPlayer = serialID;
|
||||
unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
|
||||
unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
|
||||
adventureInt->infoBar.newDay(cb->getDate(1));
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include "../lib/NetPacks.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include "../hch/CObjectHandler.h"
|
||||
CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
|
||||
|
||||
CClient::CClient(void)
|
||||
{
|
||||
}
|
||||
@ -58,17 +61,18 @@ CClient::CClient(CConnection *con, StartInfo *si)
|
||||
|
||||
for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces
|
||||
{
|
||||
CCallback *cb = new CCallback(CGI->state,CGI->state->scenarioOps->playerInfos[i].color,this);
|
||||
if(!CGI->state->scenarioOps->playerInfos[i].human)
|
||||
CGI->playerint.push_back(static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,"EmptyAI.dll")));
|
||||
ui8 color = gs->scenarioOps->playerInfos[i].color;
|
||||
CCallback *cb = new CCallback(gs,color,this);
|
||||
if(!gs->scenarioOps->playerInfos[i].human)
|
||||
playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,"EmptyAI.dll"));
|
||||
else
|
||||
{
|
||||
CGI->state->currentPlayer=CGI->state->scenarioOps->playerInfos[i].color;
|
||||
CGI->playerint.push_back(new CPlayerInterface(CGI->state->scenarioOps->playerInfos[i].color,i));
|
||||
((CPlayerInterface*)(CGI->playerint[i]))->init(cb);
|
||||
gs->currentPlayer = color;
|
||||
playerint[color] = new CPlayerInterface(color,i);
|
||||
playerint[color]->init(cb);
|
||||
}
|
||||
}
|
||||
CGI->consoleh->cb = new CCallback(CGI->state,-1,this);
|
||||
CGI->consoleh->cb = new CCallback(gs,-1,this);
|
||||
}
|
||||
CClient::~CClient(void)
|
||||
{
|
||||
@ -82,7 +86,7 @@ void CClient::process(int what)
|
||||
ui8 player;
|
||||
*serv >> player;//who?
|
||||
std::cout << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
|
||||
boost::thread(boost::bind(&CGameInterface::yourTurn,CGI->playerint[gs->players[player].serial]));
|
||||
boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
|
||||
break;
|
||||
}
|
||||
case 101:
|
||||
@ -94,6 +98,42 @@ void CClient::process(int what)
|
||||
std::cout << "done!"<<std::endl;
|
||||
break;
|
||||
}
|
||||
case 501: //hero movement response - we have to notify interfaces and callback
|
||||
{
|
||||
TryMoveHero *th = new TryMoveHero;
|
||||
*serv >> *th;
|
||||
std::cout << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
|
||||
|
||||
gs->apply(th);
|
||||
int player = gs->map->objects[th->id]->getOwner();
|
||||
|
||||
if(playerint[player])
|
||||
{
|
||||
for(std::set<int3>::iterator i=th->fowRevealed.begin(); i != th->fowRevealed.end(); i++)
|
||||
playerint[player]->tileRevealed(*i);
|
||||
//boost::function<void(int3)> tr = boost::bind(&CGameInterface::tileRevealed,playerint[player]);
|
||||
//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),tr);
|
||||
}
|
||||
|
||||
//notify interfacesabout move
|
||||
int nn=0; //number of interfece of currently browsed player
|
||||
for(std::map<ui8, CGameInterface*>::iterator i=playerint.begin();i!=playerint.end();i++)
|
||||
{
|
||||
if(gs->players[i->first].fogOfWarMap[th->start.x-1][th->start.y][th->start.z] || gs->players[i->first].fogOfWarMap[th->end.x-1][th->end.y][th->end.z])
|
||||
{
|
||||
HeroMoveDetails hmd(th->start,th->end,static_cast<CGHeroInstance*>(gs->map->objects[th->id]));
|
||||
hmd.successful = th->result;
|
||||
i->second->heroMoved(hmd);
|
||||
}
|
||||
}
|
||||
|
||||
//add info for callback
|
||||
mess.mx->lock();
|
||||
mess.res->insert(th);
|
||||
mess.mx->unlock();
|
||||
mess.cv->notify_all();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::exception("Not supported server message!");
|
||||
break;
|
||||
|
@ -5,10 +5,37 @@ class CGameState;
|
||||
class CGameInterface;
|
||||
class CConnection;
|
||||
class CCallback;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class mutex;
|
||||
class condition_variable;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct CSharedCond
|
||||
{
|
||||
boost::mutex *mx;
|
||||
boost::condition_variable *cv;
|
||||
T *res;
|
||||
CSharedCond(T*R)
|
||||
{
|
||||
res = R;
|
||||
mx = new boost::mutex;
|
||||
cv = new boost::condition_variable;
|
||||
}
|
||||
~CSharedCond()
|
||||
{
|
||||
delete res;
|
||||
delete mx;
|
||||
delete cv;
|
||||
}
|
||||
};
|
||||
|
||||
class CClient
|
||||
{
|
||||
CGameState *gs;
|
||||
std::map<int,CGameInterface *> playerint;
|
||||
std::map<ui8,CGameInterface *> playerint;
|
||||
CConnection *serv;
|
||||
public:
|
||||
CClient(void);
|
||||
@ -19,4 +46,5 @@ public:
|
||||
void run();
|
||||
|
||||
friend class CCallback;
|
||||
friend class CScriptCallback;
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh)
|
||||
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
|
||||
printAt(curh->name,75,15,GEOR13,zwykly,ret);
|
||||
drawPrimarySkill(curh, ret);
|
||||
for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
|
||||
for (std::map<si32,std::pair<CCreature*,si32> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
|
||||
{
|
||||
blitAt(graphics->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||
itoa((*i).second.second,buf,10);
|
||||
@ -64,7 +64,7 @@ SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
|
||||
blitAt(halls->ourImages[pom].bitmap,77,42,ret);
|
||||
itoa(curh->dailyIncome(),buf,10);
|
||||
printAtMiddle(buf,167,70,GEORM,zwykly,ret);
|
||||
for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
|
||||
for (std::map<si32,std::pair<CCreature*,si32> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
|
||||
{
|
||||
if(!i->second.first)
|
||||
continue;
|
||||
|
@ -53,7 +53,7 @@ class DLL_EXPORT CGObjectInstance
|
||||
public:
|
||||
int3 pos; //h3m pos
|
||||
int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
|
||||
int id;//number of object in CObjectHandler's vector
|
||||
si32 id;//number of object in CObjectHandler's vector
|
||||
CGDefInfo * defInfo;
|
||||
CCPPObjectScript * state;
|
||||
CSpecObjInfo * info;
|
||||
|
20
int3.h
20
int3.h
@ -5,26 +5,26 @@ class CCreature;
|
||||
class CCreatureSet //seven combined creatures
|
||||
{
|
||||
public:
|
||||
std::map<int,std::pair<CCreature*,int> > slots;
|
||||
std::map<si32,std::pair<CCreature*,si32> > slots;
|
||||
bool formation; //false - wide, true - tight
|
||||
};
|
||||
|
||||
class int3
|
||||
{
|
||||
public:
|
||||
int x,y,z;
|
||||
si32 x,y,z;
|
||||
inline int3():x(0),y(0),z(0){}; //c-tor, x/y/z initialized to 0
|
||||
inline int3(const int & X, const int & Y, const int & Z):x(X),y(Y),z(Z){}; //c-tor
|
||||
inline int3(const si32 & X, const si32 & Y, const si32 & Z):x(X),y(Y),z(Z){}; //c-tor
|
||||
inline ~int3(){} // d-tor - does nothing
|
||||
inline int3 operator+(const int3 & i) const
|
||||
{return int3(x+i.x,y+i.y,z+i.z);}
|
||||
inline int3 operator+(const int i) const //increases all components by int
|
||||
inline int3 operator+(const si32 i) const //increases all components by si32
|
||||
{return int3(x+i,y+i,z+i);}
|
||||
inline int3 operator-(const int3 & i) const
|
||||
{return int3(x-i.x,y-i.y,z-i.z);}
|
||||
inline int3 operator-(const int i) const
|
||||
inline int3 operator-(const si32 i) const
|
||||
{return int3(x-i,y-i,z-i);}
|
||||
inline int3 operator-() const //increases all components by int
|
||||
inline int3 operator-() const //increases all components by si32
|
||||
{return int3(-x,-y,-z);}
|
||||
inline void operator+=(const int3 & i)
|
||||
{
|
||||
@ -32,7 +32,7 @@ public:
|
||||
y+=i.y;
|
||||
z+=i.z;
|
||||
}
|
||||
inline void operator+=(const int & i)
|
||||
inline void operator+=(const si32 & i)
|
||||
{
|
||||
x+=i;
|
||||
y+=i;
|
||||
@ -44,7 +44,7 @@ public:
|
||||
y-=i.y;
|
||||
z-=i.z;
|
||||
}
|
||||
inline void operator-=(const int & i)
|
||||
inline void operator-=(const si32 & i)
|
||||
{
|
||||
x+=i;
|
||||
y+=i;
|
||||
@ -70,6 +70,10 @@ public:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & x & y & z;
|
||||
}
|
||||
};
|
||||
inline std::istream & operator>>(std::istream & str, int3 & dest)
|
||||
{
|
||||
|
@ -1,13 +1,28 @@
|
||||
#include "../global.h"
|
||||
struct IPack
|
||||
{
|
||||
virtual ui16 getType()=0;
|
||||
virtual ui16 getType()const = 0 ;
|
||||
//template<ui16 Type>
|
||||
//static bool isType(const IPack * ip)
|
||||
//{
|
||||
// return Type == ip->getType();
|
||||
//}
|
||||
template<ui16 Type>
|
||||
static bool isType(IPack * ip)
|
||||
{
|
||||
return Type == ip->getType();
|
||||
}
|
||||
//template<ui16 Type>
|
||||
//static bool isType(const IPack & ip)
|
||||
//{
|
||||
// return Type == ip.getType();
|
||||
//}
|
||||
};
|
||||
template <typename T> struct CPack
|
||||
:public IPack
|
||||
{
|
||||
ui16 type;
|
||||
ui16 getType(){return type;}
|
||||
ui16 getType() const{return type;}
|
||||
T* This(){return static_cast<T*>(this);};
|
||||
};
|
||||
struct NewTurn : public CPack<NewTurn> //101
|
||||
@ -44,3 +59,17 @@ struct NewTurn : public CPack<NewTurn> //101
|
||||
h & heroes & res & day & resetBuilded;
|
||||
}
|
||||
};
|
||||
struct TryMoveHero : public CPack<TryMoveHero> //501
|
||||
{
|
||||
TryMoveHero(){type = 501;};
|
||||
|
||||
ui32 id, movePoints;
|
||||
ui8 result;
|
||||
int3 start, end;
|
||||
std::set<int3> fowRevealed; //revealed tiles
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & result & start & end & movePoints & fowRevealed;
|
||||
}
|
||||
};
|
32
map.cpp
32
map.cpp
@ -926,6 +926,8 @@ void Mapa::initFromBytes(unsigned char * bufor)
|
||||
terrain[z][c].malle = (Eroad)bufor[i++];
|
||||
terrain[z][c].roadDir = bufor[i++];
|
||||
terrain[z][c].siodmyTajemniczyBajt = bufor[i++];
|
||||
terrain[z][c].blocked = 0;
|
||||
terrain[z][c].visitable = 0;
|
||||
}
|
||||
}
|
||||
if (twoLevel) // read underground terrain
|
||||
@ -941,6 +943,8 @@ void Mapa::initFromBytes(unsigned char * bufor)
|
||||
undergroungTerrain[z][c].malle = (Eroad)bufor[i++];
|
||||
undergroungTerrain[z][c].roadDir = bufor[i++];
|
||||
undergroungTerrain[z][c].siodmyTajemniczyBajt = bufor[i++];
|
||||
undergroungTerrain[z][c].blocked = 0;
|
||||
undergroungTerrain[z][c].visitable = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2289,6 +2293,34 @@ borderguardend:
|
||||
|
||||
//map readed, bufor no longer needed
|
||||
delete[] bufor; bufor=NULL;
|
||||
|
||||
|
||||
for(int f=0; f<objects.size(); ++f) //calculationg blocked / visitable positions
|
||||
{
|
||||
if(!objects[f]->defInfo)
|
||||
continue;
|
||||
CDefHandler * curd = objects[f]->defInfo->handler;
|
||||
for(int fx=0; fx<8; ++fx)
|
||||
{
|
||||
for(int fy=0; fy<6; ++fy)
|
||||
{
|
||||
int xVal = objects[f]->pos.x + fx - 7;
|
||||
int yVal = objects[f]->pos.y + fy - 5;
|
||||
int zVal = objects[f]->pos.z;
|
||||
if(xVal>=0 && xVal<width && yVal>=0 && yVal<height)
|
||||
{
|
||||
TerrainTile & curt = (zVal) ? (undergroungTerrain[xVal][yVal]) : (terrain[xVal][yVal]);
|
||||
if(((objects[f]->defInfo->visitMap[fy] >> (7 - fx)) & 1))
|
||||
{
|
||||
curt.visitableObjects.push_back(objects[f]);
|
||||
curt.visitable = true;
|
||||
}
|
||||
if(!((objects[f]->defInfo->blockMap[fy] >> (7 - fx)) & 1))
|
||||
curt.blocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mapa::Mapa(std::string filename)
|
||||
|
5
map.h
5
map.h
@ -263,6 +263,11 @@ struct DLL_EXPORT TerrainTile
|
||||
Eroad malle; // type of Eroad (0 if there is no Eriver)
|
||||
unsigned char roadDir; // direction of Eroad
|
||||
unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics
|
||||
|
||||
bool visitable; //false = not visitable; true = visitable
|
||||
bool blocked; //false = free; true = blocked;
|
||||
|
||||
std::vector <CGObjectInstance*> visitableObjects; //pointers to objects hero can visit while being on this tile
|
||||
};
|
||||
struct DLL_EXPORT SheroName //name of starting hero
|
||||
{
|
||||
|
@ -1325,7 +1325,7 @@ unsigned char CMapHandler::getHeroFrameNum(const unsigned char &dir, const bool
|
||||
case 8:
|
||||
return 11;
|
||||
default:
|
||||
return -1; //should never happen
|
||||
throw std::exception("Something very wrong1.");
|
||||
}
|
||||
}
|
||||
else //if(isMoving)
|
||||
@ -1349,7 +1349,7 @@ unsigned char CMapHandler::getHeroFrameNum(const unsigned char &dir, const bool
|
||||
case 8:
|
||||
return 14;
|
||||
default:
|
||||
return -1; //should never happen
|
||||
throw std::exception("Something very wrong2.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include "CGameHandler.h"
|
||||
#include "../CLua.h"
|
||||
#include "../CGameState.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../map.h"
|
||||
@ -19,6 +20,11 @@ boost::condition_variable cTurn;
|
||||
boost::mutex mTurn;
|
||||
boost::shared_mutex gsm;
|
||||
|
||||
double neighbours(int3 a, int3 b)
|
||||
{
|
||||
return std::sqrt( (double)(a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
|
||||
}
|
||||
|
||||
void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
try
|
||||
@ -29,12 +35,126 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
c >> pom;
|
||||
switch(pom)
|
||||
{
|
||||
case 100: //my interface end its turn
|
||||
case 100: //my interface ended its turn
|
||||
{
|
||||
mTurn.lock();
|
||||
makingTurn = false;
|
||||
mTurn.unlock();
|
||||
cTurn.notify_all();
|
||||
break;
|
||||
}
|
||||
case 501://interface wants to move hero
|
||||
{
|
||||
int3 start, end;
|
||||
si32 id;
|
||||
c >> id >> start >> end;
|
||||
int3 hmpos = end + int3(-1,0,0);
|
||||
TerrainTile t = (hmpos.z) ? (gs->map->undergroungTerrain[hmpos.x][hmpos.y]) : (gs->map->terrain[hmpos.x][hmpos.y]);
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance *>(gs->map->objects[id]);
|
||||
int cost = (double)h->getTileCost(t.tertype,t.malle,t.nuine) * neighbours(start,end);
|
||||
|
||||
TryMoveHero tmh;
|
||||
tmh.id = id;
|
||||
tmh.start = tmh.end = start;
|
||||
tmh.end = end;
|
||||
tmh.result = 0;
|
||||
tmh.movePoints = h->movement;
|
||||
|
||||
if((h->getOwner() != gs->currentPlayer) || //not turn of that hero
|
||||
(neighbours(start,end)>=1.5) || //tiles are not neighouring
|
||||
(h->movement < cost) || //lack of movement points
|
||||
(t.tertype == rock) || //rock
|
||||
(!h->canWalkOnSea() && t.tertype == water) ||
|
||||
(t.blocked && !t.visitable) ) //tile is blocked andnot visitable
|
||||
goto fail;
|
||||
|
||||
//we start moving
|
||||
bool blockvis = false;
|
||||
tmh.movePoints = h->movement = (h->movement-cost); //take move points
|
||||
BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
|
||||
{
|
||||
if(obj->blockVisit)
|
||||
{
|
||||
blockvis = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(blockvis)//interaction with blocking object (like resources)
|
||||
{
|
||||
gs->apply(&tmh);
|
||||
sendToAllClients(&tmh);
|
||||
BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
|
||||
{
|
||||
if (obj->blockVisit)
|
||||
{
|
||||
if(gs->checkFunc(obj->ID,"heroVisit")) //script function
|
||||
gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
|
||||
if(obj->state) //hard-coded function
|
||||
obj->state->onHeroVisit(obj,h->subID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else //normal move
|
||||
{
|
||||
tmh.result = 1;
|
||||
|
||||
BOOST_FOREACH(CGObjectInstance *obj, ((start.z) ? (gs->map->undergroungTerrain[start.x][start.y]) : (gs->map->terrain[start.x][start.y])).visitableObjects)
|
||||
{
|
||||
//TODO: allow to handle this in script-languages
|
||||
if(obj->state) //hard-coded function
|
||||
obj->state->onHeroLeave(obj,h->subID);
|
||||
}
|
||||
|
||||
//reveal fog of war
|
||||
int heroSight = h->getSightDistance();
|
||||
int xbeg = start.x - heroSight - 2;
|
||||
if(xbeg < 0)
|
||||
xbeg = 0;
|
||||
int xend = start.x + heroSight + 2;
|
||||
if(xend >= gs->map->width)
|
||||
xend = gs->map->width;
|
||||
int ybeg = start.y - heroSight - 2;
|
||||
if(ybeg < 0)
|
||||
ybeg = 0;
|
||||
int yend = start.y + heroSight + 2;
|
||||
if(yend >= gs->map->height)
|
||||
yend = gs->map->height;
|
||||
for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
|
||||
{
|
||||
for(int yd=ybeg; yd<yend; ++yd)
|
||||
{
|
||||
int deltaX = (hmpos.x-xd)*(hmpos.x-xd);
|
||||
int deltaY = (hmpos.y-yd)*(hmpos.y-yd);
|
||||
if(deltaX+deltaY<h->getSightDistance()*h->getSightDistance())
|
||||
{
|
||||
if(gs->players[h->getOwner()].fogOfWarMap[xd][yd][hmpos.z] == 0)
|
||||
{
|
||||
tmh.fowRevealed.insert(int3(xd,yd,hmpos.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gs->apply(&tmh);
|
||||
sendToAllClients(&tmh);
|
||||
|
||||
//call objects if they arevisited
|
||||
BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
|
||||
{
|
||||
if(gs->checkFunc(obj->ID,"heroVisit")) //script function
|
||||
gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
|
||||
if(obj->state) //hard-coded function
|
||||
obj->state->onHeroVisit(obj,h->subID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
fail:
|
||||
gs->apply(&tmh);
|
||||
sendToAllClients(&tmh);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::exception("Not supported client message!");
|
||||
break;
|
||||
@ -79,7 +199,7 @@ void CGameHandler::init(StartInfo *si, int Seed)
|
||||
}
|
||||
int lowestSpeed(CGHeroInstance * chi)
|
||||
{
|
||||
std::map<int,std::pair<CCreature*,int> >::iterator i = chi->army.slots.begin();
|
||||
std::map<si32,std::pair<CCreature*,si32> >::iterator i = chi->army.slots.begin();
|
||||
int ret = (*i++).second.first->speed;
|
||||
for (;i!=chi->army.slots.end();i++)
|
||||
{
|
||||
@ -174,6 +294,7 @@ void CGameHandler::run()
|
||||
{
|
||||
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser
|
||||
makingTurn = true;
|
||||
gs->currentPlayer = i->first;
|
||||
*connections[i->first] << ui16(100) << i->first;
|
||||
//wait till turn is done
|
||||
boost::unique_lock<boost::mutex> lock(mTurn);
|
||||
|
Loading…
Reference in New Issue
Block a user