1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-15 01:24:45 +02:00

Better implementation of creature window, minor fixes.

Check forum for new graphics.
This commit is contained in:
DjWarmonger
2011-03-06 12:12:22 +00:00
parent 7dbf105f6e
commit b9f301b600
11 changed files with 358 additions and 304 deletions

View File

@ -1,19 +1,15 @@
 
Microsoft Visual Studio Solution File, Format Version 10.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2008 # Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_client", "client\VCMI_client.vcproj", "{8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_client", "client\VCMI_client.vcxproj", "{8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}"
ProjectSection(ProjectDependencies) = postProject
{B952FFC5-3039-4DE1-9F08-90ACDA483D8F} = {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_lib", "lib\VCMI_lib.vcproj", "{B952FFC5-3039-4DE1-9F08-90ACDA483D8F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_lib", "lib\VCMI_lib.vcxproj", "{B952FFC5-3039-4DE1-9F08-90ACDA483D8F}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_server", "server\VCMI_server.vcproj", "{8AF697C3-465E-4910-B31B-576A9ECDB309}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_server", "server\VCMI_server.vcxproj", "{8AF697C3-465E-4910-B31B-576A9ECDB309}"
ProjectSection(ProjectDependencies) = postProject
{B952FFC5-3039-4DE1-9F08-90ACDA483D8F} = {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genius", "AI\GeniusAI\genius.vcproj", "{B6A14ED9-E7C1-411B-A596-2FE90B3145B4}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genius", "AI\GeniusAI\genius.vcxproj", "{B6A14ED9-E7C1-411B-A596-2FE90B3145B4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StupidAI", "AI\StupidAI\StupidAI.vcxproj", "{15DABC90-234A-4B6B-9EEB-777C4768B82B}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{B952FFC5-3039-4DE1-9F08-90ACDA483D8F} = {B952FFC5-3039-4DE1-9F08-90ACDA483D8F} {B952FFC5-3039-4DE1-9F08-90ACDA483D8F} = {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}
EndProjectSection EndProjectSection
@ -49,6 +45,12 @@ Global
{B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.RD|Win32.Build.0 = RD|Win32 {B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.RD|Win32.Build.0 = RD|Win32
{B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.Release|Win32.ActiveCfg = Release|Win32 {B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.Release|Win32.ActiveCfg = Release|Win32
{B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.Release|Win32.Build.0 = Release|Win32 {B6A14ED9-E7C1-411B-A596-2FE90B3145B4}.Release|Win32.Build.0 = Release|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.Debug|Win32.ActiveCfg = Debug|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.Debug|Win32.Build.0 = Debug|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.RD|Win32.ActiveCfg = RD|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.RD|Win32.Build.0 = RD|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.Release|Win32.ActiveCfg = Release|Win32
{15DABC90-234A-4B6B-9EEB-777C4768B82B}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -12,7 +12,7 @@
#include "Graphics.h" #include "Graphics.h"
#include "AdventureMapButton.h" #include "AdventureMapButton.h"
#include "CPlayerInterface.h" #include "CPlayerInterface.h"
#include "CMessage.h" #include "CConfigHandler.h"
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/assign/std/vector.hpp> #include <boost/assign/std/vector.hpp>
@ -50,37 +50,75 @@ CCreatureWindow::CCreatureWindow (const CStackInstance &stack, int Type)
init(&stack, &stack, dynamic_cast<const CGHeroInstance*>(stack.armyObj)); init(&stack, &stack, dynamic_cast<const CGHeroInstance*>(stack.armyObj));
} }
CCreatureWindow::CCreatureWindow(int Cid, int Type, int creatureCount)
:type(Type)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
CStackInstance * stack = new CStackInstance(Type,creatureCount); //TODO: simplify?
init(stack, CGI->creh->creatures[Cid], NULL);
delete stack;
}
void CCreatureWindow::init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner) void CCreatureWindow::init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner)
{ {
c = stack->type; c = stack->type;
if(!stackNode) stackNode = c; if(!stackNode) stackNode = c;
//Basic graphics //Basic graphics - need to calculate size
std::pair<int,int> winSize;
winSize.first = 560 + 30;
winSize.second = 448 + 60;
bitmap = new CPicture(CMessage::drawBox1 (winSize.first, winSize.second, LOCPLINT->playerID), winSize.first, winSize.second, true); CBonusSystemNode node = CBonusSystemNode() ;
//bitmap = new CPicture("CreWin3.pcx"); node.bonuses = stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT));
//graphics->blueToPlayersAdv(bitmap->bg, LOCPLINT->playerID); BonusList bl;
//bitmap->colorizeAndConvert(LOCPLINT->playerID);
while (node.bonuses.size())
{
Bonus * b = node.bonuses.front();
bl.push_back (new Bonus(*b));
bl.back()->val = node.valOfBonuses(Selector::typeSybtype(b->type, b->subtype)); //merge multiple bonuses into one
node.bonuses.remove_if (Selector::typeSybtype(b->type, b->subtype)); //remove used bonuses
}
std::vector<std::pair<std::string, std::string>> descriptions; //quick, yet slow solution
std::string text, text2;
BOOST_FOREACH(Bonus* b, bl)
{
text = stack->bonusToString(b, false);
if (text.size())
{
text2 = stack->bonusToString(b, true);
descriptions.push_back(std::pair<std::string,std::string>(text, text2));
}
}
int bonusRows = std::min ((int)((descriptions.size() + 1) / 2), (conf.cc.resy - 230) / 60);
amin(bonusRows, 4);
amax(bonusRows, 1);
//TODO: Scroll them
bitmap = new CPicture("CreWin" + boost::lexical_cast<std::string>(bonusRows) + ".pcx"); //1 to 4 rows for now
bitmap->colorizeAndConvert(LOCPLINT->playerID);
pos = bitmap->center(); pos = bitmap->center();
//Buttons //Buttons
ok = new AdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CCreatureWindow::close,this), 489, 148, "IOKAY32.DEF", SDLK_RETURN); ok = new AdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CCreatureWindow::close,this), 489, 148, "hsbtns.def", SDLK_RETURN);
if (type <= BATTLE) //in battle or info window if (type <= BATTLE) //in battle or info window
{ {
upgrade = NULL; upgrade = NULL;
dismiss = NULL; dismiss = NULL;
} }
anim = new CCreaturePic(20, 46, c); anim = new CCreaturePic(22, 48, c);
count = boost::lexical_cast<std::string>(stack->count);
if (count.size()) //TODO
printTo(count, 117, 174, FONT_SMALL, tytulowy,*bitmap);
printAtMiddle(c->namePl, 180, 30, FONT_SMALL, tytulowy,*bitmap); //creature name printAtMiddle(c->namePl, 180, 30, FONT_SMALL, tytulowy,*bitmap); //creature name
//Stats //Stats
morale = new MoraleLuckBox(true, genRect(42, 42, 333, 98)); morale = new MoraleLuckBox(true, genRect(42, 42, 335, 100));
morale->set(stack); morale->set(stack);
luck = new MoraleLuckBox(false, genRect(42, 42, 385, 98)); luck = new MoraleLuckBox(false, genRect(42, 42, 387, 100));
luck->set(stack); luck->set(stack);
printLine(0, CGI->generaltexth->primarySkillNames[0], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK)); printLine(0, CGI->generaltexth->primarySkillNames[0], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK));
@ -101,8 +139,8 @@ void CCreatureWindow::init(const CStackInstance *stack, const CBonusSystemNode *
{ {
if (STACK_EXP) if (STACK_EXP)
{ {
printAtMiddle("Rank " + boost::lexical_cast<std::string>(stack->getExpRank()), 425, 60, FONT_MEDIUM, tytulowy,*bitmap); printAtMiddle("Rank " + boost::lexical_cast<std::string>(stack->getExpRank()), 436, 62, FONT_MEDIUM, tytulowy,*bitmap);
printAtMiddle(boost::lexical_cast<std::string>(stack->experience), 425, 80, FONT_SMALL, zwykly,*bitmap); printAtMiddle(boost::lexical_cast<std::string>(stack->experience), 436, 82, FONT_SMALL, zwykly,*bitmap);
} }
if (STACK_ARTIFACT && type > BATTLE) if (STACK_ARTIFACT && type > BATTLE)
@ -125,7 +163,7 @@ void CCreatureWindow::init(const CStackInstance *stack, const CBonusSystemNode *
std::vector<si32> spells = battleStack->activeSpells(); std::vector<si32> spells = battleStack->activeSpells();
BOOST_FOREACH(si32 effect, spells) BOOST_FOREACH(si32 effect, spells)
{ {
blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 21 + 52 * printed, 186, *bitmap); blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 20 + 52 * printed, 184, *bitmap);
if (++printed >= 10) //we can fit only 10 effects if (++printed >= 10) //we can fit only 10 effects
break; break;
} }
@ -135,31 +173,21 @@ void CCreatureWindow::init(const CStackInstance *stack, const CBonusSystemNode *
//All bonuses - abilities //All bonuses - abilities
BonusList bl = stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT));
//BonusList bl = stackNode->getBonuses(Selector::sourceTypeSel(Bonus::CREATURE_ABILITY));
int bonusRows = bl.size() / 3;
int bonusHeight = bonusRows * 60;
//TODO: Scroll them
std::string text;
int i = 0, j = 0; int i = 0, j = 0;
typedef std::pair<std::string, std::string> stringpair; //jeez
BOOST_FOREACH(Bonus* b, bl) BOOST_FOREACH(stringpair p, descriptions)
{ {
int offsetx = 60*i; int offsetx = 257*j;
int offsety = 170*j; int offsety = 60*i;
text = stack->bonusToString(b, false); printAt(p.first, 84 + offsetx, 238 + offsety, FONT_SMALL, tytulowy, *bitmap);
if (text.size()) printAt(p.second, 84 + offsetx, 258 + offsety, FONT_SMALL, zwykly, *bitmap);
{
printAt(text, 80 + offsety, 242 + offsetx, FONT_SMALL, tytulowy, *bitmap); if (++j > 1) //next line
//graphics (21 + offsetx, 233 + offsetty)
if (++j > 2) //next line
{ {
++i; ++i;
j = 0; j = 0;
} }
}
//text = stack->bonusToString(*it, true); //text = stack->bonusToString(*it, true);
//if (text.size()) //if (text.size())
// printAt(text, 80 + offsety, 262 + offsetx, FONT_SMALL, zwykly, *bitmap); // printAt(text, 80 + offsety, 262 + offsetx, FONT_SMALL, zwykly, *bitmap);
@ -214,13 +242,12 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::func
cfl = boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[12],std::vector<SComponent*>(),fs[0],fs[1],false); cfl = boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[12],std::vector<SComponent*>(),fs[0],fs[1],false);
dismiss = new AdventureMapButton("",CGI->generaltexth->zelp[445].second,cfl,333, 148,"IVIEWCR2.DEF",SDLK_d); dismiss = new AdventureMapButton("",CGI->generaltexth->zelp[445].second,cfl,333, 148,"IVIEWCR2.DEF",SDLK_d);
} }
ok = new AdventureMapButton("",CGI->generaltexth->zelp[445].second,boost::bind(&CCreatureWindow::close,this),489, 148,"IOKAY.DEF",SDLK_RETURN); //TODO: Remove duplicate
} }
} }
void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/) void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/)
{ {
printAt(text, 155, 48 + nr*19, FONT_SMALL, zwykly, *bitmap); printAt(text, 162, 48 + nr*19, FONT_SMALL, zwykly, *bitmap);
std::string hlp; std::string hlp;
if(range && baseVal != val) if(range && baseVal != val)
@ -233,11 +260,32 @@ void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, in
printTo(hlp, 325, 64 + nr*19, FONT_SMALL, zwykly, *bitmap); printTo(hlp, 325, 64 + nr*19, FONT_SMALL, zwykly, *bitmap);
} }
//void CCreatureWindow::activate()
//{
// CIntObject::activate();
// if(type < 3)
// activateRClick();
//}
void CCreatureWindow::scrollArt(int dir) void CCreatureWindow::scrollArt(int dir)
{ {
} }
void CCreatureWindow::clickRight(tribool down, bool previousState)
{
if(down)
return;
if (type < 3)
close();
}
void CCreatureWindow::close() void CCreatureWindow::close()
{ {
GH.popIntTotally(this); GH.popIntTotally(this);
} }
CCreatureWindow::~CCreatureWindow()
{
for(int i=0; i<upgResCost.size();i++)
delete upgResCost[i];
}

