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:
parent
8c937d92ad
commit
48cb63f144
@ -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];
|
||||
|
@ -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;
|
||||
|
30
CLua.cpp
30
CLua.cpp
@ -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
1
CLua.h
@ -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);
|
||||
|
2
CMT.cpp
2
CMT.cpp
@ -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__
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
29
ChangeLog
29
ChangeLog
@ -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
|
||||
|
@ -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
|
||||
|
2
global.h
2
global.h
@ -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
|
||||
|
||||
|
@ -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;};
|
||||
|
2
map.cpp
2
map.cpp
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user