From 6e02c1c5dbfdd32c0adb2038f3dc2e5bf4f72fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sun, 10 Aug 2008 04:46:16 +0000 Subject: [PATCH] * corrected typo in cr_shots * recruiting creatures --- CBattleInterface.cpp | 9 ++-- CCallback.cpp | 68 ++----------------------- CCallback.h | 4 +- CGameState.cpp | 37 +++++++------- CGameState.h | 1 + client/Client.cpp | 18 +++++-- config/cr_shots.txt | 2 +- int3.h | 13 ++++- lib/NetPacks.h | 103 +++++++++++++++++++------------------- server/CGameHandler.cpp | 94 +++++++++++++++++++++++++++------- server/VCMI_server.vcproj | 2 +- 11 files changed, 187 insertions(+), 164 deletions(-) diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index ebd7f7319..0454257c8 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -728,19 +728,18 @@ void CBattleInterface::hexLclicked(int whichOne) if(!myTurn) return; //we are not permit to do anything - int atCre = LOCPLINT->cb->battleGetStack(whichOne); //creature at destination tile; -1 if there is no one - //LOCPLINT->cb->battleGetCreature(); - if(atCre==-1) //no creature at that tile + CStack* dest = LOCPLINT->cb->battleGetStackByPos(whichOne); //creature at destination tile; -1 if there is no one + if(!dest || !dest->alive) //no creature at that tile { if(std::find(shadedHexes.begin(),shadedHexes.end(),whichOne)!=shadedHexes.end())// and it's in our range giveCommand(2,whichOne,activeStack); } - else if(LOCPLINT->cb->battleGetStackByID(atCre)->owner != attackingHeroInstance->tempOwner + else if(dest->owner != attackingHeroInstance->tempOwner && LOCPLINT->cb->battleCanShoot(activeStack, whichOne)) //shooting { giveCommand(7,whichOne,activeStack); } - else if(LOCPLINT->cb->battleGetStackByID(atCre)->owner != attackingHeroInstance->tempOwner) //attacking + else if(dest->owner != attackingHeroInstance->tempOwner) //attacking { std::vector n = BattleInfo::neighbouringTiles(whichOne); for(int i=0;ichosen(selection); } -void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount) +void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount) { - if(amount<=0) return; - if(obj->ID==98) //recruiting from town - { - int ser=-1; //used dwelling level - CGTownInstance *t = const_cast(static_cast(obj)); - - //verify - bool found = false; - typedef std::pair Parka; - for(std::map::iterator av=t->strInfo.creatures.begin();av!=t->strInfo.creatures.end();av++) - { - if( ( found = (ID == t->town->basicCreatures[av->first]) ) //creature is available among basic cretures - || (found = (ID == t->town->upgradedCreatures[av->first])) )//creature is available among upgraded cretures - { - amount = std::min(amount,(int)av->second); //reduce recruited amount up to available amount - ser = av->first; - break; - } - } - if(!found) //no such creature - return; - - if(amount > CGI->creh->creatures[ID].maxAmount(gs->players[player].resources)) - return; //not enough resources - - //for(int i=0;iplayers[player].resources[i] < (CGI->creh->creatures[ID].cost[i] * amount)) - // return; //not enough resources - - if(amount<=0) return; - - //recruit - int slot = -1; //slot ID - std::pair > parb; - - for(int i=0;i<7;i++) //TODO: if there is already stack of same creatures it should be used always - { - if(((!t->army.slots[i].first) && (!t->army.slots[i].second)) || (t->army.slots[i].first == ID)) //slot is free or there is saem creature - { - slot = i; - break; - } - } - - if(slot<0) //no free slot - return; - - for(int i=0;iplayers[player].resources[i] -= (CGI->creh->creatures[ID].cost[i] * amount); - - t->strInfo.creatures[ser] -= amount; - if(t->army.slots[slot].first) //add new creatures to the existing stack - { - t->army.slots[slot].second += amount; - } - else //create new stack in the garrison - { - t->army.slots[slot].first = ID; - t->army.slots[slot].second = amount; - } - cl->playerint[player]->garrisonChanged(obj); - - } - //TODO: recruit from dwellings on the adventure map + if(player!=obj->tempOwner) return; + *cl->serv << ui16(506) << obj->id << ID << amount; } diff --git a/CCallback.h b/CCallback.h index 8cb7ce1ae..643946b7f 100644 --- a/CCallback.h +++ b/CCallback.h @@ -42,7 +42,7 @@ public: virtual int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly virtual bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2)=0; //swaps artifacts between two given heroes - virtual void recruitCreatures(const CGObjectInstance *obj, int ID, int amount)=0; + virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0; virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made virtual void endTurn()=0; @@ -114,7 +114,7 @@ public: bool dismissHero(const CGHeroInstance * hero); bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2); bool buildBuilding(const CGTownInstance *town, si32 buildingID); - void recruitCreatures(const CGObjectInstance *obj, int ID, int amount); + void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount); bool dismissCreature(const CArmedInstance *obj, int stackPos); bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1); void endTurn(); diff --git a/CGameState.cpp b/CGameState.cpp index 373245b44..37b3f0c5a 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -249,9 +249,8 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO) :creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints) { } -void CGameState::apply(IPack * pack) +void CGameState::applyNL(IPack * pack) { - mx->lock(); switch(pack->getType()) { case 101://NewTurn @@ -263,11 +262,10 @@ void CGameState::apply(IPack * pack) static_cast(map->objects[h.id])->movement = h.move; static_cast(map->objects[h.id])->mana = h.mana; } - BOOST_FOREACH(NewTurn::Resources h, n->res) //give resources - { - for(int i=0;ires) //give resources + applyNL(&h); + BOOST_FOREACH(SetAvailableCreatures h, n->cres) //set available creatures in towns + applyNL(&h); if(n->resetBuilded) //reset amount of structures set in this turn in towns BOOST_FOREACH(CGTownInstance* t, map->towns) t->builded = 0; @@ -340,8 +338,8 @@ void CGameState::apply(IPack * pack) } case 503: { - SetStrInfo *ssi = static_cast(pack); - static_cast(map->objects[ssi->tid])->strInfo.creatures = ssi->cres; + //SetStrInfo *ssi = static_cast(pack); + //static_cast(map->objects[ssi->tid])->strInfo.creatures = ssi->cres; break; } case 504: @@ -353,6 +351,12 @@ void CGameState::apply(IPack * pack) t->builded = ns->builded; break; } + case 506: + { + SetAvailableCreatures *sac = static_cast(pack); + static_cast(map->objects[sac->tid])->strInfo.creatures = sac->creatures; + break; + } case 1001://set object property { SetObjectProperty *p = static_cast(pack); @@ -417,18 +421,15 @@ void CGameState::apply(IPack * pack) case 3006: { BattleAttack *br = static_cast(pack); - mx->unlock(); - apply(&br->bsa); - mx->lock(); + applyNL(&br->bsa); break; } - //case 1002://set hover name - // { - // SetHoverName * shn = static_cast(pack); - // map->objects[shn->id]->hoverName = toString(shn->name); - // break; - // } } +} +void CGameState::apply(IPack * pack) +{ + mx->lock(); + applyNL(pack); mx->unlock(); } int CGameState::pickHero(int owner) diff --git a/CGameState.h b/CGameState.h index a15411c3a..b6a5f9207 100644 --- a/CGameState.h +++ b/CGameState.h @@ -128,6 +128,7 @@ private: CGameState(); ~CGameState(); void init(StartInfo * si, Mapa * map, int Seed); + void applyNL(IPack * pack); void apply(IPack * pack); void randomizeObject(CGObjectInstance *cur); std::pair pickObject(CGObjectInstance *obj); diff --git a/client/Client.cpp b/client/Client.cpp index 687b1fd68..324648613 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -280,6 +280,7 @@ void CClient::process(int what) { SetGarrisons sg; *serv >> sg; + std::cout << "Setting garrisons." << std::endl; gs->apply(&sg); for(std::map::iterator i = sg.garrs.begin(); i!=sg.garrs.end(); i++) playerint[gs->map->objects[i->first]->tempOwner]->garrisonChanged(gs->map->objects[i->first]); @@ -287,9 +288,9 @@ void CClient::process(int what) } case 503: { - SetStrInfo ssi; - *serv >> ssi; - gs->apply(&ssi); + //SetStrInfo ssi; + //*serv >> ssi; + //gs->apply(&ssi); //TODO: notify interfaces break; } @@ -297,11 +298,21 @@ void CClient::process(int what) { NewStructures ns; *serv >> ns; + std::cout << "New structure(s) in " << ns.tid << " - " << *ns.bid.begin() << std::endl; gs->apply(&ns); BOOST_FOREACH(si32 bid, ns.bid) playerint[gs->map->objects[ns.tid]->tempOwner]->buildChanged(static_cast(gs->map->objects[ns.tid]),bid,1); break; } + case 506: + { + SetAvailableCreatures ns; + *serv >> ns; + std::cout << "Setting available creatures in " << ns.tid << std::endl; + gs->apply(&ns); + //TODO: do we need to inform interface? + break; + } case 1001: { SetObjectProperty sop; @@ -398,6 +409,7 @@ void CClient::process(int what) { BattleAttack ba; *serv >> ba; + std::cout << "Stack: " << ba.stackAttacking << " is attacking stack "<< ba.bsa.stackAttacked <apply(&ba); LOCPLINT->battleAttack(&ba); break; diff --git a/config/cr_shots.txt b/config/cr_shots.txt index 267ee540b..5d39e8b78 100644 --- a/config/cr_shots.txt +++ b/config/cr_shots.txt @@ -34,7 +34,7 @@ 169 SMBALX.DEF 0 170 PLCBOWX.DEF 0 171 PLCBOWX.DEF 0 -173 CPGRE.DEF 1 +173 CPRGRE.DEF 1 193 SMBALX.DEF 0 196 SMBALX.DEF 0 -1 \ No newline at end of file diff --git a/int3.h b/int3.h index 2b28a2885..301598434 100644 --- a/int3.h +++ b/int3.h @@ -6,7 +6,18 @@ class CCreatureSet //seven combined creatures { public: std::map > slots; //slots[slot_id]=> pair(creature_id,creature_quantity) - bool formation; //false - wide, true - tight + bool formation; //false - wide, true - tight + si32 getSlotFor(ui32 creature, ui32 slotsAmount=7) //returns -1 if no slot available + { + + for(std::map >::iterator i=slots.begin(); i!=slots.end(); i++) + if(i->second.first == creature) + return i->first; //if there is already such creature we return its slot id + for(si32 i=0; i void serialize(Handler &h, const int version) { h & slots & formation; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 94b5af6d3..010dbbdc3 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -25,40 +25,17 @@ template struct CPack ui16 getType() const{return type;} T* This(){return static_cast(this);}; }; -struct NewTurn : public CPack //101 +struct SetResources : public CPack //104 { - struct Hero - { - ui32 id, move, mana; //id is a general serial id - template void serialize(Handler &h, const int version) - { - h & id & move & mana; - } - bool operator<(const Hero&h)const{return id < h.id;} - }; - struct Resources - { - ui8 player; - si32 resources[RESOURCE_QUANTITY]; - template void serialize(Handler &h, const int version) - { - h & player & resources; - } - bool operator<(const Resources&h)const{return player < h.player;} - }; - - std::set heroes; //updates movement and mana points - std::set res;//resource list - ui32 day; - bool resetBuilded; - - NewTurn(){type = 101;}; + SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;}; + ui8 player; + std::vector res; //res[resid] => res amount template void serialize(Handler &h, const int version) { - h & heroes & res & day & resetBuilded; + h & player & res; } -}; +}; struct SetResource : public CPack //102 { SetResource(){type = 102;}; @@ -71,17 +48,6 @@ struct SetResource : public CPack //102 h & player & resid & val; } }; -struct SetResources : public CPack //104 -{ - SetResources(){type = 104;}; - ui8 player; - std::vector res; //res[resid] => res amount - - template void serialize(Handler &h, const int version) - { - h & player & res; - } -}; struct SetPrimSkill : public CPack //105 { SetPrimSkill(){type = 105;}; @@ -129,17 +95,6 @@ struct SetGarrisons : public CPack //502 h & garrs; } }; -struct SetStrInfo : public CPack //503 -{ - SetStrInfo(){type = 503;}; - si32 tid; - std::map cres; - - template void serialize(Handler &h, const int version) - { - h & tid & cres; - } -}; struct NewStructures : public CPack //504 { NewStructures(){type = 504;}; @@ -152,6 +107,52 @@ struct NewStructures : public CPack //504 h & tid & bid & builded; } }; +struct SetAvailableCreatures : public CPack //506 +{ + SetAvailableCreatures(){type = 506;}; + si32 tid; + std::map creatures; + + template void serialize(Handler &h, const int version) + { + h & tid & creatures; + } +}; +struct NewTurn : public CPack //101 +{ + struct Hero + { + ui32 id, move, mana; //id is a general serial id + template void serialize(Handler &h, const int version) + { + h & id & move & mana; + } + bool operator<(const Hero&h)const{return id < h.id;} + }; + + std::set heroes; //updates movement and mana points + std::vector res;//resource list + std::vector cres;//resource list + ui32 day; + bool resetBuilded; + + NewTurn(){type = 101;}; + + template void serialize(Handler &h, const int version) + { + h & heroes & cres & res & day & resetBuilded; + } +}; +//struct SetStrInfo : public CPack //503 +//{ +// SetStrInfo(){type = 503;}; +// SetAvailableCreatures sac; +// +// template void serialize(Handler &h, const int version) +// { +// h & sac; +// } +//}; struct MetaString : public CPack //2001 helper for object scrips { std::vector strings; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 0c45abe66..7209c558c 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -588,10 +588,10 @@ void CGameHandler::handleConnection(std::set players, CConnection &c) } else if(bid >= 30) //bas. dwelling { - SetStrInfo ssi; + SetAvailableCreatures ssi; ssi.tid = tid; - ssi.cres = t->strInfo.creatures; - ssi.cres[bid-30] = VLC->creh->creatures[t->town->basicCreatures[bid-30]].growth; + ssi.creatures = t->strInfo.creatures; + ssi.creatures[bid-30] = VLC->creh->creatures[t->town->basicCreatures[bid-30]].growth; sendAndApply(&ssi); } @@ -606,6 +606,62 @@ void CGameHandler::handleConnection(std::set players, CConnection &c) sr.res[i]-=b->resources[i]; sendAndApply(&sr); + break; + } + case 506: //recruit creature + { + si32 objid, ser=-1; //ser - used dwelling level + ui32 crid, cram; //recruited creature id and amount + c >> objid >> crid >> cram; + + CGTownInstance * t = static_cast(gs->map->objects[objid]); + + //verify + bool found = false; + typedef std::pair Parka; + for(std::map::iterator av = t->strInfo.creatures.begin(); av!=t->strInfo.creatures.end(); av++) + { + if( ( found = (crid == t->town->basicCreatures[av->first]) ) //creature is available among basic cretures + || (found = (crid == t->town->upgradedCreatures[av->first])) )//creature is available among upgraded cretures + { + cram = std::min(cram,av->second); //reduce recruited amount up to available amount + ser = av->first; + break; + } + } + int slot = t->army.getSlotFor(crid); + + if(!found || //no such creature + cram > VLC->creh->creatures[crid].maxAmount(gs->players[t->tempOwner].resources) || //lack of resources + cram<=0 || + slot<0 ) + break; + + //recruit + SetResources sr; + sr.player = t->tempOwner; + for(int i=0;iplayers[t->tempOwner].resources[i] - (VLC->creh->creatures[crid].cost[i] * cram); + + SetAvailableCreatures sac; + sac.tid = objid; + sac.creatures = t->strInfo.creatures; + sac.creatures[ser] -= cram; + + SetGarrisons sg; + sg.garrs[objid] = t->army; + if(sg.garrs[objid].slots.find(slot) == sg.garrs[objid].slots.end()) //take a free slot + { + sg.garrs[objid].slots[slot] = std::make_pair(crid,cram); + } + else //add creatures to a already existing stack + { + sg.garrs[objid].slots[slot].second += cram; + } + + sendAndApply(&sr); + sendAndApply(&sac); + sendAndApply(&sg); break; } case 3002: @@ -789,14 +845,15 @@ void CGameHandler::newTurn() { NewTurn n; n.day = gs->day + 1; + n.resetBuilded = true; for ( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) { if(i->first>=PLAYER_LIMIT) continue; - NewTurn::Resources r; + SetResources r; r.player = i->first; for(int j=0;jsecond.resources[j]; + r.res[j] = i->second.resources[j]; for (unsigned j=0;j<(*i).second.heroes.size();j++) //handle heroes { @@ -806,21 +863,24 @@ void CGameHandler::newTurn() h.mana = (*i).second.heroes[j]->mana; n.heroes.insert(h); } - for(unsigned j=0;jsecond.towns.size();j++)//handle towns + for(std::vector::iterator j=i->second.towns.begin();j!=i->second.towns.end();j++)//handle towns { - i->second.towns[j]->builded=0; - //if(gs->getDate(1)==1) //first day of week - //{ - // for(int k=0;ksecond.towns[j]->creatureDwelling(k))//there is dwelling (k-level) - // i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k); - // } - //} + if(gs->getDate(1)==7) //first day of week + { + SetAvailableCreatures sac; + sac.tid = (**j).id; + sac.creatures = (**j).strInfo.creatures; + for(int k=0;kday) && i->firstsecond.towns[j]->dailyIncome(); + r.res[6] += (**j).dailyIncome(); } - n.res.insert(r); + n.res.push_back(r); } sendAndApply(&n); for (std::set::iterator i=cppscripts.begin();i!=cppscripts.end();i++) diff --git a/server/VCMI_server.vcproj b/server/VCMI_server.vcproj index 34dd0ad1d..d16b23846 100644 --- a/server/VCMI_server.vcproj +++ b/server/VCMI_server.vcproj @@ -43,7 +43,7 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" - WarningLevel="3" + WarningLevel="2" DebugInformationFormat="4" DisableSpecificWarnings="4251" />