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

* possibly fixed bug with the mage guild when no spells available

* events won't be shown and won't block movement
* casualties among hero army and neutral creatures are saved
* it's possible to build lighthouse
* increased thread-safety (may prevent some crashes)
* minor fixes
This commit is contained in:
Michał W. Urbańczyk 2008-09-20 18:30:37 +00:00
parent 8c937d92ad
commit 48cb63f144
17 changed files with 157 additions and 69 deletions

View File

@ -1440,7 +1440,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
int sp = owner->town->spellsAtLevel(i+1,false);
for(int j=0; j<sp; j++)
{
if(i < owner->town->mageGuildLevel())
if(i<owner->town->mageGuildLevel() && owner->town->spells[i].size()<j)
{
spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
spells[spells.size()-1].pos = positions[i][j];

View File

@ -505,6 +505,12 @@ void CGameState::applyNL(IPack * pack)
case 1001://set object property
{
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
if(p->what == 3) //set creatures amount
{
tlog5 << "Setting creatures amount in " << p->id << std::endl;
static_cast<CCreatureObjInfo*>(map->objects[p->id]->info)->number = p->val;
break;
}
ui8 CGObjectInstance::*point;
switch(p->what)
{
@ -894,7 +900,12 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
{
randomizeObject(map->objects[no]);
if(map->objects[no]->ID==26)
{
map->objects[no]->defInfo->handler=NULL;
map->removeBlockVisTiles(map->objects[no]);
map->objects[no]->defInfo->blockMap[5] = 255;
map->addBlockVisTiles(map->objects[no]);
}
map->objects[no]->hoverName = VLC->objh->names[map->objects[no]->ID];
}
//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;

View File

@ -791,40 +791,40 @@ void CMonsterS::newObject(int objid)
switch(VLC->creh->creatures[os->subID].level)
{
case 1:
amounts[objid] = rand()%31+20;
cb->setAmount(objid,rand()%31+20);
break;
case 2:
amounts[objid] = rand()%16+15;
cb->setAmount(objid,rand()%16+15);
break;
case 3:
amounts[objid] = rand()%16+10;
cb->setAmount(objid,rand()%16+10);
break;
case 4:
amounts[objid] = rand()%11+10;
cb->setAmount(objid,rand()%11+10);
break;
case 5:
amounts[objid] = rand()%9+8;
cb->setAmount(objid,rand()%9+8);
break;
case 6:
amounts[objid] = rand()%8+5;
cb->setAmount(objid,rand()%8+5);
break;
case 7:
amounts[objid] = rand()%7+3;
cb->setAmount(objid,rand()%7+3);
break;
case 8:
amounts[objid] = rand()%4+2;
cb->setAmount(objid,rand()%4+2);
break;
case 9:
amounts[objid] = rand()%3+2;
cb->setAmount(objid,rand()%3+2);
break;
case 10:
amounts[objid] = rand()%3+1;
cb->setAmount(objid,rand()%3+1);
break;
}
MetaString ms;
int pom = CCreature::getQuantityID(amounts[objid]);
int pom = CCreature::getQuantityID(((CCreatureObjInfo*)(os->info))->number);
pom = 174 + 3*pom + 1;
ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,os->subID);
cb->setHoverName(objid,&ms);
@ -834,7 +834,7 @@ void CMonsterS::onHeroVisit(int objid, int heroID)
DEFOS;
CCreatureSet set;
//TODO: zrobic secik w sposob wyrafinowany
set.slots[0] = std::pair<ui32,si32>(os->subID,amounts[objid]);
set.slots[0] = std::pair<ui32,si32>(os->subID,((CCreatureObjInfo*)(os->info))->number);
cb->startBattle(heroID,set,os->pos,boost::bind(&CMonsterS::endBattleWith,this,os,_1));
}
std::vector<int> CMonsterS::yourObjects() //returns IDs of objects which are handled by script
@ -852,7 +852,11 @@ void CMonsterS::endBattleWith(const CGObjectInstance *monster, BattleResult *res
}
else
{
//TODO: remove casualties
int killedAmount=0;
for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++)
if(i->first == monster->subID)
killedAmount += i->second;
cb->setAmount(monster->id,((CCreatureObjInfo*)(monster->info))->number - killedAmount);
}
}