View File

@ -22,7 +22,7 @@ class AdventureMapButton;
class CCreatureWindow : public CIntObject class CCreatureWindow : public CIntObject
{ {
public: public:
enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3}; enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3}; //only last one should open permanently
//bool active; //TODO: comment me //bool active; //TODO: comment me
int type;//0 - rclick popup; 1 - normal window int type;//0 - rclick popup; 1 - normal window
CPicture *bitmap; //background CPicture *bitmap; //background
@ -40,24 +40,20 @@ public:
CSlider * slider; //Abilities CSlider * slider; //Abilities
AdventureMapButton *dismiss, *upgrade, *ok; AdventureMapButton *dismiss, *upgrade, *ok;
AdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection - do we need it? AdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection
//TODO: Arifact drop //TODO: Arifact drop
//CCreatureWindow(const CStackInstance &st, boost::function<void()> Upg = 0, boost::function<void()> Dsm = 0, UpgradeInfo *ui = NULL); //c-tor
CCreatureWindow(const CStack & stack, int type); //battle c-tor CCreatureWindow(const CStack & stack, int type); //battle c-tor
CCreatureWindow (const CStackInstance &stack, int Type); //pop-up c-tor CCreatureWindow (const CStackInstance &stack, int Type); //pop-up c-tor
CCreatureWindow(const CStackInstance &st, int Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui); //full garrison window CCreatureWindow(const CStackInstance &st, int Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui); //full garrison window
//CCreatureWindow(int Cid, int Type, int creatureCount); //c-tor CCreatureWindow(int Cid, int Type, int creatureCount); //c-tor
void init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner); void init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner);
void printLine(int nr, const std::string &text, int baseVal, int val=-1, bool range=false); void printLine(int nr, const std::string &text, int baseVal, int val=-1, bool range=false);
//~CCreatureWindow(); //d-tor ~CCreatureWindow(); //d-tor
//void activate(); //void activate();
void close(); void close();
//void clickRight(tribool down, bool previousState); //call-in void clickRight(tribool down, bool previousState); //call-in
//void dismissF();
//void keyPressed (const SDL_KeyboardEvent & key); //call-in //void keyPressed (const SDL_KeyboardEvent & key); //call-in
//void deactivate();
//void show(SDL_Surface * to);
void scrollArt(int dir); void scrollArt(int dir);
}; };

