From e518ac67cf94e244df16078dcbc536e6b659e758 Mon Sep 17 00:00:00 2001
From: Daniel Karbach <daniel.karbach@localhorst.tv>
Date: Wed, 19 Dec 2012 22:07:30 +0100
Subject: [PATCH] rough implementation of capsule feeding

---
 src/common/Capsule.cpp       |  34 ++++++++++++++++++++++++++++
 src/common/Capsule.h         |  12 ++++++++++
 src/main.cpp                 |   2 +-
 src/menu/CapsuleFeedMenu.cpp |  42 ++++++++++++++++++++++++++++++++---
 src/menu/CapsuleFeedMenu.h   |   3 +++
 src/menu/Resources.cpp       |   8 +++++++
 src/menu/Resources.h         |   4 ++++
 test-data/capsule-feed.png   | Bin 0 -> 141 bytes
 test-data/capsules.l2s       |   1 +
 test-data/test.l2s           |  14 ++++++++++++
 10 files changed, 116 insertions(+), 4 deletions(-)
 create mode 100644 test-data/capsule-feed.png

diff --git a/src/common/Capsule.cpp b/src/common/Capsule.cpp
index f886724..4879585 100644
--- a/src/common/Capsule.cpp
+++ b/src/common/Capsule.cpp
@@ -142,6 +142,35 @@ const Capsule::Class &Capsule::GetClass() const {
 }
 
 
+int Capsule::HungerEmpty() const {
+	return HungerTotal() - HungerFull();
+}
+
+int Capsule::HungerTotal() const {
+	return GetClass().hunger;
+}
+
+int Capsule::HungerFull() const {
+	return GetClass().hungerFull;
+}
+
+bool Capsule::IsHungry() const {
+	return HungerEmpty();
+}
+
+void Capsule::Feed(const common::Item *) {
+	// TODO: find out how to calculate an item's feed value
+	// TODO: an item the capsule favors (changes on every feed and after every
+	//       battle) doubles the value
+	int value = 1;
+	GetClass().hungerFull += value;
+	if (GetClass().hungerFull >= GetClass().hunger) {
+		GetClass().hungerFull = GetClass().hunger;
+		UpgradeClass();
+	}
+}
+
+
 Capsule::Class::Class()
 : name(0)
 , tribe(0)
@@ -150,6 +179,9 @@ Capsule::Class::Class()
 , attackAnimation(0)
 , spellAnimation(0)
 
