mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* resting in town with mage guild will replenih all the mana points
* battle will end when one side has only war machines * fixed crasbug occurring on revisiting objects (by pressing space) * started writing support for artifacts
This commit is contained in:
parent
f794644c2a
commit
1983aee1b2
@ -101,6 +101,7 @@ public:
|
||||
/*****************************/
|
||||
class CAdvMapInt : public CMainInterface, public KeyInterested //adventure map interface
|
||||
{
|
||||
void hide(); //deactivates advmap interface
|
||||
public:
|
||||
CAdvMapInt(int Player);
|
||||
~CAdvMapInt();
|
||||
@ -161,7 +162,6 @@ public:
|
||||
void deactivate();
|
||||
|
||||
void show(SDL_Surface * to=NULL); //shows and activates adv. map interface
|
||||
void hide(); //deactivates advmap interface
|
||||
void update(); //redraws terrain
|
||||
|
||||
void select(const CArmedInstance *sel);
|
||||
|
@ -384,7 +384,7 @@ bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGH
|
||||
if(player!=hero1->tempOwner || player!=hero2->tempOwner)
|
||||
return false;
|
||||
|
||||
ExchangeArtifacts ea(hero1->id, pos1, hero2->id, pos2);
|
||||
ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2);
|
||||
*cl->serv << &ea;
|
||||
return true;
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ CHeroWindow::CHeroWindow(int playerColor):
|
||||
gar2button = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, pos.x+604, pos.y+491, SDLK_b);
|
||||
gar4button = new AdventureMapButton(CGI->generaltexth->allTexts[256], CGI->generaltexth->heroscrn[32], boost::function<void()>(), pos.x+604, pos.y+527, "hsbtns9.def", false, NULL, false);
|
||||
boost::algorithm::replace_first(gar4button->hoverTexts[0],"%s",CGI->generaltexth->allTexts[43]);
|
||||
leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::leftArtRoller,this), pos.x+379, pos.y+364, "hsbtns3.def", SDLK_LEFT);
|
||||
rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::rightArtRoller,this), pos.x+632, pos.y+364, "hsbtns5.def", SDLK_RIGHT);
|
||||
leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::scrollBackpack,this,-1), pos.x+379, pos.y+364, "hsbtns3.def", SDLK_LEFT);
|
||||
rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::scrollBackpack,this,+1), pos.x+632, pos.y+364, "hsbtns5.def", SDLK_RIGHT);
|
||||
|
||||
|
||||
for(int g=0; g<8; ++g)
|
||||
@ -268,6 +268,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
backpack.clear();
|
||||
|
||||
std::vector<SDL_Rect> slotPos;
|
||||
backpackPos = 0;
|
||||
|
||||
slotPos += genRect(44,44,pos.x+509,pos.y+30), genRect(44,44,pos.x+567,pos.y+240), genRect(44,44,pos.x+509,pos.y+80),
|
||||
genRect(44,44,pos.x+383,pos.y+68), genRect(44,44,pos.x+564,pos.y+183), genRect(44,44,pos.x+509,pos.y+130),
|
||||
@ -501,56 +502,26 @@ void CHeroWindow::dismissCurrent()
|
||||
void CHeroWindow::questlog()
|
||||
{
|
||||
}
|
||||
void CHeroWindow::leftArtRoller()
|
||||
|
||||
void CHeroWindow::scrollBackpack(int dir)
|
||||
{
|
||||
if(curHero->artifacts.size()>5) //if it is <=5, we have nothing to scroll
|
||||
backpackPos += dir + curHero->artifacts.size();
|
||||
backpackPos %= curHero->artifacts.size();
|
||||
|
||||
|
||||
for(size_t s=0; s<5 && s<curHero->artifacts.size(); ++s) //set new data
|
||||
{
|
||||
backpackPos+=curHero->artifacts.size()-1; //set new offset
|
||||
CArtPlace *cur = backpack[s];
|
||||
cur->slotID = 19+((s+backpackPos)%curHero->artifacts.size());
|
||||
cur->ourArt = curHero->getArt(cur->slotID);
|
||||
|
||||
for(size_t s=0; s<5 && s<curHero->artifacts.size(); ++s) //set new data
|
||||
{
|
||||
backpack[s]->ourArt = &CGI->arth->artifacts[curHero->artifacts[(s+backpackPos) % curHero->artifacts.size() ]];
|
||||
if(backpack[s]->ourArt)
|
||||
backpack[s]->text = backpack[s]->ourArt->Description();
|
||||
else
|
||||
backpack[s]->text = std::string();
|
||||
}
|
||||
if(cur->ourArt)
|
||||
cur->text = cur->ourArt->Description();
|
||||
else
|
||||
cur->text = std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void CHeroWindow::rightArtRoller()
|
||||
{
|
||||
if(curHero->artifacts.size()>5) //if it is <=5, we have nothing to scroll
|
||||
{
|
||||
backpackPos+=1; //set new offset
|
||||
|
||||
for(size_t s=0; s<5 && s<curHero->artifacts.size(); ++s) //set new data
|
||||
{
|
||||
backpack[s]->ourArt = &CGI->arth->artifacts[curHero->artifacts[(s+backpackPos) % curHero->artifacts.size() ] ];
|
||||
if(backpack[s]->ourArt)
|
||||
backpack[s]->text = backpack[s]->ourArt->Description();
|
||||
else
|
||||
backpack[s]->text = std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHeroWindow::switchHero()
|
||||
{
|
||||
//int y;
|
||||
//SDL_GetMouseState(NULL, &y);
|
||||
//for(int g=0; g<heroListMi.size(); ++g)
|
||||
//{
|
||||
// if(y>=94+54*g)
|
||||
// {
|
||||
// //quit();
|
||||
// setHero(LOCPLINT->cb->getHeroInfo(player, g, false));
|
||||
// //LOCPLINT->openHeroWindow(curHero);
|
||||
// redrawCurBack();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void CHeroWindow::redrawCurBack()
|
||||
{
|
||||
if(curBack)
|
||||
@ -754,7 +725,10 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
|
||||
//chceck if swap is possible
|
||||
if(this->fitsHere(ourWindow->activeArtPlace->ourArt) && ourWindow->activeArtPlace->fitsHere(this->ourArt))
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(ourWindow->curHero,slotID,ourWindow->curHero,ourWindow->activeArtPlace->slotID);
|
||||
int destSlot = slotID,
|
||||
srcSlot = ourWindow->activeArtPlace->slotID;
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(ourWindow->curHero,destSlot,ourWindow->curHero,srcSlot);
|
||||
|
||||
const CArtifact * pmh = ourArt;
|
||||
ourArt = ourWindow->activeArtPlace->ourArt;
|
||||
@ -786,9 +760,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
|
||||
}
|
||||
if(backID>=0) //put to backpack
|
||||
{
|
||||
/*ourWindow->activeArtPlace->ourArt = NULL;
|
||||
ourWindow->activeArtPlace->clicked = false;
|
||||
ourWindow->activeArtPlace = NULL;*/
|
||||
LOCPLINT->cb->swapArtifacts(ourWindow->curHero,ourWindow->activeArtPlace->slotID,ourWindow->curHero,ourWindow->curHero->artifacts.size()+19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,8 @@ public:
|
||||
void redrawCurBack(); //redraws curBAck from scratch
|
||||
void quit(); //stops displaying hero window
|
||||
void dismissCurrent(); //dissmissed currently displayed hero (curHero)
|
||||
void questlog(); //show quest log in hero window
|
||||
void leftArtRoller(); //scrolls artifacts in bag left
|
||||
void rightArtRoller(); //scrolls artifacts in bag right
|
||||
void questlog(); //show quest log in hero window
|
||||
void scrollBackpack(int dir); //dir==-1 => to left; dir==-2 => to right
|
||||
void switchHero(); //changes displayed hero
|
||||
|
||||
//friends
|
||||
|
@ -1214,7 +1214,7 @@ void CPlayerInterface::yourTurn()
|
||||
pim->unlock();
|
||||
SDL_framerateDelay(mainFPSmng);
|
||||
}
|
||||
adventureInt->hide();
|
||||
adventureInt->deactivate();
|
||||
cb->endTurn();
|
||||
}
|
||||
|
||||
@ -1785,7 +1785,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
||||
}
|
||||
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
||||
{
|
||||
adventureInt->hide();
|
||||
adventureInt->deactivate();
|
||||
//timeHandler t;
|
||||
//t.getDif();
|
||||
castleInt = new CCastleInterface(town,true);
|
||||
@ -2035,7 +2035,7 @@ void CPlayerInterface::showSelDialog(const std::string &text, const std::vector<
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
LOCPLINT->showingDialog->setn(true);
|
||||
adventureInt->hide(); //dezaktywacja starego interfejsu
|
||||
adventureInt->deactivate(); //dezaktywacja starego interfejsu
|
||||
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
|
||||
|
@ -211,9 +211,21 @@ void SetHeroesInTown::applyCl( CClient *cl )
|
||||
|
||||
void SetHeroArtifacts::applyCl( CClient *cl )
|
||||
{
|
||||
CGHeroInstance *t = GS(cl)->getHero(hid);
|
||||
if(vstd::contains(cl->playerint,t->tempOwner))
|
||||
cl->playerint[t->tempOwner]->heroArtifactSetChanged(t);
|
||||
CGHeroInstance *h = GS(cl)->getHero(hid);
|
||||
CGameInterface *player = (vstd::contains(cl->playerint,h->tempOwner) ? cl->playerint[h->tempOwner] : NULL);
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
player->heroArtifactSetChanged(h);
|
||||
|
||||
BOOST_FOREACH(HeroBonus *bonus, gained)
|
||||
{
|
||||
player->heroBonusChanged(h,*bonus,true);
|
||||
}
|
||||
BOOST_FOREACH(HeroBonus *bonus, lost)
|
||||
{
|
||||
player->heroBonusChanged(h,*bonus,false);
|
||||
}
|
||||
}
|
||||
|
||||
void HeroRecruited::applyCl( CClient *cl )
|
||||
|
2
global.h
2
global.h
@ -19,7 +19,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
#define THC
|
||||
#endif
|
||||
|
||||
#define NAME_VER ("VCMI 0.7d2")
|
||||
#define NAME_VER ("VCMI 0.71b")
|
||||
#define CONSOLE_LOGGING_LEVEL 5
|
||||
#define FILE_LOGGING_LEVEL 6
|
||||
|
||||
|
@ -8,6 +8,22 @@
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
|
||||
const std::string & CArtifact::Name() const
|
||||
{
|
||||
if(name.size())
|
||||
return name;
|
||||
else
|
||||
return VLC->generaltexth->artifNames[id];
|
||||
}
|
||||
|
||||
const std::string & CArtifact::Description() const
|
||||
{
|
||||
if(description.size())
|
||||
return description;
|
||||
else
|
||||
return VLC->generaltexth->artifDescriptions[id];
|
||||
}
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
@ -46,6 +62,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
artifacts.push_back(nart);
|
||||
}
|
||||
sortArts();
|
||||
addBonuses();
|
||||
}
|
||||
|
||||
int CArtHandler::convertMachineID(int id, bool creToArt )
|
||||
@ -101,18 +118,187 @@ void CArtHandler::sortArts()
|
||||
}
|
||||
}
|
||||
|
||||
const std::string & CArtifact::Name() const
|
||||
void CArtHandler::giveArtBonus( int aid, HeroBonus::BonusType type, int val, int subtype )
|
||||
{
|
||||
if(name.size())
|
||||
return name;
|
||||
else
|
||||
return VLC->generaltexth->artifNames[id];
|
||||
artifacts[aid].bonuses.push_back(HeroBonus(HeroBonus::PERMANENT,type,HeroBonus::ARTIFACT,val,aid,subtype));
|
||||
}
|
||||
|
||||
const std::string & CArtifact::Description() const
|
||||
void CArtHandler::addBonuses()
|
||||
{
|
||||
if(description.size())
|
||||
return description;
|
||||
else
|
||||
return VLC->generaltexth->artifDescriptions[id];
|
||||
}
|
||||
#define ART_PRIM_SKILL(ID, whichSkill, val) giveArtBonus(ID,HeroBonus::PRIMARY_SKILL,val,whichSkill)
|
||||
#define ART_MORALE(ID, val) giveArtBonus(ID,HeroBonus::MORALE,val)
|
||||
#define ART_LUCK(ID, val) giveArtBonus(ID,HeroBonus::LUCK,val)
|
||||
#define ART_MORALE_AND_LUCK(ID, val) giveArtBonus(ID,HeroBonus::MORALE_AND_LUCK,val)
|
||||
#define ART_ALL_PRIM_SKILLS(ID, val) ART_PRIM_SKILL(ID,0,val); ART_PRIM_SKILL(ID,1,val); ART_PRIM_SKILL(ID,2,val); ART_PRIM_SKILL(ID,3,val)
|
||||
#define ART_ATTACK_AND_DEFENSE(ID, val) ART_PRIM_SKILL(ID,0,val); ART_PRIM_SKILL(ID,1,val)
|
||||
#define ART_POWER_AND_KNOWLEDGE(ID, val) ART_PRIM_SKILL(ID,2,val); ART_PRIM_SKILL(ID,3,val)
|
||||
|
||||
//Attack bonus artifacts (Weapons)
|
||||
ART_PRIM_SKILL(7,0,+2); //Centaur Axe
|
||||
ART_PRIM_SKILL(8,0,+3);
|
||||
ART_PRIM_SKILL(9,0,+4);
|
||||
ART_PRIM_SKILL(10,0,+5);
|
||||
ART_PRIM_SKILL(11,0,+6);
|
||||
ART_PRIM_SKILL(12,0,+12);
|
||||
ART_PRIM_SKILL(12,1,-3);
|
||||
|
||||
//Defense bonus artifacts (Shields)
|
||||
ART_PRIM_SKILL(13,1,+2); //Shield of the Dwarven Lords
|
||||
ART_PRIM_SKILL(14,1,+3);
|
||||
ART_PRIM_SKILL(15,1,+4);
|
||||
ART_PRIM_SKILL(16,1,+5);
|
||||
ART_PRIM_SKILL(17,1,+6);
|
||||
ART_PRIM_SKILL(18,1,+12);
|
||||
ART_PRIM_SKILL(18,0,-3);
|
||||
|
||||
//Knowledge bonus artifacts (Helmets)
|
||||
ART_PRIM_SKILL(19,3,+1); //Helm of the Alabaster Unicorn
|
||||
ART_PRIM_SKILL(20,3,+2);
|
||||
ART_PRIM_SKILL(21,3,+3);
|
||||
ART_PRIM_SKILL(22,3,+4);
|
||||
ART_PRIM_SKILL(23,3,+5);
|
||||
ART_PRIM_SKILL(24,3,+10);
|
||||
ART_PRIM_SKILL(24,2,-2);
|
||||
|
||||
//Spell power bonus artifacts (Armours)
|
||||
ART_PRIM_SKILL(25,2,+1); //Breastplate of Petrified Wood
|
||||
ART_PRIM_SKILL(26,2,+2);
|
||||
ART_PRIM_SKILL(27,2,+3);
|
||||
ART_PRIM_SKILL(28,2,+4);
|
||||
ART_PRIM_SKILL(29,2,+5);
|
||||
ART_PRIM_SKILL(30,2,+10);
|
||||
ART_PRIM_SKILL(30,3,-2);
|
||||
|
||||
//All primary skills (various)
|
||||
ART_ALL_PRIM_SKILLS(31,+1); //Armor of Wonder
|
||||
ART_ALL_PRIM_SKILLS(32,+2);
|
||||
ART_ALL_PRIM_SKILLS(33,+3);
|
||||
ART_ALL_PRIM_SKILLS(34,+4);
|
||||
ART_ALL_PRIM_SKILLS(35,+5);
|
||||
ART_ALL_PRIM_SKILLS(36,+6); //Helm of Heavenly Enlightenment
|
||||
|
||||
//Attack and Defense (various)
|
||||
ART_ATTACK_AND_DEFENSE(37,+1); //Quiet Eye of the Dragon
|
||||
ART_ATTACK_AND_DEFENSE(38,+2);
|
||||
ART_ATTACK_AND_DEFENSE(39,+3);
|
||||
ART_ATTACK_AND_DEFENSE(40,+4);
|
||||
|
||||
//Spell power and Knowledge (various)
|
||||
ART_POWER_AND_KNOWLEDGE(41,+1); //Dragonbone Greaves
|
||||
ART_POWER_AND_KNOWLEDGE(42,+2);
|
||||
ART_POWER_AND_KNOWLEDGE(43,+3);
|
||||
ART_POWER_AND_KNOWLEDGE(44,+4);
|
||||
|
||||
//Luck and morale
|
||||
ART_MORALE(45,+1); //Still Eye of the Dragon
|
||||
ART_LUCK(46,+1); //Clover of Fortune
|
||||
ART_LUCK(47,+1); //Cards of Prophecy
|
||||
ART_LUCK(48,+1); //Ladybird of Luck
|
||||
ART_MORALE(49,+1); //Badge of Courage
|
||||
ART_MORALE(50,+1); //Crest of Valor
|
||||
ART_MORALE(51,+1); //Glyph of Gallantry
|
||||
|
||||
giveArtBonus(52,HeroBonus::SIGHT_RADIOUS,+1);//Speculum
|
||||
giveArtBonus(53,HeroBonus::SIGHT_RADIOUS,+1);//Spyglass
|
||||
|
||||
//necromancy bonus
|
||||
giveArtBonus(54,HeroBonus::SECONDARY_SKILL_PREMY,+5,12);//Amulet of the Undertaker
|
||||
giveArtBonus(55,HeroBonus::SECONDARY_SKILL_PREMY,+10,12);//Vampire's Cowl
|
||||
giveArtBonus(56,HeroBonus::SECONDARY_SKILL_PREMY,+15,12);//Dead Man's Boots
|
||||
|
||||
giveArtBonus(57,HeroBonus::MAGIC_RESISTANCE,+5);//Garniture of Interference
|
||||
giveArtBonus(58,HeroBonus::MAGIC_RESISTANCE,+10);//Surcoat of Counterpoise
|
||||
giveArtBonus(59,HeroBonus::MAGIC_RESISTANCE,+15);//Boots of Polarity
|
||||
|
||||
//archery bonus
|
||||
giveArtBonus(60,HeroBonus::SECONDARY_SKILL_PREMY,+5,1);//Bow of Elven Cherrywood
|
||||
giveArtBonus(61,HeroBonus::SECONDARY_SKILL_PREMY,+10,1);//Bowstring of the Unicorn's Mane
|
||||
giveArtBonus(62,HeroBonus::SECONDARY_SKILL_PREMY,+15,1);//Angel Feather Arrows
|
||||
|
||||
//eagle eye bonus
|
||||
giveArtBonus(63,HeroBonus::SECONDARY_SKILL_PREMY,+5,11);//Bird of Perception
|
||||
giveArtBonus(64,HeroBonus::SECONDARY_SKILL_PREMY,+10,11);//Stoic Watchman
|
||||
giveArtBonus(65,HeroBonus::SECONDARY_SKILL_PREMY,+15,11);//Emblem of Cognizance
|
||||
|
||||
//reducing cost of surrendering
|
||||
giveArtBonus(66,HeroBonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal
|
||||
giveArtBonus(67,HeroBonus::SURRENDER_DISCOUNT,+10);//Diplomat's Ring
|
||||
giveArtBonus(68,HeroBonus::SURRENDER_DISCOUNT,+10);//Ambassador's Sash
|
||||
|
||||
giveArtBonus(69,HeroBonus::STACKS_SPEED,+1);//Ring of the Wayfarer
|
||||
|
||||
giveArtBonus(70,HeroBonus::LAND_MOVEMENT,+300);//Equestrian's Gloves
|
||||
giveArtBonus(71,HeroBonus::SEA_MOVEMENT,+1000);//Necklace of Ocean Guidance
|
||||
giveArtBonus(72,HeroBonus::FLYING_MOVEMENT,+1);//Angel Wings
|
||||
|
||||
giveArtBonus(73,HeroBonus::MANA_REGENERATION,+1);//Charm of Mana
|
||||
giveArtBonus(74,HeroBonus::MANA_REGENERATION,+2);//Talisman of Mana
|
||||
giveArtBonus(75,HeroBonus::MANA_REGENERATION,+3);//Mystic Orb of Mana
|
||||
|
||||
giveArtBonus(76,HeroBonus::SPELL_DURATION,+1);//Collar of Conjuring
|
||||
giveArtBonus(77,HeroBonus::SPELL_DURATION,+2);//Ring of Conjuring
|
||||
giveArtBonus(78,HeroBonus::SPELL_DURATION,+3);//Cape of Conjuring
|
||||
|
||||
giveArtBonus(79,HeroBonus::AIR_SPELL_DMG_PREMY,+50);//Orb of the Firmament
|
||||
giveArtBonus(80,HeroBonus::EARTH_SPELL_DMG_PREMY,+50);//Orb of Silt
|
||||
giveArtBonus(81,HeroBonus::FIRE_SPELL_DMG_PREMY,+50);//Orb of Tempestuous Fire
|
||||
giveArtBonus(82,HeroBonus::WATER_SPELL_DMG_PREMY,+50);//Orb of Driving Rain
|
||||
|
||||
giveArtBonus(83,HeroBonus::BLOCK_SPELLS_ABOVE_LEVEL,3);//Recanter's Cloak
|
||||
giveArtBonus(84,HeroBonus::BLOCK_MORALE,0);//Spirit of Oppression
|
||||
giveArtBonus(85,HeroBonus::BLOCK_LUCK,0);//Hourglass of the Evil Hour
|
||||
|
||||
giveArtBonus(86,HeroBonus::FIRE_SPELLS,0);//Tome of Fire Magic
|
||||
giveArtBonus(87,HeroBonus::AIR_SPELLS,0);//Tome of Air Magic
|
||||
giveArtBonus(88,HeroBonus::WATER_SPELLS,0);//Tome of Water Magic
|
||||
giveArtBonus(89,HeroBonus::EARTH_SPELLS,0);//Tome of Earth Magic
|
||||
|
||||
giveArtBonus(90,HeroBonus::WATER_WALKING,0);//Boots of Levitation
|
||||
giveArtBonus(91,HeroBonus::NO_SHOTING_PENALTY,0);//Golden Bow
|
||||
giveArtBonus(92,HeroBonus::DISPEL_IMMUNITY,0);//Sphere of Permanence
|
||||
giveArtBonus(93,HeroBonus::NEGATE_ALL_NATURAL_IMMUNITIES,0);//Orb of Vulnerability
|
||||
|
||||
giveArtBonus(94,HeroBonus::STACK_HEALTH,+1);//Ring of Vitality
|
||||
giveArtBonus(95,HeroBonus::STACK_HEALTH,+1);//Ring of Life
|
||||
giveArtBonus(96,HeroBonus::STACK_HEALTH,+2);//Vial of Lifeblood
|
||||
|
||||
giveArtBonus(97,HeroBonus::STACKS_SPEED,+1);//Necklace of Swiftness
|
||||
giveArtBonus(98,HeroBonus::LAND_MOVEMENT,+600);//Boots of Speed
|
||||
giveArtBonus(99,HeroBonus::STACKS_SPEED,+1);//Cape of Velocity
|
||||
|
||||
giveArtBonus(100,HeroBonus::SPELL_IMMUNITY,59);//Pendant of Dispassion
|
||||
giveArtBonus(101,HeroBonus::SPELL_IMMUNITY,62);//Pendant of Second Sight
|
||||
giveArtBonus(102,HeroBonus::SPELL_IMMUNITY,42);//Pendant of Holiness
|
||||
giveArtBonus(103,HeroBonus::SPELL_IMMUNITY,24);//Pendant of Life
|
||||
giveArtBonus(104,HeroBonus::SPELL_IMMUNITY,25);//Pendant of Death
|
||||
giveArtBonus(105,HeroBonus::SPELL_IMMUNITY,60);//Pendant of Free Will
|
||||
giveArtBonus(106,HeroBonus::SPELL_IMMUNITY,17);//Pendant of Negativity
|
||||
giveArtBonus(107,HeroBonus::SPELL_IMMUNITY,61);//Pendant of Total Recall
|
||||
giveArtBonus(108,HeroBonus::MORALE_AND_LUCK,+3);//Pendant of Courage
|
||||
|
||||
giveArtBonus(109,HeroBonus::GENERATE_RESOURCE,+1,4); //Everflowing Crystal Cloak
|
||||
giveArtBonus(110,HeroBonus::GENERATE_RESOURCE,+1,5); //Ring of Infinite Gems
|
||||
giveArtBonus(111,HeroBonus::GENERATE_RESOURCE,+1,1); //Everpouring Vial of Mercury
|
||||
giveArtBonus(112,HeroBonus::GENERATE_RESOURCE,+1,2); //Inexhaustible Cart of Ore
|
||||
giveArtBonus(113,HeroBonus::GENERATE_RESOURCE,+1,3); //Eversmoking Ring of Sulfur
|
||||
giveArtBonus(114,HeroBonus::GENERATE_RESOURCE,+1,0); //Inexhaustible Cart of Lumber
|
||||
giveArtBonus(115,HeroBonus::GENERATE_RESOURCE,+1000,6); //Endless Sack of Gold
|
||||
giveArtBonus(116,HeroBonus::GENERATE_RESOURCE,+750,6); //Endless Bag of Gold
|
||||
giveArtBonus(117,HeroBonus::GENERATE_RESOURCE,+500,6); //Endless Purse of Gold
|
||||
|
||||
giveArtBonus(118,HeroBonus::CREATURE_GROWTH,+5,2); //Legs of Legion
|
||||
giveArtBonus(119,HeroBonus::CREATURE_GROWTH,+4,3); //Loins of Legion
|
||||
giveArtBonus(120,HeroBonus::CREATURE_GROWTH,+3,4); //Torso of Legion
|
||||
giveArtBonus(121,HeroBonus::CREATURE_GROWTH,+2,5); //Arms of Legion
|
||||
giveArtBonus(122,HeroBonus::CREATURE_GROWTH,+1,6); //Head of Legion
|
||||
|
||||
//Sea Captain's Hat
|
||||
giveArtBonus(123,HeroBonus::WHIRLPOOL_PROTECTION,0);
|
||||
giveArtBonus(123,HeroBonus::SEA_MOVEMENT,+500);
|
||||
giveArtBonus(123,HeroBonus::SPELL,3,0);
|
||||
giveArtBonus(123,HeroBonus::SPELL,3,1);
|
||||
|
||||
giveArtBonus(124,HeroBonus::SPELLS_OF_LEVEL,3,1); //Spellbinder's Hat
|
||||
giveArtBonus(125,HeroBonus::ENEMY_CANT_ESCAPE,0); //Shackles of War
|
||||
giveArtBonus(126,HeroBonus::BLOCK_SPELLS_ABOVE_LEVEL,0);//Orb of Inhibition
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef __CARTHANDLER_H__
|
||||
#define __CARTHANDLER_H__
|
||||
#include "../global.h"
|
||||
#include "../lib/HeroBonus.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -13,28 +15,29 @@ class DLL_EXPORT CArtifact //container for artifacts
|
||||
public:
|
||||
const std::string &Name() const;
|
||||
const std::string &Description() const;
|
||||
bool isAllowed; //true if we can use this artifact (map information)
|
||||
//std::string desc2;
|
||||
unsigned int price;
|
||||
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
//bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4, misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso, lHand, rHand, neck, shoulders, head;
|
||||
EartClass aClass;
|
||||
int id;
|
||||
std::list<HeroBonus> bonuses; //bonuses given by artifact
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & isAllowed & name & description & price & possibleSlots & aClass & id ;
|
||||
h & name & description & price & possibleSlots & aClass & id & bonuses;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CArtHandler //handles artifacts
|
||||
{
|
||||
void giveArtBonus(int aid, HeroBonus::BonusType type, int val, int subtype = -1);
|
||||
public:
|
||||
std::vector<CArtifact*> treasures, minors, majors, relics;
|
||||
std::vector<CArtifact> artifacts;
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
void addBonuses();
|
||||
static int convertMachineID(int id, bool creToArt);
|
||||
CArtHandler();
|
||||
|
||||
|
@ -348,7 +348,11 @@ bool CGHeroInstance::canWalkOnSea() const
|
||||
}
|
||||
int CGHeroInstance::getPrimSkillLevel(int id) const
|
||||
{
|
||||
return primSkills[id];
|
||||
int ret = primSkills[id];
|
||||
for(std::list<HeroBonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
|
||||
if(i->type == HeroBonus::PRIMARY_SKILL && i->subtype==id)
|
||||
ret += i->val;
|
||||
return ret;
|
||||
}
|
||||
ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const
|
||||
{
|
||||
@ -359,24 +363,23 @@ ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const
|
||||
}
|
||||
int CGHeroInstance::maxMovePoints(bool onLand) const
|
||||
{
|
||||
int ret = 1270+70*lowestSpeed(this);
|
||||
if (ret>2000)
|
||||
ret=2000;
|
||||
int ret = std::max(2000, 1270+70*lowestSpeed(this)),
|
||||
bonus = valOfBonuses(HeroBonus::MOVEMENT) + (onLand ? valOfBonuses(HeroBonus::LAND_MOVEMENT) : valOfBonuses(HeroBonus::SEA_MOVEMENT));
|
||||
|
||||
double bonus = 0;
|
||||
double modifier = 0;
|
||||
if(onLand)
|
||||
{
|
||||
//logistics:
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
bonus = 0.1;
|
||||
modifier = 0.1;
|
||||
break;
|
||||
case 2:
|
||||
bonus = 0.2;
|
||||
modifier = 0.2;
|
||||
break;
|
||||
case 3:
|
||||
bonus = 0.3;
|
||||
modifier = 0.3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -386,18 +389,19 @@ int CGHeroInstance::maxMovePoints(bool onLand) const
|
||||
switch(getSecSkillLevel(2))
|
||||
{
|
||||
case 1:
|
||||
bonus = 0.5;
|
||||
modifier = 0.5;
|
||||
break;
|
||||
case 2:
|
||||
bonus = 1.0;
|
||||
modifier = 1.0;
|
||||
break;
|
||||
case 3:
|
||||
bonus = 1.5;
|
||||
modifier = 1.5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return int(ret + ret*bonus);
|
||||
return int(ret + ret*modifier) + bonus;
|
||||
}
|
||||
|
||||
ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
|
||||
{
|
||||
if(pos<19)
|
||||
@ -411,26 +415,7 @@ ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
void CGHeroInstance::setArtAtPos(ui16 pos, int art)
|
||||
{
|
||||
if(art<0)
|
||||
{
|
||||
if(pos<19)
|
||||
artifWorn.erase(pos);
|
||||
else
|
||||
artifacts -= artifacts[pos-19];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pos<19)
|
||||
artifWorn[pos] = art;
|
||||
else
|
||||
if(pos-19 < artifacts.size())
|
||||
artifacts[pos-19] = art;
|
||||
else
|
||||
artifacts.push_back(art);
|
||||
}
|
||||
}
|
||||
|
||||
const CArtifact * CGHeroInstance::getArt(int pos) const
|
||||
{
|
||||
int id = getArtAtPos(pos);
|
||||
@ -554,6 +539,15 @@ void CGHeroInstance::initHero()
|
||||
hoverName = VLC->generaltexth->allTexts[15];
|
||||
boost::algorithm::replace_first(hoverName,"%s",name);
|
||||
boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name);
|
||||
|
||||
//clear all bonuses from artifacts and give those from artifacts
|
||||
std::remove_if(bonuses.begin(), bonuses.end(), boost::bind(HeroBonus::IsFrom,_1,HeroBonus::ARTIFACT,0xffffff));
|
||||
for (std::map<ui16,ui32>::iterator ari = artifWorn.begin(); ari != artifWorn.end(); ari++)
|
||||
{
|
||||
CArtifact &art = VLC->arth->artifacts[ari->second];
|
||||
for(std::list<HeroBonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
|
||||
bonuses.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void CGHeroInstance::initHeroDefInfo()
|
||||
@ -766,7 +760,21 @@ int3 CGHeroInstance::getSightCenter() const
|
||||
|
||||
int CGHeroInstance::getSightRadious() const
|
||||
{
|
||||
return 5 + getSecSkillLevel(3); //default + scouting
|
||||
return 5 + getSecSkillLevel(3) + valOfBonuses(HeroBonus::SIGHT_RADIOUS); //default + scouting
|
||||
}
|
||||
|
||||
si32 CGHeroInstance::manaRegain() const
|
||||
{
|
||||
return 1 + getSecSkillLevel(8) + valOfBonuses(HeroBonus::MANA_REGENERATION); //1 + Mysticism level
|
||||
}
|
||||
|
||||
int CGHeroInstance::valOfBonuses( HeroBonus::BonusType type ) const
|
||||
{
|
||||
int ret = 0;
|
||||
for(std::list<HeroBonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
|
||||
if(i->type == type)
|
||||
ret += i->val;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGTownInstance::getSightRadious() const //returns sight distance
|
||||
|
@ -229,6 +229,7 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const HeroBonus *getBonus(int from, int id) const;
|
||||
int valOfBonuses(HeroBonus::BonusType type) const;
|
||||
const std::string &getBiography() const;
|
||||
bool needsLastStack()const;
|
||||
unsigned int getTileCost(const TerrainTile &dest, const TerrainTile &from) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
|
||||
@ -237,6 +238,7 @@ public:
|
||||
float getMultiplicativeMoveBonus() const;
|
||||
int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
|
||||
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
|
||||
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
||||
bool canWalkOnSea() const;
|
||||
int getCurrentLuck(int stack=-1, bool town=false) const;
|
||||
std::vector<std::pair<int,std::string> > getCurrentLuckModifiers(int stack=-1, bool town=false) const; //args as above
|
||||
@ -246,7 +248,6 @@ public:
|
||||
ui8 getSecSkillLevel(const int & ID) const; //0 - no skill
|
||||
int maxMovePoints(bool onLand) const;
|
||||
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
|
||||
void setArtAtPos(ui16 pos, int art);
|
||||
const CArtifact * getArt(int pos) const;
|
||||
int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
|
||||
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||
|
@ -4,21 +4,56 @@
|
||||
|
||||
struct DLL_EXPORT HeroBonus
|
||||
{
|
||||
enum BonusType{NONE, MOVEMENT, LAND_MOVEMENT, SEA_MOVEMENT, MORALE, LUCK, MORALE_AND_LUCK};
|
||||
enum BonusType
|
||||
{
|
||||
//handled
|
||||
NONE,
|
||||
MOVEMENT, //both water/land
|
||||
LAND_MOVEMENT,
|
||||
SEA_MOVEMENT,
|
||||
MORALE,
|
||||
LUCK,
|
||||
MORALE_AND_LUCK,
|
||||
PRIMARY_SKILL, //uses subtype to pick skill
|
||||
SIGHT_RADIOUS,
|
||||
MANA_REGENERATION, //points per turn apart from normal (1 + mysticism)
|
||||
//not handled yet:
|
||||
MAGIC_RESISTANCE, // %
|
||||
SECONDARY_SKILL_PREMY, //%
|
||||
SURRENDER_DISCOUNT, //%
|
||||
STACKS_SPEED,
|
||||
FLYING_MOVEMENT, SPELL_DURATION, AIR_SPELL_DMG_PREMY, EARTH_SPELL_DMG_PREMY, FIRE_SPELL_DMG_PREMY,
|
||||
WATER_SPELL_DMG_PREMY, BLOCK_SPELLS_ABOVE_LEVEL, WATER_WALKING, NO_SHOTING_PENALTY, DISPEL_IMMUNITY,
|
||||
NEGATE_ALL_NATURAL_IMMUNITIES, STACK_HEALTH, SPELL_IMMUNITY, BLOCK_MORALE, BLOCK_LUCK, FIRE_SPELLS,
|
||||
AIR_SPELLS, WATER_SPELLS, EARTH_SPELLS,
|
||||
GENERATE_RESOURCE, //daily value, uses subtype (resource type)
|
||||
CREATURE_GROWTH, //for legion artifacts: value - week growth bonus, subtype - monster level
|
||||
WHIRLPOOL_PROTECTION, //hero won't lose army when teleporting through whirlpool
|
||||
SPELL, //hero knows spell, val - skill level (0 - 3), subtype - spell id
|
||||
SPELLS_OF_LEVEL, //hero knows all spells of given level, val - skill level; subtype - level
|
||||
ENEMY_CANT_ESCAPE //for shackles of war
|
||||
};
|
||||
enum BonusDuration{PERMANENT, ONE_BATTLE, ONE_DAY, ONE_WEEK};
|
||||
enum BonusSource{ARTIFACT, OBJECT};
|
||||
|
||||
ui8 duration; //uses BonusDuration values
|
||||
ui8 type; //uses BonusType values - says to what is this bonus
|
||||
si32 subtype; //-1 if not applicable
|
||||
ui8 source;//uses BonusSource values - what gave that bonus
|
||||
si32 val;//for morale/luck [-3,+3], others any
|
||||
ui32 id; //id of object/artifact
|
||||
std::string description;
|
||||
|
||||
HeroBonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc)
|
||||
:duration(Dur), type(Type), source(Src), val(Val), id(ID), description(Desc)
|
||||
HeroBonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1)
|
||||
:duration(Dur), type(Type), source(Src), val(Val), id(ID), description(Desc), subtype(Subtype)
|
||||
{}
|
||||
HeroBonus(){};
|
||||
HeroBonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype=-1)
|
||||
:duration(Dur), type(Type), source(Src), val(Val), id(ID), subtype(Subtype)
|
||||
{}
|
||||
HeroBonus()
|
||||
{
|
||||
subtype = -1;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & duration & type & source & val & id & description;
|
||||
@ -36,4 +71,8 @@ struct DLL_EXPORT HeroBonus
|
||||
{
|
||||
return hb.duration==HeroBonus::ONE_BATTLE;
|
||||
}
|
||||
static bool IsFrom(const HeroBonus &hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
||||
{
|
||||
return hb.source==source && (id==0xffffff || hb.id==id);
|
||||
}
|
||||
};
|
||||
|
@ -404,6 +404,7 @@ struct SetHeroArtifacts : public CPackForClient //509
|
||||
SetHeroArtifacts(){type = 509;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
DLL_EXPORT void setArtAtPos(ui16 pos, int art);
|
||||
|
||||
si32 hid;
|
||||
std::vector<ui32> artifacts; //hero's artifacts from bag
|
||||
@ -413,6 +414,8 @@ struct SetHeroArtifacts : public CPackForClient //509
|
||||
{
|
||||
h & hid & artifacts & artifWorn;
|
||||
}
|
||||
|
||||
std::vector<HeroBonus*> gained, lost; //used locally as hlp when applying
|
||||
};
|
||||
|
||||
struct HeroRecruited : public CPackForClient //515
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "../hch/CGeneralTextHandler.h"
|
||||
#include "../hch/CDefObjInfoHandler.h"
|
||||
#include "../hch/CArtHandler.h"
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CObjectHandler.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
@ -272,10 +273,68 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
|
||||
DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(hid);
|
||||
std::vector<ui32> equiped, unequiped;
|
||||
for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
|
||||
if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
|
||||
unequiped.push_back(i->second);
|
||||
|
||||
for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
|
||||
if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
|
||||
equiped.push_back(i->second);
|
||||
|
||||
h->artifacts = artifacts;
|
||||
h->artifWorn = artifWorn;
|
||||
|
||||
BOOST_FOREACH(ui32 id, unequiped)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
std::list<HeroBonus>::iterator hlp = std::find_if(h->bonuses.begin(),h->bonuses.end(),boost::bind(HeroBonus::IsFrom,_1,HeroBonus::ARTIFACT,id));
|
||||
if(hlp != h->bonuses.end())
|
||||
{
|
||||
lost.push_back(&*hlp);
|
||||
h->bonuses.erase(hlp);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(ui32 id, equiped)
|
||||
{
|
||||
CArtifact &art = VLC->arth->artifacts[id];
|
||||
for(std::list<HeroBonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
|
||||
{
|
||||
gained.push_back(&*i);
|
||||
h->bonuses.push_back(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
|
||||
{
|
||||
if(art<0)
|
||||
{
|
||||
if(pos<19)
|
||||
artifWorn.erase(pos);
|
||||
else
|
||||
artifacts -= artifacts[pos-19];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pos<19)
|
||||
artifWorn[pos] = art;
|
||||
else
|
||||
if(pos-19 < artifacts.size())
|
||||
artifacts[pos-19] = art;
|
||||
else
|
||||
artifacts.push_back(art);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
|
||||
{
|
||||
CGHeroInstance *h = gs->hpool.heroesPool[hid];
|
||||
@ -320,8 +379,9 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
gs->day = day;
|
||||
BOOST_FOREACH(NewTurn::Hero h, heroes) //give mana/movement point
|
||||
{
|
||||
static_cast<CGHeroInstance*>(gs->map->objects[h.id])->movement = h.move;
|
||||
static_cast<CGHeroInstance*>(gs->map->objects[h.id])->mana = h.mana;
|
||||
CGHeroInstance *hero = gs->getHero(h.id);
|
||||
hero->movement = h.move;
|
||||
hero->mana = h.mana;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(SetResources h, res) //give resources
|
||||
@ -339,7 +399,7 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
|
||||
if(gs->getDate(1) == 7) //new week
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(HeroBonus::OneWeek);
|
||||
h->bonuses.remove_if(HeroBonus::OneWeek);
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
|
||||
|
@ -646,7 +646,12 @@ void CGameHandler::newTurn()
|
||||
NewTurn::Hero hth;
|
||||
hth.id = h->id;
|
||||
hth.move = h->maxMovePoints(true); //TODO: check if hero is really on the land
|
||||
hth.mana = std::max(h->mana,std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit())); //hero regains 1 mana point + mysticism lvel
|
||||
|
||||
if(h->visitedTown && vstd::contains(h->visitedTown->builtBuildings,0)) //if hero starts turn in town with mage guild
|
||||
hth.mana = h->manaLimit(); //restore all mana
|
||||
else
|
||||
hth.mana = std::max(si32(0), std::min(h->mana + h->manaRegain(), h->manaLimit()) );
|
||||
|
||||
n.heroes.insert(hth);
|
||||
|
||||
switch(h->getSecSkillLevel(13)) //handle estates - give gold
|
||||
@ -1018,7 +1023,7 @@ void CGameHandler::checkForBattleEnd( std::vector<CStack*> &stacks )
|
||||
hasStack[0] = hasStack[1] = false;
|
||||
for(int b = 0; b<stacks.size(); ++b)
|
||||
{
|
||||
if(stacks[b]->alive())
|
||||
if(stacks[b]->alive() && !vstd::contains(stacks[b]->abilities,SIEGE_WEAPON))
|
||||
{
|
||||
hasStack[1-stacks[b]->attackerOwned] = true;
|
||||
}
|
||||
@ -1242,28 +1247,31 @@ void CGameHandler::stopHeroVisitCastle(int obj, int heroID)
|
||||
void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack
|
||||
{
|
||||
const CGHeroInstance* h = getHero(hid);
|
||||
const CArtifact &art = VLC->arth->artifacts[artid];
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = hid;
|
||||
sha.artifacts = h->artifacts;
|
||||
sha.artifWorn = h->artifWorn;
|
||||
|
||||
if(position<0)
|
||||
{
|
||||
if(position == -2)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<VLC->arth->artifacts[artid].possibleSlots.size(); i++) //try to put artifact into first avaialble slot
|
||||
for(i=0; i<art.possibleSlots.size(); i++) //try to put artifact into first available slot
|
||||
{
|
||||
if( !vstd::contains(sha.artifWorn,VLC->arth->artifacts[artid].possibleSlots[i]) )
|
||||
if( !vstd::contains(sha.artifWorn,art.possibleSlots[i]) )
|
||||
{
|
||||
sha.artifWorn[VLC->arth->artifacts[artid].possibleSlots[i]] = artid;
|
||||
//we've found a free suitable slot
|
||||
sha.artifWorn[art.possibleSlots[i]] = artid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i==VLC->arth->artifacts[artid].possibleSlots.size()) //if haven't find proper slot, use backpack
|
||||
if(i == art.possibleSlots.size()) //if haven't find proper slot, use backpack
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
else //should be -1 => putartifact into backpack
|
||||
else //should be -1 => put artifact into backpack
|
||||
{
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
@ -1271,10 +1279,15 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
else
|
||||
{
|
||||
if(!vstd::contains(sha.artifWorn,ui16(position)))
|
||||
{
|
||||
sha.artifWorn[position] = artid;
|
||||
}
|
||||
else
|
||||
{
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
|
||||
@ -1763,20 +1776,32 @@ void CGameHandler::swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 )
|
||||
CGHeroInstance *h1 = gs->getHero(hid1), *h2 = gs->getHero(hid2);
|
||||
if((distance(h1->pos,h2->pos) > 1.0) || (h1->tempOwner != h2->tempOwner))
|
||||
return;
|
||||
int a1=h1->getArtAtPos(slot1), a2=h2->getArtAtPos(slot2);
|
||||
const CArtifact *a1 = h1->getArt(slot1),
|
||||
*a2=h2->getArt(slot2);
|
||||
|
||||
if(a1 && slot2<19 && !vstd::contains(a1->possibleSlots,slot2)
|
||||
|| a2 && slot1<19 && !vstd::contains(a2->possibleSlots,slot1)
|
||||
)
|
||||
{
|
||||
//artifact doesn't fit dst slot
|
||||
complain("Cannot swap artifacts!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
h2->setArtAtPos(slot2,a1);
|
||||
h1->setArtAtPos(slot1,a2);
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = hid1;
|
||||
sha.artifacts = h1->artifacts;
|
||||
sha.artifWorn = h1->artifWorn;
|
||||
sha.setArtAtPos(slot1,h2->getArtAtPos(slot2));
|
||||
if(h1 == h2) sha.setArtAtPos(slot2,h1->getArtAtPos(slot1));
|
||||
sendAndApply(&sha);
|
||||
if(hid1 != hid2)
|
||||
{
|
||||
sha.hid = hid2;
|
||||
sha.artifacts = h2->artifacts;
|
||||
sha.artifWorn = h2->artifWorn;
|
||||
sha.setArtAtPos(slot2,h1->getArtAtPos(slot1));
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
}
|
||||
@ -1787,21 +1812,14 @@ void CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
CGTownInstance *town = hero->visitedTown;
|
||||
if(aid==0) //spellbook
|
||||
{
|
||||
if(!vstd::contains(town->builtBuildings,si32(0)))
|
||||
if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")
|
||||
|| getResource(hero->getOwner(),6)<500 && complain("Cannot buy a spellbook, not enough gold!")
|
||||
|| hero->getArt(17) && complain("Cannot buy a spellbook, hero already has a one!")
|
||||
)
|
||||
return;
|
||||
SetResource sr;
|
||||
sr.player = hero->tempOwner;
|
||||
sr.resid = 6;
|
||||
sr.val = gs->getPlayer(hero->getOwner())->resources[6] - 500;
|
||||
sendAndApply(&sr);
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = hid;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
sha.artifWorn[17] = 0;
|
||||
sendAndApply(&sha);
|
||||
|
||||
giveResource(hero->getOwner(),6,-500);
|
||||
giveHeroArtifact(0,hid,17);
|
||||
giveSpells(town,hero);
|
||||
}
|
||||
else if(aid < 7 && aid > 3) //war machine
|
||||
@ -1814,18 +1832,9 @@ void CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetResource sr;
|
||||
sr.player = hero->tempOwner;
|
||||
sr.resid = 6;
|
||||
sr.val = gs->getPlayer(hero->getOwner())->resources[6] - price;
|
||||
sendAndApply(&sr);
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = hid;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
sha.artifWorn[9+aid] = aid;
|
||||
sendAndApply(&sha);
|
||||
giveResource(hero->getOwner(),6,-price);
|
||||
giveHeroArtifact(aid,hid,9+aid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,8 @@ public:
|
||||
void heroVisitCastle(int obj, int heroID);
|
||||
void stopHeroVisitCastle(int obj, int heroID);
|
||||
void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
|
||||
void moveArtifact(int hid, int oldPosition, int destPos);
|
||||
void removeArtifact(int hid, int pos);
|
||||
void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
|
||||
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
|
||||
void setAmount(int objid, ui32 val);
|
||||
|
Loading…
Reference in New Issue
Block a user