View File

@ -2,6 +2,7 @@
#include "AdventureMapButton.h" #include "AdventureMapButton.h"
#include "CAdvmapInterface.h" #include "CAdvmapInterface.h"
#include "CPlayerInterface.h" #include "CPlayerInterface.h"
#include "CCreatureWindow.h"
#include "../CCallback.h" #include "../CCallback.h"
#include "../global.h" #include "../global.h"
#include "CConfigHandler.h" #include "CConfigHandler.h"
@ -1062,7 +1063,7 @@ void CKingdomInterface::CTownItem::CCreaPlace::clickRight(tribool down, bool pre
crid = town->town->upgradedCreatures[type]; crid = town->town->upgradedCreatures[type];
else else
crid = town->town->basicCreatures[type]; crid = town->town->basicCreatures[type];
GH.pushInt(new CCreInfoWindow(crid, 0, town->creatures[type].first)); GH.pushInt(new CCreatureWindow(crid, 0, town->creatures[type].first));
} }
} }

View File

@ -172,7 +172,7 @@ void CGarrisonSlot::clickRight(tribool down, bool previousState)
if(down && creature) if(down && creature)
{ {
//GH.pushInt(new CCreInfoWindow(*myStack)); //GH.pushInt(new CCreInfoWindow(*myStack));
GH.pushInt(new CCreatureWindow(*myStack, 4)); GH.pushInt(new CCreatureWindow(*myStack, 2));
} }
} }
void CGarrisonSlot::clickLeft(tribool down, bool previousState) void CGarrisonSlot::clickLeft(tribool down, bool previousState)
@ -194,7 +194,7 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
if (canDismiss) dism = boost::bind(&CCallback::dismissCreature, LOCPLINT->cb, getObj(), ID); if (canDismiss) dism = boost::bind(&CCallback::dismissCreature, LOCPLINT->cb, getObj(), ID);
//CCreInfoWindow *creWindow = new CCreInfoWindow( *myStack, 1, upgr, dism, &pom); //CCreInfoWindow *creWindow = new CCreInfoWindow( *myStack, 1, upgr, dism, &pom);
CCreatureWindow *creWindow = new CCreatureWindow( *myStack, 2, upgr, dism, &pom); CCreatureWindow *creWindow = new CCreatureWindow( *myStack, 3, upgr, dism, &pom);
GH.pushInt(creWindow); GH.pushInt(creWindow);
@ -1752,7 +1752,7 @@ void CRecruitmentWindow::clickRight(tribool down, bool previousState)
Rect creatureRect = genRect(132, sCREATURE_WIDTH, pos.x+curx, pos.y+64); Rect creatureRect = genRect(132, sCREATURE_WIDTH, pos.x+curx, pos.y+64);
if(isItIn(&creatureRect, GH.current->motion.x, GH.current->motion.y)) if(isItIn(&creatureRect, GH.current->motion.x, GH.current->motion.y))
{ {
CCreInfoWindow *popup = new CCreInfoWindow(creatures[i].ID, 0, 0); CCreatureWindow *popup = new CCreatureWindow(creatures[i].ID, 0, 0);
GH.pushInt(popup); GH.pushInt(popup);
break; break;
} }