1
CLua.h
View File

@ -171,7 +171,6 @@ public:
class CMonsterS : public CCPPObjectScript
{
public:
std::map<int, int> amounts; //monster id -> stack quantity
CMonsterS(CScriptCallback * CB):CCPPObjectScript(CB){};
void newObject(int objid);
void onHeroVisit(int objid, int heroID);

View File

@ -221,7 +221,7 @@ int main(int argc, char** argv)
while(1) //main SDL events loop
{
SDL_WaitEvent(&ev);
if(ev.type==SDL_QUIT)
if((ev.type==SDL_QUIT) || (ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{
cl.close();
#ifndef __unix__

View File

@ -172,7 +172,10 @@ void CPathfinder::AddNeighbors(vector<Coordinate>* branch)
bool pass = true; //checking for allowed visiting direction
for(int b=0; b<CGI->mh->ttiles[i][j][node.z].tileInfo->visitableObjects.size(); ++b) //checking destination tile
{
CGDefInfo * di = CGI->mh->ttiles[i][j][node.z].tileInfo->visitableObjects[b]->defInfo;
const TerrainTile * pom = CGI->mh->ttiles[i][j][node.z].tileInfo;
if(!vstd::contains(pom->blockingObjects,pom->visitableObjects[b]))
break;
CGDefInfo * di = pom->visitableObjects[b]->defInfo;
if( (i == node.x-1 && j == node.y-1) && !(di->visitDir & (1<<4)) )
{
pass = false; break;
@ -208,7 +211,10 @@ void CPathfinder::AddNeighbors(vector<Coordinate>* branch)
}
for(int b=0; b<CGI->mh->ttiles[node.x][node.y][node.z].tileInfo->visitableObjects.size(); ++b) //checking source tile
{
CGDefInfo * di = CGI->mh->ttiles[node.x][node.y][node.z].tileInfo->visitableObjects[b]->defInfo;
const TerrainTile * pom = CGI->mh->ttiles[node.x][node.y][node.z].tileInfo;
if(!vstd::contains(pom->blockingObjects,pom->visitableObjects[b]))
break;
CGDefInfo * di = pom->visitableObjects[b]->defInfo;
if( (i == node.x-1 && j == node.y-1) && !(di->visitDir & (1<<0)) )
{
pass = false; break;
@ -269,11 +275,12 @@ void CPathfinder::CalcH(Coordinate* node)
* If there is fog of war on the node.
* => Impossible to move there.
*/
if( (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->blocked && !(node->x==End.x && node->y==End.y && CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->visitable)) ||
(CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype==rock) ||
((blockLandSea) && (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype==water)) ||
const TerrainTile *pom = CGI->mh->ttiles[node->x][node->y][node->z].tileInfo;
if( (pom->blocked && !(node->x==End.x && node->y==End.y && pom->visitable)) ||
(pom->tertype==rock) ||
((blockLandSea) && (pom->tertype==water)) ||
(!CGI->state->players[Hero->tempOwner].fogOfWarMap[node->x][node->y][node->z]) ||
((!blockLandSea) && (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype!=water)))
((!blockLandSea) && (pom->tertype!=water)))
{
//Impossible.

View File

@ -957,7 +957,7 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
playerID=Player;
serialID=serial;
human=true;
pim = new boost::mutex;
pim = new boost::recursive_mutex;
showingDialog = new CondSh<bool>(false);
}
CPlayerInterface::~CPlayerInterface()
@ -1100,7 +1100,7 @@ int getDir(int3 src, int3 dst)
}
void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
//initializing objects and performing first step of move
const CGHeroInstance * ho = details.ho; //object representing this hero
int3 hp = details.src;
@ -1536,7 +1536,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
}
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
graphics->heroWins.erase(hero->ID);
adventureInt->heroList.updateHList();
}
@ -1721,19 +1721,6 @@ void CPlayerInterface::handleKeyDown(SDL_Event *sEvent)
LOCPLINT->adventureInt->scrollingDown = true;
break;
}
case (SDLK_F4):
{
if(sEvent->key.keysym.mod & KMOD_LALT) //Alt+F4
{
exit(0);
break;
}
}
//case (SDLK_q):
// {
// exit(0);
// break;
// }
case (SDLK_u):
{
adventureInt->underground.clickLeft(true);
@ -1853,7 +1840,7 @@ int3 CPlayerInterface::repairScreenPos(int3 pos)
}
void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
SDL_FreeSurface(graphics->heroWins[hero->subID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
graphics->heroWins[hero->subID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki.
if (adventureInt->selection == hero)
@ -1863,7 +1850,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
void CPlayerInterface::receivedResource(int type, int val)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(!curint->subInt)
adventureInt->resdatabar.draw();
}
@ -1871,7 +1858,7 @@ void CPlayerInterface::receivedResource(int type, int val)
void CPlayerInterface::showSelDialog(std::string &text, const std::vector<Component*> &components, ui32 askID)
//void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
adventureInt->hide(); //dezaktywacja starego interfejsu
std::vector<CSelectableComponent*> intComps;
for(int i=0;i<components.size();i++)
@ -1892,14 +1879,14 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std:
while(showingDialog->data)
showingDialog->cond.wait(un);
}
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
curint->deactivate();
lw->activate();
}
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
//redraw infowindow
SDL_FreeSurface(graphics->townWins[town->id]);
graphics->townWins[town->id] = infoWin(town);
@ -1928,12 +1915,12 @@ void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownIn
{
if(hero->tempOwner != town->tempOwner)
return;
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
openTownWindow(town);
}
void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(obj->ID == 34) //hero
{
const CGHeroInstance * hh;
@ -1977,7 +1964,7 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
}
void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
switch (buildingID)
{
case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15:
@ -2004,7 +1991,7 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID,
void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side) //called by engine when battle starts; side=0 - left, side=1 - right
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
curint->deactivate();
curint = new CBattleInterface(army1,army2,hero1,hero2);
curint->activate();
@ -2033,7 +2020,7 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn
{
CBattleInterface *b = dynamic_cast<CBattleInterface*>(curint);
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
b->stackActivated(stackID);
}
//wait till BattleInterface sets its command
@ -2057,7 +2044,7 @@ void CPlayerInterface::battleEnd(BattleResult *br)
void CPlayerInterface::battleResultQuited()
{
//boost::unique_lock<boost::mutex> un(*pim);
//boost::unique_lock<boost::recursive_mutex> un(*pim);
((CBattleInterface*)curint)->resWindow->deactivate();
objsToBlit -= curint;
delete curint;
@ -2067,12 +2054,12 @@ void CPlayerInterface::battleResultQuited()
void CPlayerInterface::battleStackMoved(int ID, int dest, bool startMoving, bool endMoving)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
dynamic_cast<CBattleInterface*>(curint)->stackMoved(ID, dest, startMoving, endMoving);
}
void CPlayerInterface::battleAttack(BattleAttack *ba)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(ba->shot())
dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ba->stackAttacking,cb->battleGetPos(ba->bsa.stackAttacked));
else
@ -2094,7 +2081,7 @@ void CPlayerInterface::battleStackIsShooting(int ID, int dest)
void CPlayerInterface::showComp(SComponent comp)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
adventureInt->infoBar.showComp(&comp,4000);
}
@ -2108,6 +2095,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<Compo
void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<SComponent*> & components)
{
showingDialog->set(true);
boost::unique_lock<boost::recursive_mutex> un(*pim);
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
@ -2120,6 +2108,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<SComp
}
void CPlayerInterface::showYesNoDialog(std::string &text, const std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur, bool DelComps)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(deactivateCur)
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
@ -2142,7 +2131,7 @@ void CPlayerInterface::showYesNoDialog(std::string &text, const std::vector<SCom
void CPlayerInterface::showYesNoDialog( std::string &text, const std::vector<Component*> &components, ui32 askID )
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<SComponent*> intComps;
@ -2164,20 +2153,24 @@ void CPlayerInterface::showYesNoDialog( std::string &text, const std::vector<Com
}
void CPlayerInterface::removeObjToBlit(IShowable* obj)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
objsToBlit.erase
(std::find(objsToBlit.begin(),objsToBlit.end(),obj));
//delete obj;
}
void CPlayerInterface::tileRevealed(int3 pos)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
adventureInt->minimap.showTile(pos);
}
void CPlayerInterface::tileHidden(int3 pos)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
adventureInt->minimap.hideTile(pos);
}
void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
adventureInt->heroWindow->setHero(hero);
this->objsToBlit.push_back(adventureInt->heroWindow);
curint->deactivate();
@ -2191,7 +2184,7 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(curint->subInt == adventureInt->heroWindow)
{
adventureInt->heroWindow->deactivate();
@ -2236,7 +2229,7 @@ void CPlayerInterface::updateWater()
void CPlayerInterface::availableCreaturesChanged( const CGTownInstance *town )
{
boost::unique_lock<boost::mutex> un(*pim);
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(curint == castleInt)
{
CFortScreen *fs = dynamic_cast<CFortScreen*>(curint->subInt);

View File

@ -30,6 +30,7 @@ template <typename T> struct CondSh;
namespace boost
{
class mutex;
class recursive_mutex;
};
class IShowable
@ -316,7 +317,7 @@ class CPlayerInterface : public CGameInterface
public:
//minor interfaces
CondSh<bool> *showingDialog;
boost::mutex *pim;
boost::recursive_mutex *pim;
bool makingTurn;
SDL_Event * current;
CMainInterface *curint;

View File

@ -1,3 +1,32 @@
0.62 -> 0.63 (Sep 28 2008???)
* very significant optimization of battles
* battle summary window
* fixed crashbug on exiting battle
* mostly done morketplace
* confirm window is shown before retreat
* it's possible to use other port than 3030 by passing it as an additional argument
* removed some redundant warnings
* stack queue in battle (shows when 'c' key is pressed)
* partially done spellbook
* fixed crashbug with battles on swamps and rough terrain
* counterattacks
* heroes learn spells in towns
* it's possible to attack enemy hero
* setting army formation
* fixed bug with disappearing head of a hero in adventure map
* some objects are no longer accessible from the top
* no tooltips for objects under FoW
* working resource silo
* neutral monster army disappears when defeated
* Alt+F4 quits the game
* dead stacks won't be displayed in battle queue
* possibly fixed bug with the mage guild when no spells available
* events won't be shown and won't block movement
* casualties among hero army and neutral creatures are saved
* it's possible to build lighthouse
* increased thread-safety (may prevent some crashes)
* minor fixes
0.61 -> 0.62 (Sep 01 2008)
General:
* restructured to the server-client model

View File

@ -2,7 +2,7 @@
0
TPTHBKCS.BMP
10 11 12 13 | 7 8 9 | 5 22 | 16
14 15 | 0 1 2 3 | 6
14 15 | 0 1 2 3 | 6 17
21 | 18 19
30 37 | 31 38 | 32 39 | 33 40
34 41 | 35 42 | 36 43

View File

@ -16,7 +16,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
#define THC
#endif
#define NAME_VER ("VCMI 0.63")
#define NAME_VER ("VCMI 0.62b")
#define CONSOLE_LOGGING_LEVEL 5
#define FILE_LOGGING_LEVEL 6

View File

@ -286,7 +286,7 @@ struct InfoWindow : public CPack<InfoWindow> //103 - displays simple info windo
struct SetObjectProperty : public CPack<SetObjectProperty>//1001
{
ui32 id;
ui8 what; //1 - owner; 2 - blockvis
ui8 what; //1 - owner; 2 - blockvis; 3 - amount (works with creatures stacks)
ui32 val;
SetObjectProperty(){type = 1001;};
SetObjectProperty(ui32 ID, ui8 What, ui32 Val):id(ID),what(What),val(Val){type = 1001;};

View File

@ -500,7 +500,7 @@ void Mapa::removeBlockVisTiles(CGObjectInstance * obj)
if(!((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1))
{
curt.blockingObjects -= obj;
curt.blocked = curt.visitableObjects.size();
curt.blocked = curt.blockingObjects.size();
}
}
}

View File

@ -458,6 +458,8 @@ void CMapHandler::initObjectRects()
}
void processDef (CGDefInfo* def)
{
if(def->id == 26)
return;
def->handler=CDefHandler::giveDef(def->name);
def->width = def->handler->ourImages[0].bitmap->w/32;
def->height = def->handler->ourImages[0].bitmap->h/32;

View File

@ -241,6 +241,23 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
}
}
CCreatureSet takeCasualties(int color, const CCreatureSet &set, BattleInfo *bat)
{
CCreatureSet ret(set);
for(int i=0; i<bat->stacks.size();i++)
{
CStack *st = bat->stacks[i];
if(st->owner==color && vstd::contains(set.slots,st->slot) && st->amount < set.slots.find(st->slot)->second.second)
{
if(st->alive())
ret.slots[st->slot].second = st->amount;
else
ret.slots.erase(st->slot);
}
}
return ret;
}
void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)
{
BattleInfo *curB = new BattleInfo;
@ -285,17 +302,35 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
if(hero1->tempOwner<PLAYER_LIMIT)
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,false);
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,false);
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,false);
//casualties among heroes armies
SetGarrisons sg;
if(hero1)
sg.garrs[hero1->id] = takeCasualties(hero1->tempOwner,hero1->army,gs->curB);
if(hero2)
sg.garrs[hero2->id] = takeCasualties(hero2->tempOwner,hero2->army,gs->curB);
sendAndApply(&sg);
//end battle, remove all info, free memory
sendAndApply(battleResult.data);
if(cb)
cb(battleResult.data);
//if one hero has lost we will erase him
if(battleResult.data->winner!=0 && hero1)
{
RemoveObject ro(hero1->id);
sendAndApply(&ro);
}
if(battleResult.data->winner!=1 && hero2)
{
RemoveObject ro(hero2->id);
sendAndApply(&ro);
}
delete battleResult.data;
//for(int i=0;i<stacks.size();i++)
// delete stacks[i];
//delete curB;
//curB = NULL;
}
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
{
@ -349,7 +384,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
states.setFlag(gs->currentPlayer,&PlayerStatus::makingTurn,false);
break;
}
case 500:
case 500: //dismiss hero
{
si32 id;
c >> id;
@ -521,7 +556,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
sendAndApply(&sg);
break;
}
case 503:
case 503: //disband creature
{
si32 id;
ui8 pos;
@ -533,7 +568,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
sendAndApply(&sg);
break;
}
case 504:
case 504: //build structure
{
si32 tid, bid;
c >> tid >> bid;
@ -1368,7 +1403,7 @@ void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h
cs.learn = true;
for(int i=0; i<std::min(t->mageGuildLevel(),h->getSecSkillLevel(7)+4);i++)
{
for(int j=0; j<t->spellsAtLevel(i+1,true); j++)
for(int j=0; j<t->spellsAtLevel(i+1,true) && j<t->spells[i].size(); j++)
{
if(!vstd::contains(h->spells,t->spells[i][j]))
cs.spells.insert(t->spells[i][j]);

View File

@ -33,6 +33,12 @@ void CScriptCallback::removeObject(int objid)
gh->sendAndApply(&ro);
}
void CScriptCallback::setAmount(int objid, ui32 val)
{
SetObjectProperty sop(objid,3,val);
gh->sendAndApply(&sop);
}
void CScriptCallback::setOwner(int objid, ui8 owner)
{
SetObjectProperty sop(objid,1,owner);

View File

@ -55,6 +55,7 @@ public:
void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack
void startBattle(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void startBattle(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
void setAmount(int objid, ui32 val);
//friends
friend class CGameHandler;