1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* corrected typo in cr_shots

* recruiting creatures
This commit is contained in:
Michał W. Urbańczyk 2008-08-10 04:46:16 +00:00
parent 15ff21e84c
commit 6e02c1c5db
11 changed files with 187 additions and 164 deletions

View File

@ -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<int> n = BattleInfo::neighbouringTiles(whichOne);
for(int i=0;i<n.size();i++)

View File

@ -110,72 +110,10 @@ void CCallback::selectionMade(int selection, int asker)
//IChosen * ask = (IChosen *)asker;
//ask->chosen(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<CGTownInstance*>(static_cast<const CGTownInstance*>(obj));
//verify
bool found = false;
typedef std::pair<const int,int> Parka;
for(std::map<si32,ui32>::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;i<RESOURCE_QUANTITY;i++)
// if (gs->players[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<si32,std::pair<ui32,si32> > 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;i<RESOURCE_QUANTITY;i++)
gs->players[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;
}

View File

@ -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();

View File

@ -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<CGHeroInstance*>(map->objects[h.id])->movement = h.move;
static_cast<CGHeroInstance*>(map->objects[h.id])->mana = h.mana;
}
BOOST_FOREACH(NewTurn::Resources h, n->res) //give resources
{
for(int i=0;i<RESOURCE_QUANTITY;i++)
players[h.player].resources[i] = h.resources[i];
}
BOOST_FOREACH(SetResources h, n->res) //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<SetStrInfo*>(pack);
static_cast<CGTownInstance*>(map->objects[ssi->tid])->strInfo.creatures = ssi->cres;
//SetStrInfo *ssi = static_cast<SetStrInfo*>(pack);
//static_cast<CGTownInstance*>(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<SetAvailableCreatures*>(pack);
static_cast<CGTownInstance*>(map->objects[sac->tid])->strInfo.creatures = sac->creatures;
break;
}
case 1001://set object property
{
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
@ -417,18 +421,15 @@ void CGameState::apply(IPack * pack)
case 3006:
{
BattleAttack *br = static_cast<BattleAttack*>(pack);
mx->unlock();
apply(&br->bsa);
mx->lock();
applyNL(&br->bsa);
break;
}
//case 1002://set hover name
// {
// SetHoverName * shn = static_cast<SetHoverName*>(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)

View File

@ -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<int,int> pickObject(CGObjectInstance *obj);

View File

@ -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<ui32,CCreatureSet>::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<CGTownInstance*>(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 <<std::endl;
gs->apply(&ba);
LOCPLINT->battleAttack(&ba);
break;

View File

@ -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

13
int3.h
View File

@ -6,7 +6,18 @@ class CCreatureSet //seven combined creatures
{
public:
std::map<si32,std::pair<ui32,si32> > 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<si32,std::pair<ui32,si32> >::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<slotsAmount; i++)
if(slots.find(i) == slots.end())
return i; //return first free slot
return -1; //no slot available
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & slots & formation;

View File

@ -25,40 +25,17 @@ template <typename T> struct CPack
ui16 getType() const{return type;}
T* This(){return static_cast<T*>(this);};
};
struct NewTurn : public CPack<NewTurn> //101
struct SetResources : public CPack<SetResources> //104
{
struct Hero
{
ui32 id, move, mana; //id is a general serial id
template <typename Handler> 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 <typename Handler> void serialize(Handler &h, const int version)
{
h & player & resources;
}
bool operator<(const Resources&h)const{return player < h.player;}
};
std::set<Hero> heroes; //updates movement and mana points
std::set<Resources> res;//resource list
ui32 day;
bool resetBuilded;
NewTurn(){type = 101;};
SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;};
ui8 player;
std::vector<si32> res; //res[resid] => res amount
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroes & res & day & resetBuilded;
h & player & res;
}
};
};
struct SetResource : public CPack<SetResource> //102
{
SetResource(){type = 102;};
@ -71,17 +48,6 @@ struct SetResource : public CPack<SetResource> //102
h & player & resid & val;
}
};
struct SetResources : public CPack<SetResources> //104
{
SetResources(){type = 104;};
ui8 player;
std::vector<si32> res; //res[resid] => res amount
template <typename Handler> void serialize(Handler &h, const int version)
{
h & player & res;
}
};
struct SetPrimSkill : public CPack<SetPrimSkill> //105
{
SetPrimSkill(){type = 105;};
@ -129,17 +95,6 @@ struct SetGarrisons : public CPack<SetGarrisons> //502
h & garrs;
}
};
struct SetStrInfo : public CPack<SetStrInfo> //503
{
SetStrInfo(){type = 503;};
si32 tid;
std::map<si32,ui32> cres;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & cres;
}
};
struct NewStructures : public CPack<NewStructures> //504
{
NewStructures(){type = 504;};
@ -152,6 +107,52 @@ struct NewStructures : public CPack<NewStructures> //504
h & tid & bid & builded;
}
};
struct SetAvailableCreatures : public CPack<SetAvailableCreatures> //506
{
SetAvailableCreatures(){type = 506;};
si32 tid;
std::map<si32,ui32> creatures;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & creatures;
}
};
struct NewTurn : public CPack<NewTurn> //101
{
struct Hero
{
ui32 id, move, mana; //id is a general serial id
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & move & mana;
}
bool operator<(const Hero&h)const{return id < h.id;}
};
std::set<Hero> heroes; //updates movement and mana points
std::vector<SetResources> res;//resource list
std::vector<SetAvailableCreatures> cres;//resource list
ui32 day;
bool resetBuilded;
NewTurn(){type = 101;};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroes & cres & res & day & resetBuilded;
}
};
//struct SetStrInfo : public CPack<SetStrInfo> //503
//{
// SetStrInfo(){type = 503;};
// SetAvailableCreatures sac;
//
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & sac;
// }
//};
struct MetaString : public CPack<MetaString> //2001 helper for object scrips
{
std::vector<std::string> strings;

View File

@ -588,10 +588,10 @@ void CGameHandler::handleConnection(std::set<int> 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<int> 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<CGTownInstance*>(gs->map->objects[objid]);
//verify
bool found = false;
typedef std::pair<const int,int> Parka;
for(std::map<si32,ui32>::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;i<RESOURCE_QUANTITY;i++)
sr.res[i] = gs->players[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<ui8, PlayerState>::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;j<RESOURCE_QUANTITY;j++)
r.resources[j] = i->second.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;j<i->second.towns.size();j++)//handle towns
for(std::vector<CGTownInstance *>::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;k<CREATURES_PER_TOWN;k++) //creature growths
// {
// if(i->second.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;k<CREATURES_PER_TOWN;k++) //creature growths
{
if((**j).creatureDwelling(k))//there is dwelling (k-level)
sac.creatures[k] += (**j).creatureGrowth(k);
}
n.cres.push_back(sac);
}
if((gs->day) && i->first<PLAYER_LIMIT)//not the first day and town not neutral
r.resources[6] += i->second.towns[j]->dailyIncome();
r.res[6] += (**j).dailyIncome();
}
n.res.insert(r);
n.res.push_back(r);
}
sendAndApply(&n);
for (std::set<CCPPObjectScript *>::iterator i=cppscripts.begin();i!=cppscripts.end();i++)

View File

@ -43,7 +43,7 @@
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
WarningLevel="2"
DebugInformationFormat="4"
DisableSpecificWarnings="4251"
/>