View File

@ -1,41 +1,43 @@
Bonus Name (24 characters?) Description Bonus Name (30 characters?) Description (30)
FLYING Fly Can Fly (ignores obstacles)
UNLIMITED_RETALIATIONS Unlimited retaliations May retaliate any number of attacks
SHOOTER Ranged Creature can make a Ranged Attack
FREE_SHOOTING Shoot Close Can make a Ranged Attack in Close Combat
NO_SHOTING_PENALTY ? ??? NO_SHOTING_PENALTY ? ???
NO_MELEE_PENALTY No melee penalty Creature has no Melee Penalty
NO_DISTANCE_PENALTY No distance penalty Does full ranged damage from any distance
NO_OBSTACLES_PENALTY No obstacle penalty Creature has no Obstacle Penalty
JOUSTING Champion Champion Distance Bonus (+5% damage per square travelled)
RETURN_AFTER_STRIKE Attack and Return Returns to starting position after making a melee attack
BLOCKS_RETALIATION No retaliation Enemy cannot Retaliate
TWO_HEX_ATTACK_BREATH Breath Creature has a Breath Attack (2-hex range)
THREE_HEADED_ATTACK Three-headed attack Creature attacks three adjacent units
ATTACKS_ALL_ADJACENT Attack all around Creature attacks all adjacent enemies
FULL_HP_REGENERATION Regeneration May Regenerate full Health
LIFE_DRAIN Drain life Drains life equal to damage dealt
SELF_MORALE Positive morale Always has Positive Morale
SELF_LUCK Positive luck Always has Positive Luck
FEAR Fear Has a chance to cause Fear on an enemy stack
FEARLESS Fearless Immune to Fear ability
CHARGE_IMMUNITY Immune to Charge Immune to Champion charge bonus
HEALER Healer Heals allied units
CATAPULT Catapult Attacks siege walls
DRAGON_NATURE Dragon Creature has a Dragon Nature
NON_LIVING Non living Creature is immune to effects affecting Living units
UNDEAD Undead Creature is Undead
HATE Hates %s Does %d% more damage to %s
DOUBLE_DAMAGE_CHANCE Death Blow Has %d% chance to deal double damage
MAGIC_RESISTANCE Magic Resistance Has %d% chance to resist enemy spell
SPELL_DAMAGE_REDUCTION Spell Resistance Damage from spells reduced 50%.
LEVEL_SPELL_IMMUNITY Spell immunity 1-%d Immune to spells levels 1-%d
HP_REGENERATION Regeneration Heals %d hit points every round
SPELL_IMMUNITY Immune to %s Immune to %s spell
ENEMY_DEFENCE_REDUCTION Reduces Enemy Defense Reduces Enemy Defense by %d% for this attack
MAGIC_MIRROR Magic Mirror Has %d% chance to redirect offensive spell back to enemy
ADDITIONAL_RETALIATION Additional retaliations May Retaliate %d extra times ADDITIONAL_RETALIATION Additional retaliations May Retaliate %d extra times
CHANGES_SPELL_COST_FOR_ALLY Reduce Casting Cost Reduce Casting Cost of allied hero spells by %d ATTACKS_ALL_ADJACENT Attack all around Attacks all adjacent enemies
CHANGES_SPELL_COST_FOR_ENEMY Magic Damper Increase Casting Cost of enemy hero spells by %d RETURN_AFTER_STRIKE Attack and Return Returns after melee attack
MANA_CHANNELING Magic Channel %d% mana spent by enemy is transfered to your hero SPELL_RESISTANCE_AURA Aura of Resistance Nearby stacks get %d% resistance
SPELL_AFTER_ATTACK Caster - %s %d% chance to cast %s after attack TWO_HEX_ATTACK_BREATH Breath Breath Attack (2-hex range)
SPELL_AFTER_ATTACK Caster - %s %d% chance to cast after attack
CATAPULT Catapult Attacks siege walls
JOUSTING Champion Charge +5% damage per hex travelled
DOUBLE_DAMAGE_CHANCE Death Blow %d% chance for double damage
ADDITIONAL_ATTACK Double Strike Attacks twice
DRAGON_NATURE Dragon Creature has a Dragon Nature
LIFE_DRAIN Drain life Drains life equal to damage dealt
FEAR Fear Causes Fear on an enemy stack
FEARLESS Fearless Immune to Fear ability
FLYING Fly Can Fly (ignores obstacles)
HATE Hates %s Does %d% more damage
HEALER Healer Heals allied units
SPELL_IMMUNITY Immune to %s
CHARGE_IMMUNITY Immune to Charge Immune to Champion charge
MANA_CHANNELING Magic Channel %d% Gives mana spent by enemy
CHANGES_SPELL_COST_FOR_ENEMY Magic Damper (%d) Increase Cost of enemy spells
MAGIC_MIRROR Magic Mirror (%d%) Redirects offensive spell to enemy
MAGIC_RESISTANCE Magic Resistance %d% chance to resist enemy spell
NO_DISTANCE_PENALTY No distance penalty Full damage from any distance
NO_MELEE_PENALTY No melee penalty Creature has no Melee Penalty
NO_OBSTACLES_PENALTY No obstacle penalty Creature has no Obstacle Penalty
BLOCKS_RETALIATION No retaliation Enemy cannot Retaliate
NON_LIVING Non living Immunity to many effects
SELF_LUCK Positive luck Always has Positive Luck
SELF_MORALE Positive morale Always has Positive Morale
SHOOTER Ranged Creature can shoot
CHANGES_SPELL_COST_FOR_ALLY Reduce Casting Cost (%d) Reduce Casting Cost for hero
ENEMY_DEFENCE_REDUCTION Reduce Enemy Defense (%d%) Reduces Defense for one attack
FULL_HP_REGENERATION Regeneration May Regenerate full Health
HP_REGENERATION Regeneration Heals %d hit points every round
FREE_SHOOTING Shoot Close Can shoot in Close Combat
LEVEL_SPELL_IMMUNITY Spell immunity 1-%d Immune to spells levels 1-%d
SPELL_DAMAGE_REDUCTION Spell Resistance Damage from spells reduced 50%.
THREE_HEADED_ATTACK Three-headed attack Attacks three adjacent units
UNDEAD Undead Creature is Undead
UNLIMITED_RETALIATIONS Unlimited retaliations Retaliate any number of attacks

