diff --git a/CGameState.cpp b/CGameState.cpp index 75f9053a6..57bf47d21 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -327,6 +327,43 @@ void CGameState::applyNL(IPack * pack) } break; } + case 108: + { + HeroVisitCastle *vc = static_cast(pack); + CGHeroInstance *h = getHero(vc->hid); + CGTownInstance *t = getTown(vc->tid); + if(vc->start()) + { + if(vc->garrison()) + { + t->garrisonHero = h; + h->visitedTown = t; + h->inTownGarrison = true; + } + else + { + t->visitingHero = h; + h->visitedTown = t; + h->inTownGarrison = false; + } + } + else + { + if(vc->garrison()) + { + t->garrisonHero = NULL; + h->visitedTown = NULL; + h->inTownGarrison = false; + } + else + { + t->visitingHero = NULL; + h->visitedTown = NULL; + h->inTownGarrison = false; + } + } + break; + } case 500: { RemoveObject *rh = static_cast(pack); @@ -502,6 +539,12 @@ CGHeroInstance *CGameState::getHero(int objid) return NULL; return static_cast(map->objects[objid]); } +CGTownInstance *CGameState::getTown(int objid) +{ + if(objid<0 || objid>=map->objects.size()) + return NULL; + return static_cast(map->objects[objid]); +} std::pair CGameState::pickObject(CGObjectInstance *obj) { switch(obj->ID) @@ -788,6 +831,17 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) int h=pickHero(i); CGHeroInstance * nnn = static_cast(createObject(34,h,hpos,i)); nnn->id = map->objects.size(); + hpos = map->players[i].posOfMainTown;hpos.x+=2; + for(int o=0;otowns.size();o++) //find main town + { + if(map->towns[o]->pos == hpos) + { + map->towns[o]->visitingHero = nnn; + nnn->visitedTown = map->towns[o]; + nnn->inTownGarrison = false; + break; + } + } //nnn->defInfo->handler = graphics->flags1[0]; map->heroes.push_back(nnn); map->objects.push_back(nnn); diff --git a/CGameState.h b/CGameState.h index b6a5f9207..ac7f0cdaa 100644 --- a/CGameState.h +++ b/CGameState.h @@ -135,6 +135,7 @@ private: int pickHero(int owner); CGHeroInstance *getHero(int objid); + CGTownInstance *getTown(int objid); bool battleMoveCreatureStack(int ID, int dest); bool battleAttackCreatureStack(int ID, int dest); diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index feed4c8d6..cfc7075e8 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -131,6 +131,7 @@ void CGarrisonSlot::clickRight (tribool down) { pom = new StackState(); const CGHeroInstance *h = static_cast(getObj()); + pom->currentHealth = 0; pom->attackBonus = h->primSkills[0]; pom->defenseBonus = h->primSkills[1]; pom->luck = h->getCurrentLuck(); @@ -3023,7 +3024,7 @@ CCreInfoWindow::CCreInfoWindow printToWR(pom,276,137,GEOR13,zwykly,bitmap); //remaining health - if(State) + if(State && State->currentHealth) { printAt(CGI->preth->zelp[440].first,155,143,GEOR13,zwykly,bitmap); SDL_itoa(State->currentHealth,pom,10); diff --git a/client/Client.cpp b/client/Client.cpp index 74eb83402..d4fd58704 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -239,6 +239,17 @@ void CClient::process(int what) static_cast(playerint[sii.player])->showComp(sc); break; } + case 108: + { + HeroVisitCastle vc; + *serv >> vc; + gs->apply(&vc); + if(vc.start() && !vc.garrison() && vstd::contains(playerint,gs->getHero(vc.hid)->tempOwner)) + { + playerint[gs->getHero(vc.hid)->tempOwner]->heroVisitsTown(gs->getHero(vc.hid),gs->getTown(vc.tid)); + } + break; + } case 500: { RemoveObject rh; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 3839e5a56..d300bb261 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -77,6 +77,25 @@ struct SetSecSkill : public CPack //106 h & abs & id & which & val; } }; +struct HeroVisitCastle : public CPack //108 +{ + HeroVisitCastle(){flags=0;type = 108;}; + ui8 flags; //1 - start, 2 - garrison + ui32 tid, hid; + + bool start() //if hero is entering castle (if false - leaving) + { + return flags & 1; + } + bool garrison() //if hero is entering/leaving garrison (if false - it's only visiting hero) + { + return flags & 2; + } + template void serialize(Handler &h, const int version) + { + h & flags & tid & hid; + } +}; struct RemoveObject : public CPack //500 { RemoveObject(){type = 500;}; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 9e8dc6df5..c1f03a9ec 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -553,7 +553,7 @@ void CGameHandler::handleConnection(std::set players, CConnection &c) { tmh.result = 1; - BOOST_FOREACH(CGObjectInstance *obj, gs->map->terrain[start.x][start.y][start.z].visitableObjects) + BOOST_FOREACH(CGObjectInstance *obj, gs->map->terrain[start.x-1][start.y][start.z].visitableObjects) { //TODO: allow to handle this in script-languages if(obj->state) //hard-coded function diff --git a/server/CScriptCallback.cpp b/server/CScriptCallback.cpp index 595d1c3fe..f5c1d61d2 100644 --- a/server/CScriptCallback.cpp +++ b/server/CScriptCallback.cpp @@ -105,29 +105,19 @@ void CScriptCallback::showCompInfo(ShowInInfobox * comp) } void CScriptCallback::heroVisitCastle(int obj, int heroID) { - //CGTownInstance * n; - //if(n = dynamic_cast(ob)) - //{ - // n->visitingHero = CGI->state->map->getHero(heroID,0); - // gh->gs->map->getHero(heroID,0)->visitedTown = n; - // sv->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n); - //} - //else - // return; + HeroVisitCastle vc; + vc.hid = heroID; + vc.tid = obj; + vc.flags |= 1; + gh->sendAndApply(&vc); } void CScriptCallback::stopHeroVisitCastle(int obj, int heroID) { - //CGTownInstance * n; - //if(n = dynamic_cast(ob)) - //{ - // CGI->state->map->getHero(heroID,0)->visitedTown = NULL; - // if(n->visitingHero && n->visitingHero->type->ID == heroID) - // n->visitingHero = NULL; - // return; - //} - //else - // return; + HeroVisitCastle vc; + vc.hid = heroID; + vc.tid = obj; + gh->sendAndApply(&vc); } void CScriptCallback::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack {