mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* version set to 0.62
* almost redone treasure chest * working gaining levels for heroes (including dialog with skill selection) * corrected another typo i cr_shots
This commit is contained in:
parent
6e02c1c5db
commit
b89c951d09
@ -20,4 +20,8 @@ void CEmptyAI::heroCreated(const CGHeroInstance *)
|
||||
}
|
||||
void CEmptyAI::heroMoved(const HeroMoveDetails &)
|
||||
{
|
||||
}
|
||||
void CEmptyAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
callback(rand()%skills.size());
|
||||
}
|
@ -13,6 +13,7 @@ public:
|
||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
||||
void tileRevealed(int3 pos){};
|
||||
void tileHidden(int3 pos){};
|
||||
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
};
|
||||
|
||||
#define NAME "EmptyAI 0.1"
|
@ -5,7 +5,6 @@
|
||||
#include "hch/CLodHandler.h"
|
||||
#include "hch/CPreGameTextHandler.h"
|
||||
#include "hch/CTownHandler.h"
|
||||
#include "CLua.h"
|
||||
#include "CCallback.h"
|
||||
#include "client/Graphics.h"
|
||||
AdventureMapButton::AdventureMapButton ()
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "CMessage.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "CLua.h"
|
||||
#include "hch/CHeroHandler.h"
|
||||
#include <sstream>
|
||||
#include "AdventureMapButton.h"
|
||||
|
@ -106,9 +106,7 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
|
||||
void CCallback::selectionMade(int selection, int asker)
|
||||
{
|
||||
//todo - jak bedzie multiplayer po sieci, to moze wymagac przerobek zaleznych od obranego modelu
|
||||
//IChosen * ask = (IChosen *)asker;
|
||||
//ask->chosen(selection);
|
||||
*cl->serv << ui16(2001) << ui32(asker) << ui32(selection);
|
||||
}
|
||||
void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "global.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <boost/function.hpp>
|
||||
#include "lib/BattleAction.h"
|
||||
BOOST_TRIBOOL_THIRD_STATE(outOfRange)
|
||||
|
||||
@ -55,9 +56,10 @@ public:
|
||||
virtual void tileHidden(int3 pos){};
|
||||
virtual void receivedResource(int type, int val){};
|
||||
virtual void showInfoDialog(std::string text, std::vector<Component*> &components){};
|
||||
virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)=0;
|
||||
virtual void showSelDialog(std::string text, std::vector<Component*> &components, ui32 askID){};
|
||||
virtual void garrisonChanged(const CGObjectInstance * obj){};
|
||||
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||
//battle call-ins
|
||||
virtual void 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
|
||||
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning
|
||||
|
@ -304,6 +304,29 @@ void CGameState::applyNL(IPack * pack)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 106:
|
||||
{
|
||||
SetSecSkill *sr = static_cast<SetSecSkill*>(pack);
|
||||
CGHeroInstance *hero = getHero(sr->id);
|
||||
if(hero->getSecSkillLevel(sr->which) < 0)
|
||||
{
|
||||
hero->secSkills.push_back(std::pair<int,int>(sr->which, (sr->abs)? (sr->val) : (sr->val-1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned i=0;i<hero->secSkills.size();i++)
|
||||
{
|
||||
if(hero->secSkills[i].first == sr->which)
|
||||
{
|
||||
if(sr->abs)
|
||||
hero->secSkills[i].second = sr->val;
|
||||
else
|
||||
hero->secSkills[i].second += sr->val;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
{
|
||||
RemoveHero *rh = static_cast<RemoveHero*>(pack);
|
||||
@ -360,7 +383,7 @@ void CGameState::applyNL(IPack * pack)
|
||||
case 1001://set object property
|
||||
{
|
||||
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
|
||||
int CGObjectInstance::*point;
|
||||
ui8 CGObjectInstance::*point;
|
||||
switch(p->what)
|
||||
{
|
||||
case 1:
|
||||
@ -373,6 +396,12 @@ void CGameState::applyNL(IPack * pack)
|
||||
map->objects[p->id]->*point = p->val;
|
||||
break;
|
||||
}
|
||||
case 2000:
|
||||
{
|
||||
HeroLevelUp * bs = static_cast<HeroLevelUp*>(pack);
|
||||
getHero(bs->heroid)->level = bs->level;
|
||||
break;
|
||||
}
|
||||
case 3000:
|
||||
{
|
||||
BattleStart * bs = static_cast<BattleStart*>(pack);
|
||||
|
@ -62,7 +62,6 @@ CHeroWindow::CHeroWindow(int playerColor):
|
||||
heroListMi[g]->id = g;
|
||||
}
|
||||
|
||||
skillpics = CDefHandler::giveDef("pskil42.def");
|
||||
flags = CDefHandler::giveDef("CREST58.DEF");
|
||||
//areas
|
||||
portraitArea = new LRClickableAreaWText();
|
||||
@ -126,7 +125,6 @@ CHeroWindow::~CHeroWindow()
|
||||
if(curBack)
|
||||
SDL_FreeSurface(curBack);
|
||||
|
||||
delete skillpics;
|
||||
delete flags;
|
||||
|
||||
delete garInt;
|
||||
@ -219,22 +217,8 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
{
|
||||
secSkillAreas[g]->type = hero->secSkills[g].first;
|
||||
secSkillAreas[g]->bonus = hero->secSkills[g].second;
|
||||
std::string hlp;
|
||||
switch(hero->secSkills[g].second)
|
||||
{
|
||||
case 0: //basic level
|
||||
hlp = CGI->abilh->abilities[ hero->secSkills[g].first ]->basicText;
|
||||
secSkillAreas[g]->text = hlp.substr(1, hlp.size()-2);
|
||||
break;
|
||||
case 1: //adv level
|
||||
hlp = CGI->abilh->abilities[ hero->secSkills[g].first ]->advText;
|
||||
secSkillAreas[g]->text = hlp.substr(1, hlp.size()-2);
|
||||
break;
|
||||
case 2: //expert level
|
||||
hlp = CGI->abilh->abilities[ hero->secSkills[g].first ]->expText;
|
||||
secSkillAreas[g]->text = hlp.substr(1, hlp.size()-2);
|
||||
break;
|
||||
}
|
||||
std::string hlp = CGI->abilh->abilities[ hero->secSkills[g].first ]->infoTexts[hero->secSkills[g].second];
|
||||
secSkillAreas[g]->text = hlp.substr(1, hlp.size()-2);
|
||||
|
||||
char * hlpp = new char[200];
|
||||
sprintf(hlpp, CGI->generaltexth->heroscrn[21].c_str(), CGI->abilh->levels[hero->secSkills[g].second].c_str(), CGI->abilh->abilities[hero->secSkills[g].first]->name.c_str());
|
||||
@ -729,12 +713,12 @@ void CHeroWindow::redrawCurBack()
|
||||
SDL_FreeSurface(curBack);
|
||||
curBack = SDL_DisplayFormat(background);
|
||||
|
||||
blitAt(skillpics->ourImages[0].bitmap, 32, 111, curBack);
|
||||
blitAt(skillpics->ourImages[1].bitmap, 102, 111, curBack);
|
||||
blitAt(skillpics->ourImages[2].bitmap, 172, 111, curBack);
|
||||
blitAt(skillpics->ourImages[5].bitmap, 242, 111, curBack);
|
||||
blitAt(skillpics->ourImages[4].bitmap, 20, 230, curBack);
|
||||
blitAt(skillpics->ourImages[3].bitmap, 162, 230, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[0].bitmap, 32, 111, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[1].bitmap, 102, 111, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[2].bitmap, 172, 111, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[5].bitmap, 242, 111, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[4].bitmap, 20, 230, curBack);
|
||||
blitAt(graphics->pskillsm->ourImages[3].bitmap, 162, 230, curBack);
|
||||
|
||||
blitAt(graphics->portraitLarge[curHero->portrait], 19, 19, curBack);
|
||||
|
||||
|
@ -88,7 +88,7 @@ class CHeroWindow: public IActivable, public IShowable, public virtual CIntObjec
|
||||
CStatusBar * ourBar; //heroWindow's statusBar
|
||||
|
||||
//general graphics
|
||||
CDefHandler * skillpics, *flags;
|
||||
CDefHandler *flags;
|
||||
|
||||
//buttons
|
||||
AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
|
||||
|
104
CLua.cpp
104
CLua.cpp
@ -1,5 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include <sstream>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "hch/CHeroHandler.h"
|
||||
@ -516,12 +518,12 @@ void CPickable::onHeroVisit(int objid, int heroID)
|
||||
DEFOS;
|
||||
switch(os->ID)
|
||||
{
|
||||
case 5:
|
||||
case 5: //artifact
|
||||
{
|
||||
cb->giveHeroArtifact(os->subID,heroID,-1); //TODO: na pozycje
|
||||
break;
|
||||
}
|
||||
case 79:
|
||||
case 79: //resource
|
||||
{
|
||||
//TODO: handle guards (when battles are finished)
|
||||
CResourceObjInfo * t2 = static_cast<CResourceObjInfo *>(os->info);
|
||||
@ -561,64 +563,60 @@ void CPickable::onHeroVisit(int objid, int heroID)
|
||||
cb->showCompInfo(&sii);
|
||||
break;
|
||||
}
|
||||
case 101:
|
||||
case 101: //treasure chest
|
||||
{
|
||||
//if (os->subID)
|
||||
// break; //not OH3 treasure chest
|
||||
//int wyn = rand()%100;
|
||||
//if (wyn<32)
|
||||
//{
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
|
||||
//}//1k/0.5k
|
||||
//else if(wyn<64)
|
||||
//{
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1500));
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1000));
|
||||
//}//1.5k/1k
|
||||
//else if(wyn<95)
|
||||
//{
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::resource,6,2000));
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1500));
|
||||
//}//2k/1.5k
|
||||
//else
|
||||
//{
|
||||
// if (1/*TODO: backpack is full*/)
|
||||
// {
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
|
||||
// tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //TODO: give treasure artifact
|
||||
// break;
|
||||
// }
|
||||
//}//random treasure artifact, or (if backapack is full) 1k/0.5k
|
||||
//tempStore[1]->ID = heroID;
|
||||
//player = cb->getHeroOwner(heroID);
|
||||
//cb->showSelDialog(player,VLC->objh->advobtxt[146],&tempStore,this);
|
||||
if (os->subID) //not OH3 treasure chest
|
||||
break;
|
||||
int wyn = rand()%100, val=0;
|
||||
if (wyn<32) //1k/0.5k
|
||||
{
|
||||
val = 1000;
|
||||
}
|
||||
else if(wyn<64) //1.5k/1k
|
||||
{
|
||||
val = 1500;
|
||||
}
|
||||
else if(wyn<95) //2k/1.5k
|
||||
{
|
||||
val = 2000;
|
||||
}
|
||||
else //random treasure artifact, or (if backapack is full) 1k/0.5k
|
||||
{
|
||||
if (1/*TODO: backpack is full*/)
|
||||
{
|
||||
val = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: give treasure artifact
|
||||
break;
|
||||
}
|
||||
}
|
||||
SelectionDialog sd;
|
||||
sd.player = cb->getHeroOwner(heroID);
|
||||
sd.text << std::pair<ui8,ui32>(11,146);
|
||||
sd.components.push_back(Component(2,6,val,0));
|
||||
sd.components.push_back(Component(5,0,val-500,0));
|
||||
boost::function<void(ui32)> fun = boost::bind(&CPickable::chosen,this,_1,heroID,val);
|
||||
cb->showSelectionDialog(&sd,fun);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//VLC->mh->removeObject(os);
|
||||
}
|
||||
void CPickable::chosen(int which)
|
||||
void CPickable::chosen(ui32 which, int heroid, int val)
|
||||
{
|
||||
//switch(tempStore[which]->type)
|
||||
//{
|
||||
//case SComponent::resource:
|
||||
// cb->giveResource(player,tempStore[which]->subtype,tempStore[which]->val);
|
||||
// break;
|
||||
//case SComponent::experience:
|
||||
// cb->changePrimSkill(tempStore[which]->ID,4,tempStore[which]->val);
|
||||
// break;
|
||||
//default:
|
||||
// throw new std::exception("Unhandled choice");
|
||||
//
|
||||
//}
|
||||
//for (int i=0;i<tempStore.size();i++)
|
||||
// delete tempStore[i];
|
||||
//tempStore.clear();
|
||||
switch(which)
|
||||
{
|
||||
case 0: //player pick gold
|
||||
cb->giveResource(cb->getHeroOwner(heroid),6,val);
|
||||
break;
|
||||
case 1: //player pick exp
|
||||
cb->changePrimSkill(heroid, 4, val-500);
|
||||
break;
|
||||
default:
|
||||
throw std::string("Unhandled choice");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> CPickable::yourObjects() //returns IDs of objects which are handled by script
|
||||
|
12
CLua.h
12
CLua.h
@ -60,11 +60,6 @@ public:
|
||||
CScript();
|
||||
virtual ~CScript();
|
||||
};
|
||||
class IChosen
|
||||
{
|
||||
public:
|
||||
virtual void chosen(int which)=0;
|
||||
};
|
||||
class CLua :public CScript
|
||||
{
|
||||
protected:
|
||||
@ -140,14 +135,11 @@ public:
|
||||
void newTurn ();
|
||||
};
|
||||
|
||||
class CPickable : public CCPPObjectScript, public IChosen //pickable - resources, artifacts, etc
|
||||
class CPickable : public CCPPObjectScript //pickable - resources, artifacts, etc
|
||||
{
|
||||
public:
|
||||
std::vector<CSelectableComponent*> tempStore;
|
||||
int player;
|
||||
|
||||
CPickable(CScriptCallback * CB):CCPPObjectScript(CB){};
|
||||
void chosen(int which);
|
||||
void chosen(ui32 which, int heroid, int val); //val - value of treasure in gold
|
||||
void newObject(int objid);
|
||||
void onHeroVisit(int objid, int heroID);
|
||||
std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
|
||||
|
1
CMT.cpp
1
CMT.cpp
@ -22,7 +22,6 @@
|
||||
#include "CCallback.h"
|
||||
#include "CPlayerInterface.h"
|
||||
#include "CLuaHandler.h"
|
||||
#include "CLua.h"
|
||||
#include "CAdvmapInterface.h"
|
||||
#include "hch/CBuildingHandler.h"
|
||||
#include "hch/CVideoHandler.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "CGameInfo.h"
|
||||
#include "SDL_Extensions.h"
|
||||
#include <sstream>
|
||||
#include "CLua.h"
|
||||
#include "hch/CGeneralTextHandler.h"
|
||||
#include "client/Graphics.h"
|
||||
SDL_Color tytulowy, tlo, zwykly ;
|
||||
@ -464,10 +463,10 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_S
|
||||
CSelWindow * CMessage::genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner)
|
||||
{
|
||||
CSelWindow * ret = new CSelWindow();
|
||||
for(int i=0;i<comps.size();i++)
|
||||
for(unsigned i=0;i<comps.size();i++)
|
||||
{
|
||||
ret->components.push_back(comps[i]);
|
||||
comps[i]->owner = ret;
|
||||
comps[i]->onSelect = boost::bind(&CSelWindow::selectionChange,ret,i);
|
||||
}
|
||||
std::vector<std::string> * tekst = breakText(text,charperline);
|
||||
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst);
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "hch/CObjectHandler.h"
|
||||
#include "CBattleInterface.h"
|
||||
#include "CGameInfo.h"
|
||||
#include "CLua.h"
|
||||
#include <cmath>
|
||||
#include "client/CCreatureAnimation.h"
|
||||
#include "client/Graphics.h"
|
||||
@ -540,6 +539,10 @@ void SComponent::init(Etype Type, int Subtype, int Val)
|
||||
oss << ((Val>0)?("+"):("-")) << Val << " " << CGI->heroh->pskillsn[Subtype];
|
||||
subtitle = oss.str();
|
||||
break;
|
||||
case secskill44:
|
||||
subtitle += CGI->abilh->levels[Val] + " " + CGI->abilh->abilities[Subtype]->name;
|
||||
description = CGI->abilh->abilities[Subtype]->infoTexts[Val];
|
||||
break;
|
||||
case resource:
|
||||
description = CGI->generaltexth->allTexts[242];
|
||||
oss << Val;
|
||||
@ -569,13 +572,13 @@ SComponent::SComponent(const Component &c)
|
||||
init(experience,0,c.val);
|
||||
else
|
||||
init((Etype)c.id,c.subtype,c.val);
|
||||
switch(c.id)
|
||||
{
|
||||
case resource:
|
||||
if(c.when == -1)
|
||||
subtitle += CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2);
|
||||
break;
|
||||
}
|
||||
|
||||
if(c.id==2 && c.when==-1)
|
||||
subtitle += CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2);
|
||||
}
|
||||
void SComponent::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(getImg(),pos.x,pos.y,to);
|
||||
}
|
||||
SDL_Surface * SComponent::getImg()
|
||||
{
|
||||
@ -584,6 +587,9 @@ SDL_Surface * SComponent::getImg()
|
||||
case primskill:
|
||||
return graphics->pskillsb->ourImages[subtype].bitmap;
|
||||
break;
|
||||
case secskill44:
|
||||
return CGI->abilh->abils44->ourImages[subtype*3 + 3 + val].bitmap;
|
||||
break;
|
||||
case secskill:
|
||||
return CGI->abilh->abils82->ourImages[subtype*3 + 3 + val].bitmap;
|
||||
break;
|
||||
@ -613,12 +619,11 @@ void CSelectableComponent::clickLeft(tribool down)
|
||||
{
|
||||
if (down)
|
||||
{
|
||||
select(true);
|
||||
owner->selectionChange(this);
|
||||
if(onSelect)
|
||||
onSelect();
|
||||
}
|
||||
}
|
||||
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, CSelWindow * Owner, SDL_Surface * Border)
|
||||
:SComponent(Type,Sub,Val),owner(Owner)
|
||||
void CSelectableComponent::init(SDL_Surface * Border)
|
||||
{
|
||||
SDL_Surface * symb = SComponent::getImg();
|
||||
myBitmap = CSDL_Ext::newSurface(symb->w+2,symb->h+2,screen);
|
||||
@ -648,6 +653,16 @@ CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, CSelWin
|
||||
}
|
||||
selected = false;
|
||||
}
|
||||
CSelectableComponent::CSelectableComponent(const Component &c, boost::function<void()> OnSelect, SDL_Surface * Border)
|
||||
:SComponent(c),onSelect(OnSelect)
|
||||
{
|
||||
init(Border);
|
||||
}
|
||||
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect, SDL_Surface * Border)
|
||||
:SComponent(Type,Sub,Val),onSelect(OnSelect)
|
||||
{
|
||||
init(Border);
|
||||
}
|
||||
CSelectableComponent::~CSelectableComponent()
|
||||
{
|
||||
SDL_FreeSurface(myBitmap);
|
||||
@ -686,7 +701,11 @@ void CSelectableComponent::select(bool on)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CSelectableComponent::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(myBitmap,pos.x,pos.y,to);
|
||||
printAtMiddleWB(subtitle,pos.x+pos.w/2,pos.y+pos.h+14,GEOR13,12,zwykly,to);
|
||||
}
|
||||
void CSimpleWindow::show(SDL_Surface * to)
|
||||
{
|
||||
if(!to)
|
||||
@ -702,22 +721,14 @@ CSimpleWindow::~CSimpleWindow()
|
||||
}
|
||||
}
|
||||
|
||||
void CSelWindow::selectionChange(CSelectableComponent * to)
|
||||
void CSelWindow::selectionChange(unsigned to)
|
||||
{
|
||||
blitAt(to->getImg(),to->pos.x-pos.x,to->pos.y-pos.y,bitmap);
|
||||
for (int i=0;i<components.size();i++)
|
||||
for (unsigned i=0;i<components.size();i++)
|
||||
{
|
||||
if(components[i]==to)
|
||||
{
|
||||
if (to->selected)
|
||||
continue;
|
||||
else
|
||||
to->select(true);
|
||||
}
|
||||
CSelectableComponent * pom = dynamic_cast<CSelectableComponent*>(components[i]);
|
||||
if (!pom)
|
||||
continue;
|
||||
pom->select(false);
|
||||
pom->select(i==to);
|
||||
blitAt(pom->getImg(),pom->pos.x-pos.x,pom->pos.y-pos.y,bitmap);
|
||||
}
|
||||
}
|
||||
@ -736,6 +747,7 @@ void CSelWindow::close()
|
||||
ret = i;
|
||||
}
|
||||
components[i]->deactivate();
|
||||
delete components[i];
|
||||
}
|
||||
components.clear();
|
||||
okb.deactivate();
|
||||
@ -1869,10 +1881,16 @@ void CPlayerInterface::receivedResource(int type, int val)
|
||||
adventureInt->resdatabar.draw();
|
||||
}
|
||||
|
||||
void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)
|
||||
void CPlayerInterface::showSelDialog(std::string text, 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);
|
||||
adventureInt->hide(); //dezaktywacja starego interfejsu
|
||||
CSelWindow * temp = CMessage::genSelWindow(text,LOCPLINT->playerID,35,components,playerID);
|
||||
std::vector<CSelectableComponent*> intComps;
|
||||
for(int i=0;i<components.size();i++)
|
||||
intComps.push_back(new CSelectableComponent(*components[i])); //will be deleted by CSelWindow::close
|
||||
|
||||
CSelWindow * temp = CMessage::genSelWindow(text,LOCPLINT->playerID,35,intComps,playerID);
|
||||
LOCPLINT->objsToBlit.push_back(temp);
|
||||
temp->pos.x=300-(temp->pos.w/2);
|
||||
temp->pos.y=300-(temp->pos.h/2);
|
||||
@ -1886,10 +1904,18 @@ void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableCo
|
||||
temp->components[i]->pos.y += temp->pos.y;
|
||||
}
|
||||
temp->ID = askID;
|
||||
components[0]->clickLeft(true);
|
||||
intComps[0]->clickLeft(true);
|
||||
}
|
||||
void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16>& skills, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(*pim);
|
||||
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
|
||||
curint->deactivate();
|
||||
lw->activate();
|
||||
}
|
||||
void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(*pim);
|
||||
openTownWindow(town);
|
||||
}
|
||||
void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
@ -3087,3 +3113,100 @@ void CCreInfoWindow::deactivate()
|
||||
if(upgrade)
|
||||
upgrade->deactivate();
|
||||
}
|
||||
|
||||
void CLevelWindow::close()
|
||||
{
|
||||
deactivate();
|
||||
for(int i=0;i<comps.size();i++)
|
||||
{
|
||||
if(comps[i]->selected)
|
||||
{
|
||||
cb(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
LOCPLINT->curint->activate();
|
||||
}
|
||||
CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
heroType = hero->subID;
|
||||
cb = callback;
|
||||
for(int i=0;i<skills.size();i++)
|
||||
comps.push_back(new CSelectableComponent(SComponent::secskill44,skills[i],hero->getSecSkillLevel(skills[i])+1,boost::bind(&CLevelWindow::selectionChanged,this,i)));
|
||||
bitmap = BitmapHandler::loadBitmap("LVLUPBKG.bmp");
|
||||
graphics->blueToPlayersAdv(bitmap,hero->tempOwner);
|
||||
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
|
||||
pos.x = screen->w/2 - bitmap->w/2;
|
||||
pos.y = screen->h/2 - bitmap->h/2;
|
||||
pos.w = bitmap->w;
|
||||
pos.h = bitmap->h;
|
||||
ok = new AdventureMapButton("","",boost::bind(&CLevelWindow::close,this),pos.x+297,pos.y+413,"IOKAY.DEF");
|
||||
|
||||
//draw window
|
||||
char buf[100], buf2[100];
|
||||
strcpy(buf2,CGI->generaltexth->allTexts[444].c_str()); //%s has gained a level.
|
||||
sprintf(buf,buf2,hero->name.c_str());
|
||||
printAtMiddle(buf,192,35,GEOR16,zwykly,bitmap);
|
||||
|
||||
strcpy(buf2,CGI->generaltexth->allTexts[445].c_str()); //%s is now a level %d %s.
|
||||
sprintf(buf,buf2,hero->name.c_str(),hero->level,hero->type->heroClass->name.c_str());
|
||||
printAtMiddle(buf,192,162,GEOR16,zwykly,bitmap);
|
||||
|
||||
blitAt(graphics->pskillsm->ourImages[pskill].bitmap,174,190,bitmap);
|
||||
|
||||
printAtMiddle((CGI->generaltexth->primarySkillNames[pskill] + " +1"),192,252,GEOR16,zwykly,bitmap);
|
||||
|
||||
SDL_Surface * ort = TTF_RenderText_Blended(GEOR16,CGI->generaltexth->allTexts[4].c_str(),zwykly);
|
||||
int curx = bitmap->w/2 - ( skills.size()*44 + (skills.size()-1)*(36+ort->w) )/2;
|
||||
for(int i=0;i<comps.size();i++)
|
||||
{
|
||||
comps[i]->pos.x = curx+pos.x;
|
||||
comps[i]->pos.y = 326+pos.y;
|
||||
if( i < (comps.size()-1) )
|
||||
{
|
||||
curx += 44 + 18; //skill width + margin to "or"
|
||||
blitAt(ort,curx,346,bitmap);
|
||||
curx += ort->w + 18;
|
||||
}
|
||||
}
|
||||
SDL_FreeSurface(ort);
|
||||
|
||||
}
|
||||
void CLevelWindow::selectionChanged(unsigned to)
|
||||
{
|
||||
for(int i=0;i<comps.size();i++)
|
||||
if(i==to)
|
||||
comps[i]->select(true);
|
||||
else
|
||||
comps[i]->select(false);
|
||||
}
|
||||
CLevelWindow::~CLevelWindow()
|
||||
{
|
||||
delete ok;
|
||||
for(int i=0;i<comps.size();i++)
|
||||
delete comps[i];
|
||||
SDL_FreeSurface(bitmap);
|
||||
}
|
||||
void CLevelWindow::activate()
|
||||
{
|
||||
LOCPLINT->objsToBlit.push_back(this);
|
||||
ok->activate();
|
||||
for(int i=0;i<comps.size();i++)
|
||||
comps[i]->activate();
|
||||
}
|
||||
void CLevelWindow::deactivate()
|
||||
{
|
||||
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
|
||||
ok->deactivate();
|
||||
for(int i=0;i<comps.size();i++)
|
||||
comps[i]->deactivate();
|
||||
}
|
||||
void CLevelWindow::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(bitmap,pos.x,pos.y,screen);
|
||||
blitAt(graphics->portraitLarge[heroType],170+pos.x,66+pos.y);
|
||||
ok->show();
|
||||
for(int i=0;i<comps.size();i++)
|
||||
comps[i]->show();
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
#include "CGameInterface.h"
|
||||
#include "SDL_framerate.h"
|
||||
#include <map>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
class CDefEssential;
|
||||
class AdventureMapButton;
|
||||
@ -169,9 +168,9 @@ public:
|
||||
virtual ~CInfoWindow();
|
||||
};
|
||||
class CSelWindow : public CInfoWindow //component selection window
|
||||
{ //uwaga - to okno nie usuwa swoich komponentow przy usuwaniu, moga sie one jeszcze przydac skryptowi - tak wiec skrypt korzystajacyz tego okna musi je usunac
|
||||
{ //uwaga - to okno usuwa swoje komponenty przy zamykaniu
|
||||
public:
|
||||
void selectionChange(CSelectableComponent * to);
|
||||
void selectionChange(unsigned to);
|
||||
void okClicked(boost::logic::tribool down);
|
||||
void close();
|
||||
CSelWindow(){};
|
||||
@ -204,7 +203,7 @@ class SComponent : public ClickableR
|
||||
public:
|
||||
enum Etype
|
||||
{
|
||||
primskill, secskill, resource, creature, artifact, experience
|
||||
primskill, secskill, resource, creature, artifact, experience, secskill44
|
||||
} type;
|
||||
int subtype;
|
||||
int val;
|
||||
@ -218,6 +217,7 @@ public:
|
||||
|
||||
void clickRight (boost::logic::tribool down);
|
||||
virtual SDL_Surface * getImg();
|
||||
virtual void show(SDL_Surface * to = NULL);
|
||||
virtual void activate();
|
||||
virtual void deactivate();
|
||||
};
|
||||
@ -229,12 +229,15 @@ public:
|
||||
|
||||
bool customB;
|
||||
SDL_Surface * border, *myBitmap;
|
||||
CSelWindow * owner;
|
||||
boost::function<void()> onSelect;
|
||||
|
||||
|
||||
void clickLeft(boost::logic::tribool down);
|
||||
CSelectableComponent(Etype Type, int Sub, int Val, CSelWindow * Owner=NULL, SDL_Surface * Border=NULL);
|
||||
void init(SDL_Surface * Border);
|
||||
CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect = 0, SDL_Surface * Border=NULL);
|
||||
CSelectableComponent(const Component &c, boost::function<void()> OnSelect = 0, SDL_Surface * Border=NULL);
|
||||
~CSelectableComponent();
|
||||
virtual void show(SDL_Surface * to = NULL);
|
||||
void activate();
|
||||
void deactivate();
|
||||
void select(bool on);
|
||||
@ -328,10 +331,11 @@ public:
|
||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
|
||||
void receivedResource(int type, int val);
|
||||
void showInfoDialog(std::string text, std::vector<Component*> &components);
|
||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID);
|
||||
void showSelDialog(std::string text, std::vector<Component*> &components, ui32 askID);
|
||||
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
|
||||
void garrisonChanged(const CGObjectInstance * obj);
|
||||
void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
|
||||
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
//for battles
|
||||
void 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
|
||||
void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
|
||||
@ -533,6 +537,24 @@ public:
|
||||
void show(SDL_Surface * to = NULL);
|
||||
};
|
||||
|
||||
class CLevelWindow : public IShowable, public CIntObject
|
||||
{
|
||||
public:
|
||||
int heroType;
|
||||
SDL_Surface *bitmap;
|
||||
std::vector<CSelectableComponent *> comps; //skills to select
|
||||
AdventureMapButton *ok;
|
||||
boost::function<void(ui32)> cb;
|
||||
|
||||
void close();
|
||||
CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
~CLevelWindow();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void selectionChanged(unsigned to);
|
||||
void show(SDL_Surface * to = NULL);
|
||||
};
|
||||
|
||||
extern CPlayerInterface * LOCPLINT;
|
||||
|
||||
#endif //CPLAYERINTERFACE_H
|
||||
|
@ -44,6 +44,7 @@ void blitAtWR(SDL_Surface * src, int x, int y, SDL_Surface * dst)
|
||||
}
|
||||
void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst)
|
||||
{
|
||||
if(!dst) dst = screen;
|
||||
SDL_Rect pom = genRect(src->h,src->w,x,y);
|
||||
SDL_BlitSurface(src,NULL,dst,&pom);
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
|
||||
playerint[color]->init(cb);
|
||||
}
|
||||
}
|
||||
CGI->consoleh->cb = new CCallback(gs,-1,this);
|
||||
cb = CGI->consoleh->cb = new CCallback(gs,-1,this);
|
||||
}
|
||||
CClient::~CClient(void)
|
||||
{
|
||||
@ -220,6 +220,15 @@ void CClient::process(int what)
|
||||
playerint[gs->getHero(sps.id)->tempOwner]->heroPrimarySkillChanged(gs->getHero(sps.id),sps.which,sps.val);
|
||||
break;
|
||||
}
|
||||
case 106:
|
||||
{
|
||||
SetSecSkill sr;
|
||||
*serv >> sr;
|
||||
std::cout << "Changing hero secondary skill"<<std::endl;
|
||||
gs->apply(&sr);
|
||||
//TODO? - maybe inform interfaces
|
||||
break;
|
||||
}
|
||||
case 107:
|
||||
{
|
||||
ShowInInfobox sii;
|
||||
@ -331,6 +340,28 @@ void CClient::process(int what)
|
||||
gs->mx->unlock();
|
||||
break;
|
||||
}
|
||||
case 2000:
|
||||
{
|
||||
HeroLevelUp bs;
|
||||
*serv >> bs;
|
||||
std::cout << "Hero levels up!" <<std::endl;
|
||||
gs->apply(&bs);
|
||||
CGHeroInstance *h = gs->getHero(bs.heroid);
|
||||
if(vstd::contains(playerint,h->tempOwner))
|
||||
playerint[h->tempOwner]->heroGotLevel(h,bs.primskill,bs.skills,boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,cb,_1,bs.id)));
|
||||
break;
|
||||
}
|
||||
case 2001:
|
||||
{
|
||||
SelectionDialog sd;
|
||||
*serv >> sd;
|
||||
std::cout << "Showing selection dialog " <<std::endl;
|
||||
std::vector<Component*> comps;
|
||||
for(int i=0;i<sd.components.size();i++)
|
||||
comps.push_back(&sd.components[i]);
|
||||
playerint[sd.player]->showSelDialog(toString(sd.text),comps,sd.id);
|
||||
break;
|
||||
}
|
||||
case 3000:
|
||||
{
|
||||
BattleStart bs;
|
||||
|
@ -35,6 +35,7 @@ struct CSharedCond
|
||||
|
||||
class CClient
|
||||
{
|
||||
CCallback *cb;
|
||||
CGameState *gs;
|
||||
std::map<ui8,CGameInterface *> playerint;
|
||||
CConnection *serv;
|
||||
|
@ -174,6 +174,7 @@ Graphics::Graphics()
|
||||
tasks += GET_DEF_ESS(halls,"ITMTLS.DEF");
|
||||
tasks += GET_DEF_ESS(bigTownPic,"ITPT.DEF");
|
||||
tasks += GET_DEF(pskillsb,"PSKILL.DEF");
|
||||
tasks += GET_DEF(pskillsm,"PSKIL42.DEF");
|
||||
tasks += GET_DEF(resources,"RESOUR82.DEF");
|
||||
tasks += GET_DEF(un44,"UN44.DEF");
|
||||
tasks += GET_DEF(smallIcons,"ITPA.DEF");
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
std::vector<SDL_Surface *> portraitLarge; //58x64 px portraits of heroes
|
||||
std::vector<CDefHandler *> flags1, flags2, flags3, flags4; //flags blitted on heroes when ,
|
||||
CDefHandler * pskillsb, *resources; //82x93
|
||||
CDefHandler * pskillsm; //42x42
|
||||
CDefHandler * un44; //many things
|
||||
CDefHandler * smallIcons, *resources32; //resources 32x32
|
||||
//creatures
|
||||
|
@ -39,6 +39,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP2"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="G:\vcmt\repa\include"
|
||||
GeneratePreprocessedFile="0"
|
||||
|
@ -6,8 +6,8 @@
|
||||
18 PELFX.DEF 0
|
||||
19 PELFX.DEF 0
|
||||
29 CPRGRE.DEF 1
|
||||
34 PMAGX.DEF 1
|
||||
35 PMAGX.DEF 1
|
||||
34 PMAGEX.DEF 1
|
||||
35 PMAGEX.DEF 1
|
||||
41 SMBALX.DEF 0
|
||||
44 CPRGOGX.DEF 1
|
||||
45 CPRGOGX.DEF 1
|
||||
|
7
global.h
7
global.h
@ -16,7 +16,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
#define THC
|
||||
#endif
|
||||
|
||||
#define NAME_VER ("VCMI \"Altanatse\" 0.7")
|
||||
#define NAME_VER ("VCMI 0.62")
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -97,6 +97,11 @@ namespace vstd
|
||||
{
|
||||
return std::find(c.begin(),c.end(),i) != c.end();
|
||||
}
|
||||
template <typename V, typename Item>
|
||||
bool contains(const std::map<Item,V> & c, const Item &i)
|
||||
{
|
||||
return c.find(i)!=c.end();
|
||||
}
|
||||
template <typename Container, typename Item>
|
||||
typename Container::iterator find(const Container & c, const Item &i)
|
||||
{
|
||||
|
@ -17,10 +17,11 @@ void CAbilityHandler::loadAbilities()
|
||||
for (int i=0; i<SKILL_QUANTITY; i++)
|
||||
{
|
||||
CAbility * nab = new CAbility; //new skill, that will be read
|
||||
nab->infoTexts.resize(3);
|
||||
loadToIt(nab->name,buf,it,4);
|
||||
loadToIt(nab->basicText,buf,it,4);
|
||||
loadToIt(nab->advText,buf,it,4);
|
||||
loadToIt(nab->expText,buf,it,3);
|
||||
loadToIt(nab->infoTexts[0],buf,it,4);
|
||||
loadToIt(nab->infoTexts[1],buf,it,4);
|
||||
loadToIt(nab->infoTexts[2],buf,it,3);
|
||||
nab->idNumber = abilities.size();
|
||||
abilities.push_back(nab);
|
||||
}
|
||||
|
@ -10,9 +10,7 @@ class CAbility
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::string basicText;
|
||||
std::string advText;
|
||||
std::string expText;
|
||||
std::vector <std::string> infoTexts; //0 - basic; 2 - advanced
|
||||
int idNumber;
|
||||
bool isAllowed; //true if we can use this hero's ability (map information)
|
||||
};
|
||||
|
@ -54,8 +54,8 @@ public:
|
||||
unsigned char animPhaseShift;
|
||||
std::string hoverName;
|
||||
|
||||
int tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
|
||||
int blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
|
||||
ui8 tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
|
||||
ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
|
||||
|
||||
virtual bool isHero() const;
|
||||
int getOwner() const;
|
||||
|
@ -25,6 +25,11 @@ template <typename T> struct CPack
|
||||
ui16 getType() const{return type;}
|
||||
T* This(){return static_cast<T*>(this);};
|
||||
};
|
||||
template <typename T> struct Query
|
||||
:public CPack<T>
|
||||
{
|
||||
ui32 id;
|
||||
};
|
||||
struct SetResources : public CPack<SetResources> //104
|
||||
{
|
||||
SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;};
|
||||
@ -60,6 +65,18 @@ struct SetPrimSkill : public CPack<SetPrimSkill> //105
|
||||
h & abs & id & which & val;
|
||||
}
|
||||
};
|
||||
struct SetSecSkill : public CPack<SetSecSkill> //106
|
||||
{
|
||||
SetSecSkill(){type = 106;};
|
||||
ui8 abs; //0 - changes by value; 1 - sets to value
|
||||
si32 id;
|
||||
ui16 which, val;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & abs & id & which & val;
|
||||
}
|
||||
};
|
||||
struct RemoveHero : public CPack<RemoveHero> //500
|
||||
{
|
||||
RemoveHero(){type = 500;};
|
||||
@ -239,19 +256,34 @@ struct SetHoverName : public CPack<SetHoverName>//1002
|
||||
h & id & name;
|
||||
}
|
||||
};
|
||||
struct HeroLevelUp : public CPack<HeroLevelUp>//2000
|
||||
struct HeroLevelUp : public Query<HeroLevelUp>//2000
|
||||
{
|
||||
si32 id;
|
||||
si32 heroid;
|
||||
ui8 primskill, level;
|
||||
std::set<ui16> skills;
|
||||
std::vector<ui16> skills;
|
||||
|
||||
HeroLevelUp(){type = 2000;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & primskill & level & skills;
|
||||
h & id & heroid & primskill & level & skills;
|
||||
}
|
||||
};
|
||||
|
||||
struct SelectionDialog : public Query<SelectionDialog>//2001
|
||||
{
|
||||
MetaString text;
|
||||
std::vector<Component> components;
|
||||
ui8 player;
|
||||
|
||||
SelectionDialog(){type = 2001;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & text & components & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleInfo;
|
||||
struct BattleStart : public CPack<BattleStart>//3000
|
||||
{
|
||||
|
@ -39,6 +39,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP2"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="G:\vcmt\repa\include"
|
||||
MinimalRebuild="true"
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "hch/CDefObjInfoHandler.h"
|
||||
#include <algorithm>
|
||||
#include "CGameState.h"
|
||||
#include "CLua.h"
|
||||
#include "hch/CHeroHandler.h"
|
||||
#include "hch/CTownHandler.h"
|
||||
#include "client/Graphics.h"
|
||||
|
@ -32,14 +32,15 @@ extern bool end2;
|
||||
#define NEW_ROUND BattleNextRound bnr;\
|
||||
bnr.round = gs->curB->round + 1;\
|
||||
sendAndApply(&bnr);
|
||||
boost::condition_variable cTurn;
|
||||
boost::mutex mTurn;
|
||||
boost::shared_mutex gsm;
|
||||
|
||||
boost::mutex gsm;
|
||||
ui32 CGameHandler::QID = 1;
|
||||
|
||||
CondSh<bool> battleMadeAction;
|
||||
CondSh<BattleResult *> battleResult(NULL);
|
||||
|
||||
std::map<ui32, boost::function<void(ui32)> > callbacks; //question id => callback function - for selection dialogs
|
||||
|
||||
class CMP_stack
|
||||
{
|
||||
public:
|
||||
@ -64,7 +65,86 @@ double distance(int3 a, int3 b)
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
PlayerStatus PlayerStatuses::operator[](ui8 player)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
return players[player];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
}
|
||||
void PlayerStatuses::addPlayer(ui8 player)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
players[player];
|
||||
}
|
||||
bool PlayerStatuses::hasQueries(ui8 player)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
return players[player].queries.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
}
|
||||
bool PlayerStatuses::checkFlag(ui8 player, bool PlayerStatus::*flag)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
return players[player].*flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
}
|
||||
void PlayerStatuses::setFlag(ui8 player, bool PlayerStatus::*flag, bool val)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
players[player].*flag = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
cv.notify_all();
|
||||
}
|
||||
void PlayerStatuses::addQuery(ui8 player, ui32 id)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
players[player].queries.insert(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
cv.notify_all();
|
||||
}
|
||||
void PlayerStatuses::removeQuery(ui8 player, ui32 id)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> l(mx);
|
||||
if(players.find(player) != players.end())
|
||||
{
|
||||
players[player].queries.erase(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::string("No such player!");
|
||||
}
|
||||
cv.notify_all();
|
||||
}
|
||||
void CGameHandler::handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script)
|
||||
{
|
||||
std::vector<int> tempv = script->yourObjects();
|
||||
@ -74,6 +154,21 @@ void CGameHandler::handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObj
|
||||
}
|
||||
cppscripts.insert(script);
|
||||
}
|
||||
template <typename T>
|
||||
void callWith(std::vector<T> args, boost::function<void(T)> fun, ui32 which)
|
||||
{
|
||||
fun(args[which]);
|
||||
}
|
||||
|
||||
void CGameHandler::changeSecSkill(int ID, ui16 which, int val, bool abs)
|
||||
{
|
||||
SetSecSkill sps;
|
||||
sps.id = ID;
|
||||
sps.which = which;
|
||||
sps.abs = abs;
|
||||
sps.val = val;
|
||||
sendAndApply(&sps);
|
||||
}
|
||||
|
||||
void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
{
|
||||
@ -83,13 +178,11 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
sps.abs = abs;
|
||||
sps.val = val;
|
||||
sendAndApply(&sps);
|
||||
if(which==4)
|
||||
if(which==4) //only for exp - hero may level up
|
||||
{
|
||||
CGHeroInstance *hero = static_cast<CGHeroInstance *>(gs->map->objects[ID]);
|
||||
if(hero->exp >= VLC->heroh->reqExp(hero->level+1)) //new level
|
||||
{
|
||||
//hero->level++;
|
||||
|
||||
//give prim skill
|
||||
std::cout << hero->name <<" got level "<<hero->level<<std::endl;
|
||||
int r = rand()%100, pom=0, x=0;
|
||||
@ -107,10 +200,13 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
sps.abs = false;
|
||||
sps.val = 1;
|
||||
sendAndApply(&sps);
|
||||
hero->primSkills[x]++;
|
||||
|
||||
std::set<ui16> choice;
|
||||
HeroLevelUp hlu;
|
||||
hlu.heroid = ID;
|
||||
hlu.primskill = x;
|
||||
hlu.level = hero->level+1;
|
||||
|
||||
//picking sec. skills for choice
|
||||
std::set<int> basicAndAdv, expert, none;
|
||||
for(int i=0;i<SKILL_QUANTITY;i++) none.insert(i);
|
||||
for(unsigned i=0;i<hero->secSkills.size();i++)
|
||||
@ -123,25 +219,24 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs)
|
||||
}
|
||||
if(hero->secSkills.size() < hero->type->heroClass->skillLimit) //free skill slot
|
||||
{
|
||||
choice.insert(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = hero->type->heroClass->chooseSecSkill(basicAndAdv);
|
||||
choice.insert(s);
|
||||
hlu.skills.push_back(s);
|
||||
basicAndAdv.erase(s);
|
||||
}
|
||||
if(basicAndAdv.size())
|
||||
{
|
||||
choice.insert(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //new skill
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //new skill
|
||||
}
|
||||
else if(hero->secSkills.size() < hero->type->heroClass->skillLimit)
|
||||
{
|
||||
choice.insert(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
|
||||
}
|
||||
|
||||
applyAndAsk(&hlu,hero->tempOwner,boost::function<void(ui32)>(boost::bind(callWith<ui16>,hlu.skills,boost::function<void(ui16)>(boost::bind(&CGameHandler::changeSecSkill,this,ID,_1,1,0)),_1))); //call changeSecSkill with appropriate args when client responds
|
||||
}
|
||||
//TODO - powiadomic interfejsy, sprawdzic czy nie ma awansu itp
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,10 +249,12 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
battleResult.set(NULL);
|
||||
std::vector<CStack*> & stacks = (curB->stacks);
|
||||
|
||||
curB->tile = tile;
|
||||
curB->siege = 0; //TODO: add sieges
|
||||
curB->army1=army1;
|
||||
curB->army2=army2;
|
||||
curB->hero1=(hero1)?(hero1->id):(-1);
|
||||
curB->hero2=(hero1)?(hero1->id):(-1);
|
||||
curB->hero2=(hero2)?(hero2->id):(-1);
|
||||
curB->side1=(hero1)?(hero1->tempOwner):(-1);
|
||||
curB->side2=(hero2)?(hero2->tempOwner):(-1);
|
||||
curB->round = -2;
|
||||
@ -283,9 +380,9 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
|
||||
//block engaged players
|
||||
if(hero1->tempOwner<PLAYER_LIMIT)
|
||||
states[hero1->tempOwner] += 10;
|
||||
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);
|
||||
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
|
||||
states[hero2->tempOwner] += 10;
|
||||
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
|
||||
|
||||
//send info about battles
|
||||
BattleStart bs;
|
||||
@ -329,6 +426,12 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
}
|
||||
}
|
||||
|
||||
//unblock engaged players
|
||||
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);
|
||||
|
||||
//end battle, remove all info, free memory
|
||||
sendAndApply(battleResult.data);
|
||||
delete battleResult.data;
|
||||
@ -380,10 +483,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
case 100: //my interface ended its turn
|
||||
{
|
||||
mTurn.lock();
|
||||
states[gs->currentPlayer] = 0;
|
||||
mTurn.unlock();
|
||||
cTurn.notify_all();
|
||||
states.setFlag(gs->currentPlayer,&PlayerStatus::makingTurn,false);
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
@ -444,7 +544,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
//if(gs->checkFunc(obj->ID,"heroVisit")) //script function
|
||||
// gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
|
||||
if(obj->state) //hard-coded function
|
||||
obj->state->onHeroVisit(obj->id,h->subID);
|
||||
obj->state->onHeroVisit(obj->id,h->id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -457,7 +557,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
//TODO: allow to handle this in script-languages
|
||||
if(obj->state) //hard-coded function
|
||||
obj->state->onHeroLeave(obj->id,h->subID);
|
||||
obj->state->onHeroLeave(obj->id,h->id);
|
||||
}
|
||||
|
||||
//reveal fog of war
|
||||
@ -664,6 +764,17 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
sendAndApply(&sg);
|
||||
break;
|
||||
}
|
||||
case 2001:
|
||||
{
|
||||
ui32 qid, answer;
|
||||
c >> qid >> answer;
|
||||
gsm.lock();
|
||||
boost::function<void(ui32)> callb = callbacks[qid];
|
||||
callbacks.erase(qid);
|
||||
gsm.unlock();
|
||||
callb(answer);
|
||||
break;
|
||||
}
|
||||
case 3002:
|
||||
{
|
||||
BattleAction ba;
|
||||
@ -949,6 +1060,8 @@ void CGameHandler::run()
|
||||
//if(checkFunc(map->objects[i]->ID,temps))
|
||||
// (*skrypty)[map->objects[i]->ID][temps]->newObject(map->objects[i]);
|
||||
}
|
||||
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
|
||||
states.addPlayer(i->first);
|
||||
|
||||
while (!end2)
|
||||
{
|
||||
@ -956,17 +1069,18 @@ void CGameHandler::run()
|
||||
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
|
||||
{
|
||||
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0 || i->first>=PLAYER_LIMIT ) continue; //players has not towns/castle - loser
|
||||
states[i->first] = 1;
|
||||
states.setFlag(i->first,&PlayerStatus::makingTurn,true);
|
||||
gs->currentPlayer = i->first;
|
||||
*connections[i->first] << ui16(100) << i->first;
|
||||
|
||||
//wait till turn is done
|
||||
boost::unique_lock<boost::mutex> lock(mTurn);
|
||||
while(states[i->first] && !end2)
|
||||
boost::unique_lock<boost::mutex> lock(states.mx);
|
||||
while(states.players[i->first].makingTurn && !end2)
|
||||
{
|
||||
boost::posix_time::time_duration p;
|
||||
p= boost::posix_time::seconds(1);
|
||||
#ifdef _MSC_VER
|
||||
cTurn.timed_wait(lock,p);
|
||||
states.cv.timed_wait(lock,p);
|
||||
#else
|
||||
boost::xtime time={0,0};
|
||||
time.sec = static_cast<boost::xtime::xtime_sec_t>(p.total_seconds());
|
||||
|
@ -3,31 +3,54 @@
|
||||
#include <set>
|
||||
#include "../CGameState.h"
|
||||
#include "../lib/Connection.h"
|
||||
#ifndef _MSC_VER
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#endif
|
||||
class CVCMIServer;
|
||||
class CGameState;
|
||||
//class CConnection;
|
||||
struct StartInfo;
|
||||
class CCPPObjectScript;
|
||||
class CScriptCallback;
|
||||
template <typename T> struct CPack;
|
||||
template <typename T> struct Query;
|
||||
class CGHeroInstance;
|
||||
extern std::map<ui32, boost::function<void(ui32)> > callbacks; //question id => callback function - for selection dialogs
|
||||
extern boost::mutex gsm;
|
||||
|
||||
struct PlayerStatus
|
||||
{
|
||||
bool makingTurn, engagedIntoBattle;
|
||||
std::set<ui32> queries;
|
||||
PlayerStatus():makingTurn(false),engagedIntoBattle(false){};
|
||||
};
|
||||
class PlayerStatuses
|
||||
{
|
||||
public:
|
||||
std::map<ui8,PlayerStatus> players;
|
||||
boost::mutex mx;
|
||||
boost::condition_variable cv; //notifies when any changes are made
|
||||
void addPlayer(ui8 player);
|
||||
PlayerStatus operator[](ui8 player);
|
||||
bool hasQueries(ui8 player);
|
||||
bool checkFlag(ui8 player, bool PlayerStatus::*flag);
|
||||
void setFlag(ui8 player, bool PlayerStatus::*flag, bool val);
|
||||
void addQuery(ui8 player, ui32 id);
|
||||
void removeQuery(ui8 player, ui32 id);
|
||||
};
|
||||
class CGameHandler
|
||||
{
|
||||
|
||||
static ui32 QID;
|
||||
CGameState *gs;
|
||||
std::set<CCPPObjectScript *> cppscripts; //C++ scripts
|
||||
//std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts
|
||||
|
||||
CVCMIServer *s;
|
||||
std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
|
||||
std::map<int,int> states; //player color -> player state
|
||||
PlayerStatuses states; //player color -> player state
|
||||
std::set<CConnection*> conns;
|
||||
|
||||
void handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script);
|
||||
void changePrimSkill(int ID, int which, int val, bool abs=false);
|
||||
void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
|
||||
void moveStack(int stack, int dest);
|
||||
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
|
||||
|
||||
@ -37,6 +60,27 @@ public:
|
||||
~CGameHandler(void);
|
||||
void init(StartInfo *si, int Seed);
|
||||
void handleConnection(std::set<int> players, CConnection &c);
|
||||
template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
QID++;
|
||||
sendAndApply(sel);
|
||||
gsm.unlock();
|
||||
}
|
||||
template <typename T> void ask(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
gsm.lock();
|
||||
sel->id = QID;
|
||||
callbacks[QID] = callback;
|
||||
states.addQuery(player,QID);
|
||||
sendToAllClients(sel);
|
||||
QID++;
|
||||
gsm.unlock();
|
||||
}
|
||||
|
||||
template <typename T>void sendToAllClients(CPack<T> * info)
|
||||
{
|
||||
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
|
||||
CScriptCallback::CScriptCallback(void)
|
||||
{
|
||||
}
|
||||
@ -62,32 +64,13 @@ int CScriptCallback::getHeroOwner(int heroID)
|
||||
void CScriptCallback::showInfoDialog(InfoWindow *iw)
|
||||
{
|
||||
gh->sendToAllClients(iw);
|
||||
//TODO: upewniac sie ze mozemy to zrzutowac (przy customowych interfejsach cos moze sie kopnac)
|
||||
//if (player>=0)
|
||||
//{
|
||||
// CGameInterface * temp = sv->playerint[player];
|
||||
// if (temp->human)
|
||||
// ((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
|
||||
// return;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// typedef std::pair<const ui8, CGameInterface*> intf;
|
||||
// BOOST_FOREACH(intf & i, sv->playerint)
|
||||
// {
|
||||
// if (i.second->human)
|
||||
// ((CPlayerInterface*)(i.second))->showInfoDialog(text,*components);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
|
||||
void CScriptCallback::showSelectionDialog(SelectionDialog *iw, boost::function<void(ui32),std::allocator<void> > &callback)
|
||||
{
|
||||
//CGameInterface * temp = sv->playerint[player];
|
||||
//if (temp->human)
|
||||
// ((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
|
||||
return;
|
||||
gh->ask(iw,iw->player,callback);
|
||||
}
|
||||
|
||||
int CScriptCallback::getSelectedHero()
|
||||
{
|
||||
//int ret;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "../global.h"
|
||||
#include <vector>
|
||||
#include <boost/function.hpp>
|
||||
class CVCMIServer;
|
||||
class CGameHandler;
|
||||
class SComponent;
|
||||
@ -16,6 +17,7 @@ struct lua_State;
|
||||
struct MetaString;
|
||||
struct InfoWindow;
|
||||
struct ShowInInfobox;
|
||||
struct SelectionDialog;
|
||||
class CScriptCallback
|
||||
{
|
||||
CScriptCallback(void);
|
||||
@ -38,7 +40,7 @@ public:
|
||||
void setHoverName(int objid, MetaString * name);
|
||||
void changePrimSkill(int ID, int which, int val, bool abs=false);
|
||||
void showInfoDialog(InfoWindow *iw);
|
||||
void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
|
||||
void showSelectionDialog(SelectionDialog *iw, boost::function<void(ui32),std::allocator<void> > &callback); //returns question id
|
||||
void giveResource(int player, int which, int val);
|
||||
void showCompInfo(ShowInInfobox * comp);
|
||||
void heroVisitCastle(int obj, int heroID);
|
||||
|
@ -39,8 +39,9 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP2"
|
||||
Optimization="0"
|
||||
MinimalRebuild="true"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="2"
|
||||
|
Loading…
Reference in New Issue
Block a user