11 virtual void Backfire(Creature self, Creature opponent)
13 self.health -= damage/4;
16 virtual void Success(Creature self, Creature opponent)
18 if(damage > opponent.health) damage = opponent.health;
19 PrintLn(self._class.name, " did ", damage, " damage to ", opponent._class.name, ".");
20 opponent.health -= damage;
24 class FireBall : Spell { difficulty = 20, damage = 8; manaCost = 5; };
25 class Lightning : Spell { difficulty = 10, damage = 4; manaCost = 3; };
30 void Success(Creature self, Creature opponent)
32 self.health += self.maxHealth / 5;
33 if(self.health > self.maxHealth) self.health = self.maxHealth;
36 void Backfire(Creature self, Creature opponent)
38 self.health -= damage/4;
46 int health, maxHealth;
53 Array<Equipment> equipment;
55 void CastSpell(Spell spell, Creature opponent)
57 if(mana >= spell.manaCost)
59 int r = GetRandom(0, spell.difficulty);
60 mana -= spell.manaCost;
63 PrintLn(_class.name, " cast ", spell._class.name, " successfully.");
64 spell.Success(this, opponent);
66 else if(r > magic * 2)
68 PrintLn(_class.name, "'s ", spell._class.name, " backfired.");
69 spell.Backfire(this, opponent);
72 PrintLn(_class.name, " unsucessfully cast ", spell._class.name, ".");
76 void Attack(Creature opponent)
78 Weapon weapon = (Weapon)(equipment ? equipment[EquipmentSlot::rightHand] : null);
80 if(!weapon) weapon = bareHand;
81 o = GetRandom(0, opponent.dexterity);
82 d = GetRandom(0, dexterity - weapon.difficulty);
85 int d = GetRandom(1, strength);
86 int where = GetRandom(0, 100);
112 if(opponent.equipment && opponent.equipment[slot])
113 armor = ((Armor)opponent.equipment[slot]).decDamage;
114 damage = Max(1, (d * weapon.damage - armor) * howBad / 10);
115 if(damage > opponent.health) damage = opponent.health;
116 opponent.health -= damage;
117 PrintLn(_class.name, " did ", damage, " damage to ", opponent._class.name, ".");
120 PrintLn(_class.name, " missed.");
124 Weapon bareHand { difficulty = 3, damage = 1 };
126 enum EquipmentSlot { leftHand, rightHand, head, feet, body, legs, ring, ring2, ring3, ring4 };
141 class Armor : Equipment
148 Print("Damage -", decDamage);
152 class Weapon : Equipment
160 Print("Difficulty: ", difficulty, ", Damage +", damage);
164 class LightShield : Armor { decDamage = 2; slot = leftHand; value = 20; };
165 class HeavyShield : Armor { decDamage = 5; slot = leftHand; value = 100; };
166 class Helmet : Armor { decDamage = 5; slot = head; value = 60; };
167 class SteelBoots : Armor { decDamage = 2; slot = feet; value = 40; };
168 class LightArmor : Armor { decDamage = 4; slot = body; value = 40; };
169 class PlateArmor : Armor { decDamage = 8; slot = body; value = 150; };
170 class PlateLeggings : Armor { decDamage = 3; slot = legs; value = 50; };
172 class Dagger : Weapon { difficulty = 2, damage = 2, value = 10, slot = rightHand; };
173 class LongSword : Weapon { difficulty = 4, damage = 4, value = 40, slot = rightHand; };
174 class BattleSword : Weapon { difficulty = 8, damage = 10, value = 100, slot = rightHand, twoHands = true; };
176 class Slug : Creature { xp = 10; maxHealth = 10; dexterity = 7; strength = 5; gold = 1; }
177 class GiantRat : Creature { xp = 30; maxHealth = 20; dexterity = 9; strength = 8; gold = 3; }
178 class GiantSpider : Creature { xp = 50; maxHealth = 30; dexterity = 20; strength = 10; gold = 4; }
179 class Bat : Creature { xp = 70; maxHealth = 10; dexterity = 40; strength = 5; gold = 6; }
180 class Goblin : Creature
182 xp = 120; maxHealth = 50; dexterity = 50; strength = 25; gold = 10;
184 class Ghoul : Creature { xp = 250; maxHealth = 70; dexterity = 20; strength = 30; gold = 30; }
185 class DarkKnight : Creature
187 xp = 500; maxHealth = 100; dexterity = 50; strength = 50; gold = 50; magic = 30; maxMana = 50;
188 spells = { [ FireBall { } ] };
189 equipment = { [ HeavyShield { }, LongSword { }, Helmet { }, SteelBoots { }, PlateArmor { }, PlateLeggings { }, null, null, null, null ] };
192 Array<Class> badGuys { [ class(Slug), class(GiantRat), class(GiantSpider), class(Goblin), class(Bat), class(DarkKnight), class(Ghoul) ] };
194 class EvilSorcerer : Creature
196 xp = 1000; maxHealth = 1000; dexterity = 75; strength = 50; gold = 20000; magic = 50; maxMana = 500;
197 equipment = { [ HeavyShield { }, LongSword { }, Helmet { }, SteelBoots { }, PlateArmor { }, PlateLeggings { }, null, null, null, null ] };
198 spells = { [ FireBall { }, Lightning { }, Healing { } ] };
201 Array<Equipment> shopInventory
218 enum GameState { realm, shop, fight, training, sorcerer, end };
220 class Player : Creature
226 spells = { [ FireBall { }, Lightning { }, Healing { } ] };
227 equipment = { [ null, null, null, null, null, null, null, null, null, null ] };
230 Player player { xp = 0, maxHealth = 40, health = 40, mana = 20, maxMana = 20, magic = 10, strength = 10, dexterity = 10, gold = 50, training = 2 };
233 class RPGApp : Application
245 PrintLn("You are fighting a ", opponent._class.name);
246 PrintLn(opponent._class.name, "'s Health: ", opponent.health, "/",opponent.maxHealth);
247 PrintLn("Your Health: ", player.health, "/", player.maxHealth, ", Mana: ", player.mana, "/",player.maxMana);
250 if(player.healthPotions)
251 PrintLn("[H]ealth potion");
252 if(player.manaPotions)
253 PrintLn("[M]ana potion");
254 if(player.spells.count)
257 PrintLn("Cast a spell:");
258 for(s : player.spells)
259 PrintLn(" ", n++, ". ", s._class.name);
265 PrintLn("Welcome to the village shop! What could we interest you in?");
266 PrintLn(" [H]ealth potions (10) [M]ana potions (15) Go [B]ack to the realm");
267 PrintLn(" You have ", player.gold, " gold coins");
268 for(i : shopInventory)
270 Print(" ", n++, ". ", i._class.name, ": ");
272 PrintLn(" (", i.value, ")");
277 PrintLn("You are wandering in the realm. What would you like to do?");
278 PrintLn("[F]ight bad guys Visit the [S]hop [R]est St[a]ts");
279 if(player.xp >= 1000)
280 PrintLn("Are you ready to rescue the [P]rincess?");
282 PrintLn("Do you want to [T]rain? You have ", player.training, " training points.");
285 PrintLn("You have ", player.training, " training points. What would you like to improve?");
288 PrintLn("[S]trength");
289 PrintLn("[D]exterity");
291 PrintLn(" Go [B]ack to the realm");
306 return input[0] == 'y';
309 void OpponentAttacks()
311 if(opponent.health > 0 && player.health > 0)
313 if(opponent.spells && opponent.spells.count && opponent.mana > opponent.maxMana / 5)
315 if(GetRandom(0,1) == 1)
317 int s = GetRandom(0, opponent.spells.count-1);
318 if(opponent.mana >= opponent.spells[s].manaCost)
319 opponent.CastSpell(opponent.spells[s], player);
321 opponent.Attack(player);
324 opponent.Attack(player);
327 opponent.Attack(player);
329 if(player.health <= 0)
331 PrintLn("You died :(");
334 else if(opponent.health <= 0)
336 int trainingPointsBefore = player.xp / 50;
337 PrintLn("Congratulations! You won the fight. You gained ", opponent.xp/10, " xp points and ", opponent.gold, " gold.");
338 player.gold += opponent.gold;
339 player.xp += opponent.xp / 10;
340 player.training += player.xp / 50 - trainingPointsBefore;
342 if(state == sorcerer)
343 PrintLn("You saved the princess!! The end.");
352 int c = GetRandom(0, badGuys.count-1);
353 opponent = eInstance_New(badGuys[c]);
354 if(opponent.xp < 40 || opponent.xp <= player.xp)
358 opponent.health = opponent.maxHealth;
359 opponent.mana = opponent.maxMana;
363 void ProcessCommand()
365 if(command[0] == 'q')
367 PrintLn("Are you sure you want to quit?");
376 case 'b': state = realm; break;
379 int price = (command[0] == 'm') ? 15 : 10;
380 if(player.gold < price)
381 PrintLn("You do not have enough gold!");
384 (command[0] == 'm') ? player.manaPotions++ : player.healthPotions++;
385 player.gold -= price;
391 int item = atoi(command);
392 if(item && item <= shopInventory.count)
394 Equipment eq = shopInventory[item-1];
395 EquipmentSlot slot = eq.slot;
397 Equipment tradeIn1 = null, tradeIn2 = null;
399 while(player.equipment[slot] && slot < ring4)
402 if(slot == rightHand && eq.twoHands)
404 if(player.equipment[EquipmentSlot::leftHand])
405 tradeIn1 = player.equipment[EquipmentSlot::leftHand];
406 if(player.equipment[EquipmentSlot::rightHand])
407 tradeIn2 = player.equipment[EquipmentSlot::rightHand];
409 else if((slot == leftHand || slot == rightHand) && player.equipment[EquipmentSlot::rightHand] && player.equipment[EquipmentSlot::rightHand].twoHands)
411 if(player.equipment[EquipmentSlot::rightHand])
412 tradeIn1 = player.equipment[EquipmentSlot::rightHand];
414 else if(player.equipment[slot])
415 tradeIn1 = player.equipment[slot];
417 tradeIn = ((tradeIn1 ? tradeIn1.value : 0) + (tradeIn2 ? tradeIn2.value : 0)) / 2;
418 if(player.gold + tradeIn < eq.value)
419 PrintLn("You do not have enough gold!");
422 if(player.equipment[slot])
423 PrintLn("You will need to trade in your ", player.equipment[slot]._class.name, ", for ", tradeIn, ".");
425 PrintLn("Are you sure you want to buy this ", eq._class.name, " for ", eq.value, "?");
428 if(tradeIn1) shopInventory.Add(tradeIn1);
429 if(tradeIn2) shopInventory.Add(tradeIn2);
430 player.equipment[slot] = eq;
431 player.gold += tradeIn - eq.value;
433 shopInventory.Remove(shopInventory.Find(eq));
435 //shopInventory.TakeOut(eq);
445 bool fightBack = false;
450 player.Attack(opponent);
454 if(player.manaPotions)
456 player.manaPotions--;
457 player.mana += player.maxMana / 5;
458 if(player.mana > player.maxMana) player.mana = player.maxMana;
462 if(player.healthPotions)
464 player.healthPotions--;
465 player.health += player.maxHealth / 5;
466 if(player.health > player.maxHealth) player.health = player.maxHealth;
471 if(player.health > 0)
476 int item = atoi(command);
477 if(item && item <= player.spells.count)
479 if(player.mana >= player.spells[item-1].manaCost)
481 player.CastSpell(player.spells[item-1], opponent);
485 PrintLn("Not enough mana to cast that spell.");
499 PrintLn("\nYour statistics:");
500 PrintLn("XP: ", player.xp);
501 PrintLn("Health: ", player.health, "/", player.maxHealth);
502 PrintLn("Mana: ", player.mana, "/", player.maxMana);
503 PrintLn("Strength: ", player.strength, ", Dexterity: ", player.dexterity, ", Magic: ", player.magic);
504 PrintLn("Gold: ", player.gold);
505 PrintLn("Equipment:");
506 for(c = leftHand; c <= ring4; c++)
508 Equipment eq = player.equipment[c];
511 Print(c, ": ", eq._class.name, ": ");
516 if(player.manaPotions)
517 PrintLn(player.manaPotions, " mana potions");
518 if(player.healthPotions)
519 PrintLn(player.healthPotions, " health potions");
521 PrintLn(player.training, " training points");
524 case 's': state = shop; break;
525 case 'b': state = realm; break;
526 case 'f': FindOpponent(); break;
527 case 't': state = training; break;
531 opponent = EvilSorcerer { };
537 if(GetRandom(0, 3) == 0)
539 PrintLn("Your rest was interrupted!");
545 player.health += player.maxHealth / 5;
546 if(player.health > player.maxHealth) player.health = player.maxHealth;
547 player.mana += player.maxMana / 5;
548 if(player.mana > player.maxMana) player.mana = player.maxMana;
558 case 'h': player.health += player.maxHealth / 5; player.maxHealth += player.maxHealth / 5; break;
559 case 'm': player.mana += player.maxMana / 5; player.maxMana += player.maxMana / 5; break;
560 case 's': player.strength += player.strength / 5; break;
561 case 'd': player.dexterity += player.dexterity / 5; break;
562 case 'g': player.magic += player.magic / 5; break;
563 case 'b': state = realm;
564 default: valid = false;
579 RandomSeed((uint)(((uint64)(GetTime() * 1000)) & MAXDWORD));
580 PrintLn("Welcome to this great minimalist RPG!");
581 PrintLn("You will need to save the princess from an Evil Sorcerer.");
582 PrintLn("But first you should wander the realm to fight the sorcerer's minions, ");
583 PrintLn("gaining experience and equipment in the process. You will need to reach");
584 PrintLn("at least 1000 experience points to search for the sorcerer's hideout.");
585 PrintLn("At any time you can [Q]uit.");