../src/battle/NumberAnimation.cpp \
../src/battle/PartyLayout.cpp \
../src/battle/SmallHeroTag.cpp \
+../src/battle/Stats.cpp \
../src/battle/TargetSelection.cpp
OBJS += \
./src/battle/NumberAnimation.o \
./src/battle/PartyLayout.o \
./src/battle/SmallHeroTag.o \
+./src/battle/Stats.o \
./src/battle/TargetSelection.o
CPP_DEPS += \
./src/battle/NumberAnimation.d \
./src/battle/PartyLayout.d \
./src/battle/SmallHeroTag.d \
+./src/battle/Stats.d \
./src/battle/TargetSelection.d
../src/battle/NumberAnimation.cpp \
../src/battle/PartyLayout.cpp \
../src/battle/SmallHeroTag.cpp \
+../src/battle/Stats.cpp \
../src/battle/TargetSelection.cpp
OBJS += \
./src/battle/NumberAnimation.o \
./src/battle/PartyLayout.o \
./src/battle/SmallHeroTag.o \
+./src/battle/Stats.o \
./src/battle/TargetSelection.o
CPP_DEPS += \
./src/battle/NumberAnimation.d \
./src/battle/PartyLayout.d \
./src/battle/SmallHeroTag.d \
+./src/battle/Stats.d \
./src/battle/TargetSelection.d
public:
OrderCompare(BattleState *battle) : battle(battle) { }
bool operator ()(const BattleState::Order &lhs, const BattleState::Order &rhs) {
- int lagl(lhs.isMonster ? battle->MonsterAt(lhs.index).Agility() : battle->HeroAt(lhs.index).Agility());
- int ragl(rhs.isMonster ? battle->MonsterAt(rhs.index).Agility() : battle->HeroAt(rhs.index).Agility());
+ int lagl(lhs.isMonster ? battle->MonsterAt(lhs.index).GetStats().Agility() : battle->HeroAt(lhs.index).GetStats().Agility());
+ int ragl(rhs.isMonster ? battle->MonsterAt(rhs.index).GetStats().Agility() : battle->HeroAt(rhs.index).GetStats().Agility());
return lagl > ragl;
}
private:
void BattleState::CalculateDamage() {
if (CurrentAttack().isMonster) {
+ const Stats &attackerStats(MonsterAt(CurrentAttack().index).GetStats());
// TODO: run monster's attack script
monsterAttacks[CurrentAttack().index].SetType(AttackChoice::SWORD);
monsterAttacks[CurrentAttack().index].Selection().SelectSingle();
monsterAttacks[CurrentAttack().index].Selection().SelectHeroes();
- monsterAttacks[CurrentAttack().index].Selection().SetBad(0, 15);
+ for (int i(0); i < NumHeroes(); ++i) {
+ if (HeroAt(i).Health() > 0) {
+ const Stats &defenderStats(HeroAt(i).GetStats());
+ Uint16 damage(CalculateDamage(attackerStats, defenderStats));
+ monsterAttacks[CurrentAttack().index].Selection().SetBad(0, damage);
+ break;
+ }
+ }
} else {
+ const Stats &attackerStats(HeroAt(CurrentAttack().index).GetStats());
TargetSelection &ts(AttackChoiceAt(CurrentAttack().index).Selection());
bool hitSome(false);
if (ts.TargetsEnemies()) {
for (int i(0); i < MaxMonsters(); ++i) {
if (ts.IsSelected(i)) {
if (MonsterAt(i).Health() > 0) {
- ts.SetBad(i, 15);
+ const Stats &defenderStats(MonsterAt(i).GetStats());
+ Uint16 damage(CalculateDamage(attackerStats, defenderStats));
+ ts.SetBad(i, damage);
hitSome = true;
} else {
ts.Unselect(i);
if (hitSome) return;
for (int i(0); i < MaxMonsters(); ++i) {
if (MonsterAt(i).Health() > 0) {
- ts.SetBad(i, 15);
+ const Stats &defenderStats(MonsterAt(i).GetStats());
+ Uint16 damage(CalculateDamage(attackerStats, defenderStats));
+ ts.SetBad(i, damage);
break;
}
}
for (int i(0); i < NumHeroes(); ++i) {
if (ts.IsSelected(i)) {
if (HeroAt(i).Health() > 0) {
- ts.SetBad(i, 15);
+ const Stats &defenderStats(HeroAt(i).GetStats());
+ Uint16 damage(CalculateDamage(attackerStats, defenderStats));
+ ts.SetBad(i, damage);
hitSome = true;
} else {
ts.Unselect(i);
if (hitSome) return;
for (int i(0); i < NumHeroes(); ++i) {
if (HeroAt(i).Health() > 0) {
- ts.SetBad(i, 15);
+ const Stats &defenderStats(HeroAt(i).GetStats());
+ Uint16 damage(CalculateDamage(attackerStats, defenderStats));
+ ts.SetBad(i, damage);
break;
}
}
}
}
+Uint16 BattleState::CalculateDamage(const Stats &attacker, const Stats &defender) const {
+ // TODO: find out real formula and add some randomness
+ return attacker.Attack() / 2 - defender.Defense() / 4;
+}
+
void BattleState::ApplyDamage() {
if (attackCursor < 0) return;
AttackChoice &ac(CurrentAttack().isMonster ? monsterAttacks[CurrentAttack().index] : AttackChoiceAt(CurrentAttack().index));
namespace battle {
class PartyLayout;
+class Stats;
class BattleState
: public app::State {
void LoadIkariMenu(std::vector<Hero>::size_type heroIndex);
void LoadInventory();
+ Uint16 CalculateDamage(const Stats &attacker, const Stats &defender) const;
+
private:
SDL_Surface *background;
const PartyLayout *monstersLayout;
, maxMana(0)
, mana(0)
-, attack(0)
-, defense(0)
-, agility(0)
-, intelligence(0)
-, gut(0)
-, magicResistance(0)
-
, level(0)
, ip(0) {
health = 0;
} else {
health -= amount;
+ int ipGain(amount * 255 / health);
+ if (ip + ipGain > 255) {
+ ip = 255;
+ } else {
+ ip += ipGain;
+ }
}
}
#ifndef BATTLE_HERO_H_
#define BATTLE_HERO_H_
+#include "Stats.h"
+
#include <vector>
#include <SDL.h>
Uint8 IP() const { return ip; }
int RelativeIP(int max) const { return IP() * max / MaxIP(); }
- Uint16 Attack() const { return attack; }
- Uint16 Defense() const { return defense; }
- Uint16 Agility() const { return agility; }
- Uint16 Intelligence() const { return intelligence; }
- Uint16 Gut() const { return gut; }
- Uint16 MagicResistance() const { return magicResistance; }
+ Stats &GetStats() { return stats; }
+ const Stats &GetStats() const { return stats; }
common::Item *Weapon() { return weapon; }
common::Item *Armor() { return armor; }
void SetMana(Uint16 m) { mana = m; }
void SetIP(Uint8 i) { ip = i; }
+ void SetStats(const Stats &s) { stats = s; }
+
void SetWeapon(common::Item *i) { weapon = i; }
void SetArmor(common::Item *i) { armor = i; }
void SetShield(common::Item *i) { shield = i; }
Uint16 maxHealth, health;
Uint16 maxMana, mana;
- Uint16 attack;
- Uint16 defense;
- Uint16 agility;
- Uint16 intelligence;
- Uint16 gut;
- Uint16 magicResistance;
+ Stats stats;
Uint8 level;
Uint8 ip;
, maxMana(0)
, mana(0)
-, attack(0)
-, defense(0)
-, agility(0)
-, intelligence(0)
-, gut(0)
-, magicResistance(0)
-
, expReward(0)
, goldReward(0)
#ifndef BATTLE_MONSTER_H_
#define BATTLE_MONSTER_H_
+#include "Stats.h"
+
#include <SDL.h>
namespace graphics { class Sprite; }
Uint16 Mana() const { return mana; }
int RelativeMana(int max) const { return mana * max / maxMana; }
- Uint16 Attack() const { return attack; }
- Uint16 Defense() const { return defense; }
- Uint16 Agility() const { return agility; }
- Uint16 Intelligence() const { return intelligence; }
- Uint16 Gut() const { return gut; }
- Uint16 MagicResistance() const { return magicResistance; }
+ Stats &GetStats() { return stats; }
+ const Stats &GetStats() const { return stats; }
Uint16 ExpReward() const { return expReward; }
Uint16 GoldReward() const { return goldReward; }
public:
void SetName(const char *n) { name = n; }
void SetSprite(graphics::Sprite *s) { sprite = s; }
+ void SetLevel(Uint8 l) { level = l; }
void SetMaxHealth(Uint16 m) { maxHealth = m; }
void SetHealth(Uint16 h) { health = h; }
+ void SetMaxMana(Uint16 m) { maxMana = m; }
+ void SetMana(Uint16 m) { mana = m; }
+ void SetStats(const Stats &s) { stats = s; }
+ void SetReward(Uint16 exp, Uint16 gold) { expReward = exp; goldReward = gold; }
private:
const char *name;
Uint16 maxHealth, health;
Uint16 maxMana, mana;
- Uint16 attack;
- Uint16 defense;
- Uint16 agility;
- Uint16 intelligence;
- Uint16 gut;
- Uint16 magicResistance;
+ Stats stats;
Uint16 expReward, goldReward;
--- /dev/null
+/*
+ * Stats.cpp
+ *
+ * Created on: Aug 19, 2012
+ * Author: holy
+ */
+
+#include "Stats.h"
+
+namespace battle {
+
+Stats::Stats()
+: attack(0)
+, defense(0)
+, strength(0)
+, agility(0)
+, intelligence(0)
+, gut(0)
+, magicResistance(0) {
+
+}
+
+Stats::Stats(Uint16 attack, Uint16 defense, Uint16 strength, Uint16 agility, Uint16 intelligence, Uint8 gut, Uint16 magicResistance)
+: attack(attack)
+, defense(defense)
+, strength(strength)
+, agility(agility)
+, intelligence(intelligence)
+, gut(gut)
+, magicResistance(magicResistance) {
+
+}
+
+}
--- /dev/null
+/*
+ * Stats.h
+ *
+ * Created on: Aug 19, 2012
+ * Author: holy
+ */
+
+#ifndef BATTLE_STATS_H_
+#define BATTLE_STATS_H_
+
+#include <SDL.h>
+
+namespace battle {
+
+class Stats {
+
+public:
+ Stats();
+ Stats(Uint16 attack, Uint16 defense, Uint16 strength, Uint16 agility, Uint16 intelligence, Uint8 gut, Uint16 magicResistance);
+
+public:
+ Uint16 Attack() const { return attack; }
+ Uint16 Defense() const { return defense; }
+ Uint16 Strength() const { return strength; }
+ Uint16 Agility() const { return agility; }
+ Uint16 Intelligence() const { return intelligence; }
+ Uint8 Gut() const { return gut; }
+ Uint16 MagicResistance() const { return magicResistance; }
+
+private:
+ Uint16 attack;
+ Uint16 defense;
+ Uint16 strength;
+ Uint16 agility;
+ Uint16 intelligence;
+ Uint16 magicResistance;
+ Uint8 gut;
+
+};
+
+}
+
+#endif /* BATTLE_STATS_H_ */
#include "battle/Monster.h"
#include "battle/PartyLayout.h"
#include "battle/Resources.h"
+#include "battle/Stats.h"
#include "common/Ikari.h"
#include "common/Inventory.h"
#include "common/Item.h"
using battle::Hero;
using battle::Monster;
using battle::PartyLayout;
+using battle::Stats;
using common::Ikari;
using common::Inventory;
using common::Item;
SDL_Surface *monsterImg(IMG_Load("test-data/monster.png"));
Sprite dummySprite(monsterImg, 64, 64);
Monster monster;
- monster.SetName("Monster");
+ monster.SetName("Lizard");
monster.SetSprite(&dummySprite);
- monster.SetMaxHealth(10);
- monster.SetHealth(10);
+ monster.SetLevel(1);
+ monster.SetMaxHealth(8);
+ monster.SetHealth(8);
+ monster.SetStats(Stats(14, 6, 6, 6, 6, 6, 6));
+ monster.SetReward(3, 5);
SDL_Surface *maximImg(IMG_Load("test-data/maxim.png"));
Sprite maximSprite(maximImg, 64, 64);
maxim.SetMaxMana(20);
maxim.SetMana(20);
maxim.SetIP(0);
+ maxim.SetStats(Stats(28, 22, 28, 17, 14, 100, 10));
ComplexAnimation maximAttackAnimation(&maximSprite, framerate);
// TODO: cross check double frames; could be related to differences in framerates
maximAttackAnimation.AddFrames(1, 0, Vector<int>(0, 0), 7); // TODO: maybe this could also be a pause before the battle animation
selan.SetHealth(28);
selan.SetMaxMana(23);
selan.SetMana(23);
- selan.SetIP(1);
+ selan.SetIP(0);
+ selan.SetStats(Stats(23, 21, 23, 19, 22, 80, 13));
ComplexAnimation selanAttackAnimation(&selanSprite, framerate);
selanAttackAnimation.AddFrames(1, 0, Vector<int>(4, 0), 2);
selanAttackAnimation.AddFrame(1, 0, Vector<int>(8, 2));
guy.SetHealth(38);
guy.SetMaxMana(0);
guy.SetMana(0);
- guy.SetIP(254);
+ guy.SetIP(0);
+ guy.SetStats(Stats(38, 25, 38, 13, 8, 90, 8));
ComplexAnimation guyAttackAnimation(&guySprite, framerate);
guyAttackAnimation.AddFrames(1, 0, Vector<int>(-4, 0), 2);
guyAttackAnimation.AddFrames(1, 0, Vector<int>(-8, 0), 2);
dekar.SetHealth(38);
dekar.SetMaxMana(0);
dekar.SetMana(0);
- dekar.SetIP(255);
+ dekar.SetIP(0);
+ dekar.SetStats(Stats(46, 29, 46, 13, 7, 100, 5));
ComplexAnimation dekarAttackAnimation(&dekarSprite, framerate);
dekarAttackAnimation.AddFrame(1, 0, Vector<int>(4, 0));
dekarAttackAnimation.AddFrame(1, 0, Vector<int>(8, 2));