+, hunger(32)
+, hungerFull(0)
+
 , healthBoost(0) {
 	attacks[0] = 0;
 	attacks[1] = 0;
@@ -210,6 +242,8 @@ void Capsule::Class::CreateTypeDescription() {
 	td.AddField("attackAnimation", FieldDescription(((char *)&c.attackAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
 	td.AddField("spellAnimation", FieldDescription(((char *)&c.spellAnimation) - ((char *)&c), Animation::TYPE_ID).SetReferenced());
 
+	td.AddField("hunger", FieldDescription(((char *)&c.hunger) - ((char *)&c), Interpreter::NUMBER_ID));
+
 	td.AddField("healthBoost", FieldDescription(((char *)&c.healthBoost) - ((char *)&c), Interpreter::NUMBER_ID));
 	td.AddField("statBoost", FieldDescription(((char *)&c.statBoost) - ((char *)&c), Stats::TYPE_ID));
 }
diff --git a/src/common/Capsule.h b/src/common/Capsule.h
index f68ba53..ef4caf6 100644
--- a/src/common/Capsule.h
+++ b/src/common/Capsule.h
@@ -1,6 +1,9 @@
 #ifndef COMMON_CAPSULE_H_
 #define COMMON_CAPSULE_H_
 
+namespace common {
+	class Item;
+}
 namespace graphics {
 	class Animation;
 	class Sprite;
@@ -45,6 +48,12 @@ public:
 	int ClassIndex() const { return curClass; }
 	void SetClass(int index);
 
+	int HungerEmpty() const;
+	int HungerTotal() const;
+	int HungerFull() const;
+	bool IsHungry() const;
+	void Feed(const common::Item *);
+
 	Uint16 MaxHealth() const;
 
 	Stats GetStats() const;
@@ -79,6 +88,9 @@ private:
 		graphics::Animation *attackAnimation;
 		graphics::Animation *spellAnimation;
 
+		int hunger;
+		int hungerFull;
+
 		int healthBoost;
 		Stats statBoost;
 	};
diff --git a/src/main.cpp b/src/main.cpp
index 96bfad7..dc4c669 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -233,7 +233,7 @@ int main(int argc, char **argv) {
 		gameState.heroes[0].AddSpell(valorSpell);
 		gameState.heroes[1].AddSpell(valorSpell);
 
-		gameState.inventory.Add(caster.GetItem("zirconPlateItem"));
+		gameState.inventory.Add(caster.GetItem("zirconPlateItem"), 32);
 		gameState.inventory.Add(caster.GetItem("antidoteItem"), 9);
 		gameState.inventory.Add(caster.GetItem("powerRingItem"));
 		gameState.inventory.Add(caster.GetItem("magicJarItem"), 4);
diff --git a/src/menu/CapsuleFeedMenu.cpp b/src/menu/CapsuleFeedMenu.cpp
index 184212d..f2631b9 100644
--- a/src/menu/CapsuleFeedMenu.cpp
+++ b/src/menu/CapsuleFeedMenu.cpp
@@ -100,9 +100,7 @@ void CapsuleFeedMenu::HandleEvents(const Input &input) {
 		} else if (itemMenu.SelectedIndex() == itemMenu.SecondaryIndex()) {
 			switch (menu.Selected()) {
 				case CHOICE_SELECT:
-					if (true /* can feed */) {
-						// TODO: implement capsule feeding
-					}
+					FeedSelected();
 					itemMenu.SetActive();
 					break;
 				case CHOICE_SORT:
@@ -131,6 +129,18 @@ void CapsuleFeedMenu::HandleEvents(const Input &input) {
 	}
 }
 
+void CapsuleFeedMenu::FeedSelected() {
+	if (itemMenu.Selected()) {
+		// TODO: feed and grow animations
+		GetCapsule().Feed(itemMenu.Selected());
+		parent->Game().state->inventory.Remove(itemMenu.Selected(), 1);
+		LoadInventory();
+	} else {
+		// beep
+	}
+}
+
+
 void CapsuleFeedMenu::UpdateWorld(float deltaT) {
 
 }
@@ -144,6 +154,9 @@ void CapsuleFeedMenu::Render(SDL_Surface *screen) {
 	const Vector<int> spriteOffset(
 				3 * font.CharWidth() + font.CharWidth() * 3 / 4,
 				4 * font.CharHeight() + font.CharHeight() / 4);
+	const Vector<int> growthOffset(
+			13 * font.CharWidth(),
+			7 * font.CharHeight() + font.CharHeight() / 4);
 	const Vector<int> hungerOffset(
 			13 * font.CharWidth(),
 			9 * font.CharHeight() + font.CharHeight() / 8);
@@ -157,6 +170,9 @@ void CapsuleFeedMenu::Render(SDL_Surface *screen) {
 	parent->RenderBackground(screen);
 	RenderName(screen, offset + nameOffset);
 	RenderSprite(screen, offset + spriteOffset);
+	if (GetCapsule().IsHungry()) {
+		RenderGrowth(screen, offset + growthOffset);
+	}
 	RenderHunger(screen, offset + hungerOffset);
 	RenderMenu(screen, offset + menuOffset);
 	RenderItems(screen, offset + itemsOffset);
@@ -177,6 +193,22 @@ void CapsuleFeedMenu::RenderSprite(SDL_Surface *screen, const Vector<int> &offse
 	GetCapsule().BattleSprite()->Draw(screen, offset);
 }
 
+void CapsuleFeedMenu::RenderGrowth(SDL_Surface *screen, const Vector<int> &offset) const {
+	Vector<int> cursor(offset);
+	parent->Res().capsuleGrowthLabel->Draw(screen, offset);
+	cursor.X() += parent->Res().capsuleGrowthLabel->Width();
+
+	for (int i = 0; i < GetCapsule().HungerFull(); ++i) {
+		parent->Res().capsuleGrowthBarFilled->Draw(screen, cursor);
+		cursor.X() += parent->Res().capsuleGrowthBarFilled->Width();
+	}
+
+	for (int i = 0; i < GetCapsule().HungerEmpty(); ++i) {
+		parent->Res().capsuleGrowthBar->Draw(screen, cursor);
+		cursor.X() += parent->Res().capsuleGrowthBar->Width();
+	}
+}
+
 void CapsuleFeedMenu::RenderHunger(SDL_Surface *screen, const Vector<int> &offset) const {
 	const Font &font(*parent->Res().normalFont);
 	const Frame &frame(*parent->Res().statusFrame);
@@ -217,6 +249,10 @@ int CapsuleFeedMenu::Height() const {
 	return parent->Height();
 }
 
+Capsule &CapsuleFeedMenu::GetCapsule() {
+	return parent->GetCapsule();
+}
+
 const Capsule &CapsuleFeedMenu::GetCapsule() const {
 	return parent->GetCapsule();
 }
diff --git a/src/menu/CapsuleFeedMenu.h b/src/menu/CapsuleFeedMenu.h
index 8c75edd..1999674 100644
--- a/src/menu/CapsuleFeedMenu.h
+++ b/src/menu/CapsuleFeedMenu.h
@@ -34,12 +34,15 @@ private:
 
 	virtual void OnResize(int width, int height);
 
+	common::Capsule &GetCapsule();
 	const common::Capsule &GetCapsule() const;
 
 	void LoadInventory();
+	void FeedSelected();
 
 	void RenderName(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
 	void RenderSprite(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+	void RenderGrowth(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
 	void RenderHunger(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
 	void RenderMenu(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
 	void RenderItems(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
diff --git a/src/menu/Resources.cpp b/src/menu/Resources.cpp
index 548afc3..2c75291 100644
--- a/src/menu/Resources.cpp
+++ b/src/menu/Resources.cpp
@@ -136,6 +136,10 @@ Resources::Resources()
 , capsuleAlignmentWheel(0)
 , capsuleAlignmentCursor(0)
 
+, capsuleGrowthLabel(0)
+, capsuleGrowthBar(0)
+, capsuleGrowthBarFilled(0)
+
 { }
 
 
@@ -259,6 +263,10 @@ void Resources::CreateTypeDescription() {
 
 	td.AddField("capsuleAlignmentWheel", FieldDescription(((char *)&r.capsuleAlignmentWheel) - ((char *)&r), Sprite::TYPE_ID).SetReferenced());
 	td.AddField("capsuleAlignmentCursor", FieldDescription(((char *)&r.capsuleAlignmentCursor) - ((char *)&r), Sprite::TYPE_ID).SetReferenced());
+
+	td.AddField("capsuleGrowthLabel", FieldDescription(((char *)&r.capsuleGrowthLabel) - ((char *)&r), Sprite::TYPE_ID).SetReferenced());
+	td.AddField("capsuleGrowthBar", FieldDescription(((char *)&r.capsuleGrowthBar) - ((char *)&r), Sprite::TYPE_ID).SetReferenced());
+	td.AddField("capsuleGrowthBarFilled", FieldDescription(((char *)&r.capsuleGrowthBarFilled) - ((char *)&r), Sprite::TYPE_ID).SetReferenced());
 }
 
 void Resources::Construct(void *data) {
diff --git a/src/menu/Resources.h b/src/menu/Resources.h
index 1f6d207..1790a27 100644
--- a/src/menu/Resources.h
+++ b/src/menu/Resources.h
@@ -124,6 +124,10 @@ struct Resources {
 	graphics::Sprite *capsuleAlignmentWheel;
 	graphics::Sprite *capsuleAlignmentCursor;
 
+	graphics::Sprite *capsuleGrowthLabel;
+	graphics::Sprite *capsuleGrowthBar;
+	graphics::Sprite *capsuleGrowthBarFilled;
+
 	Resources();
 
 	static void CreateTypeDescription();
diff --git a/test-data/capsule-feed.png b/test-data/capsule-feed.png
new file mode 100644
index 0000000000000000000000000000000000000000..929483bc594063e7817a2a6337ed67639ac2570a
GIT binary patch
literal 141
zcmeAS@N?(olHy`uVBq!ia0vp^3P3Ev#0(@S{=a?)Nbv;tgt!9fmZp}yr~f~H{5(nc
z$t574u_VYZn8D%MjWi%f-_yl0gd;jRVk-lSxK2WYaf1NQ1PSgi!v)3;38F&DqBEiz
kj{NwqXwtyQvf?ZQ180fn)ql2S%0R6Qp00i_>zopr0E(C?mjD0&

literal 0
HcmV?d00001

diff --git a/test-data/capsules.l2s b/test-data/capsules.l2s
index a626958..296e6bb 100644
--- a/test-data/capsules.l2s
+++ b/test-data/capsules.l2s
@@ -197,6 +197,7 @@ export Capsule flash {
 					{ column: 0, row: 0, disposition: < 0, -16> }
 				]
 			},
+			hunger: 0,
 			healthBoost: 208,
 			statBoost: Stats {
 				atp:  38,
diff --git a/test-data/test.l2s b/test-data/test.l2s
index c691e17..ed457ca 100644
--- a/test-data/test.l2s
+++ b/test-data/test.l2s
@@ -943,5 +943,19 @@ export MenuResources menuResources {
 		image: :"capsule-sprites.png",
 		size: <32, 32>,
 		offset: <128, 128>
+	},
+	capsuleGrowthLabel: Sprite {
+		image: :"capsule-feed.png",
+		size: <32, 10>
+	},
+	capsuleGrowthBar: Sprite {
+		image: :"capsule-feed.png",
+		size: <8, 10>,
+		offset: <8, 10>
+	},
+	capsuleGrowthBarFilled: Sprite {
+		image: :"capsule-feed.png",
+		size: <8, 10>,
+		offset: <0, 10>
 	}
 }
-- 
2.39.5