1
0
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:
Michał W. Urbańczyk 2009-03-14 11:25:25 +00:00
parent e961655b1a
commit 6ce9a253a4
16 changed files with 183 additions and 31 deletions

View File

@ -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++)

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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()

View File

@ -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;
}

View File

@ -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);
}
};

View File

@ -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";
}
}

View File

@ -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;

View File

@ -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

View File

@ -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>();
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}