mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* support for Redwood Observatory
* support for Shrine of Magic Incantation / Gesture / Thought * minor improvements
This commit is contained in:
parent
e961655b1a
commit
6ce9a253a4
@ -99,6 +99,11 @@ std::string DLL_EXPORT toString(MetaString &ms)
|
||||
ret += VLC->generaltexth->mines[ser].second;
|
||||
continue;
|
||||
}
|
||||
else if(type == MetaString::SPELL_NAME)
|
||||
{
|
||||
ret += VLC->spellh->spells[ser].name;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
@ -1325,27 +1330,6 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player) const
|
||||
{
|
||||
std::set<int3> ret;
|
||||
if(player >= PLAYER_LIMIT)
|
||||
{
|
||||
tlog1 << "Illegal call to tilesToReveal!\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, map->width-1); xd++)
|
||||
{
|
||||
for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>( pos.y + radious, map->height-1); yd++)
|
||||
{
|
||||
double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
|
||||
if(distance <= radious && (player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0))
|
||||
ret.insert(int3(xd,yd,pos.z));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameState::loadTownDInfos()
|
||||
{
|
||||
for(int i=0;i<F_NUMBER;i++)
|
||||
|
@ -241,7 +241,6 @@ public:
|
||||
int battleGetBattlefieldType(int3 tile = int3());// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||
UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
|
||||
float getMarketEfficiency(int player, int mode=0);
|
||||
std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
|
||||
int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
|
||||
CGameState();
|
||||
|
@ -630,9 +630,12 @@ void CInfoPopup::close()
|
||||
if(free)
|
||||
SDL_FreeSurface(bitmap);
|
||||
delete this;
|
||||
if(LOCPLINT->curint->subInt)
|
||||
return;
|
||||
|
||||
if(LOCPLINT->curint == LOCPLINT->adventureInt)
|
||||
LOCPLINT->adventureInt->show();
|
||||
else if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt)
|
||||
else if(LOCPLINT->curint == LOCPLINT->castleInt)
|
||||
LOCPLINT->castleInt->showAll();
|
||||
}
|
||||
void CInfoPopup::show(SDL_Surface * to)
|
||||
@ -684,6 +687,11 @@ void SComponent::init(Etype Type, int Subtype, int Val)
|
||||
subtype = Subtype;
|
||||
val = Val;
|
||||
SDL_Surface * temp = this->getImg();
|
||||
if(!temp)
|
||||
{
|
||||
tlog1 << "Error: cannot find graphic for component with id=" << type << " subid=" << subtype << " val=" << val << std::endl;
|
||||
return;
|
||||
}
|
||||
pos.w = temp->w;
|
||||
pos.h = temp->h;
|
||||
}
|
||||
@ -696,6 +704,8 @@ SComponent::SComponent(const Component &c)
|
||||
{
|
||||
if(c.id==5)
|
||||
init(experience,c.subtype,c.val);
|
||||
else if(c.id == Component::SPELL)
|
||||
init(spell,c.subtype,c.val);
|
||||
else
|
||||
init((Etype)c.id,c.subtype,c.val);
|
||||
|
||||
@ -734,6 +744,9 @@ SDL_Surface * SComponent::getImg()
|
||||
case luck:
|
||||
return graphics->luck82->ourImages[val+3].bitmap;
|
||||
break;
|
||||
case spell:
|
||||
return graphics->spellscr->ourImages[subtype].bitmap;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1124,7 +1137,7 @@ void CPlayerInterface::yourTurn()
|
||||
|
||||
|
||||
//if there are any waiting dialogs, show them
|
||||
if(dialogs.size())
|
||||
if(dialogs.size() && !showingDialog->get())
|
||||
{
|
||||
dialogs.front()->buttons[0]->callback += boost::bind(&IActivable::activate,LOCPLINT->curint);
|
||||
showingDialog->set(true);
|
||||
|
@ -91,6 +91,8 @@ public:
|
||||
void setManaPoints(int hid, int val){};
|
||||
void giveHero(int id, int player){};
|
||||
void changeObjPos(int objid, int3 newPos, ui8 flags){};
|
||||
void sendAndApply(CPackForClient * info){};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
friend class CCallback; //handling players actions
|
||||
friend void processCommand(const std::string &message, CClient *&client); //handling console
|
||||
|
@ -223,6 +223,7 @@ Graphics::Graphics()
|
||||
tasks += GET_DEF(abils32,"SECSK32.DEF");
|
||||
tasks += GET_DEF(abils44,"SECSKILL.DEF");
|
||||
tasks += GET_DEF(abils82,"SECSK82.DEF");
|
||||
tasks += GET_DEF(spellscr,"SPELLSCR.DEF");
|
||||
|
||||
std::ifstream ifs("config/cr_bgs.txt");
|
||||
int id;
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
std::vector<std::string> guildBgs;// name of bitmaps with imgs for mage guild screen
|
||||
//abilities
|
||||
CDefHandler * abils32, * abils44, * abils82;
|
||||
//spells
|
||||
CDefHandler *spellscr; //spell on the scroll 83x61
|
||||
//functions
|
||||
Graphics();
|
||||
void initializeBattleGraphics();
|
||||
|
@ -457,6 +457,8 @@ void CCreatureHandler::loadCreatures()
|
||||
creatures[123].abilities.insert(DOUBLE_WIDE);//ice elemental should be treated as double-wide
|
||||
creatures[140].abilities.insert(DOUBLE_WIDE);//boar should be treated as double-wide
|
||||
creatures[142].abilities.insert(DOUBLE_WIDE);//nomads should be treated as double-wide
|
||||
|
||||
creatures[46].abilities -= FLYING;
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadAnimationInfo()
|
||||
|
@ -1893,4 +1893,88 @@ void CGEvent::activated( const CGHeroInstance * h ) const
|
||||
if(guarders)
|
||||
cb->startBattleI(h->id,guarders,pos,boost::bind(&CGEvent::endBattle,this,_1));
|
||||
cb->removeObject(id);
|
||||
}
|
||||
|
||||
void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
FoWChange fw;
|
||||
fw.player = h->tempOwner;
|
||||
fw.mode = 1;
|
||||
cb->getTilesInRange(fw.tiles,pos,20,h->tempOwner,1);
|
||||
cb->sendAndApply(&fw);
|
||||
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,98);
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(spell == 255)
|
||||
{
|
||||
tlog1 << "Not initialized shrine visited!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,127 + ID - 88);
|
||||
iw.text.addTxt(MetaString::SPELL_NAME,spell);
|
||||
iw.text << ".";
|
||||
|
||||
if(!h->getArt(17)) //no spellbook
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,131);
|
||||
}
|
||||
else if(ID == 90 && !h->getSecSkillLevel(7)) //it's third level spell and hero doesn't have wisdom
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,130);
|
||||
}
|
||||
else if(vstd::contains(h->spells,spell))//hero already knows the spell
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,174);
|
||||
}
|
||||
else //give spell
|
||||
{
|
||||
std::set<ui32> spells;
|
||||
spells.insert(spell);
|
||||
cb->changeSpells(h->id,true,spells);
|
||||
|
||||
iw.components.push_back(Component(Component::SPELL,spell,0,0));
|
||||
}
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void CGShrine::initObj()
|
||||
{
|
||||
if(spell == 255) //spell not set
|
||||
{
|
||||
int level = ID-87;
|
||||
std::vector<ui32> possibilities;
|
||||
|
||||
//add all allowed spells of wanted level
|
||||
for(int i=0; i<SPELLS_QUANTITY; i++)
|
||||
{
|
||||
if(VLC->spellh->spells[i].level == level
|
||||
&& cb->isAllowed(0,VLC->spellh->spells[i].id))
|
||||
{
|
||||
possibilities.push_back(VLC->spellh->spells[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
if(!possibilities.size())
|
||||
{
|
||||
tlog1 << "Error: cannot init shrine, no allowed spells!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
spell = possibilities[ran() % possibilities.size()];
|
||||
}
|
||||
}
|
||||
|
||||
const std::string & CGShrine::getHoverText() const
|
||||
{
|
||||
return hoverName;
|
||||
}
|
@ -536,6 +536,9 @@ class DLL_EXPORT CGShrine : public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
ui8 spell; //number of spell or 255 if random
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void initObj();
|
||||
const std::string & getHoverText() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -657,6 +660,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGObservatory : public CGObjectInstance //Redwood observatory
|
||||
{
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -69,4 +69,40 @@ int IGameCallback::getHeroCount( int player, bool includeGarrisoned )
|
||||
if(!gs->getPlayer(player)->heroes[i]->inTownGarrison)
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ )
|
||||
{
|
||||
if(player >= PLAYER_LIMIT)
|
||||
{
|
||||
tlog1 << "Illegal call to getTilesInRange!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gs->map->width - 1); xd++)
|
||||
{
|
||||
for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gs->map->height - 1); yd++)
|
||||
{
|
||||
double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
|
||||
if(distance <= radious)
|
||||
{
|
||||
if(player < 0
|
||||
|| (mode == 1 && gs->players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0)
|
||||
|| (mode == -1 && gs->players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==1)
|
||||
)
|
||||
tiles.insert(int3(xd,yd,pos.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IGameCallback::isAllowed( int type, int id )
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
return gs->map->allowedSpell[id];
|
||||
default:
|
||||
tlog1 << "Wrong call to IGameCallback::isAllowed!\n";
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ struct ShowInInfobox;
|
||||
struct BattleResult;
|
||||
class CGameState;
|
||||
struct PlayerSettings;
|
||||
struct CPackForClient;
|
||||
|
||||
class DLL_EXPORT IGameCallback
|
||||
{
|
||||
@ -38,6 +39,8 @@ public:
|
||||
virtual int getSelectedHero()=0;
|
||||
virtual const PlayerSettings * getPlayerSettings(int color);
|
||||
virtual int getHeroCount(int player, bool includeGarrisoned);
|
||||
virtual void getTilesInRange(std::set<int3> &tiles, int3 pos, int radious, int player=-1, int mode=0); //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
|
||||
virtual bool isAllowed(int type, int id); //type: 0 - spell
|
||||
|
||||
//do sth
|
||||
virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;
|
||||
@ -65,6 +68,8 @@ public:
|
||||
virtual void setManaPoints(int hid, int val)=0;
|
||||
virtual void giveHero(int id, int player)=0;
|
||||
virtual void changeObjPos(int objid, int3 newPos, ui8 flags)=0;
|
||||
virtual void sendAndApply(CPackForClient * info)=0;
|
||||
|
||||
|
||||
friend struct CPackForClient;
|
||||
friend struct CPackForServer;
|
||||
|
@ -59,6 +59,8 @@ struct Query : public CPackForClient
|
||||
|
||||
struct MetaString : public CPack //2001 helper for object scrips
|
||||
{
|
||||
enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,
|
||||
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME};
|
||||
std::vector<std::string> strings;
|
||||
std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt
|
||||
std::vector<si32> message;
|
||||
@ -68,7 +70,10 @@ struct MetaString : public CPack //2001 helper for object scrips
|
||||
{
|
||||
h & strings & texts & message & replacements;
|
||||
}
|
||||
|
||||
void addTxt(ui8 type, ui32 serial)
|
||||
{
|
||||
*this << std::make_pair(type,serial);
|
||||
}
|
||||
MetaString& operator<<(const std::pair<ui8,ui32> &txt)
|
||||
{
|
||||
message.push_back(-((si32)texts.size())-1);
|
||||
@ -472,7 +477,7 @@ struct NewTurn : public CPackForClient //101
|
||||
|
||||
struct Component : public CPack //2002 helper for object scrips informations
|
||||
{
|
||||
enum {PRIM_SKILL,SEC_SKILL,RESOURCE,CREATURE,ARTIFACT,EXPERIENCE};
|
||||
enum {PRIM_SKILL,SEC_SKILL,RESOURCE,CREATURE,ARTIFACT,EXPERIENCE,SPELL};
|
||||
ui16 id, subtype; //id uses ^^^ enums, when id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels)
|
||||
si32 val; // + give; - take
|
||||
si16 when; // 0 - now; +x - within x days; -x - per x days
|
||||
|
@ -25,6 +25,7 @@ template<typename Serializer> DLL_EXPORT void registerTypes1(Serializer &s)
|
||||
s.registerType<CGQuestGuard>();
|
||||
s.registerType<CGBonusingObject>();
|
||||
s.registerType<CGMagicWell>();
|
||||
s.registerType<CGObservatory>();
|
||||
s.registerType<CGObjectInstance>();
|
||||
}
|
||||
|
||||
|
5
map.cpp
5
map.cpp
@ -1808,6 +1808,11 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
nobj = new CGMagicWell();
|
||||
break;
|
||||
}
|
||||
case 58: //Redwood Observatory
|
||||
{
|
||||
nobj = new CGObservatory();
|
||||
break;
|
||||
}
|
||||
case 214: //hero placeholder
|
||||
{
|
||||
i+=3; //TODO: handle it more properly
|
||||
|
@ -1229,7 +1229,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
{
|
||||
obj->onHeroLeave(h);
|
||||
}
|
||||
tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner);
|
||||
getTilesInRange(tmh.fowRevealed,h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner,1);
|
||||
sendAndApply(&tmh);
|
||||
tlog5 << "Moved to " <<tmh.end<<std::endl;
|
||||
|
||||
@ -1256,7 +1256,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
}
|
||||
}
|
||||
tmh.result = instant+1;
|
||||
tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner);
|
||||
getTilesInRange(tmh.fowRevealed,h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner,1);
|
||||
sendAndApply(&tmh);
|
||||
}
|
||||
}
|
||||
@ -2406,9 +2406,9 @@ void CGameHandler::handleTimeEvents()
|
||||
if( pinfo //player exists
|
||||
&& (ev->players & 1<<player) //event is enabled to this player
|
||||
&& ((ev->computerAffected && !pinfo->human)
|
||||
|| (ev->humanAffected && pinfo->human)
|
||||
)
|
||||
|| (ev->humanAffected && pinfo->human)
|
||||
)
|
||||
)
|
||||
{
|
||||
//give resources
|
||||
SetResources sr;
|
||||
|
@ -136,5 +136,5 @@ void PlayerMessage::applyGh( CGameHandler *gh )
|
||||
void SetSelection::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
||||
gh->sendToAllClients(this);
|
||||
gh->sendAndApply(this);
|
||||
}
|
Loading…
Reference in New Issue
Block a user