View File

@ -22,7 +22,7 @@
+ 24 SPELL_AFTER_ATTACK 0 62 20 //unicorns cast blind with 20% probability + 24 SPELL_AFTER_ATTACK 0 62 20 //unicorns cast blind with 20% probability
+ 24 SPELL_RESISTANCE_AURA 0 55 0 //unicorn + 24 SPELL_RESISTANCE_AURA 0 55 0 //unicorn
+ 25 SPELL_AFTER_ATTACK 0 62 20 //war unicorns cast blind with 20% probability + 25 SPELL_AFTER_ATTACK 0 62 20 //war unicorns cast blind with 20% probability
+ 25 SPELL_RESISTANCE_AURA 0 55 0 //war unicorn + 25 SPELL_RESISTANCE_AURA 20 55 0 //war unicorn
+ 26 LEVEL_SPELL_IMMUNITY 3 0 0 //green dragon's spell immunity + 26 LEVEL_SPELL_IMMUNITY 3 0 0 //green dragon's spell immunity
+ 26 TWO_HEX_ATTACK_BREATH 0 0 0 //green dragon's breath + 26 TWO_HEX_ATTACK_BREATH 0 0 0 //green dragon's breath
+ 26 DRAGON_NATURE 0 0 0 //green dragon is a dragon + 26 DRAGON_NATURE 0 0 0 //green dragon is a dragon
@ -114,7 +114,7 @@
+ 103 SPELL_AFTER_ATTACK 0 79 10 //mighty gorgons + 103 SPELL_AFTER_ATTACK 0 79 10 //mighty gorgons
+ 104 SPELL_AFTER_ATTACK 0 78 100 //serpent fly + 104 SPELL_AFTER_ATTACK 0 78 100 //serpent fly
+ 105 SPELL_AFTER_ATTACK 0 45 100 //mighty gorgons + 105 SPELL_AFTER_ATTACK 0 45 100 //mighty gorgons
+ 105 SPELL_AFTER_ATTACK 0 78 100 //dragon fly + 105 SPELL_AFTER_ATTACK 0 78 10'file:///F:/Programowanie/VCMI/config/bonusnames.txt'#Arkusz1.C110 //dragon fly
+ 106 SPELL_AFTER_ATTACK 0 70 20 //basilisks + 106 SPELL_AFTER_ATTACK 0 70 20 //basilisks
+ 107 SPELL_AFTER_ATTACK 0 70 20 //greater basilisks + 107 SPELL_AFTER_ATTACK 0 70 20 //greater basilisks
+ 109 SPELL_AFTER_ATTACK 0 71 20 //Wyvern Monarch + 109 SPELL_AFTER_ATTACK 0 71 20 //Wyvern Monarch

