mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Rewrote hero moving code. Seems to be working.
This commit is contained in:
337
CCallback.cpp
337
CCallback.cpp
@ -17,8 +17,16 @@
|
|||||||
#include "lib/Connection.h"
|
#include "lib/Connection.h"
|
||||||
#include "client/Client.h"
|
#include "client/Client.h"
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include "lib/NetPacks.h"
|
||||||
//LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
//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)
|
bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||||
{
|
{
|
||||||
CGHeroInstance * hero = NULL;
|
CGHeroInstance * hero = NULL;
|
||||||
@ -69,120 +77,123 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
|||||||
return false;
|
return false;
|
||||||
for(int i=ourPath->nodes.size()-1; i>0; i--)
|
for(int i=ourPath->nodes.size()-1; i>0; i--)
|
||||||
{
|
{
|
||||||
int3 stpos, endpos;
|
int3 stpos(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, hero->pos.z),
|
||||||
stpos = int3(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);
|
||||||
endpos = int3(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, hero->pos.z);
|
HeroMoveDetails curd(stpos,endpos,hero);
|
||||||
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();
|
|
||||||
|
|
||||||
std::vector< CGObjectInstance * > vis = CGI->mh->getVisitableObjs(CGHeroInstance::convertPosition(curd.dst,false));
|
*cl->serv << ui16(501) << hero->id << stpos << endpos;
|
||||||
bool blockvis = false;
|
{//wait till there is server answer
|
||||||
for (int pit = 0; pit<vis.size();pit++)
|
boost::unique_lock<boost::mutex> lock(*mess.mx);
|
||||||
if (vis[pit]->blockVisit)
|
while(std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>) == mess.res->end())
|
||||||
blockvis = true;
|
mess.cv->wait(lock);
|
||||||
|
std::set<IPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),IPack::isType<501>);
|
||||||
if (!blockvis)
|
TryMoveHero tmh = *static_cast<TryMoveHero*>(*itr);
|
||||||
{
|
mess.res->erase(itr);
|
||||||
curd.successful = true;
|
if(!tmh.result)
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// if(hero->movement >= (ourPath->nodes.size()>=2 ? (*(ourPath->nodes.end()-2)).dist : 0) - ourPath->nodes[i].dist || player==-1)
|
||||||
else
|
// { //performing move
|
||||||
return true; //move ended - no more movement points
|
// 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;
|
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].first = &CGI->creh->creatures[ID];
|
||||||
t->army.slots[slot].second = amount;
|
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
|
//TODO: recruit from dwellings on the adventure map
|
||||||
@ -267,7 +278,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
|
|||||||
return false;
|
return false;
|
||||||
CArmedInstance *ob = const_cast<CArmedInstance*>(obj);
|
CArmedInstance *ob = const_cast<CArmedInstance*>(obj);
|
||||||
ob->army.slots.erase(stackPos);
|
ob->army.slots.erase(stackPos);
|
||||||
CGI->playerint[gs->players[player].serial]->garrisonChanged(obj);
|
cl->playerint[player]->garrisonChanged(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
|
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);
|
S2->slots.erase(p2);
|
||||||
|
|
||||||
if(s1->tempOwner<PLAYER_LIMIT)
|
if(s1->tempOwner<PLAYER_LIMIT)
|
||||||
{
|
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||||
{
|
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,27 +548,10 @@ int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s
|
|||||||
S1->slots.erase(p1);
|
S1->slots.erase(p1);
|
||||||
|
|
||||||
if(s1->tempOwner<PLAYER_LIMIT)
|
if(s1->tempOwner<PLAYER_LIMIT)
|
||||||
{
|
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||||
{
|
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
|
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)
|
if(s1->tempOwner<PLAYER_LIMIT)
|
||||||
{
|
{
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
cl->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s1->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
|
||||||
{
|
{
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
cl->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == s2->tempOwner)
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->garrisonChanged(s2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -686,7 +648,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, int buildingID)
|
|||||||
for(int i=0;i<7;i++)
|
for(int i=0;i<7;i++)
|
||||||
gs->players[player].resources[i]-=b->resources[i];
|
gs->players[player].resources[i]-=b->resources[i];
|
||||||
t->builded++;
|
t->builded++;
|
||||||
CGI->playerint[CGI->state->players[player].serial]->buildChanged(town,buildingID,1);
|
cl->playerint[player]->buildChanged(town,buildingID,1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,18 +744,11 @@ int3 CScriptCallback::getPos(CGObjectInstance * ob)
|
|||||||
}
|
}
|
||||||
void CScriptCallback::changePrimSkill(int ID, int which, int val)
|
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)
|
if (which<PRIMARY_SKILLS)
|
||||||
{
|
{
|
||||||
hero->primSkills[which]+=val;
|
hero->primSkills[which]+=val;
|
||||||
for (int i=0; i<CGI->playerint.size(); i++)
|
cl->playerint[hero->getOwner()]->heroPrimarySkillChanged(hero, which, val);
|
||||||
{
|
|
||||||
if (CGI->playerint[i]->playerID == hero->getOwner())
|
|
||||||
{
|
|
||||||
CGI->playerint[i]->heroPrimarySkillChanged(hero, which, val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (which==4)
|
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)
|
//TODO: upewniac sie ze mozemy to zrzutowac (przy customowych interfejsach cos moze sie kopnac)
|
||||||
if (player>=0)
|
if (player>=0)
|
||||||
{
|
{
|
||||||
CGameInterface * temp = CGI->playerint[CGI->state->players[player].serial];
|
CGameInterface * temp = cl->playerint[player];
|
||||||
if (temp->human)
|
if (temp->human)
|
||||||
((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
|
((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (i.second->human)
|
||||||
((CPlayerInterface*)(CGI->playerint[i]))->showInfoDialog(text,*components);
|
((CPlayerInterface*)(i.second))->showInfoDialog(text,*components);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
|
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)
|
if (temp->human)
|
||||||
((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
|
((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
|
||||||
return;
|
return;
|
||||||
@ -891,11 +847,11 @@ int CScriptCallback::getDate(int mode)
|
|||||||
void CScriptCallback::giveResource(int player, int which, int val)
|
void CScriptCallback::giveResource(int player, int which, int val)
|
||||||
{
|
{
|
||||||
gs->players[player].resources[which]+=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)
|
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)
|
if(i)
|
||||||
i->showComp(*comp);
|
i->showComp(*comp);
|
||||||
}
|
}
|
||||||
@ -905,15 +861,8 @@ void CScriptCallback::heroVisitCastle(CGObjectInstance * ob, int heroID)
|
|||||||
if(n = dynamic_cast<CGTownInstance*>(ob))
|
if(n = dynamic_cast<CGTownInstance*>(ob))
|
||||||
{
|
{
|
||||||
n->visitingHero = CGI->state->map->getHero(heroID,0);
|
n->visitingHero = CGI->state->map->getHero(heroID,0);
|
||||||
CGI->state->map->getHero(heroID,0)->visitedTown = n;
|
gs->map->getHero(heroID,0)->visitedTown = n;
|
||||||
for(int b=0; b<CGI->playerint.size(); ++b)
|
cl->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
|
||||||
{
|
|
||||||
if(CGI->playerint[b]->playerID == getHeroOwner(heroID))
|
|
||||||
{
|
|
||||||
CGI->playerint[b]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -78,6 +78,8 @@ public:
|
|||||||
|
|
||||||
struct HeroMoveDetails
|
struct HeroMoveDetails
|
||||||
{
|
{
|
||||||
|
HeroMoveDetails(){};
|
||||||
|
HeroMoveDetails(int3 Src, int3 Dst, CGHeroInstance*Ho);
|
||||||
int3 src, dst; //source and destination points
|
int3 src, dst; //source and destination points
|
||||||
CGHeroInstance * ho; //object instance of this hero
|
CGHeroInstance * ho; //object instance of this hero
|
||||||
int owner;
|
int owner;
|
||||||
@ -152,8 +154,10 @@ public:
|
|||||||
};
|
};
|
||||||
class CScriptCallback
|
class CScriptCallback
|
||||||
{
|
{
|
||||||
|
CScriptCallback(){};
|
||||||
public:
|
public:
|
||||||
CGameState * gs;
|
CGameState * gs;
|
||||||
|
CClient *cl;
|
||||||
|
|
||||||
//get info
|
//get info
|
||||||
static int3 getPos(CGObjectInstance * ob);
|
static int3 getPos(CGObjectInstance * ob);
|
||||||
@ -162,7 +166,7 @@ public:
|
|||||||
int getDate(int mode=0);
|
int getDate(int mode=0);
|
||||||
|
|
||||||
//do sth
|
//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 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 showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
|
||||||
void giveResource(int player, int which, int val);
|
void giveResource(int player, int which, int val);
|
||||||
|
@ -58,8 +58,6 @@ public:
|
|||||||
CPathfinder * pathf;
|
CPathfinder * pathf;
|
||||||
CCursorHandler * curh;
|
CCursorHandler * curh;
|
||||||
CScreenHandler * screenh;
|
CScreenHandler * screenh;
|
||||||
int localPlayer;
|
|
||||||
std::vector<CGameInterface *> playerint;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CGAMEINFO_H
|
#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
|
if(n->resetBuilded) //reset amount of structures set in this turn in towns
|
||||||
BOOST_FOREACH(CGTownInstance* t, map->towns)
|
BOOST_FOREACH(CGTownInstance* t, map->towns)
|
||||||
t->builded = 0;
|
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();
|
mx->unlock();
|
||||||
|
@ -340,7 +340,7 @@ void CGarrisonInt::createSlots()
|
|||||||
{
|
{
|
||||||
sup = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
sup = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
||||||
for
|
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++)
|
i!=set1->slots.end(); i++)
|
||||||
{
|
{
|
||||||
(*sup)[i->first] =
|
(*sup)[i->first] =
|
||||||
@ -354,7 +354,7 @@ void CGarrisonInt::createSlots()
|
|||||||
{
|
{
|
||||||
sdown = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
sdown = new std::vector<CGarrisonSlot*>(7,(CGarrisonSlot *)(NULL));
|
||||||
for
|
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++)
|
i!=set2->slots.end(); i++)
|
||||||
{
|
{
|
||||||
(*sdown)[i->first] =
|
(*sdown)[i->first] =
|
||||||
@ -902,13 +902,11 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
|
|||||||
LOCPLINT = this;
|
LOCPLINT = this;
|
||||||
playerID=Player;
|
playerID=Player;
|
||||||
serialID=serial;
|
serialID=serial;
|
||||||
CGI->localPlayer = playerID;
|
|
||||||
human=true;
|
human=true;
|
||||||
}
|
}
|
||||||
void CPlayerInterface::init(ICallback * CB)
|
void CPlayerInterface::init(ICallback * CB)
|
||||||
{
|
{
|
||||||
cb = dynamic_cast<CCallback*>(CB);
|
cb = dynamic_cast<CCallback*>(CB);
|
||||||
CGI->localPlayer = serialID;
|
|
||||||
adventureInt = new CAdvMapInt(playerID);
|
adventureInt = new CAdvMapInt(playerID);
|
||||||
castleInt = NULL;
|
castleInt = NULL;
|
||||||
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
|
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
|
||||||
@ -928,7 +926,6 @@ void CPlayerInterface::yourTurn()
|
|||||||
{
|
{
|
||||||
LOCPLINT = this;
|
LOCPLINT = this;
|
||||||
makingTurn = true;
|
makingTurn = true;
|
||||||
CGI->localPlayer = serialID;
|
|
||||||
unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
|
unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
|
||||||
unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
|
unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
|
||||||
adventureInt->infoBar.newDay(cb->getDate(1));
|
adventureInt->infoBar.newDay(cb->getDate(1));
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "../lib/NetPacks.h"
|
#include "../lib/NetPacks.h"
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
#include "../hch/CObjectHandler.h"
|
||||||
|
CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
|
||||||
|
|
||||||
CClient::CClient(void)
|
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
|
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);
|
ui8 color = gs->scenarioOps->playerInfos[i].color;
|
||||||
if(!CGI->state->scenarioOps->playerInfos[i].human)
|
CCallback *cb = new CCallback(gs,color,this);
|
||||||
CGI->playerint.push_back(static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,"EmptyAI.dll")));
|
if(!gs->scenarioOps->playerInfos[i].human)
|
||||||
|
playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,"EmptyAI.dll"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CGI->state->currentPlayer=CGI->state->scenarioOps->playerInfos[i].color;
|
gs->currentPlayer = color;
|
||||||
CGI->playerint.push_back(new CPlayerInterface(CGI->state->scenarioOps->playerInfos[i].color,i));
|
playerint[color] = new CPlayerInterface(color,i);
|
||||||
((CPlayerInterface*)(CGI->playerint[i]))->init(cb);
|
playerint[color]->init(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CGI->consoleh->cb = new CCallback(CGI->state,-1,this);
|
CGI->consoleh->cb = new CCallback(gs,-1,this);
|
||||||
}
|
}
|
||||||
CClient::~CClient(void)
|
CClient::~CClient(void)
|
||||||
{
|
{
|
||||||
@ -82,7 +86,7 @@ void CClient::process(int what)
|
|||||||
ui8 player;
|
ui8 player;
|
||||||
*serv >> player;//who?
|
*serv >> player;//who?
|
||||||
std::cout << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case 101:
|
case 101:
|
||||||
@ -94,6 +98,42 @@ void CClient::process(int what)
|
|||||||
std::cout << "done!"<<std::endl;
|
std::cout << "done!"<<std::endl;
|
||||||
break;
|
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:
|
default:
|
||||||
throw std::exception("Not supported server message!");
|
throw std::exception("Not supported server message!");
|
||||||
break;
|
break;
|
||||||
|
@ -5,10 +5,37 @@ class CGameState;
|
|||||||
class CGameInterface;
|
class CGameInterface;
|
||||||
class CConnection;
|
class CConnection;
|
||||||
class CCallback;
|
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
|
class CClient
|
||||||
{
|
{
|
||||||
CGameState *gs;
|
CGameState *gs;
|
||||||
std::map<int,CGameInterface *> playerint;
|
std::map<ui8,CGameInterface *> playerint;
|
||||||
CConnection *serv;
|
CConnection *serv;
|
||||||
public:
|
public:
|
||||||
CClient(void);
|
CClient(void);
|
||||||
@ -19,4 +46,5 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
|
|
||||||
friend class CCallback;
|
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));
|
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
|
||||||
printAt(curh->name,75,15,GEOR13,zwykly,ret);
|
printAt(curh->name,75,15,GEOR13,zwykly,ret);
|
||||||
drawPrimarySkill(curh, 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);
|
blitAt(graphics->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||||
itoa((*i).second.second,buf,10);
|
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);
|
blitAt(halls->ourImages[pom].bitmap,77,42,ret);
|
||||||
itoa(curh->dailyIncome(),buf,10);
|
itoa(curh->dailyIncome(),buf,10);
|
||||||
printAtMiddle(buf,167,70,GEORM,zwykly,ret);
|
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)
|
if(!i->second.first)
|
||||||
continue;
|
continue;
|
||||||
|
@ -53,7 +53,7 @@ class DLL_EXPORT CGObjectInstance
|
|||||||
public:
|
public:
|
||||||
int3 pos; //h3m pos
|
int3 pos; //h3m pos
|
||||||
int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
|
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;
|
CGDefInfo * defInfo;
|
||||||
CCPPObjectScript * state;
|
CCPPObjectScript * state;
|
||||||
CSpecObjInfo * info;
|
CSpecObjInfo * info;
|
||||||
|
20
int3.h
20
int3.h
@ -5,26 +5,26 @@ class CCreature;
|
|||||||
class CCreatureSet //seven combined creatures
|
class CCreatureSet //seven combined creatures
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::map<int,std::pair<CCreature*,int> > slots;
|
std::map<si32,std::pair<CCreature*,si32> > slots;
|
||||||
bool formation; //false - wide, true - tight
|
bool formation; //false - wide, true - tight
|
||||||
};
|
};
|
||||||
|
|
||||||
class int3
|
class int3
|
||||||
{
|
{
|
||||||
public:
|
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():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(){} // d-tor - does nothing
|
||||||
inline int3 operator+(const int3 & i) const
|
inline int3 operator+(const int3 & i) const
|
||||||
{return int3(x+i.x,y+i.y,z+i.z);}
|
{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);}
|
{return int3(x+i,y+i,z+i);}
|
||||||
inline int3 operator-(const int3 & i) const
|
inline int3 operator-(const int3 & i) const
|
||||||
{return int3(x-i.x,y-i.y,z-i.z);}
|
{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);}
|
{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);}
|
{return int3(-x,-y,-z);}
|
||||||
inline void operator+=(const int3 & i)
|
inline void operator+=(const int3 & i)
|
||||||
{
|
{
|
||||||
@ -32,7 +32,7 @@ public:
|
|||||||
y+=i.y;
|
y+=i.y;
|
||||||
z+=i.z;
|
z+=i.z;
|
||||||
}
|
}
|
||||||
inline void operator+=(const int & i)
|
inline void operator+=(const si32 & i)
|
||||||
{
|
{
|
||||||
x+=i;
|
x+=i;
|
||||||
y+=i;
|
y+=i;
|
||||||
@ -44,7 +44,7 @@ public:
|
|||||||
y-=i.y;
|
y-=i.y;
|
||||||
z-=i.z;
|
z-=i.z;
|
||||||
}
|
}
|
||||||
inline void operator-=(const int & i)
|
inline void operator-=(const si32 & i)
|
||||||
{
|
{
|
||||||
x+=i;
|
x+=i;
|
||||||
y+=i;
|
y+=i;
|
||||||
@ -70,6 +70,10 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
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)
|
inline std::istream & operator>>(std::istream & str, int3 & dest)
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,28 @@
|
|||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
struct IPack
|
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
|
template <typename T> struct CPack
|
||||||
:public IPack
|
:public IPack
|
||||||
{
|
{
|
||||||
ui16 type;
|
ui16 type;
|
||||||
ui16 getType(){return type;}
|
ui16 getType() const{return type;}
|
||||||
T* This(){return static_cast<T*>(this);};
|
T* This(){return static_cast<T*>(this);};
|
||||||
};
|
};
|
||||||
struct NewTurn : public CPack<NewTurn> //101
|
struct NewTurn : public CPack<NewTurn> //101
|
||||||
@ -44,3 +59,17 @@ struct NewTurn : public CPack<NewTurn> //101
|
|||||||
h & heroes & res & day & resetBuilded;
|
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].malle = (Eroad)bufor[i++];
|
||||||
terrain[z][c].roadDir = bufor[i++];
|
terrain[z][c].roadDir = bufor[i++];
|
||||||
terrain[z][c].siodmyTajemniczyBajt = bufor[i++];
|
terrain[z][c].siodmyTajemniczyBajt = bufor[i++];
|
||||||
|
terrain[z][c].blocked = 0;
|
||||||
|
terrain[z][c].visitable = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (twoLevel) // read underground terrain
|
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].malle = (Eroad)bufor[i++];
|
||||||
undergroungTerrain[z][c].roadDir = bufor[i++];
|
undergroungTerrain[z][c].roadDir = bufor[i++];
|
||||||
undergroungTerrain[z][c].siodmyTajemniczyBajt = 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
|
//map readed, bufor no longer needed
|
||||||
delete[] bufor; bufor=NULL;
|
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)
|
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)
|
Eroad malle; // type of Eroad (0 if there is no Eriver)
|
||||||
unsigned char roadDir; // direction of Eroad
|
unsigned char roadDir; // direction of Eroad
|
||||||
unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics
|
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
|
struct DLL_EXPORT SheroName //name of starting hero
|
||||||
{
|
{
|
||||||
|
@ -1325,7 +1325,7 @@ unsigned char CMapHandler::getHeroFrameNum(const unsigned char &dir, const bool
|
|||||||
case 8:
|
case 8:
|
||||||
return 11;
|
return 11;
|
||||||
default:
|
default:
|
||||||
return -1; //should never happen
|
throw std::exception("Something very wrong1.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //if(isMoving)
|
else //if(isMoving)
|
||||||
@ -1349,7 +1349,7 @@ unsigned char CMapHandler::getHeroFrameNum(const unsigned char &dir, const bool
|
|||||||
case 8:
|
case 8:
|
||||||
return 14;
|
return 14;
|
||||||
default:
|
default:
|
||||||
return -1; //should never happen
|
throw std::exception("Something very wrong2.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <boost/thread/shared_mutex.hpp>
|
#include <boost/thread/shared_mutex.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include "CGameHandler.h"
|
#include "CGameHandler.h"
|
||||||
|
#include "../CLua.h"
|
||||||
#include "../CGameState.h"
|
#include "../CGameState.h"
|
||||||
#include "../StartInfo.h"
|
#include "../StartInfo.h"
|
||||||
#include "../map.h"
|
#include "../map.h"
|
||||||
@ -19,6 +20,11 @@ boost::condition_variable cTurn;
|
|||||||
boost::mutex mTurn;
|
boost::mutex mTurn;
|
||||||
boost::shared_mutex gsm;
|
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)
|
void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -29,12 +35,126 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
|||||||
c >> pom;
|
c >> pom;
|
||||||
switch(pom)
|
switch(pom)
|
||||||
{
|
{
|
||||||
case 100: //my interface end its turn
|
case 100: //my interface ended its turn
|
||||||
|
{
|
||||||
mTurn.lock();
|
mTurn.lock();
|
||||||
makingTurn = false;
|
makingTurn = false;
|
||||||
mTurn.unlock();
|
mTurn.unlock();
|
||||||
cTurn.notify_all();
|
cTurn.notify_all();
|
||||||
break;
|
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:
|
default:
|
||||||
throw std::exception("Not supported client message!");
|
throw std::exception("Not supported client message!");
|
||||||
break;
|
break;
|
||||||
@ -79,7 +199,7 @@ void CGameHandler::init(StartInfo *si, int Seed)
|
|||||||
}
|
}
|
||||||
int lowestSpeed(CGHeroInstance * chi)
|
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;
|
int ret = (*i++).second.first->speed;
|
||||||
for (;i!=chi->army.slots.end();i++)
|
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
|
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser
|
||||||
makingTurn = true;
|
makingTurn = true;
|
||||||
|
gs->currentPlayer = i->first;
|
||||||
*connections[i->first] << ui16(100) << i->first;
|
*connections[i->first] << ui16(100) << i->first;
|
||||||
//wait till turn is done
|
//wait till turn is done
|
||||||
boost::unique_lock<boost::mutex> lock(mTurn);
|
boost::unique_lock<boost::mutex> lock(mTurn);
|
||||||
|
Reference in New Issue
Block a user