mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
* flaggable objects change their color on minimap when taken over
* corrected damage inflicted by spells and ballista * minor changes
This commit is contained in:
parent
fec75cdc04
commit
8e63c73cf8
@ -185,6 +185,11 @@ const CGHeroInstance * CCallback::getHeroInfo(int val, int mode) const //mode =
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CGObjectInstance * CCallback::getObjectInfo(int ID) const
|
||||
{
|
||||
return gs->map->objects[ID];
|
||||
}
|
||||
|
||||
bool CCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const
|
||||
{
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero);
|
||||
@ -264,7 +269,7 @@ std::vector< std::vector< std::vector<unsigned char> > > & CCallback::getVisibil
|
||||
bool CCallback::isVisible(int3 pos, int Player) const
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
return gs->players[Player].fogOfWarMap[pos.x][pos.y][pos.z];
|
||||
return gs->isVisible(pos, Player);
|
||||
}
|
||||
|
||||
std::vector < const CGTownInstance *> CCallback::getTownsInfo(bool onlyOur) const
|
||||
@ -306,24 +311,14 @@ bool CCallback::isVisible(int3 pos) const
|
||||
|
||||
bool CCallback::isVisible( const CGObjectInstance *obj, int Player ) const
|
||||
{
|
||||
//object is visible when at least one blocked tile is visible
|
||||
for(int fx=0; fx<8; ++fx)
|
||||
{
|
||||
for(int fy=0; fy<6; ++fy)
|
||||
{
|
||||
int3 pos = obj->pos + int3(fx-7,fy-5,0);
|
||||
if(gs->map->isInTheMap(pos)
|
||||
&& !((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1)
|
||||
&& isVisible(pos,Player) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return gs->isVisible(obj, Player);
|
||||
}
|
||||
|
||||
int CCallback::getMyColor() const
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
int CCallback::getHeroSerial(const CGHeroInstance * hero) const
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
@ -334,6 +329,7 @@ int CCallback::getHeroSerial(const CGHeroInstance * hero) const
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) const
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
|
@ -205,6 +205,7 @@ public:
|
||||
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
std::vector< std::vector< std::vector<unsigned char> > > & getVisibilityMap() const; //returns visibility map (TODO: make it const)
|
||||
const CGHeroInstance * getHeroInfo(int val, int mode=2) const; //mode = 0 -> val = serial; mode = 1 -> val = hero type id (subID); mode = 2 -> val = global object serial id (id)
|
||||
const CGObjectInstance * getObjectInfo(int ID) const; //global object serial id (ID)
|
||||
int getResourceAmount(int type) const;
|
||||
std::vector<si32> getResourceAmount() const;
|
||||
int howManyHeroes(bool includeGarrisoned = true) const;
|
||||
|
@ -39,6 +39,7 @@ struct SpellCast;
|
||||
struct SetStackEffect;
|
||||
struct HeroBonus;
|
||||
struct PackageApplied;
|
||||
struct SetObjectProperty;
|
||||
class CLoadFile;
|
||||
class CSaveFile;
|
||||
template <typename Serializer> class CISer;
|
||||
@ -59,6 +60,7 @@ struct StackState
|
||||
int shotsLeft;
|
||||
std::set<int> effects; //IDs of spells affecting stack
|
||||
int morale, luck;
|
||||
int dmgMultiplier; //for ballista dmg bonus handling
|
||||
};
|
||||
|
||||
class CGameInterface
|
||||
@ -97,6 +99,7 @@ public:
|
||||
virtual void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
|
||||
virtual void requestRealized(PackageApplied *pa){};
|
||||
virtual void heroExchangeStarted(si32 hero1, si32 hero2){};
|
||||
virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged
|
||||
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
||||
|
||||
|
@ -45,6 +45,7 @@ extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
|
||||
using namespace boost::logic;
|
||||
using namespace boost::assign;
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
CMinimap::CMinimap(bool draw)
|
||||
{
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
@ -157,6 +158,26 @@ void CMinimap::draw(SDL_Surface * to)
|
||||
}
|
||||
void CMinimap::redraw(int level)// (level==-1) => redraw all levels
|
||||
{
|
||||
initMap(level);
|
||||
|
||||
//FoW
|
||||
initFoW(level);
|
||||
|
||||
//flaggable objects
|
||||
initFlaggableObjs(level);
|
||||
|
||||
//showing tiles
|
||||
showVisibleTiles();
|
||||
}
|
||||
|
||||
void CMinimap::initMap(int level)
|
||||
{
|
||||
/*for(int g=0; g<map.size(); ++g)
|
||||
{
|
||||
SDL_FreeSurface(map[g]);
|
||||
}
|
||||
map.clear();*/
|
||||
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
for (size_t i=0; i<CGI->mh->sizes.z; i++)
|
||||
{
|
||||
@ -184,8 +205,17 @@ void CMinimap::redraw(int level)// (level==-1) => redraw all levels
|
||||
map.push_back(pom);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//FoW
|
||||
void CMinimap::initFoW(int level)
|
||||
{
|
||||
/*for(int g=0; g<FoW.size(); ++g)
|
||||
{
|
||||
SDL_FreeSurface(FoW[g]);
|
||||
}
|
||||
FoW.clear();*/
|
||||
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
int mw = map[0]->w, mh = map[0]->h;//,
|
||||
//wo = mw/mapSizes.x, ho = mh/mapSizes.y; //TODO use me
|
||||
for(int d=0; d<CGI->mh->map->twoLevel+1; ++d)
|
||||
@ -206,8 +236,18 @@ void CMinimap::redraw(int level)// (level==-1) => redraw all levels
|
||||
}
|
||||
FoW.push_back(pt);
|
||||
}
|
||||
//FoW end
|
||||
//flaggable objects
|
||||
}
|
||||
|
||||
void CMinimap::initFlaggableObjs(int level)
|
||||
{
|
||||
/*for(int g=0; g<flObjs.size(); ++g)
|
||||
{
|
||||
SDL_FreeSurface(flObjs[g]);
|
||||
}
|
||||
flObjs.clear();*/
|
||||
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
int mw = map[0]->w, mh = map[0]->h;
|
||||
for(int d=0; d<CGI->mh->map->twoLevel+1; ++d)
|
||||
{
|
||||
if(level>=0 && d!=level)
|
||||
@ -222,30 +262,16 @@ void CMinimap::redraw(int level)// (level==-1) => redraw all levels
|
||||
}
|
||||
flObjs.push_back(pt);
|
||||
}
|
||||
//showing tiles
|
||||
for(int d=0; d<CGI->mh->map->twoLevel+1; ++d)
|
||||
{
|
||||
if(level>=0 && d!=level)
|
||||
continue;
|
||||
for(int x=0; x<mapSizes.x; ++x)
|
||||
{
|
||||
for(int y=0; y<mapSizes.y; ++y)
|
||||
{
|
||||
if(LOCPLINT->cb->isVisible(int3(x, y, d)))
|
||||
{
|
||||
showTile(int3(x, y, d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMinimap::updateRadar()
|
||||
{}
|
||||
|
||||
void CMinimap::clickRight (tribool down)
|
||||
{
|
||||
LOCPLINT->adventureInt->handleRightClick(rcText,down,this);
|
||||
}
|
||||
|
||||
void CMinimap::clickLeft (tribool down)
|
||||
{
|
||||
if (down && (!pressedL))
|
||||
@ -268,6 +294,7 @@ void CMinimap::clickLeft (tribool down)
|
||||
newCPos.z = LOCPLINT->adventureInt->position.z;
|
||||
LOCPLINT->adventureInt->centerOn(newCPos);
|
||||
}
|
||||
|
||||
void CMinimap::hover (bool on)
|
||||
{
|
||||
Hoverable::hover(on);
|
||||
@ -276,6 +303,7 @@ void CMinimap::hover (bool on)
|
||||
else if (LOCPLINT->adventureInt->statusbar.current==statusbarTxt)
|
||||
LOCPLINT->adventureInt->statusbar.clear();
|
||||
}
|
||||
|
||||
void CMinimap::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
{
|
||||
if (pressedL)
|
||||
@ -291,6 +319,7 @@ void CMinimap::activate()
|
||||
if (pressedL)
|
||||
MotionInterested::activate();
|
||||
}
|
||||
|
||||
void CMinimap::deactivate()
|
||||
{
|
||||
if (pressedL)
|
||||
@ -299,6 +328,7 @@ void CMinimap::deactivate()
|
||||
ClickableR::deactivate();
|
||||
Hoverable::deactivate();
|
||||
}
|
||||
|
||||
void CMinimap::showTile(const int3 &pos)
|
||||
{
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
@ -371,6 +401,27 @@ void CMinimap::showTile(const int3 &pos)
|
||||
}
|
||||
//flaggable objects drawn
|
||||
}
|
||||
|
||||
void CMinimap::showVisibleTiles(int level)
|
||||
{
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
for(int d=0; d<CGI->mh->map->twoLevel+1; ++d)
|
||||
{
|
||||
if(level>=0 && d!=level)
|
||||
continue;
|
||||
for(int x=0; x<mapSizes.x; ++x)
|
||||
{
|
||||
for(int y=0; y<mapSizes.y; ++y)
|
||||
{
|
||||
if(LOCPLINT->cb->isVisible(int3(x, y, d)))
|
||||
{
|
||||
showTile(int3(x, y, d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMinimap::hideTile(const int3 &pos)
|
||||
{
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ public:
|
||||
~CMinimap();
|
||||
void draw(SDL_Surface * to);
|
||||
void redraw(int level=-1);// (level==-1) => redraw all levels
|
||||
void initMap(int level=-1);// (level==-1) => redraw all levels
|
||||
void initFoW(int level=-1);// (level==-1) => redraw all levels
|
||||
void initFlaggableObjs(int level=-1);// (level==-1) => redraw all levels
|
||||
|
||||
void updateRadar();
|
||||
|
||||
void clickRight (boost::logic::tribool down);
|
||||
@ -50,6 +54,7 @@ public:
|
||||
void deactivate(); // makes button inactive (but don't deletes)
|
||||
void hideTile(const int3 &pos); //puts FoW
|
||||
void showTile(const int3 &pos); //removes FoW
|
||||
void showVisibleTiles(int level=-1);// (level==-1) => redraw all levels
|
||||
};
|
||||
class CTerrainRect
|
||||
: public ClickableL, public ClickableR, public Hoverable, public MotionInterested
|
||||
|
@ -2607,6 +2607,10 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
pom->morale = myst.Morale();
|
||||
pom->speedBonus = myst.Speed() - myst.creature->speed;
|
||||
pom->healthBonus = myst.MaxHealth() - myst.creature->hitPoints;
|
||||
if(myst.hasFeatureOfType(StackFeature::SIEGE_WEAPON))
|
||||
pom->dmgMultiplier = h->getPrimSkillLevel(0) + 1;
|
||||
else
|
||||
pom->dmgMultiplier = 1;
|
||||
|
||||
pom->shotsLeft = myst.shots;
|
||||
for(int vb=0; vb<myst.effects.size(); ++vb)
|
||||
@ -2614,7 +2618,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
pom->effects.insert(myst.effects[vb].id);
|
||||
}
|
||||
pom->currentHealth = myst.firstHPleft;
|
||||
LOCPLINT->pushInt(new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,0,0,NULL));
|
||||
LOCPLINT->pushInt(new CCreInfoWindow(myst.creature->idNumber, 0, myst.amount, pom, 0, 0, NULL));
|
||||
}
|
||||
delete pom;
|
||||
}
|
||||
|
@ -1712,6 +1712,22 @@ void CPlayerInterface::heroExchangeStarted(si32 hero1, si32 hero2)
|
||||
pushInt(new CExchangeWindow(hero2, hero1));
|
||||
}
|
||||
|
||||
void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
{
|
||||
//redraw minimap if owner changed
|
||||
if(sop->what == 1)
|
||||
{
|
||||
LOCPLINT->adventureInt->minimap.initFlaggableObjs();
|
||||
const CGObjectInstance * obj = LOCPLINT->cb->getObjectInfo(sop->id);
|
||||
std::set<int3> pos = obj->getBlockedPos();
|
||||
for(std::set<int3>::const_iterator it = pos.begin(); it != pos.end(); ++it)
|
||||
{
|
||||
LOCPLINT->adventureInt->minimap.showTile(*it);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CPlayerInterface::recreateWanderingHeroes()
|
||||
{
|
||||
wanderingHeroes.clear();
|
||||
|
@ -174,6 +174,7 @@ public:
|
||||
void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain);//if gain hero received bonus, else he lost it
|
||||
void requestRealized(PackageApplied *pa);
|
||||
void heroExchangeStarted(si32 hero1, si32 hero2);
|
||||
void objectPropertyChanged(const SetObjectProperty * sop);
|
||||
void serialize(COSer<CSaveFile> &h, const int version); //saving
|
||||
void serialize(CISer<CLoadFile> &h, const int version); //loading
|
||||
|
||||
|
@ -75,6 +75,7 @@ static StackState* getStackState(const CGObjectInstance *obj, int pos, bool town
|
||||
pom->luck = h->getCurrentLuck();
|
||||
pom->morale = h->getCurrentMorale(pos,town);
|
||||
pom->speedBonus = h->valOfBonuses(HeroBonus::STACKS_SPEED);
|
||||
pom->dmgMultiplier = 1;
|
||||
return pom;
|
||||
}
|
||||
|
||||
@ -170,7 +171,7 @@ void CGarrisonSlot::clickRight (tribool down)
|
||||
StackState *pom = getStackState(getObj(),ID, LOCPLINT->topInt() == LOCPLINT->castleInt);
|
||||
if(down && creature)
|
||||
{
|
||||
LOCPLINT->pushInt(new CCreInfoWindow(creature->idNumber,0,count,pom,0,0,NULL));
|
||||
LOCPLINT->pushInt(new CCreInfoWindow(creature->idNumber, 0, count, pom, 0, 0, NULL));
|
||||
}
|
||||
delete pom;
|
||||
}
|
||||
@ -196,15 +197,15 @@ void CGarrisonSlot::clickLeft(tribool down)
|
||||
{
|
||||
|
||||
creWindow = new CCreInfoWindow(
|
||||
creature->idNumber,1,count,pom2,
|
||||
boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,pom.newID[0]), //bind upgrade function
|
||||
boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),&pom);
|
||||
creature->idNumber, 1, count, pom2,
|
||||
boost::bind(&CCallback::upgradeCreature, LOCPLINT->cb, getObj(), ID, pom.newID[0]), //bind upgrade function
|
||||
boost::bind(&CCallback::dismissCreature, LOCPLINT->cb, getObj(), ID), &pom);
|
||||
}
|
||||
else
|
||||
{
|
||||
creWindow = new CCreInfoWindow(
|
||||
creature->idNumber,1,count,pom2,0,
|
||||
boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID), NULL);
|
||||
creature->idNumber, 1, count, pom2, 0,
|
||||
boost::bind(&CCallback::dismissCreature, LOCPLINT->cb, getObj(), ID), NULL);
|
||||
}
|
||||
|
||||
LOCPLINT->pushInt(creWindow);
|
||||
@ -1681,7 +1682,7 @@ void CRecruitmentWindow::clickRight( boost::logic::tribool down )
|
||||
{
|
||||
if(isItIn(&genRect(132,102,pos.x+curx,pos.y+64),LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
|
||||
{
|
||||
CCreInfoWindow *popup = new CCreInfoWindow(creatures[i].ID,0,0,NULL,NULL,NULL,NULL);
|
||||
CCreInfoWindow *popup = new CCreInfoWindow(creatures[i].ID, 0, 0, NULL, NULL, NULL, NULL);
|
||||
LOCPLINT->pushInt(popup);
|
||||
break;
|
||||
}
|
||||
@ -2007,7 +2008,7 @@ void CCreInfoWindow::show(SDL_Surface * to)
|
||||
}
|
||||
|
||||
CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui)
|
||||
:type(Type),dsm(Dsm),dismiss(0),upgrade(0),ok(0)
|
||||
: type(Type), dsm(Dsm), dismiss(0), upgrade(0), ok(0)
|
||||
{
|
||||
//active = false;
|
||||
anf = 0;
|
||||
@ -2069,24 +2070,27 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
|
||||
//shots
|
||||
if(c->shots)
|
||||
{
|
||||
printAt(CGI->generaltexth->allTexts[198],155,86,GEOR13,zwykly,bitmap);
|
||||
printAt(CGI->generaltexth->allTexts[198], 155, 86, GEOR13, zwykly, bitmap);
|
||||
if(State && State->shotsLeft >= 0)
|
||||
sprintf(pom,"%d (%d)",c->shots,State->shotsLeft);
|
||||
sprintf(pom,"%d (%d)", c->shots, State->shotsLeft);
|
||||
else
|
||||
SDL_itoa(c->shots,pom,10);
|
||||
printToWR(pom,276,99,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(c->shots, pom, 10);
|
||||
printToWR(pom, 276, 99, GEOR13, zwykly, bitmap);
|
||||
}
|
||||
|
||||
//damage
|
||||
printAt(CGI->generaltexth->allTexts[199],155,105,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(c->damageMin,pom,10);
|
||||
if(c->damageMin > 0)
|
||||
hlp = log10f(c->damageMin)+2;
|
||||
int dmgMin = c->damageMin * State->dmgMultiplier;
|
||||
int dmgMax = c->damageMax * State->dmgMultiplier;
|
||||
|
||||
printAt(CGI->generaltexth->allTexts[199], 155, 105, GEOR13, zwykly, bitmap);
|
||||
SDL_itoa(dmgMin, pom, 10);
|
||||
if(dmgMin > 0)
|
||||
hlp = log10f(dmgMin) + 2;
|
||||
else
|
||||
hlp = 2;
|
||||
pom[hlp-1]=' '; pom[hlp]='-'; pom[hlp+1]=' ';
|
||||
SDL_itoa(c->damageMax,pom+hlp+2,10);
|
||||
printToWR(pom,276,118,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(dmgMax, pom+hlp+2, 10);
|
||||
printToWR(pom, 276, 118, GEOR13, zwykly, bitmap);
|
||||
|
||||
//health
|
||||
printAt(CGI->generaltexth->allTexts[388],155,124,GEOR13,zwykly,bitmap);
|
||||
|
@ -280,6 +280,16 @@ void InfoWindow::applyCl( CClient *cl )
|
||||
tlog2 << "We received InfoWindow for not our player...\n";
|
||||
}
|
||||
|
||||
void SetObjectProperty::applyCl( CClient *cl )
|
||||
{
|
||||
//inform all players that see this object
|
||||
for(std::map<ui8,CGameInterface *>::const_iterator it = cl->playerint.begin(); it != cl->playerint.end(); ++it)
|
||||
{
|
||||
//if(cl->gs->isVisible(cl->gs->map->objects[id]), it->first)
|
||||
INTERFACE_CALL_IF_PRESENT(it->first, objectPropertyChanged, this);
|
||||
}
|
||||
}
|
||||
|
||||
void HeroLevelUp::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *h = GS(cl)->getHero(heroid);
|
||||
|
@ -185,8 +185,8 @@ bool CGObjectInstance::blockingAt(int x, int y) const
|
||||
if(x<0 || y<0 || x>=getWidth() || y>=getHeight() || defInfo==NULL)
|
||||
return false;
|
||||
if((defInfo->blockMap[y+6-getHeight()] >> (7-(8-getWidth()+x) )) & 1)
|
||||
return true;
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGObjectInstance::coveringAt(int x, int y) const
|
||||
@ -196,6 +196,20 @@ bool CGObjectInstance::coveringAt(int x, int y) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
{
|
||||
std::set<int3> ret;
|
||||
for(int w=0; w<getWidth(); ++w)
|
||||
{
|
||||
for(int h=0; h<getHeight(); ++h)
|
||||
{
|
||||
if(blockingAt(w, h))
|
||||
ret.insert(int3(pos.x - getWidth() + w + 1, pos.y - getHeight() + h + 1, pos.z));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const //screen printing priority comparing
|
||||
{
|
||||
if(defInfo->printPriority==1 && cmp.defInfo->printPriority==0)
|
||||
|
@ -147,6 +147,7 @@ public:
|
||||
int3 getVisitableOffset() const; //returns (x,y,0) offset to first visitable tile from bottom right obj tile (0,0,0) (h3m pos)
|
||||
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) form left top tile of image (x, y in tiles)
|
||||
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) form left top tile of maximal possible image (8 x 6 tiles) (x, y in tiles)
|
||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||
bool operator<(const CGObjectInstance & cmp) const; //screen printing priority comparing
|
||||
CGObjectInstance();
|
||||
virtual ~CGObjectInstance();
|
||||
|
@ -1754,6 +1754,28 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameState::isVisible(int3 pos, int player)
|
||||
{
|
||||
return players[player].fogOfWarMap[pos.x][pos.y][pos.z];
|
||||
}
|
||||
|
||||
bool CGameState::isVisible( const CGObjectInstance *obj, int player )
|
||||
{
|
||||
//object is visible when at least one blocked tile is visible
|
||||
for(int fx=0; fx<8; ++fx)
|
||||
{
|
||||
for(int fy=0; fy<6; ++fy)
|
||||
{
|
||||
int3 pos = obj->pos + int3(fx-7,fy-5,0);
|
||||
if(map->isInTheMap(pos)
|
||||
&& !((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1)
|
||||
&& isVisible(pos, player) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const
|
||||
{
|
||||
const TerrainTile * pom = &map->getTile(dst);
|
||||
@ -1805,6 +1827,12 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
|
||||
minDmg = attacker->creature->damageMin * attacker->amount,
|
||||
maxDmg = attacker->creature->damageMax * attacker->amount;
|
||||
|
||||
if(attacker->hasFeatureOfType(StackFeature::SIEGE_WEAPON)) //any siege weapon, but only ballista can attack
|
||||
{ //minDmg and maxDmg are multiplied by hero attack + 1
|
||||
minDmg *= attackerHero->getPrimSkillLevel(0) + 1;
|
||||
maxDmg *= attackerHero->getPrimSkillLevel(0) + 1;
|
||||
}
|
||||
|
||||
//calculating total attack/defense skills modifier
|
||||
|
||||
if(!shooting && attacker->hasFeatureOfType(StackFeature::ATTACK_BONUS, 0)) //bloodlust handling (etc.)
|
||||
|
@ -282,6 +282,9 @@ public:
|
||||
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if dst tile is visitable from dst tile
|
||||
bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
|
||||
|
||||
bool isVisible(int3 pos, int player);
|
||||
bool isVisible(const CGObjectInstance *obj, int player);
|
||||
|
||||
CGameState(); //c-tor
|
||||
~CGameState(); //d-tor
|
||||
void getNeighbours(int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand);
|
||||
|
@ -610,6 +610,7 @@ struct InfoWindow : public CPackForClient //103 - displays simple info window
|
||||
struct SetObjectProperty : public CPackForClient//1001
|
||||
{
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
ui32 id;
|
||||
ui8 what; //1 - owner; 2 - blockvis; 3 - first stack count; 4 - visitors; 5 - visited; 6 - ID (if 34 then also def is replaced)
|
||||
|
@ -2499,46 +2499,57 @@ static ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster,
|
||||
case 15: //magic arrow
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 16: //ice bolt
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 20 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 17: //lightning bolt
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 25 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 18: //implosion
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 75 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 20: //frost ring
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 21: //fireball
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 22: //inferno
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 23: //meteor shower
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 24: //death ripple
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 5 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 25: //destroy undead
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
case 26: //armageddon
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 50 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
//applying sorcerery secondary skill
|
||||
@ -2604,7 +2615,7 @@ static ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const std::set<CStack*> affectedCreatures)
|
||||
static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<CStack*> affectedCreatures)
|
||||
{
|
||||
std::vector<ui32> ret;
|
||||
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
|
||||
@ -2613,21 +2624,30 @@ static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHero
|
||||
if(sp->positiveness >= 0 && (*it)->owner == caster->tempOwner)
|
||||
continue;
|
||||
|
||||
int prob = (*it)->valOfFeatures(StackFeature::MAGIC_RESISTANCE); //probability of resistance in %
|
||||
//caster's resistance support (secondary skils and artifacts)
|
||||
prob += caster->valOfBonuses(HeroBonus::MAGIC_RESISTANCE);
|
||||
const CGHeroInstance * bonusHero; //hero we should take bonuses from
|
||||
if((*it)->owner == caster->tempOwner)
|
||||
bonusHero = caster;
|
||||
else
|
||||
bonusHero = hero2;
|
||||
|
||||
switch(caster->getSecSkillLevel(26)) //resistance
|
||||
int prob = (*it)->valOfFeatures(StackFeature::MAGIC_RESISTANCE); //probability of resistance in %
|
||||
if(bonusHero)
|
||||
{
|
||||
case 1: //basic
|
||||
prob += 5;
|
||||
break;
|
||||
case 2: //advanced
|
||||
prob += 10;
|
||||
break;
|
||||
case 3: //expert
|
||||
prob += 20;
|
||||
break;
|
||||
//bonusHero's resistance support (secondary skils and artifacts)
|
||||
prob += bonusHero->valOfBonuses(HeroBonus::MAGIC_RESISTANCE);
|
||||
|
||||
switch(bonusHero->getSecSkillLevel(26)) //resistance
|
||||
{
|
||||
case 1: //basic
|
||||
prob += 5;
|
||||
break;
|
||||
case 2: //advanced
|
||||
prob += 10;
|
||||
break;
|
||||
case 3: //expert
|
||||
prob += 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(prob > 100) prob = 100;
|
||||
@ -2685,7 +2705,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
std::set<CStack*> attackedCres = gs->curB->getAttackedCreatures(s, h, ba.destinationTile);
|
||||
|
||||
//checking if creatures resist
|
||||
sc.resisted = calculateResistedStacks(s, h, attackedCres);
|
||||
sc.resisted = calculateResistedStacks(s, h, secondHero, attackedCres);
|
||||
|
||||
sendAndApply(&sc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user