View File

@ -194,3 +194,4 @@
193 -1 193 -1
194 -1 194 -1
195 -1 195 -1
196 -1

View File

@ -653,7 +653,7 @@ void CArtHandler::addBonuses()
giveArtBonus(101,Bonus::SPELL_IMMUNITY,0,62);//Pendant of Second Sight giveArtBonus(101,Bonus::SPELL_IMMUNITY,0,62);//Pendant of Second Sight
giveArtBonus(102,Bonus::SPELL_IMMUNITY,0,42);//Pendant of Holiness giveArtBonus(102,Bonus::SPELL_IMMUNITY,0,42);//Pendant of Holiness
giveArtBonus(103,Bonus::SPELL_IMMUNITY,0,24);//Pendant of Life giveArtBonus(103,Bonus::SPELL_IMMUNITY,0,24);//Pendant of Life
giveArtBonus(104,Bonus::SPELL_IMMUNITY,0,25);//Pendant of Death giveArtBonus(104,Bonus::SPELL_IMMUNITY,0,25, 1, new HasAnotherBonusLimiter(Bonus::UNDEAD));//Pendant of Death does not display info for living stacks
giveArtBonus(105,Bonus::SPELL_IMMUNITY,0,60);//Pendant of Free Will giveArtBonus(105,Bonus::SPELL_IMMUNITY,0,60);//Pendant of Free Will
giveArtBonus(106,Bonus::SPELL_IMMUNITY,0,17);//Pendant of Negativity giveArtBonus(106,Bonus::SPELL_IMMUNITY,0,17);//Pendant of Negativity
giveArtBonus(107,Bonus::SPELL_IMMUNITY,0,61);//Pendant of Total Recall giveArtBonus(107,Bonus::SPELL_IMMUNITY,0,61);//Pendant of Total Recall

