mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
* town visiting
* improvements in garrisons
This commit is contained in:
@@ -126,24 +126,31 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
{
|
||||
curd.successful = true;
|
||||
hero->pos = curd.dst;
|
||||
int heroSight = hero->getSightDistance();
|
||||
|
||||
//inform leaved objects
|
||||
std::vector< CGObjectInstance * > leave = CGI->mh->getVisitableObjs(CHeroInstance::convertPosition(curd.src,false));
|
||||
for (int iii=0; iii<leave.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
{
|
||||
//TODO: allow to handle this in LUA
|
||||
if(leave[iii]->state) //hard-coded function
|
||||
leave[iii]->state->onHeroLeave(leave[iii],curd.ho->subID);
|
||||
}
|
||||
|
||||
|
||||
//reveal fog of war
|
||||
int heroSight = hero->getSightDistance();
|
||||
int xbeg = stpos.x - heroSight - 2;
|
||||
if(xbeg < 0)
|
||||
xbeg = 0;
|
||||
|
||||
int xend = stpos.x + heroSight + 2;
|
||||
if(xend >= CGI->ac->map.width)
|
||||
xend = CGI->ac->map.width;
|
||||
|
||||
int ybeg = stpos.y - heroSight - 2;
|
||||
if(ybeg < 0)
|
||||
ybeg = 0;
|
||||
|
||||
int yend = stpos.y + heroSight + 2;
|
||||
if(yend >= CGI->ac->map.height)
|
||||
yend = CGI->ac->map.height;
|
||||
|
||||
for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
|
||||
{
|
||||
for(int yd=ybeg; yd<yend; ++yd)
|
||||
@@ -161,6 +168,8 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//notify interfacesabout move
|
||||
int nn=0; //number of interfece of currently browsed player
|
||||
for(std::map<int, PlayerState>::iterator j=CGI->state->players.begin(); j!=CGI->state->players.end(); ++j)//CGI->state->players.size(); ++j) //for testing
|
||||
{
|
||||
@@ -172,6 +181,9 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
}
|
||||
++nn;
|
||||
}
|
||||
|
||||
|
||||
//call objects if they arevisited
|
||||
for (int iii=0; iii<vis.size(); iii++) //if object is visitable we call onHeroVisit
|
||||
{
|
||||
if(gs->checkFunc(vis[iii]->ID,"heroVisit")) //script function
|
||||
@@ -373,10 +385,18 @@ int CCallback::getHeroSerial(const CGHeroInstance * hero)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CCallback::swapCreatures(const CCreatureSet *s1, const CCreatureSet *s2, int p1, int p2)
|
||||
const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj)
|
||||
{
|
||||
CCreatureSet *S1=const_cast<CCreatureSet *>(s1), *S2 = const_cast<CCreatureSet *>(s2);//todo - ugly
|
||||
if(obj->ID == 34)
|
||||
return &(dynamic_cast<const CGHeroInstance*>(obj))->army;
|
||||
else if(obj->ID == 98)
|
||||
return &(dynamic_cast<const CGTownInstance*>(obj)->garrison);
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)
|
||||
{
|
||||
CCreatureSet *S1 = const_cast<CCreatureSet*>(getGarrison(s1)), *S2 = const_cast<CCreatureSet*>(getGarrison(s2));
|
||||
if (false)
|
||||
{
|
||||
//TODO: check if we are allowed to swap these creatures
|
||||
@@ -392,6 +412,15 @@ int CCallback::swapCreatures(const CCreatureSet *s1, const CCreatureSet *s2, int
|
||||
int pom2 = S2->slots[p2].second;
|
||||
S2->slots[p2].second = S1->slots[p1].second;
|
||||
S1->slots[p1].second = pom2;
|
||||
|
||||
if(!S1->slots[p1].first)
|
||||
S1->slots.erase(p1);
|
||||
if(!S2->slots[p2].first)
|
||||
S2->slots.erase(p2);
|
||||
if(s1->tempOwner<PLAYER_LIMIT)
|
||||
CGI->playerint[s1->tempOwner]->garrisonChanged(s1);
|
||||
if(s2->tempOwner<PLAYER_LIMIT)
|
||||
CGI->playerint[s2->tempOwner]->garrisonChanged(s2);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -519,7 +548,29 @@ void CScriptCallback::showCompInfo(int player, SComponent * comp)
|
||||
if(i)
|
||||
i->showComp(*comp);
|
||||
}
|
||||
void CScriptCallback::heroVisitCastle(CGObjectInstance * ob, int heroID)
|
||||
{
|
||||
CGTownInstance * n;
|
||||
if(n = dynamic_cast<CGTownInstance*>(ob))
|
||||
{
|
||||
n->visitingHero = CGI->state->getHero(heroID,0);
|
||||
CGI->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->getHero(heroID,0),n);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
void CScriptCallback::stopHeroVisitCastle(CGObjectInstance * ob, int heroID)
|
||||
{
|
||||
CGTownInstance * n;
|
||||
if(n = dynamic_cast<CGTownInstance*>(ob))
|
||||
{
|
||||
if(n->visitingHero->type->ID == heroID)
|
||||
n->visitingHero = NULL;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
void CLuaCallback::registerFuncs(lua_State * L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
@@ -544,8 +595,7 @@ void CLuaCallback::registerFuncs(lua_State * L)
|
||||
|
||||
|
||||
lua_setglobal(L, "vcmi");
|
||||
#undef REGISTER_C_FUNC(x)
|
||||
|
||||
#undef REGISTER_C_FUNC
|
||||
}
|
||||
int CLuaCallback::getPos(lua_State * L)//(CGObjectInstance * object);
|
||||
{
|
||||
|
@@ -34,8 +34,9 @@ public:
|
||||
virtual int getMyColor()=0;
|
||||
virtual int getMySerial()=0;
|
||||
virtual int getHeroSerial(const CGHeroInstance * hero)=0;
|
||||
virtual int swapCreatures(const CCreatureSet *s1, const CCreatureSet *s2, int p1, int p2)=0;//swaps creatures between two posiibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual int swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//swaps creatures between two posiibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly
|
||||
virtual const CCreatureSet* getGarrison(const CGObjectInstance *obj)=0;
|
||||
};
|
||||
|
||||
struct HeroMoveDetails
|
||||
@@ -80,8 +81,9 @@ public:
|
||||
int getMyColor();
|
||||
int getHeroSerial(const CGHeroInstance * hero);
|
||||
int getMySerial();
|
||||
int swapCreatures(const CCreatureSet *s1, const CCreatureSet *s2, int p1, int p2);
|
||||
int swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
const CCreatureSet* getGarrison(const CGObjectInstance *obj);
|
||||
|
||||
//friends
|
||||
friend int _tmain(int argc, _TCHAR* argv[]);
|
||||
@@ -103,6 +105,9 @@ public:
|
||||
void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
|
||||
void giveResource(int player, int which, int val);
|
||||
void showCompInfo(int player, SComponent * comp);
|
||||
void heroVisitCastle(CGObjectInstance * ob, int heroID);
|
||||
void stopHeroVisitCastle(CGObjectInstance * ob, int heroID);
|
||||
|
||||
|
||||
//friends
|
||||
friend void initGameState(CGameInfo * cgi);
|
||||
|
@@ -168,6 +168,8 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
|
||||
statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
|
||||
std::set< std::pair<int,int> > s; //group - id
|
||||
|
||||
|
||||
//buildings
|
||||
for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
|
||||
{
|
||||
if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
|
||||
@@ -218,8 +220,10 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//garrison
|
||||
std::sort(buildings.begin(),buildings.end(),srthlp);
|
||||
garr = new CGarrisonInt(305,387,4,32,townInt,243,13,&town->garrison,(town->garrisonHero)?(&town->garrisonHero->army):(NULL));
|
||||
garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
|
||||
|
||||
if(Activate)
|
||||
{
|
||||
|
@@ -21,10 +21,12 @@ public:
|
||||
virtual void heroCreated(const CGHeroInstance*)=0{};
|
||||
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val)=0{};
|
||||
virtual void heroMoved(const HeroMoveDetails & details)=0{};
|
||||
virtual void tileRevealed(int3 pos)=0{};
|
||||
virtual void tileHidden(int3 pos)=0{};
|
||||
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
|
||||
virtual void tileRevealed(int3 pos){};
|
||||
virtual void tileHidden(int3 pos){};
|
||||
virtual void receivedResource(int type, int val){};
|
||||
virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)=0{};
|
||||
virtual void garrisonChanged(const CGObjectInstance * obj){};
|
||||
};
|
||||
class CAIHandler
|
||||
{
|
||||
|
26
CLua.cpp
26
CLua.cpp
@@ -12,6 +12,7 @@
|
||||
#include "CGameState.h"
|
||||
#include <sstream>
|
||||
#include "hch/CObjectHandler.h"
|
||||
#include "hch/CTownHandler.h"
|
||||
#include "CCallback.h"
|
||||
#include "hch/CGeneralTextHandler.h"
|
||||
#include <sstream>
|
||||
@@ -589,4 +590,27 @@ std::vector<int> CPickable::yourObjects() //returns IDs of objects which are han
|
||||
ret.push_back(5); //artifact
|
||||
ret.push_back(101); //treasure chest / commander stone
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void CTownScript::onHeroVisit(CGObjectInstance *os, int heroID)
|
||||
{
|
||||
cb->heroVisitCastle(os,heroID);
|
||||
}
|
||||
void CTownScript::onHeroLeave(CGObjectInstance *os, int heroID)
|
||||
{
|
||||
cb->stopHeroVisitCastle(os,heroID);
|
||||
}
|
||||
std::string CTownScript::hoverText(CGObjectInstance *os)
|
||||
{
|
||||
CGTownInstance * n;
|
||||
if(n = dynamic_cast<CGTownInstance*>(os))
|
||||
return n->name + ", " + n->town->name;
|
||||
else return "";
|
||||
}
|
||||
|
||||
std::vector<int> CTownScript::yourObjects() //returns IDs of objects which are handled by script
|
||||
{
|
||||
std::vector<int> ret(1);
|
||||
ret.push_back(98); //town
|
||||
return ret;
|
||||
}
|
||||
|
12
CLua.h
12
CLua.h
@@ -26,6 +26,7 @@ public:
|
||||
//virtual void init(){};
|
||||
virtual void newObject(CGObjectInstance *os){};
|
||||
virtual void onHeroVisit(CGObjectInstance *os, int heroID){};
|
||||
virtual void onHeroLeave(CGObjectInstance *os, int heroID){};
|
||||
virtual std::string hoverText(CGObjectInstance *os){return "";};
|
||||
virtual void newTurn (){};
|
||||
|
||||
@@ -148,5 +149,16 @@ class CPickable : public CCPPObjectScript, public IChosen //pickable - resource
|
||||
std::string hoverText(CGObjectInstance *os);
|
||||
std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
|
||||
|
||||
friend void initGameState(CGameInfo * cgi);
|
||||
};
|
||||
|
||||
class CTownScript : public CCPPObjectScript //pickable - resources, artifacts, etc
|
||||
{
|
||||
CTownScript(CScriptCallback * CB):CCPPObjectScript(CB){};
|
||||
void onHeroVisit(CGObjectInstance *os, int heroID);
|
||||
void onHeroLeave(CGObjectInstance *os, int heroID);
|
||||
std::string hoverText(CGObjectInstance *os);
|
||||
std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
|
||||
|
||||
friend void initGameState(CGameInfo * cgi);
|
||||
};
|
6
CMT.cpp
6
CMT.cpp
@@ -188,8 +188,9 @@ void initGameState(CGameInfo * cgi)
|
||||
/****************************TOWNS************************************************/
|
||||
for (int i=0;i<cgi->townh->townInstances.size();i++)
|
||||
{
|
||||
CGTownInstance * vti = new CGTownInstance();
|
||||
(*vti)=*(cgi->townh->townInstances[i]);
|
||||
//CGTownInstance * vti = new CGTownInstance();
|
||||
//(*vti)=*(cgi->townh->townInstances[i]);
|
||||
CGTownInstance * vti =(cgi->townh->townInstances[i]);
|
||||
vti->creatureIncome.resize(CREATURES_PER_TOWN);
|
||||
vti->creaturesLeft.resize(CREATURES_PER_TOWN);
|
||||
if (vti->name.length()==0) // if town hasn't name we draw it
|
||||
@@ -226,6 +227,7 @@ void initGameState(CGameInfo * cgi)
|
||||
handleCPPObjS(&scripts,new CVisitableOPW(csc));
|
||||
handleCPPObjS(&scripts,new CPickable(csc));
|
||||
handleCPPObjS(&scripts,new CMines(csc));
|
||||
handleCPPObjS(&scripts,new CTownScript(csc));
|
||||
//created map
|
||||
|
||||
/****************************LUA OBJECT SCRIPTS************************************************/
|
||||
|
@@ -47,8 +47,8 @@ void CGarrisonSlot::clickLeft(tribool down)
|
||||
if(owner->highlighted)
|
||||
{
|
||||
LOCPLINT->cb->swapCreatures(
|
||||
(!upg)?(owner->set1):(owner->set2),
|
||||
(!owner->highlighted->upg)?(owner->set1):(owner->set2),
|
||||
(!upg)?(owner->oup):(owner->odown),
|
||||
(!owner->highlighted->upg)?(owner->oup):(owner->odown),
|
||||
ID,owner->highlighted->ID);
|
||||
owner->highlighted = NULL;
|
||||
owner->recreateSlots();
|
||||
@@ -71,9 +71,9 @@ void CGarrisonSlot::deactivate()
|
||||
ClickableR::deactivate();
|
||||
Hoverable::deactivate();
|
||||
}
|
||||
CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, const CCreature * Creature, int Count)
|
||||
CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg, const CCreature * Creature, int Count)
|
||||
{
|
||||
upg = 0;
|
||||
upg = Upg;
|
||||
count = Count;
|
||||
ID = IID;
|
||||
creature = Creature;
|
||||
@@ -190,11 +190,11 @@ void CGarrisonInt::createSlots()
|
||||
i!=set1->slots.end(); i++)
|
||||
{
|
||||
(*sup)[i->first] =
|
||||
new CGarrisonSlot(this, pos.x + (i->first*(58+interx)), pos.y,i->first, i->second.first,i->second.second);
|
||||
new CGarrisonSlot(this, pos.x + (i->first*(58+interx)), pos.y,i->first, 0, i->second.first,i->second.second);
|
||||
}
|
||||
for(int i=0; i<sup->size(); i++)
|
||||
if((*sup)[i] == NULL)
|
||||
(*sup)[i] = new CGarrisonSlot(this, pos.x + (i*(58+interx)), pos.y,i, NULL, 0);
|
||||
(*sup)[i] = new CGarrisonSlot(this, pos.x + (i*(58+interx)), pos.y,i,0,NULL, 0);
|
||||
}
|
||||
if(set2)
|
||||
{
|
||||
@@ -204,11 +204,11 @@ void CGarrisonInt::createSlots()
|
||||
i!=set2->slots.end(); i++)
|
||||
{
|
||||
(*sdown)[i->first] =
|
||||
new CGarrisonSlot(this, pos.x + (i->first*(58+interx)), pos.y + 64 + intery,i->first, i->second.first,i->second.second);
|
||||
new CGarrisonSlot(this, pos.x + (i->first*(58+interx)), pos.y + 64 + intery,i->first,1, i->second.first,i->second.second);
|
||||
}
|
||||
for(int i=0; i<sup->size(); i++)
|
||||
if((*sdown)[i] == NULL)
|
||||
(*sdown)[i] = new CGarrisonSlot(this, pos.x + (i*(58+interx)), pos.y,i, NULL, 0);
|
||||
(*sdown)[i] = new CGarrisonSlot(this, pos.x + (i*(58+interx)), pos.y + 64 + intery,i,1, NULL, 0);
|
||||
}
|
||||
}
|
||||
void CGarrisonInt::deleteSlots()
|
||||
@@ -243,11 +243,12 @@ void CGarrisonInt::recreateSlots()
|
||||
activeteSlots();
|
||||
show();
|
||||
}
|
||||
CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CCreatureSet * s1, const CCreatureSet *s2)
|
||||
:interx(inx),intery(iny),sur(pomsur),highlighted(NULL),sup(NULL),sdown(NULL),set1(s1),set2(s2),
|
||||
CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2)
|
||||
:interx(inx),intery(iny),sur(pomsur),highlighted(NULL),sup(NULL),sdown(NULL),oup(s1),odown(s2),
|
||||
offx(OX),offy(OY)
|
||||
{
|
||||
|
||||
set1 = LOCPLINT->cb->getGarrison(s1);
|
||||
set2 = LOCPLINT->cb->getGarrison(s2);
|
||||
ignoreEvent = false;
|
||||
pos.x=(x);
|
||||
pos.y=(y);
|
||||
@@ -1796,7 +1797,25 @@ void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableCo
|
||||
temp->ID = askID;
|
||||
components[0]->clickLeft(true);
|
||||
}
|
||||
|
||||
void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town)
|
||||
{
|
||||
openTownWindow(town);
|
||||
}
|
||||
void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
{
|
||||
if(obj->ID == 34) //hero
|
||||
{
|
||||
const CGHeroInstance * hh;
|
||||
if(hh = dynamic_cast<const CGHeroInstance*>(obj))
|
||||
{
|
||||
SDL_FreeSurface(heroWins[hh->subID]);
|
||||
heroWins[hh->subID] = infoWin(hh);
|
||||
}
|
||||
}
|
||||
else if (obj->ID == 98) //town
|
||||
{
|
||||
}
|
||||
}
|
||||
void CPlayerInterface::showComp(SComponent comp)
|
||||
{
|
||||
adventureInt->infoBar.showComp(&comp,4000);
|
||||
|
@@ -204,7 +204,7 @@ public:
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show();
|
||||
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, const CCreature * Creature=NULL, int Count=0);
|
||||
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg=0, const CCreature * Creature=NULL, int Count=0);
|
||||
};
|
||||
|
||||
class CGarrisonInt :public CIntObject
|
||||
@@ -221,6 +221,7 @@ public:
|
||||
const CCreatureSet *set2;
|
||||
|
||||
std::vector<CGarrisonSlot*> *sup, *sdown;
|
||||
const CGObjectInstance *oup, *odown;
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
@@ -231,7 +232,7 @@ public:
|
||||
void createSlots();
|
||||
void recreateSlots();
|
||||
|
||||
CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CCreatureSet * s1, const CCreatureSet *s2=NULL);
|
||||
CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2=NULL);
|
||||
~CGarrisonInt();
|
||||
};
|
||||
|
||||
@@ -274,6 +275,8 @@ public:
|
||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
|
||||
void receivedResource(int type, int val);
|
||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID);
|
||||
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
|
||||
void garrisonChanged(const CGObjectInstance * obj);
|
||||
|
||||
void showComp(SComponent comp);
|
||||
|
||||
|
@@ -280,6 +280,7 @@ CGTownInstance::CGTownInstance()
|
||||
//state->owner=-1;
|
||||
town=NULL;
|
||||
income = 500;
|
||||
visitingHero = NULL;
|
||||
}
|
||||
|
||||
CGObjectInstance::CGObjectInstance()
|
||||
|
@@ -442,7 +442,7 @@ public:
|
||||
std::vector<int> creatureIncome; //vector by level
|
||||
std::vector<int> creaturesLeft; //that can be recruited
|
||||
|
||||
CGHeroInstance * garrisonHero;
|
||||
const CGHeroInstance * garrisonHero, *visitingHero;
|
||||
|
||||
std::vector<CSpell *> possibleSpells, obligatorySpells, availableSpells;
|
||||
|
||||
|
Reference in New Issue
Block a user