View File

@ -416,7 +416,8 @@ void CCreatureHandler::loadCreatures()
reader >> buf; nsf->additionalInfo = buf; reader >> buf; nsf->additionalInfo = buf;
nsf->source = Bonus::CREATURE_ABILITY; nsf->source = Bonus::CREATURE_ABILITY;
nsf->sid = cre->idNumber; nsf->sid = cre->idNumber;
nsf->duration = Bonus::ONE_BATTLE; //nsf->duration = Bonus::ONE_BATTLE; //what the?
nsf->duration = Bonus::PERMANENT;
nsf->turnsRemain = 0; nsf->turnsRemain = 0;
cre->addNewBonus(nsf); cre->addNewBonus(nsf);
@ -991,6 +992,8 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
for (int i = 1; i < 11; ++i) for (int i = 1; i < 11; ++i)
{ {
loadToIt (curVal, src, it, 4); loadToIt (curVal, src, it, 4);
if (b.type == Bonus::HATE)
curVal *= 10; //odd fix
if (curVal > lastVal) //threshold, add new bonus if (curVal > lastVal) //threshold, add new bonus
{ {
b.val = curVal - lastVal; b.val = curVal - lastVal;

View File

@ -519,6 +519,7 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
case Bonus::TWO_HEX_ATTACK_BREATH: case Bonus::TWO_HEX_ATTACK_BREATH:
case Bonus::THREE_HEADED_ATTACK: case Bonus::THREE_HEADED_ATTACK:
case Bonus::ATTACKS_ALL_ADJACENT: case Bonus::ATTACKS_ALL_ADJACENT:
case Bonus::ADDITIONAL_ATTACK: //TODO: what with more than one attack? Axe of Ferocity for example
case Bonus::FULL_HP_REGENERATION: case Bonus::FULL_HP_REGENERATION:
case Bonus::LIFE_DRAIN: //TODO: chance, hp percentage? case Bonus::LIFE_DRAIN: //TODO: chance, hp percentage?
case Bonus::SELF_MORALE: case Bonus::SELF_MORALE:
@ -533,33 +534,27 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
case Bonus::UNDEAD: case Bonus::UNDEAD:
break; break;
//One numeric value //One numeric value
//case Bonus::STACKS_SPEED: //Do we need description for creature stats?
//case Bonus::STACK_HEALTH:
case Bonus::MAGIC_RESISTANCE: case Bonus::MAGIC_RESISTANCE:
case Bonus::SPELL_RESISTANCE_AURA:
case Bonus::SPELL_DAMAGE_REDUCTION: case Bonus::SPELL_DAMAGE_REDUCTION:
case Bonus::LEVEL_SPELL_IMMUNITY: case Bonus::LEVEL_SPELL_IMMUNITY:
case Bonus::CHANGES_SPELL_COST_FOR_ALLY:
case Bonus::CHANGES_SPELL_COST_FOR_ENEMY:
case Bonus::MANA_CHANNELING:
case Bonus::MANA_DRAIN: case Bonus::MANA_DRAIN:
case Bonus::HP_REGENERATION: case Bonus::HP_REGENERATION:
case Bonus::ADDITIONAL_RETALIATION: case Bonus::ADDITIONAL_RETALIATION:
case Bonus::DOUBLE_DAMAGE_CHANCE: case Bonus::DOUBLE_DAMAGE_CHANCE:
case Bonus::ENEMY_DEFENCE_REDUCTION:
case Bonus::MAGIC_MIRROR:
case Bonus::DARKNESS: //Darkness Dragons any1? case Bonus::DARKNESS: //Darkness Dragons any1?
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val)); boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSybtype(bonus->type, bonus->subtype))));
break; break;
//Complex descriptions //Complex descriptions
case Bonus::HATE: case Bonus::HATE:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val)); boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSybtype(bonus->type, bonus->subtype))));
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl); boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
break; break;
case Bonus::SPELL_IMMUNITY: case Bonus::SPELL_IMMUNITY:
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break; break;
case Bonus::SPELL_AFTER_ATTACK: case Bonus::SPELL_AFTER_ATTACK:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->additionalInfo % 100)); boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->additionalInfo));
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break; break;
default: default:
@ -571,13 +566,19 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
text = it->second.first; text = it->second.first;
switch (bonus->type) switch (bonus->type)
{ {
case Bonus::MANA_CHANNELING:
case Bonus::MAGIC_MIRROR:
case Bonus::CHANGES_SPELL_COST_FOR_ALLY:
case Bonus::CHANGES_SPELL_COST_FOR_ENEMY:
case Bonus::ENEMY_DEFENCE_REDUCTION:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSybtype(bonus->type, bonus->subtype))));
break;
case Bonus::HATE: case Bonus::HATE:
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl); boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
break; break;
case Bonus::LEVEL_SPELL_IMMUNITY: case Bonus::LEVEL_SPELL_IMMUNITY:
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val)); boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val));
break; break;
case Bonus::SPELL_IMMUNITY:
case Bonus::SPELL_AFTER_ATTACK: case Bonus::SPELL_AFTER_ATTACK:
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
break; break;