Page MenuHomePhabricator (Chris)

No OneTemporary

Size
249 KB
Referenced Files
None
Subscribers
None
diff --git a/data/labels.txt b/data/labels.txt
index d413f48..20574dd 100644
--- a/data/labels.txt
+++ b/data/labels.txt
@@ -1,1791 +1,1804 @@
[english]
start_new_game#Start a new game
start_desc#Old game will be destroyed
restore#Restore game
at#at
level#level
begin_journey#Begin your journey in a new dungeon
config_keys#Configure keys
redef_input#Redefine player's input
exit_game#Exit game
return_to_desktop#Return to the desktop
key_configuration#Keys' configuration
key_configuration_desc#Please configure the keys
key_configuration_insert#[insert Key]
key_configuration_done#DONE
key_move_up#move up
key_move_down#move down
key_move_left#move left
key_move_right#move right
key_fire_up#fire up
key_fire_down#fire down
key_fire_left#fire left
key_fire_right#fire right
key_fire_select#fire select
key_time#time control
key_fire#fire (one button)
key_spell#cast a spell
configure_game#Configuration
configure_game_desc#Changes game options
config_back#Back
config_back_desc#Back to the main menu
config_lang#Language
config_lang_desc#Choose with left and right arrows
english#English
french#French
keys_move#move
keys_fire#fire
keys_select_1#fire
keys_select_2#selector
keys_time#time control
tuto_reset#Tutorial reset
tuto_reset_desc#Resets the tutorial
menu_continue#Continue
menu_continue_desc#Continue the game
menu_save_quit#Save and quit
menu_save_quit_desc#Save and return to main screen
menu_quit#Quit without saving
menu_quit_desc#Return to main screen without saving
play_again#Press [ENTER] to play again / [ESC] to go back to the menu
items_found#Items
monsters_killed#Monsters
congratulations_1#CONGRATULATIONS!
congratulations_2#You've challenged this demo and kill the bosses!
congratulations_3#See you soon for new adventures!
by#by
critical#CRITICAL X2
poison#POISON
merchant_speech_0#Best price in the entire dungeon!
merchant_speech_1#Welcome to the Pawn'n'Witches shop!
merchant_speech_2#Have a look at our merchandise!
enemy_butcher#Pigman Butcher
enemy_giant_slime#Giant Slime
enemy_rat_king#Wererat King
enemy_giant_spider#Giant Spider
item_copper#Copper coin
item_copper_desc#A copper coin (value 1)
item_silver#Silver coin
item_silver_desc#A silver coin (value 5)
item_gold#Gold coin
item_gold_desc#A gold coin (value 10)
item_titan_heart#Titan's Heart
item_titan_heart_desc#Increases Max HP
item_elven_cookie#Elven Cookie
item_elven_cookie_desc#Restores and increases Max HP
item_apple#Apple
item_apple_desc#Restores 3 HP
item_apple_green#Green apple
item_apple_green_desc#Restores 3 HP and cures poison
item_bread#Bread
item_bread_desc#Restores 7 HP
item_cheese#Cheese
item_cheese_desc#Restores 15 HP
item_boss_key#Boss Key
item_boss_key_desc#Opens the Boss gate
item_sorcerer_hat#Sorcerer's Hat
item_sorcerer_hat_desc#Increases fire rate
item_velvet_boots#Velvet Boots
item_velvet_boots_desc#Increases speed
item_spell_dual#Spell : Dual bolts
item_spell_dual_desc#Shoots two bolts
item_rage_amulet#Rage Amulet
item_rage_amulet_desc#Retaliates
item_displacement_gloves#Displacement Gloves
item_displacement_gloves_desc#Player's velocity impacts bolt's one
item_staff_desc#Increases bolt's speed and damage
item_fairy#Fairy Lilly
item_fairy_desc#Helps you in the dungeon
item_leather_belt#Leather belt
item_leather_belt_desc#Increases fire rate
item_blood_snake#Blood Snake
item_blood_snake_desc#Increases damage
item_gem_ice#Ice Gem
item_gem_ice_desc#Ice attack (freeze)
item_gem_illusion#illusion Gem
item_gem_illusion_desc#illusion attack (ignores walls and armor)
item_gem_stone#Stone Gem
item_gem_stone_desc#Stone attack (repulse)
item_gem_lightning#Lightning Gem
item_gem_lightning_desc#Lightning attack (bouncing)
item_fairy_ice#Fairy Natasha
item_fairy_ice_desc#Helps you in the dungeon
item_ring_ice#Sapphire Ring
item_ring_ice_desc#Increases ice power
item_ring_stone_desc#Increases stone power
item_ring_lightning_desc#Increases lightning power
item_ring_illusion_desc#Increases illusion power
item_spell_triple#Spell : Triple bolts
item_spell_triple_desc#Shoots three bolts
item_fairy_fire#Fairy Alicia
item_fairy_fire_desc#Helps you in the dungeon
item_fairy_target#Fairy Scarlett
item_fairy_target_desc#Helps you in the dungeon
item_robe_magician#Magician's Robe
item_robe_magician_desc#Increases armor
item_gem_fire#Fire Gem
item_gem_fire_desc#Fire attack (more damages)
item_ring_fire#Ruby Ring
item_ring_fire_desc#Increases fire power
item_manual_staff#Staff's Manual
item_manual_staff_desc#Increases fire range
item_spell_teleport#Spell: Teleport
item_spell_teleport_desc#Cast to teleport within the room
item_spell_slime_explode#Spell: Invoke Slime
item_spell_slime_explode_desc#Cast to invoke an explosive slime
item_spell_fireball#Spell: Fireball
item_spell_fireball_desc#Cast to launch a fireball
item_spell_freeze#Spell: Freeze monsters
item_spell_freeze_desc#Cast to freeze monsters
item_spell_earthquake#Spell: Earthquake
item_spell_earthquake_desc#Cast to make the dungeon shake
item_spell_protection#Spell: Magic shield
item_spell_protection_desc#Cast to summon a magic shield
item_manual_slime#Manual of Slime Mastery
item_manual_slime_desc#Slimes don't aim at you anymore
item_spell_dual_quick#Spellbook of Quick Dual bolts
item_spell_dual_quick_desc#Shoots two bolts (quick)
item_spell_triple_quick#Spellbook of Quick Triple bolts
item_spell_triple_quick_desc#Shoots three bolts (quick)
item_manual_health#Health's Manual
item_manual_health_desc#Health items give more HP
item_rear_shot#Staff cap
item_rear_shot_desc#Shots a rear bolt
item_book_random_shot#Spellbook of Random Shot
item_book_random_shot_desc#Shots a bolt in a random direction
item_spell_web#Spell: Spider Web
item_spell_web_desc#Cast to throw spider webs
item_book_magic_i#Book of magic - Tome I
item_book_magic_i_desc#Decreases spell's cooldown
item_book_magic_ii#Book of magic - Tome II
item_book_magic_ii_desc#Increases spell's power
item_sulfur#Sulfur
item_sulfur_desc#Can make corpses explode
spell_teleport#teleport
spell_slime_explode#invoke slime
spell_fireball#fireball
spell_freeze#freeze monsters
spell_earthquake#earthquake
spell_protection#magic shield
spell_web#spider web
msg_level1_0#Your quest begins!
msg_level1_1#"Witches have abducted the Archmage's daughter and brought her in their lair.
msg_level1_2#I have to recover her!"
msg_level2_0#The Archmage's daughter
msg_level2_1#"I'm coming right now to rescue you!
msg_level2_2#Hopefully, she's safe and sound..."
msg_level3_0#The Archmage's daughter
msg_level3_1#"Did I ever tell you?
msg_level3_2#The Archmage's daughter is the sweetest girl of the Magic Academy!"
msg_level4_0#The Archmage
msg_level4_1#"The Archmage is a very wise man, and also my mentor.
msg_level4_2#He's taught me we live in the best of the worlds."
msg_level5_0#The Archmage's daughter
msg_level5_1#"I remember the Archmage's daughter and me, back in the Magic Academy.
msg_level5_2#We used to play at the healer mage, hi hi!"
msg_level6_0#The Archmage
msg_level6_1#"My parents died when I was a baby.
msg_level6_2#The Archmage has raised me like his own son."
msg_rats_bats_0#Monsters
msg_rats_bats_1#"Hey! Why do we always have to exterminate rats or bats
msg_rats_bats_2#in these Rogue games ?"
msg_snakes_0#Snakes
msg_snakes_1#"I HATE snakes!"
msg_witches_0#Witches
msg_witches_1#"B... Witches!!!"
msg_gold_0#Gold
msg_gold_1#"♫ Money money money ♫
msg_gold_2#I wonder if I can buy useful items in this dungeon..."
msg_familiar_0#Fairies
msg_familiar_1#"Oh! I've got company!
msg_familiar_2#I hope I'll find others allies in the dungeon."
msg_butcher_0#The Pigman Butcher
msg_butcher_1#"Wow this one is a big guy!
msg_butcher_2#I hope I won't end up in sausages..."
msg_giant_slime_0#The Giant Slime
msg_giant_slime_1#"I am green, huge and I stink.
msg_giant_slime_2#What I am ?"
msg_cyclops_1#"How did it go in the room?
msg_cyclops_2#It's bigger and larger than the gate!"
msg_wererat_0#The Wererat
msg_wererat_1#"Looks like my old aunt..."
msg_giant_spider_before_0#The empty room
msg_giant_spider_before_1#"Is there anybody in there? "
msg_giant_spider_after_0#The Giant Spider
msg_giant_spider_after_1#"I HATE spiders"
msg_tuto_intro_0#Tutorial: Basics
msg_tuto_intro_1#Use WASD (standard) to move around the dungeon.
msg_tuto_intro_2#Fire with the arrows (standard).
msg_tuto_items_0#Tutorial: Items
msg_tuto_items_1#Items enhance your character or give you new powers.
msg_tuto_items_2#Find or buy as many as you can.
msg_tuto_heal_0#Tutorial: Health
msg_tuto_heal_1#You've lost some hit points.
msg_tuto_heal_2#Find something to heal you before you die.
msg_tuto_shops_0#Tutorial: Shops
msg_tuto_shops_1#You can find many shops in the dungeon.
msg_tuto_shops_2#Here can you spend money to buy items or food.
msg_tuto_boss_door_0#Tutorial: Boss gate
msg_tuto_boss_door_1#From here, you can see a closed golden door.
msg_tuto_boss_door_2#Here is the boss of the floor, but you need the golden key to enter.
msg_tuto_challenge_door_0#Tutorial: Challenge room
msg_tuto_challenge_door_1#Look at the decorative door. It is a challenge room.
msg_tuto_challenge_door_2#You can obtain valuable rewards here, but enter with caution!
msg_tuto_shots_0#Tutorial: Shot types
msg_tuto_shots_1#You've found a new shot type.
msg_tuto_shots_2#Press [fire select] (standard: tab) to switch between your shot types.
msg_tuto_spell_0#Tutorial: Spells
msg_tuto_spell_1#You've found a magic spell.
msg_tuto_spell_2#Press the spell key (standard: space) to cast the spell.
msg_francky_0#The... Thing
msg_francky_1#Yuk... It looks like made with various body parts!
msg_tuto_tips_0#Tutorial: Tips
msg_tuto_tips_1#Use Time Control (standard: RShift) to travel faster.
msg_tuto_tips_2#Press [Enter] to close the message box immediately.
enemy_type_bat#a bat
enemy_type_rat#a rat
enemy_type_rat_black#a black rat
enemy_type_rat_helmet#a rat with helmet
enemy_type_rat_black_helmet#a black rat with helmet
enemy_type_evil_flower#an evil flower
enemy_type_evil_flower_ice#an evil edelweiss
enemy_type_snake#a snake
enemy_type_snake_blood#a blood snake
enemy_type_slime#a slime
enemy_type_slime_red#a red slime
enemy_type_slime_blue#a blue slime
enemy_type_slime_violet#a violet slime
enemy_type_imp_blue#a blue imp
enemy_type_imp_red#a red imp
enemy_type_pumpkin#a mad pumpkin
enemy_type_witch#a witch
enemy_type_witch_red#a red witch
enemy_type_cauldron#a cauldron
enemy_type_bubble#a bubble
enemy_type_boss_butcher#the Pigman Butcher
enemy_type_boss_slime_giant#the Giant Slime
enemy_type_boss_rat_king#the Wererat King
enemy_type_boss_spider_giant#the Giant Spider
enemy_type_green_rat#a green rat
enemy_type_rock_falling#a falling rock
enemy_type_rock_missile#a throwing rock
enemy_type_spider_egg#a falling spider egg
enemy_type_spider_little#a spider
enemy_type_spider_web#a spider web
enemy_type_ghost#a ghost
enemy_type_zombie#a zombie
enemy_type_zombie_dark#a dark zombie
enemy_type_francky#the Thing
enemy_type_himself#himself
source_explosion#explosion
source_poison#poison
enemy_francky#The Thing
enemy_francky_head#The Thing's head
inventory#Inventory
dc_certificate#Death certificate
dc_killed_by#Killed by
dc_died_level#Died on level
dc_after#after
dc_minutes#min. of game
dc_killed_monsters#Slayed monsters
dc_gold#Gold
dc_challenges#Completed challenges
player_name#Player name
player_name_desc#Modify player name
hi_scores#Hall of fame
hi_scores_desc#Best scores
credits#Credits
credits_desc#Credits screen
volume_sound#Sound volume
volume_sound_desc#Use left/right arrows to change volume
volume_music#Music volume
certificate_capture#Press [F1] to save the certificate as a PNG file
certificate_saved#Saved to
msg_tuto_temple_0#Tutorial: Temple
msg_tuto_temple_1#The temple is the place where you can worship a divinity or donate.
msg_tuto_temple_2#Divinities can help you and provide bonuses.
key_interact#interact
interact_worship#Worship
interact_shop#Buy
interact_donate#Donate 10 pieces of gold
interact_donate_fail#(not enough gold)
worshipping#You're now a worshipper of
divinity_healer_0#Pomonos the Righteous
divinity_healer_1#Guardian of the righteousness and patroness of the weak.
divinity_healer_2#He appreciates donations, suffering and fighting evil.
divinity_fighter_0#Tello the Powerful
divinity_fighter_1#Lord of the fighters and the war.
divinity_fighter_2#He appreciates monsters and titans falling in battle.
divinity_ice_0#Mister Snow
divinity_ice_1#Divinity of the cold.
divinity_ice_2#He likes the use of ice.
divinity_stone_0#Gaya
divinity_stone_1#Divinity of the stone and earth.
divinity_stone_2#He likes the use of stone.
divinity_intervention_0#Divine intervention
divinity_intervention_1#intervenes in your favour.
divinity_gift_0#Divine gift
divinity_gift_1#grants you a gift.
item_floor_map#Dungeon Map
item_floor_map_desc#Reveals the map of the present floor
item_alcohol#Absinthe
item_alcohol_desc#Temporarily increases damage
item_staff#Ebony Staff
item_ring_stone#Quartz Ring
item_ring_lightning#Amethyst Ring
item_ring_illusion#Obsidian Ring
enemy_cyclops#Stone Cyclops
msg_cyclops_0#The Stone Cyclops
enemy_type_boss_cyclops#the Stone Cyclops
achiev_rats#Rodenticide
-achiev_rats_desc#Kill one rat
+achiev_rats_desc#Kill 250 rats
achiev_100#Stingy
achiev_100_desc#Collect 100 gold coins
achiev_piety_max#Faithful
achiev_piety_max_desc#Reach the max piety level
achiev_3_hits#Brochette
achiev_3_hits_desc#Hurt 3 monsters with the same shot
achiev_complete_set#Dressed
achiev_complete_set_desc#Equip robe + hat + boots + gloves
achiev_giant_slime#Giant Slime Slayer
achiev_giant_slime_desc#Kill the Giant Slime
achiev_cyclops#Cyclops Slayer
achiev_cyclops_desc#Kill the Stone Cyclops
achiev_rat_king#Wererat Slayer
achiev_rat_king_desc#Kill the Wererat king
achiev_giant_spider#Giant Spider Slayer
achiev_giant_spider_desc#Kill the Giant Spider
achiev_francky#Thing Slayer
achiev_francky_desc#Kill the Thing
+achiev_butcher#Butcher Slayer
+achiev_butcher_desc#Kill the Butcher
+achiev_witches#Inquisitor
+achiev_witches_desc#Kill 50 witches
+achiev_eggs#Bad omelette
+achiev_eggs_desc#Destroy 100 eggs
+achiev_fairies#Charlie's Angels
+achiev_fairies_desc#Free 3 fairies
+achiev_challenges#Gladiator
+achiev_challenges_desc#Complete 4 challenges
+achiev_win#Live a dream
+achiev_win_desc#Finish the demo
+
enemy_type_evil_flower_fire#an evil fire flower
menu_achievements#Achievements
menu_achievements_desc#Display the achievements
item_spell_flower#Spell: Invoke magic flower
item_spell_flower_desc#Cast to invoke a magic flower
item_rapid_shots#Spellbook of Rapid Fire
item_rapid_shots_desc#Wizard machine gun
item_fairy_poison#Fairy Vicky
item_fairy_poison_desc#Helps you in the dungeon
item_luck#Four-leaf clover
item_luck_desc#Temporarily increases gold drop
item_fairy_powder#Fairy Dust
item_fairy_powder_desc#Temporarily excites the fairies
item_ring_poison#Emerald ring
item_ring_poison_desc#Increases poison power
item_gem_poison#Poison Gem
item_gem_poison_desc#Poison attack
item_book_prayer_i#Book of prayer - Tome I
item_book_prayer_i_desc#Increases piety
item_book_prayer_ii#Book of prayer - Tome II
item_book_prayer_ii_desc#Reduces reconversion cost
item_pet_slime#Slime Pet
item_pet_slime_desc#It will follow and help you
item_hat_advanced#Warlock's Hat
item_hat_advanced_desc#Increases fire rate
item_robe_advanced#Magic robe of shock
item_robe_advanced_desc#Repulses and increases armor
item_critical#Fake mage beard
item_critical_desc#Chance to critical shot (x2)
item_critical_advanced#Fake Archmage beard
item_critical_advanced_desc#Increases critical damage (x3)
item_spell_fairy#Spell: Fairy transmutation
item_spell_fairy_desc#Cast to transmute to a fairy
item_gloves_advanced#Ranger gloves
-item_gloves_advanced_desc#Disarm traps and firerate+
+item_gloves_advanced_desc#Disarm traps and firerate up
item_boots_advanced#Ranger boots
item_boots_advanced_desc#Increases speed
[french]
start_new_game#Nouvelle partie
start_desc#L'ancienne partie sera perdue
restore#Continuer la partie
at#à
level#niveau
begin_journey#Démarrer dans un nouveau donjon
config_keys#Configurer le clavier
redef_input#Redéfinir les touches
exit_game#Quitter
return_to_desktop#Retour au bureau
key_configuration#Configuration des touches
key_configuration_desc#Veuillez configurer les touches
key_configuration_insert#[presser touche]
key_configuration_done#FAIT
key_move_up#Déplacement haut
key_move_down#Déplacement bas
key_move_left#Déplacement gauche
key_move_right#Déplacement droite
key_fire_up#Tir haut
key_fire_down#Tir bas
key_fire_left#Tir gauche
key_fire_right#Tir droite
key_fire_select#Sélecteur de tir
key_time#Accélérer le temps
key_fire#Tir (un bouton)
key_spell#Lancer un sort
configure_game#Configuration
configure_game_desc#Modifier les options
config_back#Retour
config_back_desc#Retour au menu principal
config_lang#Langue
config_lang_desc#Choisissez avec les flèches (gauche et droite)
english#Anglais
french#Français
keys_move#déplacer
keys_fire#tirer
keys_select_1#sélecteur
keys_select_2#de tir
keys_time#accélerer
tuto_reset#RAZ des tutoriels
tuto_reset_desc#Réinitialisation des tutoriels
menu_continue#Continuer
menu_continue_desc#Continuer le jeu
menu_save_quit#Sauvegarder et quitter
menu_save_quit_desc#Sauvegarder et retourner au menu principal
menu_quit#Quitter sans sauvegarder
menu_quit_desc#Retourner au menu principal sans sauvegarder
inventory#Equipement
play_again#Pressez [ENTRER] pour rejouer / [ESC] pour revenir au menu
items_found#Objets
monsters_killed#Monstres
congratulations_1#FELICITATIONS !
congratulations_2#Vous êtes brillamment arrivé au terme de cette démo !
congratulations_3#A bientôt pour de nouvelles aventures !
by#par
critical#CRITIQUE X2
poison#POISON
merchant_speech_0#Les meilleures affaires du donjon !
merchant_speech_1#Bienvenue à la boutique Pawn'n'Witches !
merchant_speech_2#Jetez un oeil à nos produits !
enemy_butcher#Boucher porcin
enemy_giant_slime#Slime géant
enemy_cyclops#Cyclope de pierre
enemy_rat_king#Roi des Rats-garous
enemy_giant_spider#Araignée géante
enemy_francky#La Chose
enemy_francky_head#La tête de la Chose
item_copper#Pièce de cuivre
item_copper_desc#Une pièce de cuivre (1)
item_silver#Pièce d'argent
item_silver_desc#Une pièce d'argent (5)
item_gold#Pièce d'or
item_gold_desc#Une pièce d'or (10)
item_titan_heart#Coeur de Titan
item_titan_heart_desc#Augmente les PV max
item_elven_cookie#Biscuit elfique
item_elven_cookie_desc#Guérit et augmente les PV
item_apple#Pomme
item_apple_desc#Guérit 3 PV
item_apple_green#Pomme verte
item_apple_green_desc#Guérit le poison et 3 PV
item_bread#Pain
item_bread_desc#Guérit 7 HP
item_cheese#Fromage
item_cheese_desc#Guérit 15 HP
item_boss_key#Clef du boss
item_boss_key_desc#Ouvre la porte du boss
item_sorcerer_hat#Chapeau d'enchanteur
item_sorcerer_hat_desc#Augmente la cadence de tir
item_velvet_boots#Bottes de velours
item_velvet_boots_desc#Augmente la vitesse
item_spell_dual#Sort: double-tir
item_spell_dual_desc#Tire deux projectiles
item_rage_amulet#Amulette de rage
item_rage_amulet_desc#Contre-attaque
item_displacement_gloves#Gants de déplacement
item_displacement_gloves_desc#La vitesse du porteur impacte la trajectoire
item_staff#Bâton d'ébène
item_staff_desc#Augmente les dégâts et la vitesse de tir
item_fairy#La fée Lilly
item_fairy_desc#Vous aide dans le donjon
item_leather_belt#Ceinture de cuir
item_leather_belt_desc#Augmente la cadence de tir
item_blood_snake#Serpent de sang
item_blood_snake_desc#Augmente les dégâts
item_gem_ice#Gemme de glace
item_gem_ice_desc#Attaque de glace (gèle)
item_gem_illusion#Gemme d'illusion
item_gem_illusion_desc#Attaque d'illusion(ignore murs et armures)
item_gem_stone#Gemme de pierre
item_gem_stone_desc#Attaque de pierre(repousse)
item_gem_lightning#Gemme de foudre
item_gem_lightning_desc#Attaque de foudre(rebondit)
item_fairy_ice#La fée Natacha
item_fairy_ice_desc#Vous aide dans le donjon
item_ring_ice#Anneau de saphir
item_ring_ice_desc#Augmente le pouvoir de glace
item_ring_stone#Anneau de quartz
item_ring_stone_desc#Augmente le pouvoir de pierre
item_ring_lightning#Anneau d'améthyste
item_ring_lightning_desc#Augmente le pouvoir de foudre
item_ring_illusion#Anneau d'obsidienne
item_ring_illusion_desc#Augmente le pouvoir d'illusion
item_spell_triple#Manuel de Triple-tir
item_spell_triple_desc#Tire trois projectiles
item_brooch_finesse#Barbe factice d'Archimage
item_brooch_finesse_desc#Chance de dégâts critiques (x2)
item_fairy_fire#La fée Alicia
item_fairy_fire_desc#Vous aide dans le donjon
item_fairy_target#La fée Scarlett
item_fairy_target_desc#Vous aide dans le donjon
item_robe_magician#Robe de magicien
item_robe_magician_desc#Augmente l'armure
item_gem_fire#Gemme de feu
item_gem_fire_desc#Attaque de feu (dégâts augmentés)
item_ring_fire#Anneau de rubis
item_ring_fire_desc#Augmente le pouvoir de feu
item_manual_staff#Manuel du bâton
item_manual_staff_desc#Augmente la portée
item_spell_teleport#Sort : Téléportation
item_spell_teleport_desc#Permet de se téléporter dans la pièce
item_spell_slime_explode#Sort: Invoquer Slime
item_spell_slime_explode_desc#Invoque un slime explosif
item_spell_fireball#Sort: Boule de feu
item_spell_fireball_desc#Envoie une boule de feu
item_spell_freeze#Sort: Geler monstres
item_spell_freeze_desc#Gèle les monstres
item_spell_earthquake#Sort: Séisme
item_spell_earthquake_desc#Fait trembler le donjon
item_spell_protection#Sort: Protection
item_spell_protection_desc#Invoque un bouclier magique
item_manual_slime#Manuel de maîtrise des slimes
item_manual_slime_desc#Les slimes ne vous visent plus
item_spell_dual_quick#Sort: Double-tir (rapide)
item_spell_dual_quick_desc#Tire deux projectiles (rapide)
item_spell_triple_quick#Sort: Triple-tir (rapide)
item_spell_triple_quick_desc#Tire trois projectiles (rapide)
item_manual_health#Manuel de santé
item_manual_health_desc#Gain de PV augmenté
item_rear_shot#Embout de bâton
item_rear_shot_desc#Tir arrière
item_book_random_shot#Sort: Tir aléatoire
item_book_random_shot_desc#Tire dans une direction aléatoire
item_spell_web#Sort: Toile d'araignée
item_spell_web_desc#Tire des toiles d'araignée
item_book_magic_i#Grimoire - Tome I
item_book_magic_i_desc#Réduit le délai entre deux sorts
item_book_magic_ii#Grimoire - Tome II
item_book_magic_ii_desc#Augmente la puissance du sort
item_sulfur#Soufre
item_sulfur_desc#Chance de faire exploser les cadavres
spell_teleport#téléportation
spell_slime_explode#invoquer slime
spell_fireball#boule de feu
spell_freeze#geler monstres
spell_earthquake#séisme
spell_protection#protection
spell_web#toile d'araignée
msg_level1_0#Votre quête commence !
msg_level1_1#"Les sorcières ont enlevé la fille de l'Archimage.
msg_level1_2#Je dois descendre dans leur antre et la secourir !"
msg_level2_0#La fille de l'Archimage
msg_level2_1#"J'arrive, je vais te sortir de là !
msg_level2_2#J'espère qu'elle est saine et sauve..."
msg_level3_0#La fille de l'Archimage
msg_level3_1#"Vous l'ai-je déjà dit ?
msg_level3_2#La fille de l'Archimage est la plus douce de l'Académie de Magie !"
msg_level4_0#L'Archimage
msg_level4_1#"L'Archimage est très sage, et est aussi mon mentor.
msg_level4_2#Il m'a appris que nous vivons dans le meilleur des monde."
msg_level5_0#La fille de l'Archimage
msg_level5_1#"Je me souviens d'elle et de moi, à l'Académie de Magie.
msg_level5_2#Enfants, nous jouions au mage guérisseur, hi hi !"
msg_level6_0#L'Archimage
msg_level6_1#"Mes parents sont décédés quand j'étais bébé.
msg_level6_2#L'Archimage m'a élevé comme si j'étais des siens."
msg_rats_bats_0#La vermine
msg_rats_bats_1#"Hey! Pourquoi faut-il toujours exterminer des rats et chauve-souris
msg_rats_bats_2#dans les Roguelikes ?"
msg_snakes_0#Les serpents
msg_snakes_1#"Je DETESTE les serpents!"
msg_witches_0#Les sorcières
msg_witches_1#"S.. Sorcières !!!"
msg_gold_0#Or
msg_gold_1#"♫ Money money money ♫
msg_gold_2#Je me demande si je peux acheter des trucs intéressants dans ce donjon..."
msg_familiar_0#Les fées
msg_familiar_1#"Oh ! De la compagnie !
msg_familiar_2#J'espère trouver d'autres alliés dans le donjon."
msg_butcher_0#Le Boucher porcin
msg_butcher_1#"Wow, ce gars est balèze !
msg_butcher_2#J'espère ne pas terminer en saucisses..."
msg_giant_slime_0#Le Slime géant
msg_giant_slime_1#"Je suis vert, énorme et je pue.
msg_giant_slime_2#Qui suis-je ?"
msg_cyclops_0#Le Cyclope de pierre
msg_cyclops_1#"Comment est-il entré dans cette pièce ?
msg_cyclops_2#Il est plus large que les portes !"
msg_wererat_0#Le Roi des Rats-garous
msg_wererat_1#"Il ressemble à ma vieille tante..."
msg_giant_spider_before_0#Une pièce vide
msg_giant_spider_before_1#"Y'a quelqu'un ? "
msg_giant_spider_after_0#L'Araignée géante
msg_giant_spider_after_1#"Je DETESTE les araignées"
msg_tuto_intro_0#Tutoriel: Bases
msg_tuto_intro_1#Utilisez ZQSD (standard) pour se déplacer dans le donjon.
msg_tuto_intro_2#Tirez avec les flèches (standard).
msg_tuto_items_0#Tutoriel: Objets
msg_tuto_items_1#Les objets améliorent le personnage ou lui octroient de nouveaux pouvoirs.
msg_tuto_items_2#trouvez ou achetez-en autant que possible.
msg_tuto_heal_0#Tutoriel: Santé
msg_tuto_heal_1#Vous avez perdu des points de vie.
msg_tuto_heal_2#Trouvez des moyens de guérir avant de mourir.
msg_tuto_shops_0#Tutoriel: Boutique
msg_tuto_shops_1#Vous pouvez trouver plusieurs boutiques dans le donjon.
msg_tuto_shops_2#Ici, vous dépenserez votre argent en objets et nourriture.
msg_tuto_boss_door_0#Tutoriel: Porte du Boss
msg_tuto_boss_door_1#D'ici, vous apercevez une porte dorée verrouillée.
msg_tuto_boss_door_2#Elle protège le Boss, trouvez la clef adéquate pour l'ouvrir.
msg_tuto_challenge_door_0#Tutoriel: Salle de Challenge
msg_tuto_challenge_door_1#Regardez la porte décorée ? C'est une salle de challenge.
msg_tuto_challenge_door_2#Vous pouvez y gagner des objets de valeur mais attention !
msg_tuto_shots_0#Tutoriel: Types de tir
msg_tuto_shots_1#Vous avez trouvé un nouveau type de tir.
msg_tuto_shots_2#Appuyez sur [sélection de tir] (standard: tab) pour changer de type de tir.
msg_tuto_spell_0#Tutoriel: Magie
msg_tuto_spell_1#Vous avez trouvé un nouveau sort.
msg_tuto_spell_2#Appuyez sur la touche de sort (standard: espace) pour le lancer.
msg_francky_0#La... Chose
msg_francky_1#Beurk... Il a l'air "fabriqué" à partir de morceaux de cadavres !
msg_tuto_tips_0#Tutoriel: Astuces
msg_tuto_tips_1#Le contrôle du temps (standard: Shift droit) permet de se déplacer plus vite.
msg_tuto_tips_2#Appuyez sur [Enter] pour fermer les boites de message.
enemy_type_bat#une chauve-souris
enemy_type_rat#un rat
enemy_type_rat_black#un rat noir
enemy_type_rat_helmet#un rat casqué
enemy_type_rat_black_helmet#un rat noir casqué
enemy_type_evil_flower#une fleur maléfique
enemy_type_evil_flower_ice#un edelweiss maléfique
enemy_type_snake#un serpent
enemy_type_snake_blood#un serpent de sang
enemy_type_slime#un slime
enemy_type_slime_red#un slime rouge
enemy_type_slime_blue#un slime bleu
enemy_type_slime_violet#un slime violet
enemy_type_imp_blue#un diablotin bleu
enemy_type_imp_red#un diablotin rouge
enemy_type_pumpkin#une citrouille démente
enemy_type_witch#une sorcière
enemy_type_witch_red#une sorcière rouge
enemy_type_cauldron#un chaudron
enemy_type_bubble#une bulle
enemy_type_boss_butcher#le Boucher porcin
enemy_type_boss_slime_giant#le Slime géant
enemy_type_boss_cyclops#le Cyclope de pierre
enemy_type_boss_rat_king#le Roi des Rats-garous
enemy_type_boss_spider_giant#l'Araignée géante
enemy_type_green_rat#un rat vert
enemy_type_rock_falling#un rocher tombant
enemy_type_rock_missile#un rocher lancé
enemy_type_spider_egg#un oeuf d'araignée tombant
enemy_type_spider_little#une araignée
enemy_type_spider_web#une toile d'araignée
enemy_type_ghost#un fantôme
enemy_type_zombie#un zombie
enemy_type_zombie_dark#un zombie sombre
enemy_type_francky#la Chose
enemy_type_himself#lui-même
source_explosion#une explosion
source_poison#du poison
dc_certificate#Certificat de décès
dc_killed_by#Tué par
dc_died_level#Mort au niveau
dc_after#après
dc_minutes#min. de jeu
dc_killed_monsters#Monstres vaincus
dc_gold#Or
dc_challenges#Défis relevés
player_name#Nom du joueur
player_name_desc#Modifier le nom du joueur
hi_scores#Hall of fame
hi_scores_desc#Meilleurs scores
credits#Crédits
credits_desc#Ecran des crédits
volume_sound#Volume du son
volume_sound_desc#Utiliser les flèches gauche/droite pour modifier le volume
volume_music#Volume de la musique
certificate_capture#Appuyez sur [F1] pour faire une copie du certificat dans un PNG
certificate_saved#Enregistré sous
msg_tuto_temple_0#Tutoriel: Temple
msg_tuto_temple_1#Au temple, vous pouvez vénérer des divinités et faire des donations.
msg_tuto_temple_2#Les divinités vous apporte leur aide et des bonus.
key_interact#interaction
interact_worship#Vénérer
interact_shop#Acheter
interact_donate#Donner 10 pièces
interact_donate_fail#(pas assez d'argent)
worshipping#Vous êtes maintenant un disciple de
divinity_healer_0#Pomonos le Juste
divinity_healer_1#Gardien de la vertue et protecteur des faibles.
divinity_healer_2#Il apprécie les dons, la souffrance, et le combat contre le mal.
divinity_fighter_0#Tello le Puissant
divinity_fighter_1#Seigneur des guerriers et de la force.
divinity_fighter_2#Il aime voir tomber les monstres et les titans.
divinity_ice_0#Mister Snow
divinity_ice_1#Divinité du Froid.
divinity_ice_2#Il apprécie l'usage de la glace.
divinity_stone_0#Gaya
divinity_stone_1#Divinité de la Terre et de la Pierre.
divinity_stone_2#Il apprécie l'usage de la pierre.
divinity_intervention_0#Intervention divine
divinity_intervention_1#intervient en votre faveur.
divinity_gift_0#Présent divin
divinity_gift_1#vous offre un présent.
item_floor_map#Carte du donjon
item_floor_map_desc#Révèle la carte de cet étage
item_alcohol#Absinthe
item_alcohol_desc#Vous rend temporairement plus fort
[german]
start_new_game#Neues Spiel starten
start_desc#Alter Speicherstand wird überschrieben !
restore#Speicherstand wiederherstellen
at#um
level#Level
begin_journey#Beginne deine Reise in einem neuen Verlies
config_keys#Steuerung
redef_input#Ändere die Tastenbelegung
exit_game#Spiel verlassen
return_to_desktop#Kehre zum Desktop zurück
key_configuration#Tastenbelegung
key_configuration_desc#Bitte belege die Tasten
key_configuration_insert#[Taste einsetzen]
key_configuration_done#FERTIG
key_move_up#Nach oben
key_move_down#Nach unten
key_move_left#Nach links
key_move_right#Nach rechts
key_fire_up#Schieße oben
key_fire_down#Schieße unten
key_fire_left#Schieße links
key_fire_right#Schieße rechts
key_fire_select#Schieße Auswahl
key_time#Zeitsteuerung
key_fire#Schießen (ein Knopf)
key_spell#Verzaubern
configure_game#Optionen
configure_game_desc#Ändere die Spieloptionen
config_back#Zurück
config_back_desc#Zurück zum Hauptmenü
config_lang#Sprache
config_lang_desc#Wähle mit linker und rechter Pfeiltaste aus
english#Englisch
french#Französisch
german#Deutsch
keys_move#Bewegen
keys_fire#Schießen
keys_select_1#Waffe
keys_select_2#wechseln
keys_time#Zeitsteuerung
play_again#Drücke [ENTER], um nochmal zu spielen / [ESC], um ins Hauptmenü zurückzukehren
items_found#Items
monsters_killed#Monster
congratulations_1#HERZLICHEN GLÜCKWUNSCH !
congratulations_2#Du hast dich der Demo Version gestellt und die Bosse getötet !
congratulations_3#Bis bald für neue Abenteuer !
by#von
critical#KRITISCH X2
poison#GIFT
merchant_speech_0#Bester Preis im gesamten Verlies!
merchant_speech_1#Willkommen im Pawn'n'Witches Shop!
merchant_speech_2#Schau dir unsere Waren an!
enemy_butcher#Schweinemetzger
enemy_giant_slime#Gigantischer Schleim
enemy_cyclops#Steinzyklop
enemy_rat_king#Werrattenkönig
enemy_giant_spider#Gigantische Spinne
item_copper#Kupfermünze
item_copper_desc#Eine Kupfermünze (Wert 1)
item_silver#Silbermünze
item_silver_desc#Eine Silbermünze (Wert 5)
item_gold#Goldmünze
item_gold_desc#Eine Goldmünze (Wert 10)
item_titan_heart#Herz des Titanen
item_titan_heart_desc#Erhöht die maximalen TP
item_elven_cookie#Elfenkeks
item_elven_cookie_desc#Regeneriert und erhöht die max. TP
item_apple#Apfel
item_apple_desc#Stellt 3 TP wieder her
item_bread#Brot
item_bread_desc#Stellt 7 TP wieder her
item_cheese#Käse
item_cheese_desc#Stellt 15 TP wieder her
item_boss_key#Boss-Schlüssel
item_boss_key_desc#Öffnet die Boss-Tür
item_sorcerer_hat#Hut des Zauberers
item_sorcerer_hat_desc#Erhöht die Feuerrate
item_velvet_boots#Samtschuhe
item_velvet_boots_desc#Erhöht die Geschwindigkeit
item_spell_dual#Zauber : Doppelter Schuss
item_spell_dual_desc#Schießt zwei Schüsse
item_rage_amulet#Wutamulett
item_rage_amulet_desc#Revanchiert sich bei Kontakt
item_displacement_gloves#Verschiebungs-Handschuhe
item_displacement_gloves_desc#Die Geschwindigkeit des Spielers beeinflusst die der Schüsse
item_staff#Elfenbeinstab
item_staff_desc#Erhöht Schussgeschwindigkeit und Schaden
item_fairy#Lilly-Fee
item_fairy_desc#Hilft dir im Verlies
item_leather_belt#Ledergürtel
item_leather_belt_desc#Erhöht die Feuerrate
item_blood_snake#Blutschlange
item_blood_snake_desc#Erhöht den Schaden
item_gem_ice#Eisjuwel
item_gem_ice_desc#Eisangriff (einfrieren)
item_gem_illusion#Illusionsjuwel
item_gem_illusion_desc#Illusionsangriff (ignoriert Wände)
item_gem_stone#Steinjuwel
item_gem_stone_desc#Steinangriff (rückstoßen)
item_gem_lightning#Blitzjuwel
item_gem_lightning_desc#Blitzangriff (abprallen)
item_fairy_ice#Natasha-Fee
item_fairy_ice_desc#Hilft dir im Verlies
item_ring_ice#Saphir Ring
item_ring_ice_desc#Erhöht die Eiskraft
item_ring_stone#Quarzring
item_ring_stone_desc#Erhöht die Steinkraft
item_ring_lightning#Amethystring
item_ring_lightning_desc#Erhöht die Blitzkraft
item_ring_illusion#Obsidianring
item_ring_illusion_desc#Erhöht die Illusionskraft
item_spell_triple#Zauber : Dreifacher Schuss
item_spell_triple_desc#Schießt drei Schüsse
item_brooch_finesse#Falscher Erzmagierbart
item_brooch_finesse_desc#Kritische Trefferchance (x2)
item_fairy_fire#Alicia-Fee
item_fairy_fire_desc#Hilft dir im Verlies
item_fairy_target#Scarlett-Fee
item_fairy_target_desc#Hilft dir im Verlies
item_robe_magician#Robe des Zauberers
item_robe_magician_desc#Erhöht die Rüstung
item_gem_fire#Feuerjuwel
item_gem_fire_desc#Feuerangriff (mehr Schaden)
item_ring_fire#Rubin Ring
item_ring_fire_desc#Erhöht die Feuerkraft
item_manual_staff#Handbuch des Zauberstabes
item_manual_staff_desc#Erhöht die Reichweite
item_spell_teleport#Spell: Teleport
item_spell_teleport_desc#Cast to teleport within the room
item_spell_slime_explode#Spell: Invoke Slime
item_spell_slime_explode_desc#Cast to invoke an explosive slime
spell_teleport#Teleportation
spell_slime_explode#invoke slime
item_spell_fireball#Zauber: Feuerball
item_spell_fireball_desc#Zauber, um einen Feuerball zu beschwören
item_spell_freeze#Zauber: Monster einfrieren
item_spell_freeze_desc#Zauber, um Monster einzufrieren
item_spell_earthquake#Zauber: Erdbeben
item_spell_earthquake_desc#Zauber, um das Verlies durchzuschütteln
item_spell_protection#Zauber: Magisches Schild
item_spell_protection_desc#Zauber, um ein magisches Schild zu beschwören
spell_fireball#Feuerball
spell_freeze#Monster einfrieren
spell_earthquake#Erdbeben
spell_protection#Magisches Schild
msg_level1_0#Deine Aufgabe beginnt!
msg_level1_1#"Hexen haben die Tochter des Erzmagiers entführt und sie in ihr Lager gebracht.
msg_level1_2#Ich muss sie retten!"
msg_level2_0#Die Tochter des Erzmagiers
msg_level2_1#"Ich komme sofort, um dich zu befreien !
msg_level2_2#Hoffentlich ist sie wohlbehalten..."
msg_level3_0#Die Tochter des Erzmagiers
msg_level3_1#"Hab ich es dir je erzählt?
msg_level3_2#Die Tochter des Erzmagiers ist das süßeste Mädchen der magischen Akademie!"
msg_level4_0#Der Erzmagier
msg_level4_1#"Der Erzmagier ist ein sehr weiser Mann, und zugleich mein Mentor.
msg_level4_2#Er hat mich gelehrt, dass wir auf der besten Welt leben."
msg_level5_0#Die Tochter des Erzmagiers
msg_level5_1#"Ich erinnere mich an die Tochter des Erzmagiers und mich, damals auf der magischen Akademie.
msg_level5_2#Wir haben beim Heilmagier gespielt, hi hi !"
msg_level6_0#Der Erzmagier
msg_level6_1#"Meine Eltern starben, als ich noch ein Baby war.
msg_level6_2#Der Erzmagier hat mich wie seinen eigenen Sohn aufgezogen."
msg_rats_bats_0#Monster
msg_rats_bats_1#"Hey! Warum müssen wir immer Ratten und Fledermäuse ausrotten
msg_rats_bats_2#in diesen Schurken Spielen ?"
msg_snakes_0#Schlangen
msg_snakes_1#"Ich HASSE Schlangen!"
msg_witches_0#Hexen
msg_witches_1#"S... Hexen !!!"
msg_gold_0#Gold
msg_gold_1#"♫ Money money money ♫
msg_gold_2#Ich frage mich, ob ich nützliche Gegenstände in diesem Verlies kaufen kann..."
msg_familiar_0#Feen
msg_familiar_1#"Oh! Ich habe Gesellschaft!
msg_familiar_2#Ich hoffe ich finde noch andere Verbündete im Verlies."
msg_butcher_0#Der Schweinemetzger
msg_butcher_1#"Wow, das ist ein großer Typ!
msg_butcher_2#Ich hoffe ich werde kein Hackfleisch..."
msg_giant_slime_0#Der gigantische Schleim
msg_giant_slime_1#"Ich bin grün, riesig und stinke.
msg_giant_slime_2#Was ich bin ?"
msg_cyclops_0#Der Steinzyklop
msg_cyclops_1#"Wie ist es in dem Raum gelaufen?
msg_cyclops_2#Es ist größer und länger als das Tor!"
msg_wererat_0#Die Werratte
msg_wererat_1#"Sieht aus wie meine alte Tante..."
msg_giant_spider_before_0#Der leere Raum
msg_giant_spider_before_1#"Ist hier jemand? "
msg_giant_spider_after_0#Die riesige Spinne
msg_giant_spider_after_1#"Ich HASSE Spinnen"
msg_tuto_intro_0#Tutorial: Wesentliches
msg_tuto_intro_1#Benutze WASD (Standard), um dich im Verlies zu bewegen.
msg_tuto_intro_2#Feuere mit den Pfeiltasten (Standard).
msg_tuto_items_0#Tutorial: Gegenstände
msg_tuto_items_1#Gegenstände verbessern deinen Charakter oder geben dir neue Kräfte.
msg_tuto_items_2#Finde oder kaufe so viele du kannst.
msg_tuto_heal_0#Tutorial: Leben
msg_tuto_heal_1#Du hast einige Trefferpunkte verloren.
msg_tuto_heal_2#Finde etwas um dich zu heilen, bevor du stirbst.
msg_tuto_shops_0#Tutorial: Geschäfte
msg_tuto_shops_1#Du kannst viele Geschäfte im Verlies finden.
msg_tuto_shops_2#Hier kannst du Geld ausgeben, um Gegenstände oder Essen zu kaufen.
msg_tuto_boss_door_0#Tutorial: Boss-Tür
msg_tuto_boss_door_1#Von hier aus kannst du eine geschlossene, goldene Tür sehen.
msg_tuto_boss_door_2#Hier ist der Boss von dieser Etage, aber du brauchst den goldenen Schlüssel, um die Tür zu öffnen.
msg_tuto_challenge_door_0#Tutorial: Raum der Herausforderung
msg_tuto_challenge_door_1#Schau auf die dekorative Tür. Es ist ein Raum der Herausforderung.
msg_tuto_challenge_door_2#Du kannst hier wertvolle Belohnungen erhalten, aber sei vorsichtig!
msg_tuto_shots_0#Tutorial: Schussarten
msg_tuto_shots_1#Du hast eine neue Schussart gefunden.
msg_tuto_shots_2#Drücke [Waffe wechseln] (Standard: Tab), um zwischen den Schussarten zu wechseln.
msg_tuto_spell_0#Tutorial: Zauber
msg_tuto_spell_1#Du hast einen magischen Zauber gefunden.
msg_tuto_spell_2#Drücke die Zaubertaste (Standard: Leertaste), um einen Zauber zu beschwören.
enemy_type_bat#eine Fledermaus
enemy_type_rat#eine Ratte
enemy_type_rat_black#eine schwarze Ratte
enemy_type_rat_helmet#eine Ratte mit Helm
enemy_type_rat_black_helmet#eine schwarze Ratte mit Helm
enemy_type_evil_flower#eine böse Blume
enemy_type_evil_flower_ice#eine böse Edelweiß
enemy_type_snake#eine Schlange
enemy_type_snake_blood#eine Blutschlange
enemy_type_slime#ein Schleim
enemy_type_slime_red#ein roter Schleim
enemy_type_slime_blue#ein blauer Schleim
enemy_type_slime_violet#ein violetter Schleim
enemy_type_imp_blue#ein blauer Imp
enemy_type_imp_red#ein roter Imp
enemy_type_pumpkin#ein verrückter Kürbis
enemy_type_witch#eine Hexe
enemy_type_witch_red#eine rote Hexe
enemy_type_cauldron#ein großer Kessel
enemy_type_bubble#eine Blase
enemy_type_boss_butcher#der Schweinemetzger
enemy_type_boss_slime_giant#der Gigantische Schleim
enemy_type_boss_cyclops#der Steinzyklop
enemy_type_boss_rat_king#der Werrattenkönig
enemy_type_boss_spider_giant#die Gigantische Spinne
enemy_type_green_rat#eine grüne Ratte
enemy_type_rock_falling#ein fallender Fels
enemy_type_rock_missile#ein geworfener Fels
enemy_type_spider_egg#ein fallendes Spinnenei
enemy_type_spider_little#eine Spinne
enemy_type_spider_web#ein Spinnennetz
enemy_type_ghost#ein Geist
enemy_type_zombie#ein Zombie
enemy_type_zombie_dark#ein dunkler Zombie
enemy_type_francky#das Ding
enemy_type_himself#selbst
source_explosion#Explosion
source_poison#Gift
enemy_francky#Das Ding
enemy_francky_head#Ding's Kopf
item_apple_green#Grüner Apfel
item_apple_green_desc#Regeneriert 3 TP und heilt Vergiftungen
item_manual_slime#Handbuch der Schleimbeherrschung
item_manual_slime_desc#Schleime zielen nicht mehr auf dich
item_spell_dual_quick#Zauberbuch der schnellen Doppelschüsse
item_spell_dual_quick_desc#Schießt zwei Schüsse (schnell)
item_spell_triple_quick#Zauberbuch der schnellen Dreifachschüsse
item_spell_triple_quick_desc#Schießt drei Schüsse (schnell)
item_manual_health#Gesundheitshandbuch
item_manual_health_desc#Gesunde Gegenstände bringen mehr TP
item_rear_shot#Mitarbeiter Kappe
item_rear_shot_desc#Schießt einen Rückwärtsschuss
item_book_random_shot#Zauberbuch der Zufallschüsse
item_book_random_shot_desc#Schießt einen Schuss in eine zufällige Richtung
item_spell_web#Zauber: Spinnennetz
item_spell_web_desc#Zaubere um ein Spinnennetz zu werfen
item_book_magic_i#Zauberbuch - Wälzer I
item_book_magic_i_desc#Verringert die Abklingzeit der Zauber
item_book_magic_ii#Zauberbuch - Wälzer II
item_book_magic_ii_desc#Erhöht die Kraft der Zauber
item_sulfur#Schwefel
item_sulfur_desc#Kann Leichen zum Explodieren bringen
spell_web#Spinnennetz
tuto_reset#Tutorial zurücksetzen
tuto_reset_desc#Setzt das Tutorial zurück
msg_francky_0#Das... Ding
msg_francky_1#Ihh... Es sieht aus als wäre es aus verschiedenen Körperteilen gemacht !
msg_tuto_tips_0#Tutorial: Tipps
msg_tuto_tips_1#Benutze die Zeitkontrolle (Standard: RShift) um schneller zu reisen.
msg_tuto_tips_2#Drücke [Enter] um Nachrichtenboxen sofort zu schließen.
menu_continue#Fortfahren
menu_continue_desc#Mit dem Spiel fortfahren
menu_save_quit#Speichern und beenden
menu_save_quit_desc#Speichern und zum Hauptbildschirm zurückkehren
menu_quit#Beenden ohne speichern
menu_quit_desc#Zum Hauptbildschirm zurückkehren ohne speichern
inventory#Inventar
dc_certificate#Todeszertifikat
dc_killed_by#Getötet hat dich
dc_died_level#Gestorben auf Level
dc_after#nach
dc_minutes#Min. vom Spiel
dc_killed_monsters#Besiegte Monster
dc_gold#Gold
dc_challenges#Abgeschlossene Herausforderungen
player_name#Spielername
player_name_desc#Ändere den Spielernamen
hi_scores#Ruhmeshalle
hi_scores_desc#Highscores
credits#Credits
credits_desc#Credits Bildschirm
volume_sound#Sound Lautstärke
volume_sound_desc#Benutze die linke und rechte Pfeiltaste um die Lautstärke zu regeln
volume_music#Musik Lautstärke
certificate_capture#Drücke [F1] um das Zertifikat als PNG Bild zu speichern
certificate_saved#Speicher auf
msg_tuto_temple_0#Tutorial: Tempel
msg_tuto_temple_1#Der Tempel ist der Ort, wo man zu einem Gott beten oder spenden kann.
msg_tuto_temple_2#Götter können dir helfen und Boni vergeben.
key_interact#interagiere
interact_worship#Anbetung
interact_shop#Kaufe
interact_donate#Spende 10 Gold
interact_donate_fail#(nicht genug Gold)
worshipping#Du bist nun ein Anbeter von
divinity_healer_0#Pomonos der Rechte
divinity_healer_1#Wächter des Rechts und Schutzpatron der Armen.
divinity_healer_2#Er würdigt Spenden, Leid und den Kampf gegen das Böse.
divinity_fighter_0#Tello der Starke
divinity_fighter_1#Gebieter der Kämpfer und der Starken.
divinity_fighter_2#Er würdigt im Kampf gefallene Monster und Titanen.
divinity_ice_0#Mister Schnee
divinity_ice_1#Gott der Kälte.
divinity_ice_2#Er würdigt den Einsatz von Eis.
divinity_stone_0#Gaya
divinity_stone_1#Gott des Gesteines und der Erde.
divinity_stone_2#Er würdigt den Einsatz von Gestein.
divinity_intervention_0#Göttliche Intervention
divinity_intervention_1#schreitet zu deinem Gunsten ein.
divinity_gift_0#Göttliche Gabe
divinity_gift_1#gewährt dir ein Geschenk.
item_floor_map#Verlieskarte
item_floor_map_desc#Offenbart die Karte der derzeitigen Etage
item_alcohol#Absinth
item_alcohol_desc#erhöht vorübergehend den Schaden
[spanish]
start_new_game#Empezar nueva partida
start_desc#La partida anterior se perderá
restore#Restaurar partida
at#en
level#nivel
begin_journey#Comienza tu aventura en un nuevo calabozo
config_keys#Configurar teclas
redef_input#Redefinir controles del jugador
exit_game#Salir del juego
return_to_desktop#Volver al escritorio
key_configuration#Configuración de teclas
key_configuration_desc#Por favor configure las teclas
key_configuration_insert#[presione tecla]
key_configuration_done#LISTO
key_move_up#moverse arriba
key_move_down#moverse abajo
key_move_left#moverse a la izquierda
key_move_right#moverse a la derecha
key_fire_up#disparar arriba
key_fire_down#disparar abajo
key_fire_left#disparar a la izquierda
key_fire_right#disparar a la derecha
key_fire_select#seleccionar disparo
key_time#control del tiempo
key_fire#disparo (un botón)
configure_game#Configuración
configure_game_desc#Cambia las opciones del juego
config_back#Volver
config_back_desc#Volver al menú principal
config_lang#Idioma
config_lang_desc#Elije usando las teclas izquierda y derecha
english#Inglés
french#Francés
german#Alemán
spanish#Español
russian#Ruso
keys_move#mover
keys_fire#disparar
keys_select_1#disparo
keys_select_2#selector
keys_time#control de tiempo
key_spell#invocar un conjuro
play_again#Presiona [ENTER] para jugar de nuevo / [ESC] para volver al menú
items_found#Items
monsters_killed#Monstruos
congratulations_1#FELICIDADES !
congratulations_2#Te haz enfrentado a este demo y has derrotado a los jefes!
congratulations_3#Nos veremos luego en una nueva aventura !
by#por
critical#CRÍTICO X2
poison#VENENO
merchant_speech_0#¡Los mejores precios de todo el calabozo!
merchant_speech_1#¡Bienvenido a la tienda Pawn'n'Witches!
merchant_speech_2#¡Echa una mirada a nuestra mercancía!
enemy_butcher#Cerdo Carnicero
enemy_giant_slime#Baba Gigante
enemy_cyclops#Cíclope de piedra
enemy_rat_king#Hombre Rata Rey
enemy_giant_spider#Araña gigante
item_copper#Moneda de cobre
item_copper_desc#Una moneda de cobre (valor 1)
item_silver#Moneda de plata
item_silver_desc#Una moneda de plata (valor 5)
item_gold#Moneda de oro
item_gold_desc#Una moneda de oro (valor 10)
item_titan_heart#Corazón de Titán
item_titan_heart_desc#Incrementa PV máximos
item_elven_cookie#Galleta Elven
item_elven_cookie_desc#Restaura y aumenta PV máximos
item_apple#Manzana
item_apple_desc#Restaura 3 PV
item_bread#Pan
item_bread_desc#Restaura 7 PV
item_cheese#Queso
item_cheese_desc#Restaura 15 PV
item_boss_key#Llave del jefe
item_boss_key_desc#Abre la puerta del jefe
item_sorcerer_hat#Sombrero del hechicero
item_sorcerer_hat_desc#Aumenta velocidad de disparo
item_velvet_boots#Botas de terciopelo
item_velvet_boots_desc#Aumenta la velocidad
item_spell_dual#Conjuro : Rayo doble
item_spell_dual_desc#Dispara dos rayos
item_rage_amulet#Amuleto de furia
item_rage_amulet_desc#Contraataca
item_displacement_gloves#Guantes de desplazamiento
item_displacement_gloves_desc#La velocidad del jugador afecta la velocidad del proyectil
item_staff#Báculo Ébano
item_staff_desc#Aumenta la velocidad y el daño del rayo
item_fairy#Hada Lilly
item_fairy_desc#Te ayuda en el calabozo
item_leather_belt#Cinturón de cuero
item_leather_belt_desc#Aumenta la velocidad de disparo
item_blood_snake#Serpiente de sangre
item_blood_snake_desc#Aumenta el daño
item_gem_ice#Gema de hielo
item_gem_ice_desc#Ataque de hielo (congelar)
item_gem_illusion#Gema de ilusión
item_gem_illusion_desc#Ataque de ilusión (ignora paredes y armaduras)
item_gem_stone#Gema de piedra
item_gem_stone_desc#Ataque de piedra (repeler)
item_gem_lightning#Gema de trueno
item_gem_lightning_desc#Ataque de trueno (rebote)
item_fairy_ice#Hada Natasha
item_fairy_ice_desc#Te ayuda en el calabozo
item_ring_ice#Anillo de safiro
item_ring_ice_desc#Aumenta el poder del hielo
item_ring_stone#Anillo de cuarso
item_ring_stone_desc#Aumenta el poder de la piedra
item_ring_lightning#Anillo de amatista
item_ring_lightning_desc#Aumenta el poder del trueno
item_ring_illusion#Anillo de obsidiana
item_ring_illusion_desc#Aumenta el poder de la ilusión
item_spell_triple#Conjuro : Rayo triple
item_spell_triple_desc#Dispara tres rayos
item_brooch_finesse#Barba falsa de archimago
item_brooch_finesse_desc#Probabilidad de disparo crítico (x2)
item_fairy_fire#Hada Alicia
item_fairy_fire_desc#Te ayuda en el calabozo
item_fairy_target#Hada Scarlett
item_fairy_target_desc#Te ayuda en el calabozo
item_robe_magician#Bata del Mago
item_robe_magician_desc#Aumenta armadura
item_gem_fire#Gema de fuego
item_gem_fire_desc#Ataque de fuego (más daño)
item_ring_fire#Anillo de rubí
item_ring_fire_desc#Aumenta el poder del fuego
item_manual_staff#Manual del báculo
item_manual_staff_desc#Aumenta rango de disparo
item_spell_teleport#Conjuro: Teletransportación
item_spell_teleport_desc#Invoca teletransportarse dentro de la habitación
item_spell_slime_explode#Conjuro: Invocar baba
item_spell_slime_explode_desc#Invoca una baba explosiva
spell_teleport#Teletransportación
spell_slime_explode#Invocar baba
spell_fireball#bola de fuego
spell_freeze#congelar monstruos
spell_earthquake#terremoto
spell_protection#escudo mágico
item_spell_fireball#Conjuro: Bola de fuego
item_spell_fireball_desc#Invocar para lanzar una bola de fuego
item_spell_freeze#Conjuro: Congelar monstruos.
item_spell_freeze_desc#Invocar para congelar a los monstruos.
item_spell_earthquake#Conjuro: Terremoto
item_spell_earthquake_desc#Invocar para hacer que el calabozo tiemble
item_spell_protection#Conjuro: Escudo mágico
item_spell_protection_desc#Invocar para crear un escudo mágico
msg_level1_0#Tu expedición comienza!
msg_level1_1#"Brujos han abducido a la hija del Archimago y la han llevado a la guarida.
msg_level1_2#Yo debo rescatarla!"
msg_level2_0#La hija del Archimago
msg_level2_1#"¡Voy ahora mismo a rescatarte!
msg_level2_2#Esperemos que ella esté sana y salva..."
msg_level3_0#La hija del Archimago
msg_level3_1#"¿No te lo he contado?
msg_level3_2#La hija del Archimago es la mujer más dulce de la Academia de Magia!"
msg_level4_0#El Archimago
msg_level4_1#"El Archimago es un hombre muy sabio, y además es mi mentor.
msg_level4_2#Él me ha enseñado que vivimos en lo mejor del mundo."
msg_level5_0#La hija del Archimago
msg_level5_1#"Recuerdo a la hija del Archimago conmigo, de vuelta en la Academia de Magia.
msg_level5_2#Solíamos jugar cerca del mago sanador."
msg_level6_0#El Archimago
msg_level6_1#"Mis padres fallecieron cuando yo era un bebé.
msg_level6_2#El Archimago me crió como si fuera su propio hijo."
msg_rats_bats_0#Monstruos
msg_rats_bats_1#"¡Oye! ¿Por qué siempre tenemos que matar ratas
msg_rats_bats_2#o murciélagos en estos juegos tipo Rogue?"
msg_snakes_0#Serpientes
msg_snakes_1#"ODIO a las serpientes!"
msg_witches_0#Brujas
msg_witches_1#"Pu... Brujas !!!"
msg_gold_0#Oro
msg_gold_1#"♫ Money money money ♫
msg_gold_2#Me pregunto si puedo comprar cosas útiles en este calabozo..."
msg_familiar_0#Hadas
msg_familiar_1#"¡Oh, tengo compañía!
msg_familiar_2#Ojalá encuentre a más aliados en este calabozo."
msg_butcher_0#El Cerdo Carnicero
msg_butcher_1#"¡Wow, este tipo si que es grandote!
msg_butcher_2#Espero no terminar hecho salchichas..."
msg_giant_slime_0#La Baba Gigante
msg_giant_slime_1#"Soy verde, grande y apesto.
msg_giant_slime_2#¿Qué soy?"
msg_cyclops_0#El Cíclope de piedra
msg_cyclops_1#"¿Cómo se pudo meter en la habitación?
msg_cyclops_2#¡Es más grande que la puerta!"
msg_wererat_0#El Hombre Rata
msg_wererat_1#"Se parece a mi vieja tía..."
msg_giant_spider_before_0#La habitación vacía
msg_giant_spider_before_1#"¿Hay alguien ahí? "
msg_giant_spider_after_0#La Araña Gigante
msg_giant_spider_after_1#"ODIO a las arañas"
msg_tuto_intro_0#Tutorial: Cosas básicas
msg_tuto_intro_1#Usa WASD (por defecto) para moverse dentr del calabozo.
msg_tuto_intro_2#Dispara usando las flechas (por defecto).
msg_tuto_items_0#Tutorial: Ítems
msg_tuto_items_1#Ítems mejoran a tu personaje o te dan nuevos poderes.
msg_tuto_items_2#Encuentra o compra la mayor cantidad que puedas.
msg_tuto_heal_0#Tutorial: Puntos de vida
msg_tuto_heal_1#Haz perdido algunos puntos de vida.
msg_tuto_heal_2#Encuentra algo para curarte antes de que mueras.
msg_tuto_shops_0#Tutorial: Tiendas
msg_tuto_shops_1#Puedes encontrar varias tiendas en el calabozo.
msg_tuto_shops_2#Aquí puedes gastar dinero para comprar ítems o comida.
msg_tuto_boss_door_0#Tutorial: Puerta del Jefe
msg_tuto_boss_door_1#Desde aquí puedes ver la puerta dorada cerrada.
msg_tuto_boss_door_2#Esa es la habitación del jefe, pero necesitas la llave dorada para entrar.
msg_tuto_challenge_door_0#Tutorial: Habitación de Desafíos
msg_tuto_challenge_door_1#Mira la puerta decorada. Es una habitación de desafíos.
msg_tuto_challenge_door_2#Puedes obtener buenas recompenzas ahí, ¡Pero entra con precaución!
msg_tuto_shots_0#Tutorial: Tipos de disparo
msg_tuto_shots_1#Haz encontrado un nuevo tipo de disparo.
msg_tuto_shots_2#Presiona la tecla de seleccionar disparos (por defecto: Tab) para cambiar entre tipos de disparo.
msg_tuto_spell_0#Tutorial: Conjuros
msg_tuto_spell_1#Haz encontrado un conjuro mágico.
msg_tuto_spell_2#Presiona la tecla de conjuros (por defecto: Espacio) para realizar el conjuro.
enemy_type_bat#un murciélago
enemy_type_rat#una rata
enemy_type_rat_black#una rata negra
enemy_type_rat_helmet#una rata con casco
enemy_type_rat_black_helmet#una rata negra con casco
enemy_type_evil_flower#una flor malvada
enemy_type_evil_flower_ice#una flor de las nieves malvada
enemy_type_snake#una serpiente
enemy_type_snake_blood#una serpiente ensangrentada
enemy_type_slime#una baba
enemy_type_slime_red#una baba roja
enemy_type_slime_blue#una baba azul
enemy_type_slime_violet#una baba violeta
enemy_type_imp_blue#un diablillo azul
enemy_type_imp_red#un diablillo rojo
enemy_type_pumpkin#una calabaza loca
enemy_type_witch#una bruja
enemy_type_witch_red#una bruja roja
enemy_type_cauldron#un caldero
enemy_type_bubble#una burbuja
enemy_type_boss_butcher#el Cerdo Carnicero
enemy_type_boss_slime_giant#la Baba Gigante
enemy_type_boss_cyclops#el Cíclope de piedra.
enemy_type_boss_rat_king#el Rey Hombre-Rata
enemy_type_boss_spider_giant#la Araña Gigante
enemy_type_green_rat#una rata verde
enemy_type_rock_falling#una roca cayendo
enemy_type_rock_missile#una roca lanzable
enemy_type_spider_egg#un huevo de araña cayendo
enemy_type_spider_little#una araña
enemy_type_spider_web#una tela-araña
enemy_type_ghost#un fantasma
enemy_type_zombie#un zombie
enemy_type_zombie_dark#un zombie oscuro
enemy_type_francky#la Cosa
enemy_type_himself#él mismo
source_explosion#explosión
source_poison#veneno
enemy_francky#La Cosa
enemy_francky_head#La cabeza de La Cosa
item_apple_green#Manzana verde
item_apple_green_desc#Restaura 3 PV y cura el veneno
item_manual_slime#Manual de Maestría de Baba
item_manual_slime_desc#Las babas ya no te atacan directamente
item_spell_dual_quick#El libro de los rayos rápidos dobles
item_spell_dual_quick_desc#Dispara dos rayos (rápido)
item_spell_triple_quick#El libro de los rayos rápidos triples
item_spell_triple_quick_desc#Dispara tres rayos (rápido)
item_manual_health#Manual de Salud
item_manual_health_desc#Los objetos de salud dan más PV
item_rear_shot#Gorra del váculo
item_rear_shot_desc#Dispara un rayo hacia trás
item_book_random_shot#Libro del disparo al azar
item_book_random_shot_desc#Dispara un rayo en una dirección al azar
item_spell_web#Conjuro: Telaraña
item_spell_web_desc#Invocar para lanzar telarañas
item_book_magic_i#Libro de magia - Tomo I
item_book_magic_i_desc#Disminuye el tiempo de espera de los conjuros
item_book_magic_ii#Libro de magia - Tomo II
item_book_magic_ii_desc#Aumenta el poder de los conjuros
item_sulfur#Sulfuro
item_sulfur_desc#Puede hacer que los cadáveres exploten
spell_web#telaraña
tuto_reset#Resetear tutorial
tuto_reset_desc#Resetea el tutorial
msg_francky_0#La... Cosa
msg_francky_1#Yuck... ¡Parece como si estuviera hecho con partes de distintos cuerpos!
msg_tuto_tips_0#Tutorial: Consejos
msg_tuto_tips_1#Usa el Control del Tiempo (por defecto: RShift) para viajar rápidamente.
msg_tuto_tips_2#Presiona [Enter] para cerrar el cuadro de mensajes inmediatamente.
menu_continue#Continuar
menu_continue_desc#Continúa con el juego
menu_save_quit#Guardar y salir
menu_save_quit_desc#Guarda la partida y se vuelve al menú principal
menu_quit#Salir sin guardar
menu_quit_desc#Vuelve al menú principal sin guardar la partida
inventory#Inventario
dc_certificate#Certificado de defunción
dc_killed_by#Matado por
dc_died_level#Muerto en nivel
dc_after#tras
dc_minutes#mins. de juego
dc_killed_monsters#Monstruos asesinados
dc_gold#Oro
dc_challenges#Desafíos completados
player_name#Nombre del jugador
player_name_desc#Modifica el nombre del jugador
hi_scores#Salón de la fama
hi_scores_desc#Mejores puntajes
credits#Créditos
credits_desc#Pantalla de créditos
volume_sound#Volumen del sonido
volume_sound_desc#Usa las flechas izquierda/derecha para cambiar el volumen
volume_music#Volumen de la música
certificate_capture#Presione [F1] para guardar el certificado en un archivo PNG
certificate_saved#Guardado en
msg_tuto_temple_0#Tutorial: Templo
msg_tuto_temple_1#El templo es el lugar en donde puedes venerar a una divinidad o donar.
msg_tuto_temple_2#Las Divinidades te pueden ayudar y te dan bonificaciones.
key_interact#interactuar
interact_worship#Venerar
interact_shop#Comprar
interact_donate#Donar 10 de oro
interact_donate_fail#(no hay suficiente oro)
worshipping#Ahora eres un venerador de
divinity_healer_0#Pomonos el Honrado
divinity_healer_1#Guardián de la honradez and patrocinador de los débiles.
divinity_healer_2#Él aprecia las donaciones, el sufrimiento y la lucha contra el mal.
divinity_fighter_0#Tello el Poderoso
divinity_fighter_1#Señor de los guerreros y los fuertes.
divinity_fighter_2#Él aprecia monstruos y titanes cayendo en la batalla.
divinity_ice_0#Señor Nieve
divinity_ice_1#Divinidad de la frialdad.
divinity_ice_2#Él aprecia el uso del hielo.
divinity_stone_0#Gaya
divinity_stone_1#Divinidad de la piedra y de la tierra.
divinity_stone_2#Él aprecia el uso de la piedra.
divinity_intervention_0#Intervención divina.
divinity_intervention_1#interviene a tu favor.
divinity_gift_0#Regalo divino.
divinity_gift_1#te concede un regalo.
item_floor_map#Mapa del calabozo
item_floor_map_desc#Revela el mapa del piso actual.
item_alcohol#Absenta
item_alcohol_desc#aumenta los daños temporalmente.
[russian]
start_new_game#Начать новую игру
start_desc#Старая игра будет стёрта
restore#Продолжить игру
at#в
level#Уровень
begin_journey#Начните ваше приключение в новом подземелье
config_keys#Настройка управления
redef_input#Сконфигурируйте управление игры
exit_game#Выход из игры
return_to_desktop#Выйти в ОС
key_configuration#Конфигурация клавиш
key_configuration_desc#Пожалуйста, задайте управление
key_configuration_insert#[нажмите клавишу]
key_configuration_done#ГОТОВО
key_move_up#Движение вверх
key_move_down#Движение вниз
key_move_left#Движение влево
key_move_right#Движение вправо
key_fire_up#Выстрел вверх
key_fire_down#Выстрел вниз
key_fire_left#Выстрел влево
key_fire_right#Выстрел вправо
key_fire_select#Выбор оружия
key_time#Ускорение времени
key_fire#Выстрел в направлении движения
key_spell#Произнести заклинание
configure_game#Конфигурация
configure_game_desc#Изменение параметров игры
config_back#Назад
config_back_desc#Назад в главное меню
config_lang#Язык
config_lang_desc#Выберите с помощью клавиш влево и вправо
russian#Русский
keys_move#движение
keys_fire#выстрел
keys_select_1#выбор
keys_select_2#оружия
keys_time#ускорение
play_again#Нажмите [ENTER] чтобы сыграть снова / [ESC] чтобы выйти в меню
items_found#Предметы
monsters_killed#Монстры
congratulations_1#ПОЗДРАВЛЯЕМ !
congratulations_2#Вы прошли демо и победили всех боссов !
congratulations_3#Скоро увидимся с новыми приключениями !
by#
critical#КРИТИЧЕСКИЙ УДАР X2
poison#ЯД
merchant_speech_0#Лучшие цены во всем подземелье!
merchant_speech_1#Добро пожаловать в магазин "Ведьмы и пешки"!
merchant_speech_2#Да вы только взгляните на наш товар!
enemy_butcher#Свин-мясник
enemy_giant_slime#Гигантский слизень
enemy_cyclops#Каменный циклоп
enemy_rat_king#Король веркрыс
enemy_giant_spider#Гигантский паук
item_copper#Медная монета
item_copper_desc#Медная монета (ценность 1)
item_silver#Серебряная монета
item_silver_desc#Серебряная монета (ценность 5)
item_gold#Золотая монета
item_gold_desc#Золотая монета (ценность 10)
item_titan_heart#Сердце титана
item_titan_heart_desc#Увеличивает максимальный уровень HP
item_elven_cookie#Печенье эльфов
item_elven_cookie_desc#Восстанавливает HP и увеличивает его максимальный уровень
item_apple#Яблоко
item_apple_desc#Восстанавливает 3 HP
item_bread#Хлеб
item_bread_desc#Восстанавливает 7 HP
item_cheese#Сыр
item_cheese_desc#Восстанавливает 15 HP
item_boss_key#Ключ Босса
item_boss_key_desc#Открывает врата в комнату Босса
item_sorcerer_hat#Шляпа мага
item_sorcerer_hat_desc#Увеличивает скорость стрельбы
item_velvet_boots#Бархатные сапоги
item_velvet_boots_desc#Увеличивает скорость
item_spell_dual#Заклинание : Двойной выстрел
item_spell_dual_desc#Позволяет стрелять двойным снарядом
item_rage_amulet#Амулет ярости
item_rage_amulet_desc#Месть
item_displacement_gloves#Перчатки перемещения
item_displacement_gloves_desc#Скорость персонажа влияет на скорость снарядов
item_staff#Эбонитовый посох
item_staff_desc#Увеличивает скорость снаряда и урон
item_fairy#Фея Лилли
item_fairy_desc#Помогает вам в подземелье
item_leather_belt#Кожаный ремень
item_leather_belt_desc#Увеличивает скорость стрельбы
item_blood_snake#Кровавый змей
item_blood_snake_desc#Увеличивает урон
item_gem_ice#Лёд
item_gem_ice_desc#Ледяная атака (заморозка)
item_gem_illusion#Камень иллюзий
item_gem_illusion_desc#Иллюзтонная атака (Игнорирует стены и броню)
item_gem_stone#Камень
item_gem_stone_desc#Каменная атака (отброс)
item_gem_lightning#Камень молний
item_gem_lightning_desc#Атака молний (отражение)
item_fairy_ice#Фея Наташа
item_fairy_ice_desc#Помогает вам в подземелье
item_ring_ice#Кольцо с сапфиром
item_ring_ice_desc#Увеличивает силу льда
item_ring_stone#Кольцо с кварцем
item_ring_stone_desc#Увеличивает силу камня
item_ring_lightning#Кольцо с аметистом
item_ring_lightning_desc#Увеличивает силу молний
item_ring_illusion#Кольцо с обсидианом
item_ring_illusion_desc#Увеличивает силу иллюзий
item_spell_triple#Заклинание : Тройной выстрел
item_spell_triple_desc#Позволяет стрелять тройным снарядом
item_brooch_finesse#Фальшивая борода архимага
item_brooch_finesse_desc#Шанс критического попадания (x2)
item_fairy_fire#Фея Алиса
item_fairy_fire_desc#Помогает вам в подземелье
item_fairy_target#Фея Скарлет
item_fairy_target_desc#Помогает вам в подземелье
item_robe_magician#Роба волшебника
item_robe_magician_desc#Увеличивает броню
item_gem_fire#Камень огня
item_gem_fire_desc#Атака огня (увеличенный урон)
item_ring_fire#Кольцо с рубином
item_ring_fire_desc#Увеличивает силу огня
item_manual_staff#Руководство к посоху
item_manual_staff_desc#Увеличивает дальность стрельбы
item_spell_teleport#Заклинание: Телепорт
item_spell_teleport_desc#Произнесите, чтобы телепортироваться в любое место комнаты
item_spell_slime_explode#Spell: Призыв слизня
item_spell_slime_explode_desc#Произнесите, чтобы призвать взрывного слизня
item_spell_fireball#Заклинание: Огненный шар
item_spell_fireball_desc#Произнесите, чтобы вызвать огненный шар
item_spell_freeze#Заклинание: Заморозка монстров
item_spell_freeze_desc#Произнесите, чтобы заморозить монстров
item_spell_earthquake#Заклинание: землетрясение
item_spell_earthquake_desc#Произнесите, чтобы сотрясти все подземелье
item_spell_protection#Заклинание: Магический щит
item_spell_protection_desc#Произнесите, чтобы призвать магический щит
spell_teleport#Телепорт
spell_slime_explode#Призвать слизня
spell_fireball#огненный шар
spell_freeze#заморозка монстров
spell_earthquake#землетрясение
spell_protection#магический щит
msg_level1_0#Ваше приключение началось!
msg_level1_1#"Ведьмы похитили дочь архимага и утащили ее в свое логово.
msg_level1_2#Мне нужно ее вернуть!"
msg_level2_0#Дочь архимага
msg_level2_1#"Я пришел чтобы спасти тебя!
msg_level2_2#Надеюсь, она жива..."
msg_level3_0#Дочь архимага
msg_level3_1#"Я когда-нибудь рассказывал тебе?
msg_level3_2#Дочь архимага - приятнейшая девушка во всей магической академии!"
msg_level4_0#Архимаг
msg_level4_1#"Архимаг - очень мудрый человек... А так же мой наставник.
msg_level4_2#Он показал мне, что мы живем в лучшем из миров."
msg_level5_0#Дочь архимага
msg_level5_1#"Я помню нас с дочерью архимага в магической академии.
msg_level5_2#Мы игрались с магией лечения, хи-хи !"
msg_level6_0#Архимаг
msg_level6_1#"Мои родители погибли, когда я был совсем крохой.
msg_level6_2#И архимаг растил меня как своего собственного сына."
msg_rats_bats_0#Монстры
msg_rats_bats_1#"Эй! Почему мы постоянно должны истреблять крыс и летучих мышей
msg_rats_bats_2#в рогаликах ?"
msg_snakes_0#Змеи
msg_snakes_1#"Я НЕНАВИЖУ ЗМЕЙ!"
msg_witches_0#Ведьмы
msg_witches_1#"Бл... Ведьмы !!!"
msg_gold_0#Золото
msg_gold_1#"♫ Money money money ♫
msg_gold_2#Я удивлюсь, если смогу купить хоть что-то полезное в этом подземелье..."
msg_familiar_0#Феи
msg_familiar_1#"Ох! Наконец-то я буду не один!
msg_familiar_2#Надеюсь, мне удастся найти больше союзников в этом подземелье."
msg_butcher_0#Свиночел-мясник
msg_butcher_1#"Эй, смотри какой здоровяк!
msg_butcher_2#Надеюсь, удастся порубить его на колбасу..."
msg_giant_slime_0#Гигантский слизень
msg_giant_slime_1#"Я зеленый, большой... И я воняю.
msg_giant_slime_2#Что же я такое?"
msg_cyclops_0#Каменный циклоп
msg_cyclops_1#"Как он прошел в комнату?
msg_cyclops_2#Он же гораздо больше двери!"
msg_wererat_0#Король веркрыс
msg_wererat_1#"Выглядит как моя старая тетка..."
msg_giant_spider_before_0#Пустая комната
msg_giant_spider_before_1#"Здесь есть кто-нибудь? "
msg_giant_spider_after_0#Гигантский паук
msg_giant_spider_after_1#"Я НЕНАВИЖУ ПАУКОВ"
msg_tuto_intro_0#Обучение: Основы
msg_tuto_intro_1#Используйте WASD (по умолчанию) для перемещения по подземелью.
msg_tuto_intro_2#Стреляйте клавишами со стрелочками (по умолчанию).
msg_tuto_items_0#Обучение: Предметы
msg_tuto_items_1#Предметы предоставляют вашему персонажу больше возможностей.
msg_tuto_items_2#Найдите или купите столько, сколько сможете.
msg_tuto_heal_0#Обучение: Здоровье
msg_tuto_heal_1#Вы потеряли немного очков здоровья.
msg_tuto_heal_2#Найдите способ вылечиться до того, как умрете.
msg_tuto_shops_0#Обучение: Магазины
msg_tuto_shops_1#Вы можете найти множество магазинов в подземелье.
msg_tuto_shops_2#В магазине вы сможете купить предметы или еду.
msg_tuto_boss_door_0#Обучение: Врата босса
msg_tuto_boss_door_1#Здесь вы видите закрытую золотую дверь.
msg_tuto_boss_door_2#За ней находится босс этого этажа, но вам нужен ключ, чтобы попасть внутрь.
msg_tuto_challenge_door_0#Обучение: Поле битвы
msg_tuto_challenge_door_1#Посмотрите на эту красивую дверь. За ней находится поле битвы
msg_tuto_challenge_door_2#Вы можете найти там ценную награду. Но входите с осторожностью!
msg_tuto_shots_0#Обучение: Типы выстрелов
msg_tuto_shots_1#Вы нашли новвое оружие.
msg_tuto_shots_2#Нажмите [выбор оружия] (по умолчанию: tab) чтобы переключаться между различными оружиями.
msg_tuto_spell_0#Обучение: Заклинания
msg_tuto_spell_1#Вы нашли магическое заклинание.
msg_tuto_spell_2#Нажмите на клавишу заклинания (по умолчанию: space) чтобы произнести его.
enemy_type_bat#летучей мышью
enemy_type_rat#крысой
enemy_type_rat_black#черной крысой
enemy_type_rat_helmet#крысой в шлеме
enemy_type_rat_black_helmet#черной крысой в шлеме
enemy_type_evil_flower#цветком зла
enemy_type_evil_flower_ice#эдельвейсом зла
enemy_type_snake#змеей
enemy_type_snake_blood#змеей крови
enemy_type_slime#слизнем
enemy_type_slime_red#красным слизнем
enemy_type_slime_blue#синим слизнем
enemy_type_slime_violet#фиолетовым слизнем
enemy_type_imp_blue#синим чертом
enemy_type_imp_red#красным чертом
enemy_type_pumpkin#сумасшедшей тыквой
enemy_type_witch#ведьмой
enemy_type_witch_red#красной ведьмой
enemy_type_cauldron#котлом
enemy_type_bubble#пузырем
enemy_type_boss_butcher#Свином-мясником
enemy_type_boss_slime_giant#Гигантским слизнем
enemy_type_boss_cyclops#каменным циклопом
enemy_type_boss_rat_king#Королем веркрысом
enemy_type_boss_spider_giant#Гигантским пауком
enemy_type_green_rat#зеленой крысой
enemy_type_rock_falling#падающим камнем
enemy_type_rock_missile#летящим камнем
enemy_type_spider_egg#упавшим паучьм яйцом
enemy_type_spider_little#пауком
enemy_type_spider_web#паучьей сетью
enemy_type_ghost#призраком
enemy_type_zombie#зомби
enemy_type_zombie_dark#темным зомби
enemy_type_francky#нечто
enemy_type_himself#по глупости
source_explosion#взрывом
source_poison#ядом
enemy_francky#Нечто
enemy_francky_head#Голова нечто
item_apple_green#Зеленое яблоко
item_apple_green_desc#Восстанавливает 3 HP и исцеляет яд
item_manual_slime#Руководство мастера слизней
item_manual_slime_desc#Слизни больше не охотятся на вас
item_spell_dual_quick#Книга быстрого двойного выстрела
item_spell_dual_quick_desc#Стреляет двумя снарядами (быстро)
item_spell_triple_quick#Книга быстрого тройного выстрела
item_spell_triple_quick_desc#Стреляет тремя снарядами (быстро)
item_manual_health#Руководство здоровья
item_manual_health_desc#Увеличенное лечение предметами
item_rear_shot#Наконечник для посоха
item_rear_shot_desc#Выстрел назад
item_book_random_shot#Книга случайного выстрела
item_book_random_shot_desc#Стреляет в случайном направлении
item_spell_web#Заклинание: Паучья сеть
item_spell_web_desc#Произнесите, чтобы метнуть паучьи сети
item_book_magic_i#Книга магии - Том первый
item_book_magic_i_desc#Уменьшает время восстановления заклинаний
item_book_magic_ii#Книга магии - Том второй
item_book_magic_ii_desc#Увеличивает силу заклинаний
item_sulfur#Сера
item_sulfur_desc#Позволяет взрывать трупы
spell_web#паучья сеть
tuto_reset#Сброс обучения
tuto_reset_desc#Сбрасывает обучение
msg_francky_0#Это.... Нечто...
msg_francky_1#Тьфу... Оно выглядит, слово сделано из нескольких трупов !
msg_tuto_tips_0#Обучение: Подсказки
msg_tuto_tips_1#Используйте управление временем (по умолчанию: RShift)
чтобы путешествовать быстрее.
msg_tuto_tips_2#Нажмите [Enter] чтобы немедленно закрыть окно сообщений.
menu_continue#Продолжить
menu_continue_desc#Продолжить игру
menu_save_quit#Сохранить и выйти
menu_save_quit_desc#Сохранить и вернуться в меню игры
menu_quit#Выход без сохранения
menu_quit_desc#Вернуться в главное меню без сохранения
inventory#Инвентарь
dc_certificate#Свидетельство о смерти
dc_killed_by#Убит
dc_died_level#Умер на уровне
dc_after#после
dc_minutes# минут игры
dc_killed_monsters#Убитые монстры
dc_gold#Золото
dc_challenges#Завершено битв
player_name#Имя игрока
player_name_desc#Изменить имя игрока
hi_scores#Зал славы
hi_scores_desc#Лучшие результаты
credits#Авторы
credits_desc#Список создателей
volume_sound#Громкость звука
volume_sound_desc#Используйте клавиши влево/вправо чтоы изменить громкость
volume_music#Громкость музыки
certificate_capture#Нажмите [F1] чтобы сохранить сертификат в PNG файл
certificate_saved#Сохранено в
msg_tuto_temple_0#Обучение: Храм
msg_tuto_temple_1#Храм - это место поклонения и пожертвования божеству.
msg_tuto_temple_2#Божества могут помочь вам предоставив дополнительную силу.
key_interact#взаимодействовать
interact_worship#Поклониться
interact_shop#Купить
interact_donate#Пожертвовать 10 золотых
interact_donate_fail#(не хватает золота)
worshipping#Теперь ваш покровитель
divinity_healer_0#Помоноса Праведная
divinity_healer_1#Защитница праведных и покровительница слабых.
divinity_healer_2#Она ценит пожертвования, страдания и борьбу со злом.
divinity_fighter_0#Телло Могущественный
divinity_fighter_1#Лорд сражающихся и сильных.
divinity_fighter_2#Он ценит монстров и титанов павших в битве.
divinity_ice_0#Мистер Снег
divinity_ice_1#Божество холода.
divinity_ice_2#Он ценит использование льда.
divinity_stone_0#Гайя
divinity_stone_1#Божество земли и камня.
divinity_stone_2#Он ценит использование камней.
divinity_intervention_0#Божественное вмешательство
divinity_intervention_1#вмешивается в вашу пользу.
divinity_gift_0#Божественный дар
divinity_gift_1#предоставляет вам дар.
item_floor_map#Карта подземелья
item_floor_map_desc#Открывает карту текущего этажа
item_alcohol#Абсент
item_alcohol_desc#временно увеличивает урон
\ No newline at end of file
diff --git a/src/Achievements.h b/src/Achievements.h
index 814881c..37d1160 100644
--- a/src/Achievements.h
+++ b/src/Achievements.h
@@ -1,64 +1,76 @@
#ifndef ACHIEVEMENTS_H
#define ACHIEVEMENTS_H
#include "Constants.h"
#include "Items.h"
/** Achievement type enum
* All the achievements.
*/
enum enumAchievementType
{
AchievementRats,
Achievement100,
AchievementPietyMax,
Achievement3Hits,
AchievementCompleteSet,
-
AchievementGiantSlime,
AchievementCyclops,
AchievementRatKing,
AchievementGiantSpider,
AchievementFrancky,
+ AchievementButcher,
+ AchievementWitches,
+ AchievementEggs,
+ AchievementFairies,
+ AchievementChallenges,
+ AchievementWin,
NB_ACHIEVEMENTS
};
enum enumUnlockType
{
UnlockNothing,
UnlockItem,
UnlockDivinity,
};
/*!
* \brief Item structure
*
* Contains all the data for an item.
*/
struct achievementStuct
{
enumAchievementType id; /**< The achievement's ID */
std::string label; /**< The achievement label */
enumUnlockType unlockType; /**< What the achievement unlocks (type) */
int unlock; /**< What the achievement unlocks */
};
/** Array with all the achievement */
const achievementStuct achievements[NB_ACHIEVEMENTS] =
{
- { AchievementRats, "achiev_rats", UnlockNothing, -1 },
+ { AchievementRats, "achiev_rats", UnlockItem, ItemFairyTarget },
{ Achievement100, "achiev_100", UnlockNothing, -1 },
{ AchievementPietyMax, "achiev_piety_max", UnlockItem, ItemBookPrayerII },
{ Achievement3Hits, "achiev_3_hits", UnlockNothing, -1 },
{ AchievementCompleteSet, "achiev_complete_set", UnlockItem, ItemHatAdvanced},
{ AchievementGiantSlime, "achiev_giant_slime", UnlockItem, ItemPetSlime },
{ AchievementCyclops, "achiev_cyclops", UnlockItem, ItemSpellEarthquake },
{ AchievementRatKing, "achiev_rat_king", UnlockItem, ItemCriticalAdvanced },
{ AchievementGiantSpider, "achiev_giant_spider", UnlockItem, ItemSpellWeb },
{ AchievementFrancky, "achiev_francky", UnlockItem, ItemRobeAdvanced },
+
+ { AchievementButcher, "achiev_butcher", UnlockNothing, -1 },
+ { AchievementWitches, "achiev_witches", UnlockItem, ItemBookMagicII },
+ { AchievementEggs, "achiev_eggs", UnlockNothing, -1 },
+ { AchievementFairies, "achiev_fairies", UnlockItem, ItemSpellFairy },
+ { AchievementChallenges, "achiev_challenges", UnlockNothing, -1 },
+ { AchievementWin, "achiev_win", UnlockNothing, -1 },
};
#endif
diff --git a/src/WitchBlastGame.cpp b/src/WitchBlastGame.cpp
index 5d53dd1..c906a14 100644
--- a/src/WitchBlastGame.cpp
+++ b/src/WitchBlastGame.cpp
@@ -1,5474 +1,5493 @@
/** This file is part of Witch Blast.
*
* Witch Blast is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Witch Blast is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WitchBlastGame.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/TileMapEntity.h"
#include "DungeonMap.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/EntityManager.h"
#include "Constants.h"
#include "RatEntity.h"
#include "BlackRatEntity.h"
#include "GreenRatEntity.h"
#include "KingRatEntity.h"
#include "CyclopsEntity.h"
#include "GiantSpiderEntity.h"
#include "GiantSlimeEntity.h"
#include "ButcherEntity.h"
#include "BatEntity.h"
#include "ImpEntity.h"
#include "SlimeEntity.h"
#include "PumpkinEntity.h"
#include "ChestEntity.h"
#include "EvilFlowerEntity.h"
#include "BubbleEntity.h"
#include "ItemEntity.h"
#include "WitchEntity.h"
#include "CauldronEntity.h"
#include "SnakeEntity.h"
#include "GhostEntity.h"
#include "ZombieEntity.h"
#include "ZombieDarkEntity.h"
#include "LittleSpiderEntity.h"
#include "SpiderEggEntity.h"
#include "FranckyEntity.h"
#include "ArtefactDescriptionEntity.h"
#include "PnjEntity.h"
#include "TextEntity.h"
#include "StandardRoomGenerator.h"
#include "Scoring.h"
#include "MessageGenerator.h"
#include "TextMapper.h"
#include "SlimePetEntity.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <ctime>
#include <algorithm>
//#define START_LEVEL 4
static std::string intToString(int n)
{
std::ostringstream oss;
oss << n;
return oss.str();
}
static std::string keyToString(sf::Keyboard::Key key)
{
std::string s = "Unknown";
if (key >= sf::Keyboard::A && key <= sf::Keyboard::Z)
{
char c = 'A' + key - sf::Keyboard::A;
std::ostringstream oss;
oss << c;
s = oss.str();
}
else if (key >= sf::Keyboard::Num0 && key <= sf::Keyboard::Num9)
{
char c = '0' + key - sf::Keyboard::Num0;
std::ostringstream oss;
oss << c;
s = oss.str();
}
else if (key >= sf::Keyboard::Numpad0 && key <= sf::Keyboard::Numpad9)
{
char c = '0' + key - sf::Keyboard::Num0;
std::ostringstream oss;
oss << c << " (numpad)";
s = oss.str();
}
else if (key >= sf::Keyboard::F1 && key <= sf::Keyboard::F15)
{
std::ostringstream oss;
oss << "F" << (int)key - (int)sf::Keyboard::F1;
s = oss.str();
}
else if (key == sf::Keyboard::Escape) s = "Escape";
else if (key == sf::Keyboard::LControl) s = "Left Control";
else if (key == sf::Keyboard::LShift) s = "Left Shift";
else if (key == sf::Keyboard::LAlt) s = "Left Alt";
else if (key == sf::Keyboard::LSystem) s = "Left System";
else if (key == sf::Keyboard::RControl) s = "Right Control";
else if (key == sf::Keyboard::RShift) s = "Right Shift";
else if (key == sf::Keyboard::RAlt) s = "Right Alt";
else if (key == sf::Keyboard::RSystem) s = "Right System";
else if (key == sf::Keyboard::Space) s = "Space";
else if (key == sf::Keyboard::Tab) s = "Tab";
else if (key == sf::Keyboard::Left) s = "Left arrow";
else if (key == sf::Keyboard::Right) s = "Right arrow";
else if (key == sf::Keyboard::Up) s = "Up arrow";
else if (key == sf::Keyboard::Down) s = "Down arrow";
else if (key == sf::Keyboard::LBracket) s = "[";
else if (key == sf::Keyboard::RBracket) s = "]";
else if (key == sf::Keyboard::SemiColon) s = ";";
else if (key == sf::Keyboard::Comma) s = ",";
else if (key == sf::Keyboard::Period) s = ".";
else if (key == sf::Keyboard::Quote) s = "Quote";
else if (key == sf::Keyboard::Slash) s = "/";
else if (key == sf::Keyboard::BackSlash) s = "\\";
else if (key == sf::Keyboard::Tilde) s = "~";
else if (key == sf::Keyboard::Equal) s = "=";
else if (key == sf::Keyboard::Dash) s = "_";
else if (key == sf::Keyboard::Return) s = "Return";
else if (key == sf::Keyboard::BackSpace) s = "BackSpace";
else if (key == sf::Keyboard::PageUp) s = "Page Up";
else if (key == sf::Keyboard::PageDown) s = "Page Down";
else if (key == sf::Keyboard::End) s = "End";
else if (key == sf::Keyboard::Home) s = "Home";
else if (key == sf::Keyboard::Insert) s = "Insert";
else if (key == sf::Keyboard::Delete) s = "Delete";
else if (key == sf::Keyboard::Add) s = "+";
else if (key == sf::Keyboard::Subtract) s = "-";
else if (key == sf::Keyboard::Multiply) s = "*";
else if (key == sf::Keyboard::Divide) s = "/";
else if (key == sf::Keyboard::Pause) s = "Pause";
else if (key == sf::Keyboard::KeyCount) s = "Key Count";
return s;
}
std::map<EnumWorldEvents, EnumMessages> eventToMessage =
{
{ EventMeetRatsOrBats, MsgInfoRatsBats },
{ EventMeetSnakes, MsgInfoSnakes },
{ EventMeetWitches, MsgInfoWitches },
{ EventGetCoin, MsgInfoGold },
{ EventGetFamiliar, MsgInfoFamiliar },
{ EventBeingHurted, MsgTutoHeal },
{ EventFindShop, MsgTutoShops },
{ EventFindBossDoor, MsgTutoBossDoor },
{ EventFindChallengeDoor, MsgTutoChallengeDoor },
{ EventFindTemple, MsgTutoTemple },
{ EventGetItem, MsgTutoItems },
{ EventGetSpecialShot, MsgTutoShots },
{ EventGetSpell, MsgTutoSpell },
};
// author: AFS
// source: https://github.com/LaurentGomila/SFML/wiki/Source:-Letterbox-effect-using-a-view
static sf::View getLetterboxView(sf::View view, int windowWidth, int windowHeight)
{
// Compares the aspect ratio of the window to the aspect ratio of the view,
// and sets the view's viewport accordingly in order to archieve a letterbox effect.
// A new view (with a new viewport set) is returned.
float windowRatio = windowWidth / (float) windowHeight;
float viewRatio = view.getSize().x / (float) view.getSize().y;
float sizeX = 1;
float sizeY = 1;
float posX = 0;
float posY = 0;
bool horizontalSpacing = true;
if (windowRatio < viewRatio)
horizontalSpacing = false;
// If horizontalSpacing is true, the black bars will appear on the left and right side.
// Otherwise, the black bars will appear on the top and bottom.
if (horizontalSpacing)
{
sizeX = viewRatio / windowRatio;
posX = (1 - sizeX) / 2.0;
}
else
{
sizeY = windowRatio / viewRatio;
posY = (1 - sizeY) / 2.0;
}
view.setViewport( sf::FloatRect(posX, posY, sizeX, sizeY) );
return view;
}
static sf::View getFullScreenLetterboxView(sf::View view, int clientWidth, int clientHeight)
{
sf::View returnView(sf::FloatRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
float clientRatio = clientWidth / (float) clientHeight;
float viewRatio = view.getSize().x / (float) view.getSize().y;
float sizeX = 1;
float sizeY = 1;
float posX = 0;
float posY = 0;
bool horizontalSpacing = true;
if (clientRatio > viewRatio)
horizontalSpacing = false;
// If horizontalSpacing is true, the black bars will appear on the left and right side.
// Otherwise, the black bars will appear on the top and bottom.
if (horizontalSpacing)
{
sizeX = clientRatio / viewRatio;
posX = (1 - sizeX) / 2.0;
}
else
{
sizeY = viewRatio / clientRatio;
posY = (1 - sizeY) / 2.0;
}
returnView.setViewport( sf::FloatRect(posX, posY, sizeX, sizeY) );
return returnView;
}
namespace
{
WitchBlastGame* gameptr;
}
WitchBlastGame::WitchBlastGame()
{
gameptr = this;
configureFromFile();
if (parameters.vsync == false)
{
app->setVerticalSyncEnabled(false);
app->setFramerateLimit(60);
}
// Fullscreen ?
if (parameters.fullscreen)
{
create(SCREEN_WIDTH, SCREEN_HEIGHT, APP_NAME + " V" + APP_VERSION, true);
sf::View view = app->getDefaultView();
view = getFullScreenLetterboxView( view, SCREEN_WIDTH, SCREEN_HEIGHT );
app->setView(view);
}
else
{
create(SCREEN_WIDTH, SCREEN_HEIGHT, APP_NAME + " V" + APP_VERSION);
}
// loading resources
const char *const images[] =
{
"media/player_0.png", "media/player_1.png",
"media/bolt.png", "media/tiles01.png",
"media/rat.png", "media/minimap.png",
"media/map_background.png",
"media/items.png", "media/items_equip.png",
"media/items.png", "media/items_equip.png",
"media/chest.png", "media/bat.png",
"media/evil_flower.png", "media/slime.png",
"media/imp.png", "media/spider_egg.png",
"media/spider_web.png", "media/little_spider.png",
"media/bubble.png", "media/witch.png",
"media/cauldron.png", "media/snake.png",
"media/pumpkin.png", "media/ghost.png",
"media/zombie.png",
"media/butcher.png", "media/giant_slime.png",
"media/king_rat.png", "media/cyclops.png",
"media/giant_spider.png", "media/francky.png",
"media/blood.png",
"media/corpses.png", "media/corpses_big.png",
"media/star.png", "media/star2.png",
"media/hurt_impact.png",
"media/interface.png", "media/hud_shots.png",
"media/explosion.png", "media/keys_qwer.png",
"media/keys_azer.png", "media/message_icons.png",
"media/night.png", "media/title.png",
"media/overlay_00.png", "media/light_cone.png",
"media/divinity.png",
"media/pnj.png", "media/fairy.png",
"media/key_area.png",
"media/ui_life.png", "media/ui_mana.png",
"media/ui_spells.png", "media/ui_message.png",
"media/ui_top_layer.png",
"media/fog.png", "media/title_animation.png",
"media/splatter.png", "media/witch_intro.png",
"media/item_description.png", "media/death_certificate.png",
"media/achievements.png",
};
for (const char *const filename : images)
ImageManager::getInstance().addImage(filename);
const char *const sounds[] =
{
"media/sound/blast00.ogg", "media/sound/blast01.ogg",
"media/sound/blast_elec.ogg", "media/sound/blast_fire.ogg",
"media/sound/blast_ice.ogg", "media/sound/blast_illusion.ogg",
"media/sound/blast_poison.ogg", "media/sound/blast_stone.ogg",
"media/sound/door_closing.ogg", "media/sound/door_opening.ogg",
"media/sound/chest_opening.ogg", "media/sound/impact.ogg",
"media/sound/bonus.ogg", "media/sound/drink.ogg",
"media/sound/eat.ogg", "media/sound/player_hit.ogg",
"media/sound/player_die.ogg", "media/sound/ennemy_dying.ogg",
"media/sound/coin.ogg", "media/sound/pay.ogg",
"media/sound/wall_impact.ogg", "media/sound/big_wall_impact.ogg",
"media/sound/king_rat_cry_1.ogg", "media/sound/king_rat_cry_2.ogg",
"media/sound/king_rat_die.ogg", "media/sound/slime_jump.ogg",
"media/sound/slime_impact.ogg", "media/sound/slime_impact_weak.ogg",
"media/sound/slime_smash.ogg", "media/sound/ice_charge.ogg",
"media/sound/electric.ogg", "media/sound/select.ogg",
"media/sound/heart.ogg", "media/sound/rat_die.ogg",
"media/sound/bat_die.ogg", "media/sound/imp_hurt.ogg",
"media/sound/imp_die.ogg", "media/sound/rock_impact.ogg",
"media/sound/rock_impact_medium.ogg", "media/sound/rock_impact_heavy.ogg",
"media/sound/throw.ogg", "media/sound/cyclop00.ogg",
"media/sound/cyclop_die.ogg", "media/sound/cyclops_impact.ogg",
"media/sound/butcher_00.ogg", "media/sound/butcher_01.ogg",
"media/sound/butcher_hurt.ogg", "media/sound/butcher_die.ogg",
"media/sound/vib.ogg",
"media/sound/boom_00.ogg", "media/sound/clang_00.ogg",
"media/sound/bubble_00.ogg", "media/sound/bubble_01.ogg",
"media/sound/trap.ogg", "media/sound/egg_smash_00.ogg",
"media/sound/egg_smash_01.ogg", "media/sound/spider_walking.ogg",
"media/sound/spider_web.ogg", "media/sound/spider_hurt.ogg",
"media/sound/spider_die.ogg", "media/sound/little_spider_die.ogg",
"media/sound/witch_00.ogg", "media/sound/witch_01.ogg",
"media/sound/witch_die_00.ogg", "media/sound/witch_die_01.ogg",
"media/sound/witch_02.ogg", "media/sound/invoke.ogg",
"media/sound/cauldron.ogg", "media/sound/cauldron_die.ogg",
"media/sound/snake_die.ogg", "media/sound/pumpkin_00.ogg",
"media/sound/pumpkin_01.ogg", "media/sound/pumpkin_die.ogg",
"media/sound/critical.ogg",
"media/sound/gong.ogg", "media/sound/teleport.ogg",
"media/sound/spell_charge.ogg", "media/sound/fireball.ogg",
"media/sound/message.ogg", "media/sound/earthquake.ogg",
"media/sound/spell_freeze.ogg", "media/sound/spell_shield.ogg",
"media/sound/heavy_step_00.ogg", "media/sound/heavy_step_01.ogg",
"media/sound/night.ogg", "media/sound/grumble.ogg",
"media/sound/zombie_00.ogg", "media/sound/zombie_01.ogg",
"media/sound/zombie_attack.ogg", "media/sound/zombie_die.ogg",
"media/sound/ghost.ogg", "media/sound/ghost_die.ogg",
"media/sound/electricity.ogg",
"media/sound/electric_blast.ogg", "media/sound/francky_00.ogg",
"media/sound/francky_01.ogg", "media/sound/francky_02.ogg",
"media/sound/francky_die.ogg", "media/sound/om.ogg",
"media/sound/glass.ogg", "media/sound/hiccup.ogg",
"media/sound/splatch.ogg", "media/sound/intro_witch.ogg",
"media/sound/force_field.ogg", "media/sound/door_opening_boss.ogg",
"media/sound/achievement.ogg",
};
// AA in fullscreen
if (parameters.fullscreen) enableAA(true);
// game main client position in the UI
xOffset = OFFSET_X;
yOffset = OFFSET_Y;
SoundManager::getInstance().setVolume(parameters.soundVolume);
for (const char *const filename : sounds)
{
SoundManager::getInstance().addSound(filename);
}
if (font.loadFromFile("media/DejaVuSans-Bold.ttf"))
{
myText.setFont(font);
}
miniMap = NULL;
currentMap = NULL;
currentFloor = NULL;
lastScore.score = 0;
lastScore.name = "";
lastScore.level = 0;
int i;
for (i = 0; i < NB_X_GAME; i++) xGame[i].active = false;
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++) equipNudeToDisplay[i] = false;
for (i = 0; i < NB_MESSAGES; i++) gameMessagesToSkip[i] = false;
for (i = 0; i < NB_ACHIEVEMENTS; i++) achievementState[i] = AchievementUndone;
for (i = 0; i < NB_ENEMY; i++) globalData.killedMonster[i] = 0;
saveInFight.monsters.clear();
isPausing = false;
showLogical = false;
showGameTime = false;
uiSprites.shotsSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_HUD_SHOTS));
uiSprites.topLayer.setTexture(*ImageManager::getInstance().getImage(IMAGE_UI_TOP_LAYER));
uiSprites.topLayer.setPosition(0, 602);
uiSprites.msgBoxSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_UI_MESSAGE));
uiSprites.iconSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_MESSAGE_ICONS));
uiSprites.iconSprite.setPosition(12, 614);
uiSprites.mapBgSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_MAP_BACKGROUND));
uiSprites.mapBgSprite.setPosition(342, 23);
introScreenSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_INTRO));
titleSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_TITLE));
titleSprite.setOrigin(titleSprite.getTextureRect().width / 2, titleSprite.getTextureRect().height / 2);
loadGameData();
loadHiScores();
srand(time(NULL));
}
void WitchBlastGame::enableAA(bool enable)
{
for (int i = 0; i < NB_IMAGES; i++)
{
if (i != IMAGE_TILES && i != IMAGE_MINIMAP && i != IMAGE_ITEMS_PRES && i != IMAGE_ITEMS_EQUIP_PRES && i != IMAGE_CORPSES
&& i != IMAGE_CORPSES_BIG)
ImageManager::getInstance().getImage(i)->setSmooth(enable);
}
}
WitchBlastGame::~WitchBlastGame()
{
// cleaning all entities
EntityManager::getInstance().clean();
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
}
DungeonMap* WitchBlastGame::getCurrentMap()
{
return currentMap;
}
DungeonMapEntity* WitchBlastGame::getCurrentMapEntity()
{
return dungeonEntity;
}
PlayerEntity* WitchBlastGame::getPlayer()
{
return player;
}
Vector2D WitchBlastGame::getPlayerPosition()
{
return Vector2D(player->getX(), player->getY());
}
int WitchBlastGame::getLevel()
{
return level;
}
int WitchBlastGame::getChallengeLevel()
{
return challengeLevel;
}
bool WitchBlastGame::getShowLogical()
{
return showLogical;
}
float WitchBlastGame::getDeltaTime()
{
return deltaTime;
}
void WitchBlastGame::onUpdate()
{
if (!isPausing) // && (achievementsQueue.empty() || !currentMap->isCleared()) )
{
if (isPlayerAlive) player->setItemToBuy(NULL);
EntityManager::getInstance().animate(deltaTime);
if (sf::Keyboard::isKeyPressed(input[KeyTimeControl]))
{
EntityManager::getInstance().animate(deltaTime);
SoundManager::getInstance().playSound(SOUND_VIB, false);
}
if (isPlayerAlive) gameTime += deltaTime;
for (int i = 0; i < NB_X_GAME; i++)
{
if (xGame[i].active)
{
xGame[i].timer -= deltaTime;
if (xGame[i].timer <= 0.0f)
{
xGame[i].active = false;
if (i == (int)xGameTypeFade && xGame[i].param == X_GAME_FADE_OUT)
{
if (player->getPlayerStatus() == PlayerEntity::playerStatusGoingNext)
{
level++;
startNewLevel();
}
else
startNewGame(false);
}
}
}
}
if (isPlayerAlive)
{
if (player->getHp() <= 0)
{
isPlayerAlive = false;
playMusic(MusicEnding);
}
}
}
}
void WitchBlastGame::startNewGame(bool fromSaveFile)
{
gameState = gameStateInit;
isPausing = false;
level = 1;
challengeLevel = 1;
gameTime = 0.0f;
initEvents();
scoreSaveFile = "";
interaction.active = false;
// cleaning all entities
EntityManager::getInstance().clean();
SoundManager::getInstance().stopSound(SOUND_NIGHT);
// cleaning the message queue
std::queue<messageStruct> empty;
std::swap( messagesQueue, empty );
// cleaning the achievements queue
std::queue<achievementStruct> empty2;
std::swap( achievementsQueue, empty2 );
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
miniMap = NULL;
currentFloor = NULL;
// init in game menu
buildInGameMenu();
dungeonEntity = new DungeonMapEntity();
// the interface
uiSprites.gui.setTexture(*ImageManager::getInstance().getImage(IMAGE_INTERFACE));
// key symbol on the interface
uiSprites.keySprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
uiSprites.keySprite.setTextureRect(sf::IntRect(ITEM_WIDTH * EQUIP_BOSS_KEY, 0, ITEM_WIDTH, ITEM_HEIGHT));
uiSprites.keySprite.setPosition(737, 612);
miniMap = new GameMap(FLOOR_WIDTH, FLOOR_HEIGHT);
// minimap on the interface
miniMapEntity = new TileMapEntity(ImageManager::getInstance().getImage(IMAGE_MINIMAP), miniMap, 19, 15, 10);
miniMapEntity->setTileBox(20, 16);
miniMapEntity->setX(800);
miniMapEntity->setY(645);
miniMapEntity->setZ(10001.0f);
// doors
doorEntity[0] = new DoorEntity(8);
doorEntity[1] = new DoorEntity(4);
doorEntity[2] = new DoorEntity(2);
doorEntity[3] = new DoorEntity(6);
saveInFight.isFight = false;
if (fromSaveFile)
{
if (!loadGame())
fromSaveFile = false;
else
playLevel(saveInFight.isFight);
}
if (!fromSaveFile)
{
// the player
player = new PlayerEntity((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT * 0.5f));
resetKilledEnemies();
#ifdef START_LEVEL
for (int i = 1; i < START_LEVEL; i++)
{
level = i;
if (level == 3)
{
player->acquireItem(getItemSpell());
player->acquireItemAfterStance();
}
player->setHpMax(player->getHpMax() + 2 + rand() % 4);
item_equip_enum item = getRandomEquipItem(false, false);
player->acquireItem((enumItemType)(item + FirstEquipItem));
player->acquireItemAfterStance();
item = getRandomEquipItem(true, true);
player->acquireItem((enumItemType)(item + FirstEquipItem));
player->acquireItemAfterStance();
if (i % 2 == 0)
{
item = getRandomEquipItem(false, false);
player->acquireItem((enumItemType)(item + FirstEquipItem));
player->acquireItemAfterStance();
}
}
level++;
player->setHp(player->getHpMax());
player->setGold(8 + rand() % 45);
#endif // START_LEVEL
startNewLevel();
}
}
void WitchBlastGame::startNewLevel()
{
// reset floor items
player->resetFloorItem();
bool needShop = false;
// create the new level
if (currentFloor != NULL)
{
if (level > 1)
{
if (!currentFloor->hasRoomOfType(roomTypeMerchant)) needShop = true;
}
delete currentFloor;
}
currentFloor = new GameFloor(level);
if (needShop) currentFloor->setForceShop();
currentFloor->createFloor();
// center it
floorX = FLOOR_WIDTH / 2;
floorY = FLOOR_HEIGHT / 2;
// move the player
if (level == 1)
player->moveTo((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT * 0.5f));
else
player->moveTo((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT - 2 * TILE_HEIGHT));
// the boss room is closed
bossRoomOpened = false;
if (level <= 6) testAndAddMessageToQueue((EnumMessages)(MsgInfoLevel1 + level - 1));
if (level == 1)
{
testAndAddMessageToQueue(MsgTutoBasics);
testAndAddMessageToQueue(MsgTutoTips);
}
playLevel(false);
}
void WitchBlastGame::playLevel(bool isFight)
{
if (level == 1)
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles01.png");
else if (level == 2)
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles02.png");
else if (level == 3)
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles03.png");
else if (level == 4)
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles04.png");
else if (level == 5)
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles05.png");
else
ImageManager::getInstance().getImage(IMAGE_TILES)->loadFromFile("media/tiles06.png");
isPlayerAlive = true;
if (!isFight)
{
player->setVelocity(Vector2D(0.0f, 0.0f));
player->setPlayerStatus(PlayerEntity::playerStatusPlaying);
}
// first map is open
roomClosed = false;
// generate the map
refreshMap();
// items from save
currentMap->restoreMapObjects();
if (isFight)
{
checkEntering();
saveMapItems();
}
// populate with monsters
if (isFight)
{
auto monsters_save = saveInFight.monsters;
saveInFight.monsters.clear();
for (auto monster: monsters_save)
addMonster(monster.id, monster.x, monster.y);
if (currentMap->getRoomType() == roomTypeBoss) playMusic(MusicBoss);
else if (currentMap->getRoomType() == roomTypeChallenge) playMusic(MusicChallenge);
else playMusic(MusicDungeon);
}
else
playMusic(MusicDungeon);
// game time counter an state
lastTime = getAbsolutTime();
gameState = gameStatePlaying;
// fade in
xGame[xGameTypeFade].active = true;
xGame[xGameTypeFade].param = X_GAME_FADE_IN;
xGame[xGameTypeFade].timer = FADE_IN_DELAY;
float x0 = MAP_WIDTH * 0.5f * TILE_WIDTH;
float y0 = MAP_HEIGHT * 0.5f * TILE_HEIGHT + 40.0f;
std::ostringstream oss;
oss << tools::getLabel("level") << " " << level;
TextEntity* text = new TextEntity(oss.str(), 30, x0, y0);
text->setAlignment(ALIGN_CENTER);
text->setLifetime(2.5f);
text->setWeight(-36.0f);
text->setZ(1000);
text->setColor(TextEntity::COLOR_FADING_WHITE);
}
void WitchBlastGame::prepareIntro()
{
EntityManager::getInstance().clean();
introSprites[0] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_FOG));
introSprites[0]->setX(SCREEN_WIDTH / 2);
introSprites[0]->setY(SCREEN_HEIGHT - 202);
introSprites[1] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_FOG));
introSprites[1]->setX(SCREEN_WIDTH / 2 + 970);
introSprites[1]->setY(SCREEN_HEIGHT - 202);
gameState = gameStateIntro;
gameTime = 0.0f;
introState = 0;
introSoundState = 0;
SoundManager::getInstance().playSound(SOUND_NIGHT);
}
void WitchBlastGame::updateIntro()
{
gameTime += deltaTime;
bool toMenu = false;
for (int i = 0; i < 2; i++)
{
introSprites[i]->setX(introSprites[i]->getX() - deltaTime * 35);
if (introSprites[i]->getX() < - SCREEN_WIDTH / 2) introSprites[i]->setX(introSprites[i]->getX() + 2 * SCREEN_WIDTH);
}
if (gameTime > 2.0f && introSoundState == 0)
{
SoundManager::getInstance().playSound(SOUND_INTRO_WITCH);
introSoundState++;
}
else if (gameTime > 7.0f && introSoundState == 1)
{
playMusic(MusicIntro);
introSoundState++;
}
if (introState == 0 && gameTime > 2.5f)
{
introState = 1;
introSprites[2] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_TITLE_ANIM),
SCREEN_WIDTH / 2,
SCREEN_HEIGHT / 2,
310, 278, 3);
introSprites[2]->setZ(50);
}
else if (introState == 1)
{
int frame = (gameTime - 2.5f) * 8.0f;
if (frame > 16)
{
frame = 16;
introState = 2;
introSprites[3] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_WITCH_INTRO));
introSprites[3]->setX(368 + 1000);
introSprites[3]->setY(424 - 480);
introSprites[3]->setZ(40);
EntityManager::getInstance().sortByZ();
}
introSprites[2]->setFrame(frame);
}
else if (introState == 2)
{
float xSprite = introSprites[3]->getX() - deltaTime * 800;
float ySprite = introSprites[3]->getY() + deltaTime * 400;
if (xSprite < 368)
{
introState = 3;
introSprites[3]->setDying(true);
EntityManager::getInstance().animate(deltaTime);
xSprite = 368;
ySprite = 424;
introSprites[4] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_SPLATTER));
introSprites[4]->setX(368);
introSprites[4]->setY(424);
introSprites[4]->setZ(45);
introSprites[4]->setScale(0.5f, 0.5f);
EntityManager::getInstance().sortByZ();
SoundManager::getInstance().stopSound(SOUND_INTRO_WITCH);
SoundManager::getInstance().playSound(SOUND_SPLATCH);
}
else
{
introSprites[3]->setX(xSprite);
introSprites[3]->setY(ySprite);
introSprites[3]->setAngle(gameTime * 500);
}
}
else if (introState == 3)
{
float scale = introSprites[4]->getScaleX();
scale += deltaTime * 5.0f;
if (scale > 1.0f) scale = 1.0f;
introSprites[4]->setScale(scale, scale);
if (gameTime > 8.0f)
{
introState = 4;
introSprites[2]->setDying(true);
introSprites[4]->setDying(true);
EntityManager::getInstance().animate(deltaTime);
toMenu = true;
}
}
sf::Event event;
while (app->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
//saveGameData();
app->close();
}
if (event.type == sf::Event::Resized)
{
enableAA(true);
sf::View view = app->getDefaultView();
view = getLetterboxView( view, event.size.width, event.size.height );
app->setView(view);
}
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Return
|| event.key.code == sf::Keyboard::Space
|| event.key.code == sf::Keyboard::Escape)
{
if (introState < 4)
{
if (introState > 0) introSprites[2]->setDying(true);
if (introState == 2) introSprites[3]->setDying(true);
if (introState > 2) introSprites[4]->setDying(true);
EntityManager::getInstance().animate(deltaTime);
if (introState < 3)
{
SoundManager::getInstance().stopSound(SOUND_INTRO_WITCH);
SoundManager::getInstance().playSound(SOUND_SPLATCH);
}
}
toMenu = true;
}
}
}
if (toMenu)
{
if (introSoundState <= 1) playMusic(MusicIntro);
switchToMenu();
}
}
void WitchBlastGame::renderIntro()
{
app->draw(introScreenSprite);
titleSprite.setPosition(SCREEN_WIDTH / 2 - 15, 371);
if (introState == 4) app->draw(titleSprite);
EntityManager::getInstance().render(app);
}
void WitchBlastGame::updateRunningGame()
{
bool backToMenu = false;
// Process events
sf::Event event;
while (app->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
if (gameState == gameStatePlaying && !player->isDead()) saveGame();
saveGameData();
app->close();
}
if (event.type == sf::Event::Resized)
{
enableAA(true);
sf::View view = app->getDefaultView();
view = getLetterboxView( view, event.size.width, event.size.height );
app->setView(view);
}
if (event.type == sf::Event::MouseWheelMoved)
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
if (player->isDead()) backToMenu = true;
else if (gameState == gameStatePlaying && !isPausing) isPausing = true;
else if (gameState == gameStatePlaying && isPausing) isPausing = false;
}
if (event.key.code == input[KeyFireSelect])
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.key.code == input[KeySpell])
{
if (gameState == gameStatePlaying && !isPausing) player->castSpell();
}
if (event.key.code == input[KeyDown] || event.key.code == sf::Keyboard::Down)
{
// in game menu ?
if (gameState == gameStatePlaying && isPausing)
{
menuInGame.index++;
if (menuInGame.index == menuInGame.items.size()) menuInGame.index = 0;
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
}
else if (event.key.code == input[KeyUp] || event.key.code == sf::Keyboard::Up)
{
// in game menu ?
if (gameState == gameStatePlaying && isPausing)
{
if (menuInGame.index == 0) menuInGame.index = menuInGame.items.size() - 1;
else menuInGame.index--;
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
}
else if (event.key.code == sf::Keyboard::Return)
{
switch (menuInGame.items[menuInGame.index].id)
{
case MenuStartNew:
case MenuStartOld:
case MenuKeys:
case MenuConfig:
case MenuTutoReset:
case MenuConfigBack:
case MenuLanguage:
case MenuCredits:
case MenuHiScores:
case MenuPlayerName:
case MenuVolumeMusic:
case MenuVolumeSound:
case MenuAchievements:
std::cout << "[ERROR] Bad Menu ID\n";
break;
case MenuExit:
backToMenu = true;
remove(SAVE_FILE.c_str());
break;
case MenuContinue:
isPausing = false;
break;
case MenuSaveAndQuit:
saveGame();
backToMenu = true;
break;
}
}
if (event.key.code == input[KeyFire])
{
if (gameState == gameStatePlaying && !isPausing) firingDirection = player->getFacingDirection();
}
if (event.key.code == sf::Keyboard::Return)
{
if (player->isDead() && !xGame[xGameTypeFade].active && sf::Keyboard::isKeyPressed(sf::Keyboard::Return))
{
if (player->getDeathAge() < DEATH_CERTIFICATE_DELAY)
player->setDeathAge(DEATH_CERTIFICATE_DELAY);
else
backToMenu = true;
}
else if (!messagesQueue.empty())
{
if (messagesQueue.front().timer > 0.5f)
messagesQueue.front().timer = 0.5f;
}
else if (!achievementsQueue.empty())
{
if (achievementsQueue.front().timer > 0.5f)
achievementsQueue.front().timer = 0.5f;
}
}
if (event.key.code == input[KeyInteract])
{
if (!player->isDead() && interaction.active)
player->interact(interaction.type, interaction.id);
}
if (event.key.code == sf::Keyboard::X)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) startNewGame(false);
}
if (event.key.code == sf::Keyboard::F1)
{
if (!isPlayerAlive && player->getDeathAge() > 3.5f)
{
if (scoreSaveFile.compare("") == 0) saveDeathScreen();
}
}
if (event.key.code == sf::Keyboard::F2)
{
showLogical = !showLogical;
}
if (event.key.code == sf::Keyboard::F3)
{
showGameTime = !showGameTime;
}
// DEBUG
#ifdef TEST_MODE
/*if (event.key.code == sf::Keyboard::Delete)
{
StructHurt hurt;
hurt.critical = false;
hurt.damage = 1;
hurt.enemyType = EnemyTypeGhost; //EnemyTypeNone;
hurt.goThrough = false;
hurt.hurtingType = ShotTypeStandard;
hurt.level = 0;
hurt.sourceType = SourceTypeMelee;
player->hurt(hurt);
}*/
if (event.key.code == sf::Keyboard::F5)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new BubbleEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 + 70,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2, BubbleTriple, 0);
new BubbleEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 - 70,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2, BubbleIce, 0);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeRat, 1);
findPlaceMonsters(EnemyTypeRatBlack, 1);
findPlaceMonsters(EnemyTypeRatGreen, 1);
findPlaceMonsters(EnemyTypeRatHelmet, 1);
findPlaceMonsters(EnemyTypeRatBlackHelmet, 1);
}
}
if (event.key.code == sf::Keyboard::F6)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new ButcherEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeBat, 2);
findPlaceMonsters(EnemyTypeImpBlue, 1);
findPlaceMonsters(EnemyTypeImpRed, 1);
}
}
if (event.key.code == sf::Keyboard::F7)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new GiantSlimeEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeEvilFlower, 1);
findPlaceMonsters(EnemyTypeEvilFlowerIce, 1);
findPlaceMonsters(EnemyTypeEvilFlowerFire, 1);
findPlaceMonsters(EnemyTypePumpkin, 1);
}
}
if (event.key.code == sf::Keyboard::F8)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new CyclopsEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeSlime, 1);
findPlaceMonsters(EnemyTypeSlimeBlue, 1);
findPlaceMonsters(EnemyTypeSlimeRed, 1);
findPlaceMonsters(EnemyTypeSlimeViolet, 1);
}
}
if (event.key.code == sf::Keyboard::F9)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new KingRatEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeSnake, 2);
findPlaceMonsters(EnemyTypeSnakeBlood, 2);
}
}
if (event.key.code == sf::Keyboard::F10)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new GiantSpiderEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeWitch, 1);
findPlaceMonsters(EnemyTypeWitchRed, 1);
findPlaceMonsters(EnemyTypeCauldron, 1);
}
}
if (event.key.code == sf::Keyboard::F11)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
{
new FranckyEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
initMonsterArray();
findPlaceMonsters(EnemyTypeSpiderEgg_invocated, 2);
findPlaceMonsters(EnemyTypeSpiderLittle_invocated, 2);
}
}
if (event.key.code == sf::Keyboard::F12)
{
initMonsterArray();
findPlaceMonsters(EnemyTypeZombie, 2);
findPlaceMonsters(EnemyTypeZombieDark, 2);
findPlaceMonsters(EnemyTypeGhost, 2);
}
if (event.key.code == sf::Keyboard::F4)
{
for (int i = 0; i < NUMBER_ITEMS; i++)
new ItemEntity((enumItemType)i, 100 + (i % 14) * 58, 100 + (i / 14) * 60);
}
#endif // TEST_MODE
}
if (event.type == sf::Event::LostFocus && !player->isDead())
isPausing = true;
}
if (gameState == gameStatePlaying && !isPausing)
{
if (player->canMove()) player->setVelocity(Vector2D(0.0f, 0.0f));
if (sf::Keyboard::isKeyPressed(input[KeyLeft]))
{
if (sf::Keyboard::isKeyPressed(input[KeyUp]))
player->move(7);
else if (sf::Keyboard::isKeyPressed(input[KeyDown]))
player->move(1);
else
player->move(4);
}
else if (sf::Keyboard::isKeyPressed(input[KeyRight]))
{
if (sf::Keyboard::isKeyPressed(input[KeyUp]))
player->move(9);
else if (sf::Keyboard::isKeyPressed(input[KeyDown]))
player->move(3);
else
player->move(6);
}
else if (sf::Keyboard::isKeyPressed(input[KeyUp]))
{
player->move(8);
}
else if (sf::Keyboard::isKeyPressed(input[KeyDown]))
{
player->move(2);
}
player->resestFireDirection();
if (sf::Keyboard::isKeyPressed(input[KeyFireLeft]))
player->fire(4);
else if (sf::Keyboard::isKeyPressed(input[KeyFireRight]))
player->fire(6);
else if (sf::Keyboard::isKeyPressed(input[KeyFireUp]))
player->fire(8);
else if (sf::Keyboard::isKeyPressed(input[KeyFireDown]))
player->fire(2);
// alternative "one button" gameplay
else if (sf::Keyboard::isKeyPressed(input[KeyFire]))
{
player->fire(firingDirection);
}
// alternative "firing with the mouse" gameplay
else if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(*app);
int xm = mousePosition.x - player->getX();
int ym = mousePosition.y - player->getY();
if (abs(xm) >= abs(ym))
{
if (xm > 0) player->fire(6);
else player->fire(4);
}
else
{
if (ym > 0) player->fire(2);
else player->fire(8);
}
}
// spell (right click)
if (sf::Mouse::isButtonPressed(sf::Mouse::Right) && (gameState == gameStatePlaying && !isPausing))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(*app);
int xm = mousePosition.x - player->getX();
int ym = mousePosition.y - player->getY();
if (abs(xm) >= abs(ym))
{
if (xm > 0) player->setFacingDirection(6);
else player->setFacingDirection(4);
}
else
{
if (ym > 0) player->setFacingDirection(2);
else player->setFacingDirection(8);
}
player->castSpell();
}
// message queue
if (!messagesQueue.empty())
{
messagesQueue.front().timer -= deltaTime;
if (messagesQueue.front().timer < 0.0f)
{
messagesQueue.pop();
if (!messagesQueue.empty()) SoundManager::getInstance().playSound(SOUND_MESSAGE);
}
}
// achievement queue
if (!achievementsQueue.empty() && achievementsQueue.front().hasStarted)
{
achievementsQueue.front().timer -= deltaTime;
if (achievementsQueue.front().timer < 0.0f)
{
achievementsQueue.pop();
if (achievementsQueue.empty()) music.play();
}
}
}
onUpdate();
verifyDoorUnlocking();
checkInteraction();
if (roomClosed)
{
if (getEnemyCount() == 0)
{
currentMap->setCleared(true);
if (currentMap->getRoomType() == roomTypeKey)
new ItemEntity( (enumItemType)(ItemBossKey),
MAP_WIDTH / 2 * TILE_WIDTH + TILE_WIDTH / 2,
MAP_HEIGHT / 2 * TILE_HEIGHT + TILE_HEIGHT / 2);
player->onClearRoom();
openDoors();
remove(SAVE_FILE.c_str());
if (currentMap->getRoomType() == roomTypeBoss)
{
playMusic(MusicDungeon);
}
else if (currentMap->getRoomType() == roomTypeChallenge && !player->isDead())
{
ChestEntity* chest = new ChestEntity((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT * 0.5f),
ChestChallenge, false);
chest->makeAppear();
// sound
SoundManager::getInstance().playSound(SOUND_GONG);
playMusic(MusicDungeon);
// text
float x0 = MAP_WIDTH * 0.5f * TILE_WIDTH;
float y0 = MAP_HEIGHT * 0.5f * TILE_HEIGHT + 40.0f;
TextEntity* text = new TextEntity("COMPLETE !", 30, x0, y0);
text->setAlignment(ALIGN_CENTER);
text->setLifetime(2.5f);
text->setWeight(-36.0f);
text->setZ(1200);
text->setColor(TextEntity::COLOR_FADING_WHITE);
challengeLevel++;
player->offerChallenge();
}
}
}
if (backToMenu)
{
if (player->isDead())
{
EntityManager::getInstance().clean();
introSprites[0] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_FOG));
introSprites[0]->setX(SCREEN_WIDTH / 2);
introSprites[0]->setY(SCREEN_HEIGHT - 202);
introSprites[1] = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_FOG));
introSprites[1]->setX(SCREEN_WIDTH / 2 + 970);
introSprites[1]->setY(SCREEN_HEIGHT - 202);
switchToMenu();
menuState = MenuStateHiScores;
}
else
{
prepareIntro();
}
}
}
void WitchBlastGame::addLifeBarToDisplay(std::string label, int hp, int hpMax)
{
lifeBar.toDisplay = true;
lifeBar.label = label;
lifeBar.hp = hp;
lifeBar.hpMax = hpMax;
}
void WitchBlastGame::renderGame()
{
lifeBar.toDisplay = false;
EntityManager::getInstance().renderUnder(app, 5000);
}
void WitchBlastGame::renderHud()
{
// boss life bar ?
if (lifeBar.toDisplay) renderLifeBar();
// interaction text ?
if (interaction.active)
{
if (interaction.type == InteractionTypeTemple)
write(interaction.label, 20, GAME_WIDTH / 2, 480, ALIGN_CENTER,sf::Color::White, app, 2, 2);
else if (interaction.type == InteractionTypeMerchandise)
write(interaction.label, 20, GAME_WIDTH / 2, 480, ALIGN_CENTER,sf::Color::White, app, 2, 2);
}
// light cone ?
float fade = player->getLightCone();
if (fade > 0.0f)
{
sf::Sprite cone;
cone.setTexture(*ImageManager::getInstance().getImage(IMAGE_LIGHT_CONE));
cone.setPosition(player->getX() - 64, player->getY() - 580);
cone.setColor(sf::Color(255, 255, 255, 255 * fade));
app->draw(cone, sf::BlendAdd);
}
app->draw(uiSprites.gui);
EntityManager::getInstance().renderAfter(app, 5000);
}
void WitchBlastGame::renderLifeBar()
{
if (lifeBar.toDisplay)
{
float l = lifeBar.hp * ((MAP_WIDTH - 1) * TILE_WIDTH) / lifeBar.hpMax;
int label_dy = 0;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(TILE_WIDTH / 2, label_dy + 22));
rectangle.setOutlineThickness(1);
rectangle.setOutlineColor(sf::Color(200, 200, 200, 200));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setOutlineThickness(0);
rectangle.setPosition(sf::Vector2f(TILE_WIDTH / 2, label_dy + 22));
app->draw(rectangle);
game().write( lifeBar.label,
18,
TILE_WIDTH / 2 + 10.0f,
label_dy + 23,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0 , 0);
}
}
void WitchBlastGame::renderRunningGame()
{
EntityManager::getInstance().sortByZ();
if (!isPlayerAlive)
{
sf::View view = app->getView();
sf::View viewSave = app->getView();
if (!parameters.zoom || player->getDeathAge() > 4.0f)
{
// do nothing
}
else if (player->getDeathAge() > 3.0f)
{
view.zoom(1.0f - 0.75f * (4.0f - player->getDeathAge()));
float xDiff = view.getCenter().x - player->getX();
float yDiff = view.getCenter().y - player->getY();
view.setCenter(view.getCenter().x - xDiff * (4.0f - player->getDeathAge()),
view.getCenter().y - yDiff * (4.0f - player->getDeathAge()));
}
else if (player->getDeathAge() > 1.0f)
{
view.zoom(0.25f);
view.setCenter(player->getX(), player->getY());
}
else
{
view.zoom(1.0f - 0.75f * (player->getDeathAge()));
float xDiff = view.getCenter().x - player->getX();
float yDiff = view.getCenter().y - player->getY();
view.setCenter(view.getCenter().x - xDiff * player->getDeathAge(),
view.getCenter().y - yDiff * player->getDeathAge());
}
view.move(-5, -5);
app->setView(view);
renderGame();
app->setView(viewSave);
renderHud();
}
else if (parameters.zoom && gameTime < 1.0f)
{
sf::View view = app->getView();
sf::View viewSave = app->getView();
view.zoom(0.25f + 0.75f * (gameTime));
view.move(-5, -5);
app->setView(view);
renderGame();
app->setView(viewSave);
renderHud();
}
else if (xGame[xGameTypeShake].active)
{
sf::View view = app->getView();
sf::View viewSave = app->getView();
view.move(-4 + rand() % 9, -4 + rand() % 9);
app->setView(view);
renderGame();
app->setView(viewSave);
renderHud();
}
else
{
sf::View view = app->getView();
sf::View viewSave = app->getView();
view.move(-OFFSET_X, -OFFSET_Y);
app->setView(view);
renderGame();
app->setView(viewSave);
renderHud();
}
sf::RectangleShape rectangle(sf::Vector2f(200, 25));
// effects
if (sf::Keyboard::isKeyPressed(input[KeyTimeControl]))
{
// effect
int effectFade = 10 + 20 * (1.0f + cos(12.0f * getAbsolutTime())) * 0.5f;
rectangle.setFillColor(sf::Color(0, 255, 255, effectFade));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
sf::RenderStates r;
r.blendMode = sf::BlendAlpha ;
app->draw(rectangle, r);
}
if (xGame[xGameTypeFade].active && xGame[xGameTypeFade].param == X_GAME_FADE_IN)
{
// fade in
rectangle.setFillColor(sf::Color(0, 0, 0, 255 - ((FADE_IN_DELAY - xGame[xGameTypeFade].timer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
else if (xGame[xGameTypeFade].active && xGame[xGameTypeFade].param == X_GAME_FADE_OUT)
{
// fade out
rectangle.setFillColor(sf::Color(0, 0, 0, ((FADE_IN_DELAY - xGame[xGameTypeFade].timer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
if (xGame[xGameTypeFadeColor].active)
{
// color fade
unsigned int r = 0, g = 0, b = 0;
switch (xGame[xGameTypeFadeColor].param)
{
case X_GAME_COLOR_RED:
r = 255;
g = 100;
break;
case X_GAME_COLOR_GREEN:
g = 255;
break;
case X_GAME_COLOR_BLUE:
b = 255;
break;
case X_GAME_COLOR_VIOLET:
r = 255;
b = 200;
break;
case X_GAME_COLOR_BROWN:
r = 200;
b = 100;
g = 150;
break;
case X_GAME_COLOR_WHITE:
r = 255;
b = 255;
g = 255;
break;
}
int alpha = xGame[xGameTypeFadeColor].timer * 200.0f / xGame[xGameTypeFadeColor].duration;
rectangle.setFillColor(sf::Color(r, g, b, alpha));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle, sf::BlendAdd);
}
renderMessages();
app->draw(uiSprites.topLayer);
std::ostringstream oss;
oss << player->getGold();
write(oss.str(), 18, 518, 619, ALIGN_CENTER, sf::Color::White, app, 0, 0);
myText.setColor(sf::Color(0, 0, 0, 255));
myText.setCharacterSize(16);
oss.str("");
oss << tools::getLabel("level") << " " << level;
write(oss.str(), 16, 880, 610, ALIGN_CENTER, sf::Color::Black, app, 0, 0);
if (gameState == gameStatePlaying)
{
// life
// if (player->isPoisoned()) TODO
sf::Sprite hpSprite;
hpSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_UI_LIFE));
int hpFade = 88.0f * (float)player->getHpDisplay() / (float)player->getHpMax();
if (hpFade < 0) hpFade = 0;
else if (hpFade > 88) hpFade = 88;
hpSprite.setPosition(170, 619 + 88 - hpFade);
hpSprite.setTextureRect(sf::IntRect(0, 88 - hpFade, 88, hpFade));
app->draw(hpSprite);
oss.str("");
oss << player->getHp() << "/" << player->getHpMax();
write(oss.str(), 16, 210, 654, ALIGN_CENTER, sf::Color::White, app, 0, 0);
// mana
sf::Sprite manaSprite;
manaSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_UI_MANA));
int manaFade = player->getPercentFireDelay() * 98;
manaSprite.setPosition(558, 614 + 98 - manaFade);
manaSprite.setTextureRect(sf::IntRect(0, 98 - manaFade, 98, manaFade));
app->draw(manaSprite);
if (player->getActiveSpell().spell != SpellNone)
{
//oss.str("");
//oss << tools::getLabel(spellLabel[player->getActiveSpell().spell]);
//if (player->isEquiped(EQUIP_BOOK_MAGIC_II)) oss << "+";
//write(oss.str(), 14, 95, 663, ALIGN_LEFT, sf::Color::White, app, 0, 0);
// TODO
sf::Sprite spellSprite;
spellSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_UI_SPELLS));
spellSprite.setPosition(568, 624);
int frame = player->getActiveSpell().spell;
spellSprite.setTextureRect(sf::IntRect(frame * 78, 78, 78, 78));
//spellSprite.scale(2.0f, 2.0f);
app->draw(spellSprite);
int spellFade = player->getPercentSpellDelay() * 78;
spellSprite.setPosition(568, 624 + 78 - spellFade);
spellSprite.setTextureRect(sf::IntRect(frame * 78, 78 - spellFade, 78, spellFade));
app->draw(spellSprite);
if (player->canCastSpell())
{
float fade = (cos(8.0f * getAbsolutTime()) + 1.0f) * 0.5f;
spellSprite .setColor(sf::Color(255, 255, 255, 255 * fade));
app->draw(spellSprite, sf::BlendAdd);
}
}
// drawing the key on the interface
if (player->isEquiped(EQUIP_BOSS_KEY)) app->draw(uiSprites.keySprite);
if (player->isEquiped(EQUIP_FLOOR_MAP))
{
sf::Sprite mapSprite;
mapSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
mapSprite.setTextureRect(sf::IntRect(ITEM_WIDTH * 3, ITEM_HEIGHT * 4, ITEM_WIDTH, ITEM_HEIGHT));
mapSprite.setPosition(737, 648);
app->draw(mapSprite);
}
if (player->isEquiped(EQUIP_ALCOHOL))
{
sf::Sprite alcSprite;
alcSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
alcSprite.setTextureRect(sf::IntRect(ITEM_WIDTH * 4, ITEM_HEIGHT * 4, ITEM_WIDTH, ITEM_HEIGHT));
alcSprite.setPosition(737, 681);
app->draw(alcSprite);
}
if (player->isEquiped(EQUIP_LUCK))
{
sf::Sprite alcSprite;
alcSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
alcSprite.setTextureRect(sf::IntRect(ITEM_WIDTH * 5, ITEM_HEIGHT * 4, ITEM_WIDTH, ITEM_HEIGHT));
alcSprite.setPosition(704, 681);
app->draw(alcSprite);
}
if (player->isEquiped(EQUIP_FAIRY_POWDER))
{
sf::Sprite alcSprite;
alcSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
alcSprite.setTextureRect(sf::IntRect(ITEM_WIDTH * 6, ITEM_HEIGHT * 4, ITEM_WIDTH, ITEM_HEIGHT));
alcSprite.setPosition(671, 681);
app->draw(alcSprite);
}
// drawing message icon
if (!messagesQueue.empty())
{
int fade = 255;
if (messagesQueue.front().timer < 0.5f)
{
fade = (2 * messagesQueue.front().timer) * 255;
}
else if (messagesQueue.front().timerMax - messagesQueue.front().timer < 0.5f)
{
fade = (2 * (messagesQueue.front().timerMax - messagesQueue.front().timer)) * 255;
}
uiSprites.iconSprite.setColor(sf::Color(255, 255, 255, fade));
uiSprites.iconSprite.setTextureRect(sf::IntRect((messagesQueue.front().icon % 10) * 72, (messagesQueue.front().icon / 10) * 96, 72, 96));
app->draw(uiSprites.iconSprite);
}
// drawing the divinity
if (player->getDivinity().divinity >= 0)
{
sf::Sprite divSprite;
divSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_DIVINITY));
divSprite.setPosition(100, 614);
divSprite.setTextureRect(sf::IntRect(player->getDivinity().divinity * 48, 0, 48, 85));
app->draw(divSprite);
float fade = player->getLightCone();
if (fade > 0.0f && player->getPlayerStatus() != PlayerEntity::playerStatusPraying)
{
divSprite.setTextureRect(sf::IntRect(player->getDivinity().divinity * 48, 85, 48, 85));
divSprite.setColor(sf::Color(255, 255, 255, 255 * fade));
app->draw(divSprite);
}
rectangle.setOutlineThickness(0);
if (player->getDivinity().interventions + 1 < player->getDivinity().level)
{
int fade = 50 + 50 * cosf(game().getAbsolutTime() * 8);
rectangle.setFillColor(sf::Color(100 + fade, 100 + fade, 200 + fade / 2, 255));
}
else
rectangle.setFillColor(sf::Color(100, 100, 200, 255));
rectangle.setPosition(sf::Vector2f(101, 689));
rectangle.setSize(sf::Vector2f(46 * player->getDivinity().percentsToNextLevels, 9));
app->draw(rectangle);
std::ostringstream oss;
if (player->getDivinity().level == MAX_DIVINITY_LEVEL + 1) oss << "MAX";
else oss << "lvl " << player->getDivinity().level;
write(oss.str(), 11, 122, 702, ALIGN_CENTER, sf::Color::White, app, 0, 0);
}
// render the shots
renderHudShots(app);
if (isPausing)
{
// background
rectangle.setFillColor(sf::Color(0, 0, 0, 200));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH, MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
// minimap
int mapx = 350;
int mapy = 30;
// background
app->draw(rectangle);
app->draw(uiSprites.mapBgSprite);
// map
float miniX = miniMapEntity->getX();
float miniY = miniMapEntity->getY();
miniMapEntity->setX(mapx);
miniMapEntity->setY(mapy);
miniMapEntity->computeVertices();
miniMapEntity->render(app);
miniMapEntity->setX(miniX);
miniMapEntity->setY(miniY);
miniMapEntity->computeVertices();
float x = 200;
float y = 480;
// items
write(tools::getLabel("inventory"), 16, x, y, ALIGN_LEFT, sf::Color::White, app, 0, 0);
int n = 0;
for (auto i: sortedEquipement)
{
if (i != EQUIP_BOSS_KEY && player->isEquiped(i))
{
sf::Sprite itemSprite;
itemSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
itemSprite.setPosition(x + n * 32, y + 20);
itemSprite.setTextureRect(sf::IntRect((i % 10) * 32, (i / 10) * 32, 32, 32));
app->draw(itemSprite);
n++;
}
}
renderInGameMenu();
}
else if (!achievementsQueue.empty() && (currentMap->isCleared() || achievementsQueue.front().hasStarted) )
{
int fade = 200;
if (achievementsQueue.front().timer < 0.5f) fade = achievementsQueue.front().timer * 400;
if (achievementsQueue.front().timer > ACHIEVEMENT_DELAY_MAX - 0.5f) fade = (ACHIEVEMENT_DELAY_MAX - achievementsQueue.front().timer) * 400;
if (!achievementsQueue.front().hasStarted)
{
music.pause();
SoundManager::getInstance().playSound(SOUND_ACHIEVEMENT);
achievementsQueue.front().hasStarted = true;
achievementState[achievementsQueue.front().type] = AchievementDone;
saveGameData();
}
sf::Sprite bg;
bg.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEM_DESCRIPTION));
bg.setPosition(800 - 4 * fade + 20 + MAP_WIDTH * TILE_WIDTH * 0.5f - bg.getTextureRect().width * 0.5, 80);
app->draw(bg);
game().write("ACHIEVEMENT UNLOCKED", 19, 800 - 4 * fade + 470.0f, 92.0f, ALIGN_CENTER, sf::Color::White, app, 0, 0);
game().write(achievementsQueue.front().message, 18, 800 - 4 * fade + 470.0f, 120.0f, ALIGN_CENTER, sf::Color::White, app, 0, 0);
game().write("Press [enter] to close", 12, 800 - 4 * fade + 675.0f, 152.0f, ALIGN_RIGHT, sf::Color::White, app, 0, 0);
}
if (player->isDead())
{
float deathAge = player->getDeathAge();
if (deathAge > DEATH_CERTIFICATE_DELAY)
{
rectangle.setFillColor(sf::Color(0, 0, 0, 180));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
renderDeathScreen(80, 110);
if (scoreSaveFile.compare("") == 0)
{
write(tools::getLabel("certificate_capture"), 16, 80, 430, ALIGN_LEFT, sf::Color::White, app, 0, 0);
}
else
{
std::stringstream ss;
ss << tools::getLabel("certificate_saved") << " " << scoreSaveFile;
write(ss.str(), 16, 80, 430, ALIGN_LEFT, sf::Color::White, app, 0, 0);
}
}
else if (deathAge > DEATH_CERTIFICATE_DELAY - 1.0f)
{
rectangle.setFillColor(sf::Color(0, 0, 0, 180 * (deathAge - 2.5f)));
rectangle.setPosition(sf::Vector2f(xOffset, yOffset));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
renderDeathScreen(80 + (DEATH_CERTIFICATE_DELAY - deathAge) * 1000, 110);
}
}
else if (currentMap->getRoomType() == roomTypeExit && level >= LAST_LEVEL)
{
float x0 = (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
write(tools::getLabel("congratulations_1"), 25, x0, 220, ALIGN_CENTER, sf::Color::White, app, 2, 2);
write(tools::getLabel("congratulations_2"), 23, x0, 250, ALIGN_CENTER, sf::Color::White, app, 2, 2);
write(tools::getLabel("congratulations_3"), 23, x0, 280, ALIGN_CENTER, sf::Color::White, app, 2, 2);
}
}
// show game time
if (showGameTime)
{
int minutes = (int)gameTime / 60;
int secondes = (int)gameTime % 60;
std::stringstream ss;
if (minutes < 10) ss << "0";
ss << minutes;
ss << ":";
if (secondes < 10) ss << "0";
ss << secondes;
write(ss.str(), 14, 4, 4, ALIGN_LEFT, sf::Color::Green, app, 0,0);
}
}
void WitchBlastGame::renderMessages()
{
// message queue
if (!messagesQueue.empty())
{
int dy = 30;
if (messagesQueue.front().timer < 0.5f)
{
dy *= (2 * messagesQueue.front().timer);
}
else if (messagesQueue.front().timerMax - messagesQueue.front().timer < 0.5f)
{
dy *= (2 * (messagesQueue.front().timerMax - messagesQueue.front().timer));
}
uiSprites.msgBoxSprite.setPosition(0, 590 - dy);
app->draw(uiSprites.msgBoxSprite);
std::stringstream ss;
ss << messagesQueue.front().message[0];
ss << ": ";
ss << messagesQueue.front().message[1];
ss << std::endl;
ss << messagesQueue.front().message[2];
write(ss.str(), 16, 10, 592 - dy, ALIGN_LEFT, sf::Color::White, app, 0,0);
}
}
void WitchBlastGame::saveDeathScreen()
{
std::stringstream ss;
ss << "rip_";
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
ss << (now->tm_year + 1900);
if (now->tm_mon < 9) ss << "0";
ss << (now->tm_mon + 1);
if (now->tm_mday < 9) ss << "0";
ss << now->tm_mday;
if (now->tm_hour <= 9) ss << "0";
ss << (now->tm_hour);
if (now->tm_min <= 9) ss << "0";
ss << (now->tm_min);
if (now->tm_sec <= 9) ss << "0";
ss << (now->tm_sec);
ss << ".png";
scoreSaveFile = ss.str();
int width = 810, height = 300, border = 4;
int x = 80, y = 110;
sf::Image screenShot(app->capture());
sf::Image savedImage;
savedImage.create(width + border * 2, height + border * 2);
savedImage.copy(screenShot,0 , 0, sf::IntRect( x - border, y - border, width + border * 2, height + border * 2));
savedImage.saveToFile(scoreSaveFile);
}
void WitchBlastGame::renderDeathScreen(float x, float y)
{
int xRect = 810;
sf::Sprite rectangle;
rectangle.setTexture(*ImageManager::getInstance().getImage(IMAGE_DEATH_CERTIFICATE));
rectangle.setPosition(x - 4, y - 4);
app->draw(rectangle);
std::stringstream ss;
ss << parameters.playerName << " - " << tools::getLabel("dc_certificate");
write(ss.str(), 18, x + xRect / 2, y + 5, ALIGN_CENTER, sf::Color::Black, app, 0, 0);
ss.str(std::string());
ss.clear();
ss << tools::getLabel("dc_killed_by") << " " << sourceToString(player->getLastHurtingSource(), player->getLastHurtingEnemy()) << "." << std::endl;
int minutes = (int)gameTime / 60;
if (minutes < 1) minutes = 1;
ss << tools::getLabel("dc_died_level") << " " << level << " " << tools::getLabel("dc_after") << " " << minutes << " " << tools::getLabel("dc_minutes") << "." << std::endl;
ss << tools::getLabel("dc_killed_monsters") << ": " << bodyCount << std::endl;
ss << tools::getLabel("dc_gold") << ": " << player->getGold() << std::endl;
ss << tools::getLabel("dc_challenges") << ": " << challengeLevel - 1 << std::endl;
write(ss.str(), 16, x + 112, y + 50, ALIGN_LEFT, sf::Color::Black, app, 0, 0);
// player
renderPlayer(x + 40, y + 48, player->getEquipment(), player->getShotType(), 1, 0);
// items
write(tools::getLabel("inventory"), 16, x + 14, y + 165, ALIGN_LEFT, sf::Color::Black, app, 0, 0);
int n = 0;
for (auto i: sortedEquipement)
{
if (i != EQUIP_BOSS_KEY && player->isEquiped(i))
{
sf::Sprite itemSprite;
itemSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ITEMS_EQUIP));
itemSprite.setPosition(x + 14 + n * 32, y + 183);
itemSprite.setTextureRect(sf::IntRect((i % 10) * 32, (i / 10) * 32, 32, 32));
app->draw(itemSprite);
n++;
}
}
ss.str("");
ss.clear();
ss << "Score: " << score;
write(ss.str(), 24, x + xRect / 2, y + 240, ALIGN_CENTER, sf::Color::Black, app, 0, 0);
}
bool compareScores(WitchBlastGame::StructScore s1, WitchBlastGame::StructScore s2)
{
return s1.score > s2.score;
}
void WitchBlastGame::calculateScore()
{
score = 0;
bodyCount = 0;
for (int enemyType = EnemyTypeBat; enemyType < EnemyTypeRockFalling; enemyType++)
{
bodyCount += killedEnemies[enemyType];
score += killedEnemies[enemyType] * getMonsterScore((enemyTypeEnum)enemyType);
}
score += getChallengeScore(challengeLevel);
score += getGoldScore(player->getGold());
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
if (player->isEquiped(i)) score += getItemScore((item_equip_enum)i);
lastScore.equip[i] = player->isEquiped(i);
}
// to save
lastScore.name = parameters.playerName;
lastScore.score = score;
lastScore.level = level;
lastScore.shotType = player->getShotType();
scores.push_back(lastScore);
std::sort (scores.begin(), scores.end(), compareScores);
saveHiScores();
}
void WitchBlastGame::switchToMenu()
{
gameState = gameStateMenu;
buildMenu(false);
if (!config.configFileExists())
{
menuState = MenuStateFirst;
menuFirst.index = 0;
menuKeyIndex = 0;
}
}
void WitchBlastGame::updateMenu()
{
SoundManager::getInstance().playSound(SOUND_NIGHT, false);
menuStuct* menu = NULL;
if (menuState == MenuStateMain)
menu = &menuMain;
else if (menuState == MenuStateConfig)
menu = &menuConfig;
else if (menuState == MenuStateFirst)
menu = &menuFirst;
EntityManager::getInstance().animate(deltaTime);
for (int i = 0; i < 2; i++)
{
introSprites[i]->setX(introSprites[i]->getX() - deltaTime * 35);
if (introSprites[i]->getX() < - SCREEN_WIDTH / 2) introSprites[i]->setX(introSprites[i]->getX() + 2 * SCREEN_WIDTH);
}
// Process events
sf::Event event;
while (app->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
saveGameData();
app->close();
}
if (event.type == sf::Event::Resized)
{
enableAA(true);
sf::View view = app->getDefaultView();
view = getLetterboxView( view, event.size.width, event.size.height );
app->setView(view);
}
if (event.type == sf::Event::TextEntered)
{
if (menuState == MenuStateChangeName)
{
if (event.text.unicode < 128)
{
char c = static_cast<char>(event.text.unicode);
if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
parameters.playerName += static_cast<char>(event.text.unicode);
}
}
}
if (event.type == sf::Event::KeyPressed && menuState == MenuStateKeys)
{
bool alreadyUsed = false;
if (event.key.code == sf::Keyboard::Escape) alreadyUsed = true;
for (unsigned int i = 0; i < menuKeyIndex; i++)
if (input[i] == event.key.code) alreadyUsed = true;
// TODO more tests
if (!alreadyUsed)
{
input[menuKeyIndex] = event.key.code;
menuKeyIndex++;
if (menuKeyIndex == NumberKeys)
{
menuState = MenuStateConfig;
saveConfigurationToFile();
}
}
}
else if (event.type == sf::Event::KeyPressed)
{
if (menuState == MenuStateCredits)
{
if (event.key.code == sf::Keyboard::Escape || event.key.code == sf::Keyboard::Return)
menuState = MenuStateMain;
}
else if (menuState == MenuStateAchievements)
{
if (event.key.code == sf::Keyboard::Escape)
menuState = MenuStateMain;
else if (event.key.code == sf::Keyboard::Right || event.key.code == input[KeyRight])
{
- menuAchIndex++;
- if (menuAchIndex >= NB_ACHIEVEMENTS) menuAchIndex = 0;
+ if (menuAchIndex % 8 < 7) menuAchIndex++;
}
else if (event.key.code == sf::Keyboard::Left || event.key.code == input[KeyLeft])
{
- menuAchIndex--;
- if (menuAchIndex >= NB_ACHIEVEMENTS) menuAchIndex = NB_ACHIEVEMENTS - 1;
+ if (menuAchIndex % 8 > 0) menuAchIndex--;
+ }
+ else if (event.key.code == sf::Keyboard::Down || event.key.code == input[KeyDown])
+ {
+ if (menuAchIndex / 8 < 1) menuAchIndex += 8;
+ }
+ else if (event.key.code == sf::Keyboard::Up || event.key.code == input[KeyUp])
+ {
+ if (menuAchIndex / 8 > 0) menuAchIndex -= 8;
}
}
else if (menuState == MenuStateHiScores)
{
if (parameters.playerName.size() > 0
&& (event.key.code == sf::Keyboard::Escape || event.key.code == sf::Keyboard::Return))
{
menuState = MenuStateMain;
if (lastScore.level > 0)
{
lastScore.level = 0;
lastScore.score = 0;
playMusic(MusicIntro);
}
}
}
else if (menuState == MenuStateChangeName)
{
if (event.key.code == sf::Keyboard::Escape || event.key.code == sf::Keyboard::Return)
{
saveConfigurationToFile();
menuState = MenuStateMain;
}
else if (event.key.code == sf::Keyboard::BackSpace)
{
if (parameters.playerName.size() > 0)
parameters.playerName.erase(parameters.playerName.size() - 1);
}
}
else if (event.key.code == sf::Keyboard::Escape)
{
if (menuState == MenuStateConfig) menuState = MenuStateMain;
else
{
saveGameData();
app->close();
}
}
else if (event.key.code == input[KeyDown] || event.key.code == sf::Keyboard::Down)
{
menu->index++;
if (menu->index == menu->items.size()) menu->index = 0;
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
else if (event.key.code == input[KeyUp] || event.key.code == sf::Keyboard::Up)
{
if (menu->index == 0) menu->index = menu->items.size() - 1;
else menu->index--;
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
else if (event.key.code == input[KeyRight] || event.key.code == sf::Keyboard::Right)
{
if (menu->items[menu->index].id == MenuLanguage)
{
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
parameters.language++;
if (parameters.language >= NB_LANGUAGES) parameters.language = 0;
if (menuState == MenuStateConfig) saveConfigurationToFile();
tools::setLanguage(languageString[parameters.language]);
buildMenu(true);
}
else if (menu->items[menu->index].id == MenuVolumeSound)
{
parameters.soundVolume = (parameters.soundVolume / 10) * 10 + 10;
if (parameters.soundVolume > 100) parameters.soundVolume = 100;
saveConfigurationToFile();
SoundManager::getInstance().setVolume(parameters.soundVolume);
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
else if (menu->items[menu->index].id == MenuVolumeMusic)
{
parameters.musicVolume = (parameters.musicVolume / 10) * 10 + 10;
if (parameters.musicVolume > 100) parameters.musicVolume = 100;
saveConfigurationToFile();
updateMusicVolume();
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
}
else if (event.key.code == input[KeyLeft] || event.key.code == sf::Keyboard::Left)
{
if (menu->items[menu->index].id == MenuLanguage)
{
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
parameters.language--;
if (parameters.language < 0) parameters.language = NB_LANGUAGES - 1;
if (menuState == MenuStateConfig) saveConfigurationToFile();
tools::setLanguage(languageString[parameters.language]);
buildMenu(true);
}
else if (menu->items[menu->index].id == MenuVolumeSound)
{
parameters.soundVolume = (parameters.soundVolume / 10) * 10 - 10;
if (parameters.soundVolume < 0) parameters.soundVolume = 0;
saveConfigurationToFile();
SoundManager::getInstance().setVolume(parameters.soundVolume);
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
else if (menu->items[menu->index].id == MenuVolumeMusic)
{
parameters.musicVolume = (parameters.musicVolume / 10) * 10 - 10;
if (parameters.musicVolume < 0) parameters.musicVolume = 0;
saveConfigurationToFile();
updateMusicVolume();
SoundManager::getInstance().playSound(SOUND_SHOT_SELECT);
}
}
else if (event.key.code == sf::Keyboard::Return)
{
switch (menu->items[menu->index].id)
{
case MenuStartNew:
startNewGame(false);
remove(SAVE_FILE.c_str());
break;
case MenuStartOld:
startNewGame(true);
break;
case MenuKeys:
menuState = MenuStateKeys;
menuKeyIndex = 0;
break;
case MenuCredits:
menuState = MenuStateCredits;
break;
case MenuHiScores:
menuState = MenuStateHiScores;
break;
case MenuAchievements:
menuState = MenuStateAchievements;
menuAchIndex = 0;
break;
case MenuPlayerName:
menuState = MenuStateChangeName;
break;
case MenuConfig:
menuState = MenuStateConfig;
break;
case MenuTutoReset:
for (int i = 0; i < NB_MESSAGES; i++) gameMessagesToSkip[i] = false;
SoundManager::getInstance().playSound(SOUND_SPELL_FREEZE);
saveGameData();
break;
case MenuConfigBack:
menuState = MenuStateMain;
break;
case MenuLanguage:
if (menuState == MenuStateFirst)
{
registerLanguage();
if (parameters.playerName.compare("") == 0 )
{
menuMain.index = 0;
menuState = MenuStateChangeName;
}
else
menuState = MenuStateMain;
}
break;
case MenuExit:
saveGameData();
app->close();
break;
case MenuVolumeSound:
case MenuVolumeMusic:
break;
case MenuContinue:
case MenuSaveAndQuit:
std::cout << "[ERROR] Bad Menu ID\n";
break;
}
}
}
}
}
void WitchBlastGame::renderMenu()
{
if (menuState == MenuStateCredits)
{
renderCredits();
return;
}
else if (menuState == MenuStateHiScores)
{
renderHiScores();
return;
}
else if (menuState == MenuStateAchievements)
{
renderAchievements();
return;
}
app->draw(introScreenSprite);
if (titleSprite.getPosition().y > 160) titleSprite.move(0, -8);
else if (titleSprite.getPosition().y < 160) titleSprite.setPosition(SCREEN_WIDTH / 2 - 15, 160);
app->draw(titleSprite);
EntityManager::getInstance().render(app);
menuStuct* menu = nullptr;
if (menuState == MenuStateMain || menuState == MenuStateChangeName)
menu = &menuMain;
else if (menuState == MenuStateConfig)
menu = &menuConfig;
else if (menuState == MenuStateFirst)
menu = &menuFirst;
int xAlign = 290;
int yTop = 320;
int yStep = 40;
if (menuState == MenuStateKeys)
{
// menu keys
if (config.configFileExists())
write(tools::getLabel("key_configuration"), 18, xAlign, 295, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 1, 1);
else
write(tools::getLabel("key_configuration_desc"), 18, xAlign, 295, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 1, 1);
for (unsigned int i = 0; i < NumberKeys; i++)
{
sf::Color itemColor;
if (menuKeyIndex == i) itemColor = sf::Color(255, 255, 255, 255);
else itemColor = sf::Color(180, 180, 180, 255);
std::ostringstream oss;
oss << tools::getLabel(inputKeyString[i]) << ": ";
if (menuKeyIndex == i) oss << tools::getLabel("key_configuration_insert");
else if (menuKeyIndex > i) oss << keyToString(input[i]);
write(oss.str(), 16, xAlign, 330 + i * 25, ALIGN_LEFT, itemColor, app, 1, 1);
}
}
else
{
// menu
for (unsigned int i = 0; i < menu->items.size(); i++)
{
sf::Color itemColor;
if (menu->index == i)
{
itemColor = sf::Color(255, 255, 255, 255);
sf::Sprite fairySprite;
fairySprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
fairySprite.setTextureRect(sf::IntRect( 48 * ((int)(20 *getAbsolutTime()) % 2), 0, 48, 48));
fairySprite.setPosition(xAlign - 60, yTop - 10 + i * yStep + 5 * cos( 6 * getAbsolutTime()));
app->draw(fairySprite);
}
else itemColor = sf::Color(120, 120, 120, 255);
std::string label = menu->items[i].label;
if (menu->items[i].id == MenuLanguage)
{
std::ostringstream oss;
oss << label << " : " << tools::getLabel(languageString[parameters.language]);
label = oss.str();
}
else if (menu->items[i].id == MenuPlayerName)
{
std::ostringstream oss;
oss << label << " : " << parameters.playerName;
if (menuState == MenuStateChangeName && (int)(getAbsolutTime() * 3) % 2 == 0) oss << "_";
label = oss.str();
}
else if (menu->items[i].id == MenuVolumeSound)
{
std::ostringstream oss;
oss << label << " : ";
if (parameters.soundVolume == 0) oss << "OFF";
else oss << parameters.soundVolume;
label = oss.str();
}
else if (menu->items[i].id == MenuVolumeMusic)
{
std::ostringstream oss;
oss << label << " : ";
if (parameters.musicVolume == 0) oss << "OFF";
else oss << parameters.musicVolume;
label = oss.str();
}
write(label, 21, xAlign, yTop + i * yStep, ALIGN_LEFT, itemColor, app, 1, 1);
}
write(menu->items[menu->index].description, 18, xAlign,
yTop + menu->items.size() * yStep + 8, ALIGN_LEFT, sf::Color(60, 80, 220), app, 0, 0);
// Keys
if (menuState == MenuStateFirst)
{
// displaying the standard key configuration
int xKeys = 270;
int yKeys = 380;
sf::Sprite keysSprite;
if (parameters.language == 1) // french
keysSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_KEYS_AZER));
else
keysSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_KEYS_QWER));
keysSprite.setPosition(xKeys, yKeys);
app->draw(keysSprite);
// legend
write(tools::getLabel("keys_move"), 16, xKeys + 190, yKeys + 10, ALIGN_LEFT, sf::Color::White, app, 1, 1);
write(tools::getLabel("keys_time"), 16, xKeys + 295, yKeys + 14, ALIGN_LEFT, sf::Color::White, app, 1, 1);
write(tools::getLabel("keys_fire"), 16, xKeys + 360, yKeys + 54, ALIGN_LEFT, sf::Color::White, app, 1, 1);
write(tools::getLabel("key_spell"), 16, xKeys + 148, yKeys + 184, ALIGN_CENTER, sf::Color::White, app, 1, 1);
// TODO key interact
std::ostringstream oss;
oss << tools::getLabel("keys_select_1") << std::endl << tools::getLabel("keys_select_2");
write(oss.str(), 16, xKeys + 4, yKeys + 100, ALIGN_LEFT, sf::Color::White, app, 1, 1);
}
}
std::ostringstream oss;
oss << APP_NAME << " v" << APP_VERSION << " - 2014 - " << " Seby (code), Pierre \"dejam0rt\" Baron (2D art)";
write(oss.str(), 17, 5, 680, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 1, 1);
}
void WitchBlastGame::renderAchievements()
{
app->draw(introScreenSprite);
if (titleSprite.getPosition().y > 160) titleSprite.move(0, -8);
else if (titleSprite.getPosition().y < 160) titleSprite.setPosition(SCREEN_WIDTH / 2 - 15, 180);
app->draw(titleSprite);
// achievements
write(tools::getLabel("menu_achievements"), 30, 485, 280, ALIGN_CENTER, sf::Color(255, 255, 255, 255), app, 1, 1);
int achWidth = 64, achHeight = 64, x0 = 180, y0 = 380, xStep = 16, yStep = 16, nbProLine = 8;
sf::RectangleShape rectangle(sf::Vector2f(achWidth, achHeight));
rectangle.setPosition(x0 + (menuAchIndex % nbProLine) * (achWidth + xStep), y0 + (menuAchIndex / nbProLine) * (achHeight + yStep));
rectangle.setOutlineThickness(3);
rectangle.setOutlineColor(sf::Color(50, 255, 50));
app->draw(rectangle);
sf::Sprite sprite;
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_ACHIEVEMENTS));
for (int i = 0; i < NB_ACHIEVEMENTS; i++)
{
sprite.setPosition(x0 + (i % nbProLine) * (achWidth + xStep), y0 + (i / nbProLine) * (achHeight + yStep));
if (achievementState[i] == AchievementDone)
{
sprite.setTextureRect(sf::IntRect( ((i + 1) % 10) * achWidth, ((i + 1) / 10) * achHeight, achWidth, achHeight));
}
else
{
sprite.setTextureRect(sf::IntRect(0, 0, achWidth, achHeight));
}
app->draw(sprite);
}
sf::Color fontColor = sf::Color::White;
std::stringstream oss;
oss << tools::getLabel(achievements[menuAchIndex].label);
oss << ": ";
if (achievementState[menuAchIndex] == AchievementDone)
{
oss << tools::getLabel(achievements[menuAchIndex].label + "_desc");
if (achievements[menuAchIndex].unlockType == UnlockItem && achievements[menuAchIndex].unlock > -1)
oss << "\nUNLOCK: " << tools::getLabel(items[achievements[menuAchIndex].unlock].name);
}
else
{
oss << "???";
fontColor = sf::Color(150, 150, 150);
}
write(oss.str(), 19, 100, 650, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 1, 1);
}
void WitchBlastGame::renderCredits()
{
app->draw(introScreenSprite);
if (titleSprite.getPosition().y > 160) titleSprite.move(0, -8);
else if (titleSprite.getPosition().y < 160) titleSprite.setPosition(SCREEN_WIDTH / 2 - 15, 180);
app->draw(titleSprite);
// credits
write(tools::getLabel("credits"), 30, 485, 230, ALIGN_CENTER, sf::Color(255, 255, 255, 255), app, 1, 1);
int yCursorInit = 340;
int yStep = 30;
int xLeft = 30;
int xRight = 470;
int xMarging = 20;
int yCursor = yCursorInit;
write("Code", 22, xLeft, yCursor, ALIGN_LEFT, sf::Color(210, 210, 255, 255), app, 0,0);
yCursor += yStep;
int i = 0;
while (creditsCode[i] != "END")
{
write(creditsCode[i], 19, xLeft + xMarging, yCursor, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0,0);
yCursor += yStep;
i++;
}
yCursor += yStep;
write("2D Art", 22, xLeft, yCursor, ALIGN_LEFT, sf::Color(210, 210, 255, 255), app, 0,0);
yCursor += yStep;
i = 0;
while (credits2D[i] != "END")
{
write(credits2D[i], 19, xLeft + xMarging, yCursor, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0,0);
yCursor += yStep;
i++;
}
yCursor += yStep;
write("Sound", 22, xLeft, yCursor, ALIGN_LEFT, sf::Color(210, 210, 255, 255), app, 0,0);
yCursor += yStep;
i = 0;
while (creditsSound[i] != "END")
{
write(creditsSound[i], 19, xLeft + xMarging, yCursor, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0,0);
yCursor += yStep;
i++;
}
yCursor += yStep;
////// RIGHT
yCursor = yCursorInit - yStep;
write("Music", 22, xRight, yCursor, ALIGN_LEFT, sf::Color(210, 210, 255, 255), app, 0,0);
yCursor += yStep;
i = 0;
while (creditsMusic[i] != "END")
{
write(creditsMusic[i], 19, xRight + xMarging, yCursor, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0,0);
yCursor += yStep;
i++;
}
yCursor += yStep;
write("Translation", 22, xRight, yCursor, ALIGN_LEFT, sf::Color(210, 210, 255, 255), app, 0,0);
yCursor += yStep;
i = 0;
while (creditsTranslate[i] != "END")
{
write(creditsTranslate[i], 19, xRight + xMarging, yCursor, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0,0);
yCursor += yStep;
i++;
}
yCursor += yStep;
}
void WitchBlastGame::renderHiScores()
{
sf::Sprite bgSprite;
bgSprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_INTRO));
app->draw(bgSprite);
// hi-scores-title
write(tools::getLabel("hi_scores"), 30, 485, 20, ALIGN_CENTER, sf::Color(255, 255, 255, 255), app, 1, 1);
int x0 = 25;
int x1 = 70;
int x2 = 125;
int x3 = 430;
int y0 = 130;
int yStep = 100;
int xRight = SCREEN_WIDTH / 2;
sf::RectangleShape line(sf::Vector2f(2, 600));
line.setPosition(SCREEN_WIDTH / 2, 80);
app->draw(line);
for (unsigned int i = 0; i < scores.size() && i < SCORES_MAX; i++)
{
int index = i < SCORES_MAX / 2 ? i : i - SCORES_MAX / 2;
sf::Color color = sf::Color( 220, 220, 220);
if (scores[i].score == lastScore.score && scores[i].level == lastScore.level && scores[i].name == lastScore.name)
{
int fade = 1 + cosf(getAbsolutTime() * 8) * 63;
color = sf::Color(255, 128 + fade, 255);
}
renderPlayer(x1 + (i / 5) * xRight, y0 + yStep * index, scores[i].equip, scores[i].shotType, 1, 0);
write(intToString(i + 1), 24, x0 + (i / 5) * xRight, y0 + 30 + yStep * index, ALIGN_CENTER, color, app, 1, 1);
std::stringstream ss;
ss << scores[i].name << " (" << scores[i].level << ")";
write(ss.str(), 17, x2 + (i / 5) * xRight, y0 + 30 + yStep * index, ALIGN_LEFT, color, app, 1, 1);
write(intToString(scores[i].score), 17, x3 + (i / 5) * xRight, y0 + 30 + yStep * index, ALIGN_RIGHT, color, app, 1, 1);
}
}
void WitchBlastGame::renderInGameMenu()
{
menuStuct* menu = &menuInGame;
int xAlign = 290;
int yAlign = 200;
{
// menu
for (unsigned int i = 0; i < menu->items.size(); i++)
{
sf::Color itemColor;
if (menu->index == i)
{
itemColor = sf::Color(255, 255, 255, 255);
sf::Sprite fairySprite;
fairySprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
fairySprite.setTextureRect(sf::IntRect( 48 * ((int)(8 *getAbsolutTime()) % 2), 0, 48, 48));
fairySprite.setPosition(xAlign - 60, yAlign + i * 90 + 5 * cos( 6 * getAbsolutTime()));
app->draw(fairySprite);
}
else itemColor = sf::Color(120, 120, 120, 255);
std::string label = menu->items[i].label;
write(label, 23, xAlign, yAlign + 10 + i * 90, ALIGN_LEFT, itemColor, app, 1, 1);
write(menu->items[i].description, 15, xAlign, yAlign + i * 90 + 50, ALIGN_LEFT, itemColor, app, 0, 0);
}
}
}
void WitchBlastGame::startGame()
{
lastTime = getAbsolutTime();
prepareIntro();
// Start game loop
while (app->isOpen())
{
deltaTime = getAbsolutTime() - lastTime;
lastTime = getAbsolutTime();
if (deltaTime > 0.05f) deltaTime = 0.05f;
switch (gameState)
{
case gameStateInit:
case gameStateKeyConfig:
case gameStateMenu:
updateMenu();
break;
case gameStateIntro:
updateIntro();
break;
case gameStatePlaying:
updateRunningGame();
break;
}
onRender();
}
quitGame();
}
void WitchBlastGame::createFloor()
{
// TODO : extracts from createNewGame
}
void WitchBlastGame::closeDoors()
{
if (!currentMap->isCleared())
{
int i;
for(i = 0; i < MAP_WIDTH; i++)
{
if (currentMap->getTile(i, 0) < 4) currentMap->setTile(i, 0, MAP_DOOR);
if (currentMap->getTile(i, MAP_HEIGHT - 1) < 4) currentMap->setTile(i, MAP_HEIGHT - 1, MAP_DOOR);
}
for(i = 0; i < MAP_HEIGHT; i++)
{
if (currentMap->getTile(0, i) < 4) currentMap->setTile(0, i, MAP_DOOR);
if (currentMap->getTile(MAP_WIDTH - 1, i) < 4) currentMap->setTile(MAP_WIDTH - 1, i, MAP_DOOR);
}
roomClosed = true;
}
}
void WitchBlastGame::openDoors()
{
int i, j;
for(i = 0; i < MAP_WIDTH; i++)
for(j = 0; j < MAP_WIDTH; j++)
if (currentMap->getTile(i, j) == MAP_DOOR) currentMap->setTile(i, j, MAP_DOOR_OPEN);
roomClosed = false;
SoundManager::getInstance().playSound(SOUND_DOOR_OPENING);
if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
else
doorEntity[0]->openDoor();
if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[1]->openDoor();
if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, MAP_DOOR);
else
doorEntity[2]->openDoor();
if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[3]->openDoor();
}
int WitchBlastGame::getEnemyCount()
{
int n=0;
EntityManager::EntityList* entityList =EntityManager::getInstance().getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
if (e->getType() >= ENTITY_ENEMY && e->getType() <= ENTITY_ENEMY_MAX_COUNT) n++;
}
return n;
}
int WitchBlastGame::getItemsCount()
{
int n=0;
EntityManager::EntityList* entityList =EntityManager::getInstance().getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
if (e->getType() == ENTITY_ITEM) n++;
}
return n;
}
Vector2D WitchBlastGame::getNearestEnemy(float x, float y)
{
Vector2D target(-100.0f, -100.0f);
float distanceMin = -1.0f;
EntityManager::EntityList* entityList =EntityManager::getInstance().getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
if (e->getType() >= ENTITY_ENEMY && e->getType() <= ENTITY_ENEMY_MAX_COUNT)
{
// enemy
EnemyEntity* enemy = dynamic_cast<EnemyEntity*>(e);
if (enemy->canCollide())
{
float d2 = (x - enemy->getX()) * (x - enemy->getX()) + (y - enemy->getY()) * (y - enemy->getY());
if (target.x < -1.0f || d2 < distanceMin)
{
distanceMin = d2;
target.x = enemy->getX();
target.y = enemy->getY();
}
}
}
}
return target;
}
void WitchBlastGame::checkDoor(int doorId, roomTypeEnum roomCurrent, roomTypeEnum roomNeighbour)
{
if (roomNeighbour == roomTypeNULL)
{
doorEntity[doorId]->setVisible(false);
return;
}
doorEntity[doorId]->setVisible(true);
doorEntity[doorId]->setDoorType(DoorStandard);
if (roomNeighbour == roomTypeBoss || roomCurrent == roomTypeBoss)
doorEntity[doorId]->setDoorType(DoorBoss);
if (roomNeighbour == roomTypeChallenge || roomCurrent == roomTypeChallenge)
doorEntity[doorId]->setDoorType(DoorChallenge);
if (roomNeighbour == roomTypeBoss && !bossRoomOpened)
{
doorEntity[doorId]->setOpen(false);
switch (doorId)
{
case 0:
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
break;
case 1:
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
break;
case 2:
currentMap->setTile(MAP_WIDTH/2, MAP_HEIGHT - 1, MAP_DOOR);
break;
case 3:
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
break;
}
}
else
doorEntity[doorId]->setOpen(true);
}
void WitchBlastGame::refreshMap()
{
// clean the sprites from old map
EntityManager::getInstance().partialClean(10);
// if new map, it has to be randomized
bool generateMap = !(currentFloor->getMap(floorX, floorY)->isVisited());
currentMap = currentFloor->getAndVisitMap(floorX, floorY);
// load the map
dungeonEntity->refreshMap();
player->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, 0, 0);
refreshMinimap();
if(generateMap)
this->generateMap();
else
{
if (currentMap->getRoomType() == roomTypeMerchant)
{
new PnjEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2 - 1) * TILE_HEIGHT,
0);
}
}
// check doors
checkDoor(0, currentMap->getRoomType(), currentMap->getNeighbourUp());
checkDoor(1, currentMap->getRoomType(), currentMap->getNeighbourLeft());
checkDoor(2, currentMap->getRoomType(), currentMap->getNeighbourDown());
checkDoor(3, currentMap->getRoomType(), currentMap->getNeighbourRight());
// keystones
if (currentMap->getNeighbourUp() || currentMap->getRoomType() == roomTypeExit)
{
SpriteEntity* keystoneEntity = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_TILES),
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
TILE_HEIGHT / 2, 192, 64, 1);
keystoneEntity->setZ(1000);
keystoneEntity->setFrame(24);
keystoneEntity->setType(ENTITY_EFFECT);
}
if (currentMap->getNeighbourDown())
{
SpriteEntity* keystoneEntity = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_TILES),
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
MAP_HEIGHT * TILE_WIDTH - TILE_HEIGHT / 2, 192, 64, 1);
keystoneEntity->setZ(1000);
keystoneEntity->setAngle(180);
keystoneEntity->setFrame(24);
keystoneEntity->setType(ENTITY_EFFECT);
}
if (currentMap->getNeighbourLeft())
{
SpriteEntity* keystoneEntity = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_TILES),
TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2, 192, 64, 1);
keystoneEntity->setZ(1000);
keystoneEntity->setAngle(270);
keystoneEntity->setFrame(24);
keystoneEntity->setType(ENTITY_EFFECT);
}
if (currentMap->getNeighbourRight())
{
SpriteEntity* keystoneEntity = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_TILES),
MAP_WIDTH * TILE_WIDTH - TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2, 192, 64, 1);
keystoneEntity->setZ(1000);
keystoneEntity->setAngle(90);
keystoneEntity->setFrame(24);
keystoneEntity->setType(ENTITY_EFFECT);
}
// pet slime
if (player->isEquiped(EQUIP_PET_SLIME)) new SlimePetEntity();
}
void WitchBlastGame::refreshMinimap()
{
for (int j=0; j < FLOOR_HEIGHT; j++)
for (int i=0; i < FLOOR_WIDTH; i++)
{
int n = currentFloor->getRoom(i, j);
if (n > 0 && currentFloor->getMap(i, j)->isVisited())
{
if (currentFloor->getRoom(i, j) == roomTypeStarting
|| currentFloor->getRoom(i, j) == roomTypeChallenge
|| currentFloor->getRoom(i, j) == roomTypeBonus
|| currentFloor->getRoom(i, j) == roomTypeKey
|| currentFloor->getRoom(i, j) == roomTypeBoss
|| currentFloor->getRoom(i, j) == roomTypeStandard)
{
if ( currentFloor->getMap(i, j)->containsHealth())
miniMap->setTile(i, j, 5);
else
miniMap->setTile(i, j, roomTypeStandard);
}
else
{
if (currentFloor->getRoom(i, j) == roomTypeMerchant)
miniMap->setTile(i, j, 3);
else if (currentFloor->getRoom(i, j) == roomTypeTemple)
miniMap->setTile(i, j, 7);
else
miniMap->setTile(i, j, currentFloor->getRoom(i, j));
}
}
else if (n > 0 && currentFloor->getMap(i, j)->isKnown())
{
switch (currentFloor->getRoom(i, j))
{
case roomTypeBoss:
miniMap->setTile(i, j, 12);
proceedEvent(EventFindBossDoor);
break;
case roomTypeChallenge:
miniMap->setTile(i, j, 15);
proceedEvent(EventFindBossDoor);
break;
case roomTypeMerchant:
miniMap->setTile(i, j,
game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP) ? 13 : 11 );
break;
case roomTypeKey:
miniMap->setTile(i, j,
game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP) ? 14 : 11 );
break;
case roomTypeExit:
miniMap->setTile(i, j,
game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP) ? 16 : 11 );
break;
case roomTypeTemple:
miniMap->setTile(i, j,
game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP) ? 17 : 11 );
break;
case roomTypeBonus:
miniMap->setTile(i, j,
game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP) ? 2 : 11 );
break;
case roomTypeStandard:
case roomTypeStarting:
miniMap->setTile(i, j, 11);
break;
case roomTypeNULL:
miniMap->setTile(i, j, 0);
break;
}
}
else
miniMap->setTile(i, j, 0);
}
miniMap->setTile(floorX, floorY, 10);
int xMap = 760 + (6 - floorX) * 19;
if (xMap < 710) xMap = 710;
else if (xMap > 795) xMap = 795;
int yMap = 620 + (3 - floorY) * 15;
if (yMap < 596) yMap = 596;
else if (yMap > 640) yMap = 640;
miniMapEntity->setX(xMap);
miniMapEntity->setY(yMap);
}
void WitchBlastGame::checkEntering()
{
if (!currentMap->isCleared())
{
player->setEntering();
SoundManager::getInstance().playSound(SOUND_DOOR_CLOSING);
for (int i=0; i<4; i++)
doorEntity[i]->closeDoor();
}
}
void WitchBlastGame::saveMapItems()
{
currentMap->cleanMapObjects();
// blood
std::vector <displayEntityStruct> blood = dungeonEntity->getBlood();
for (auto particle: blood)
currentMap->addSprite(ENTITY_BLOOD, particle.frame, particle.x, particle.y, particle.scale);
// corpses
std::vector <displayEntityStruct> corpses = dungeonEntity->getCorpses();
for (auto particle: corpses)
currentMap->addSprite(ENTITY_CORPSE, particle.frame, particle.x, particle.y, particle.scale);
EntityManager::EntityList* entityList = EntityManager::getInstance().getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity* e = *it;
it++;
ItemEntity* itemEntity = dynamic_cast<ItemEntity*>(e);
ChestEntity* chestEntity = dynamic_cast<ChestEntity*>(e);
if (itemEntity != NULL && !itemEntity->getDying())
{
currentMap->addItem(itemEntity->getItemType(), itemEntity->getX(), itemEntity->getY(), itemEntity->getMerchandise());
} // endif
else if (chestEntity != NULL && !chestEntity->getDying())
{
currentMap->addChest(chestEntity->getChestType(), chestEntity->getOpened(), chestEntity->getX(), chestEntity->getY());
} // endif
} // end for
}
void WitchBlastGame::moveToOtherMap(int direction)
{
// stairs to next level
if (direction == 8 && currentMap->getRoomType() == roomTypeExit)
{
if (player->getPlayerStatus() != PlayerEntity::playerStatusGoingNext)
{
player->setLeavingLevel();
xGame[xGameTypeFade].active = true;
xGame[xGameTypeFade].param = X_GAME_FADE_OUT;
xGame[xGameTypeFade].timer = FADE_OUT_DELAY;
player->setVelocity(Vector2D(0.0f, - INITIAL_PLAYER_SPEED / 2));
}
}
// go to another room
else
{
saveMapItems();
switch (direction)
{
case (4):
floorX--;
player->moveTo((MAP_WIDTH * TILE_WIDTH), player->getY());
player->move(4);
break;
case (6):
floorX++;
player->moveTo(0, player->getY());
player->move(6);
break;
case (8):
floorY--;
player->moveTo(player->getX(), MAP_HEIGHT * TILE_HEIGHT);
player->move(8);
break;
case (2):
floorY++;
player->moveTo(player->getX(), 0);
break;
}
refreshMap();
checkEntering();
currentMap->restoreMapObjects();
saveInFight.x = player->getX();
saveInFight.y = player->getY();
saveInFight.direction = direction;
saveMapItems();
if (!currentMap->isCleared()) saveGame();
}
}
void WitchBlastGame::onRender()
{
// clear the view
app->clear(sf::Color::Black);
switch (gameState)
{
case gameStateInit:
case gameStateKeyConfig:
case gameStateMenu:
renderMenu();
break;
case gameStatePlaying:
renderRunningGame();
break;
case gameStateIntro:
renderIntro();
break;
}
app->display();
}
void WitchBlastGame::renderHudShots(sf::RenderTarget* app)
{
int xHud = 277;
int yHud = 655;
int index = 0;
for (int i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
if (i == 0 || player->getShotType(i) != ShotTypeStandard)
{
int type_shot = player->getShotType(i);
uiSprites.shotsSprite.setPosition(xHud + 55 * index, yHud);
if (index == player->getShotIndex())
{
uiSprites.shotsSprite.setTextureRect(sf::IntRect(0, 0, 48, 48));
app->draw(uiSprites.shotsSprite);
}
uiSprites.shotsSprite.setTextureRect(sf::IntRect(48 * ( 1 + type_shot), 0, 48, 48));
app->draw(uiSprites.shotsSprite);
// level
if (i > 0)
{
std::ostringstream oss;
oss << "lvl " << player->getShotLevel(i) + 1;
write(oss.str(), 10, xHud + 55 * index + 10, yHud + 48, ALIGN_LEFT, sf::Color(255, 255, 255, 255), app, 0, 0);
}
index++;
}
}
}
void WitchBlastGame::generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor)
{
dungeonEntity->generateBlood(x, y, bloodColor);
// double blood if the "Blood Snake" object is equipped
if (player->isEquiped(EQUIP_BLOOD_SNAKE)) dungeonEntity->generateBlood(x, y, bloodColor);
}
void WitchBlastGame::addCorpse(float x, float y, int frame)
{
dungeonEntity->addCorpse(x, y, frame);
}
void WitchBlastGame::showArtefactDescription(enumItemType itemType)
{
new ArtefactDescriptionEntity(itemType);
}
void WitchBlastGame::generateMap()
{
saveInFight.monsters.clear();
if (currentMap->getRoomType() == roomTypeStandard)
generateStandardMap();
else if (currentMap->getRoomType() == roomTypeBonus)
{
currentMap->setCleared(true);
Vector2D v = currentMap->generateBonusRoom();
int bonusType = getRandomEquipItem(false, false);
if (items[FirstEquipItem + bonusType].familiar > FamiliarNone)
{
new ChestEntity(v.x, v.y, ChestFairy + items[FirstEquipItem + bonusType].familiar, false);
}
else
{
new ItemEntity( (enumItemType)(FirstEquipItem + bonusType), v.x ,v.y);
}
}
else if (currentMap->getRoomType() == roomTypeKey)
{
currentMap->generateKeyRoom();
initMonsterArray();
int x0 = MAP_WIDTH / 2;
int y0 = MAP_HEIGHT / 2;
monsterArray[x0][y0] = true;
if (level == 1)
{
findPlaceMonsters(EnemyTypeRat, 2);
findPlaceMonsters(EnemyTypeBat, 2);
}
else if (level < 6)
{
findPlaceMonsters(EnemyTypeRat, 5);
findPlaceMonsters(EnemyTypeBat, 5);
for (int i = 2; i < level; i++)
{
if (rand()%2 == 0)findPlaceMonsters(EnemyTypeImpBlue, 1);
else findPlaceMonsters(EnemyTypeImpRed, 1);
}
}
else
{
findPlaceMonsters(EnemyTypeZombie, 5);
findPlaceMonsters(EnemyTypeBat, 5);
for (int i = 5; i < level; i++)
{
if (rand()%2 == 0)findPlaceMonsters(EnemyTypeImpBlue, 1);
else findPlaceMonsters(EnemyTypeImpRed, 1);
}
}
}
else if (currentMap->getRoomType() == roomTypeMerchant)
{
currentMap->generateMerchantRoom();
ItemEntity* item1 = new ItemEntity(
ItemHealth,
(MAP_WIDTH / 2 - 1) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + 5);
item1->setMerchandise(true);
ItemEntity* item3 = new ItemEntity(
ItemHealthSmall,
(MAP_WIDTH / 2 + 1) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + 5);
item3->setMerchandise(true);
int bonusType = getRandomEquipItem(true, true);
ItemEntity* item2 = new ItemEntity(
(enumItemType)(FirstEquipItem + bonusType),
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + 5);
item2->setMerchandise(true);
// level item ?
if (rand() % 3 == 0)
{
int r = rand() % 4;
int item4Type = -1;
switch (r)
{
case 0: if (!game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP)) item4Type = ItemFloorMap; break;
case 1: if (!game().getPlayer()->isEquiped(EQUIP_ALCOHOL)) item4Type = ItemAlcohol; break;
case 2: if (!game().getPlayer()->isEquiped(EQUIP_LUCK)) item4Type = ItemLuck; break;
default: if (!game().getPlayer()->isEquiped(EQUIP_FAIRY_POWDER) && player->getFairieNumber() > 0) item4Type = ItemFairyPowder; break;
}
if (item4Type > -1)
{
ItemEntity* item4 = new ItemEntity(
(enumItemType)(item4Type),
(MAP_WIDTH / 2 + 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + 5);
item4->setMerchandise(true);
}
}
new PnjEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2 - 1) * TILE_HEIGHT,
0);
currentMap->setCleared(true);
proceedEvent(EventFindShop);
}
else if (currentMap->getRoomType() == roomTypeChallenge)
{
currentMap->generateRoomWithoutHoles(0);
if (challengeLevel == 1)
{
addMonster(EnemyTypeBubble,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
else
{
addMonster(challengeLevel >= 3 ? EnemyTypeBubbleIce : EnemyTypeBubble,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 - 80,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
addMonster(challengeLevel >= 4 ? EnemyTypeBubbleGreater : EnemyTypeBubble,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 + 80,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
}
playMusic(MusicChallenge);
}
else if (currentMap->getRoomType() == roomTypeBoss)
{
currentMap->generateRoomWithoutHoles(0);
if (level == 1)
{
findPlaceMonsters(EnemyTypeRat, 2);
addMonster(EnemyTypeButcher,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoButcher);
}
else if (level == 2)
{
addMonster(EnemyTypeSlimeBoss,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoGiantSlime);
}
else if (level == 3)
{
addMonster(EnemyTypeCyclops,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoCyclops);
}
else if (level == 4)
{
addMonster(EnemyTypeRatKing,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoWererat);
}
else if (level == 5)
{
addMonster(EnemyTypeSpiderGiant,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoGiantSpiderBefore);
}
else if (level == 6)
{
addMonster(EnemyTypeFrancky,
(MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
testAndAddMessageToQueue(MsgInfoFranky);
}
else if (level == 7)
{
// TODO
GiantSpiderEntity* b1 = new GiantSpiderEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 - 100,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b1->setLabelDy(10);
FranckyEntity* b2 = new FranckyEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b2->setLabelDy(-530);
KingRatEntity* b3 = new KingRatEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 + 100,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b3->setLabelDy(-20);
}
else // level > 6
{
GiantSpiderEntity* b1 = new GiantSpiderEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 - 100,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b1->setLabelDy(10);
GiantSlimeEntity* b2 = new GiantSlimeEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b2->setLabelDy(-510);
KingRatEntity* b3 = new KingRatEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2 + 100,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b3->setLabelDy(-20);
CyclopsEntity* b4 = new CyclopsEntity((MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
(MAP_HEIGHT / 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
b4->setLabelDy(-540);
findPlaceMonsters(EnemyTypeCauldron, 2);
findPlaceMonsters(EnemyTypeImpBlue, 4);
}
playMusic(MusicBoss);
}
else if (currentMap->getRoomType() == roomTypeStarting)
{
currentMap->generateRoomWithoutHoles(0);
currentMap->setCleared(true);
}
else if (currentMap->getRoomType() == roomTypeExit)
{
currentMap->generateExitRoom();
currentMap->setCleared(true);
new ChestEntity((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT * 0.5f),
ChestExit, false);
}
else if (currentMap->getRoomType() == roomTypeTemple)
{
currentMap->generateTempleRoom();
currentMap->setCleared(true);
proceedEvent(EventFindTemple);
}
else // "normal" room
currentMap->randomize(currentMap->getRoomType());
}
void WitchBlastGame::write(std::string str, int size, float x, float y, int align, sf::Color color, sf::RenderTarget* app, int xShadow = 0, int yShadow = 0)
{
myText.setString(str);
myText.setString(sf::String::fromUtf8(str.begin(), str.end()));
myText.setCharacterSize(size);
float xFont = x;
if (align == ALIGN_CENTER)
xFont = x - myText.getLocalBounds().width / 2;
else if (align == ALIGN_RIGHT)
xFont = x - myText.getLocalBounds().width;
if (xShadow != 0 && yShadow != 0)
{
myText.setPosition(xFont + xShadow, y + yShadow);
myText.setColor(sf::Color(0, 0, 0, 255));
app->draw(myText);
}
myText.setPosition(xFont, y);
myText.setColor(color);
app->draw(myText);
}
void WitchBlastGame::initMonsterArray()
{
for (int i = 0; i < MAP_WIDTH; i++)
for (int j = 0; j < MAP_HEIGHT; j++)
monsterArray[i][j] = false;
}
void WitchBlastGame::addMonster(enemyTypeEnum monsterType, float xm, float ym)
{
StructMonster monster;
monster.id = monsterType;
monster.x = xm;
monster.y = ym;
saveInFight.monsters.push_back(monster);
switch (monsterType)
{
case EnemyTypeRat:
new RatEntity(xm, ym - 2, RatEntity::RatTypeNormal, false);
proceedEvent(EventMeetRatsOrBats);
break;
case EnemyTypeRatGreen:
new GreenRatEntity(xm, ym - 2);
proceedEvent(EventMeetRatsOrBats);
break;
case EnemyTypeRatBlack:
new BlackRatEntity(xm, ym - 5, BlackRatEntity::RatBlackTypeNormal);
break;
case EnemyTypeRatHelmet:
new RatEntity(xm, ym - 2, RatEntity::RatTypeHelmet, false);
break;
case EnemyTypeRatBlackHelmet:
new BlackRatEntity(xm, ym - 5, BlackRatEntity::RatBlackTypeHelmet);
break;
case EnemyTypeBat:
new BatEntity(xm, ym, false);
proceedEvent(EventMeetRatsOrBats);
break;
case EnemyTypeSnake:
new SnakeEntity(xm, ym, SnakeEntity::SnakeTypeNormal, false);
proceedEvent(EventMeetSnakes);
break;
case EnemyTypeSnakeBlood:
new SnakeEntity(xm, ym, SnakeEntity::SnakeTypeBlood, false);
proceedEvent(EventMeetSnakes);
break;
case EnemyTypeEvilFlower:
new EvilFlowerEntity(xm, ym - 2, FlowerTypeStandard);
break;
case EnemyTypeEvilFlowerIce:
new EvilFlowerEntity(xm, ym - 2, FlowerTypeIce);
break;
case EnemyTypeEvilFlowerFire:
new EvilFlowerEntity(xm, ym - 2, FlowerTypeFire);
break;
case EnemyTypeSlime:
new SlimeEntity(xm, ym, SlimeTypeStandard, false);
break;
case EnemyTypeImpRed:
new ImpEntity(xm, ym, ImpEntity::ImpTypeRed);
break;
case EnemyTypeImpBlue:
new ImpEntity(xm, ym, ImpEntity::ImpTypeBlue);
break;
case EnemyTypeSlimeRed:
new SlimeEntity(xm, ym, SlimeTypeRed, false);
break;
case EnemyTypeSlimeBlue:
new SlimeEntity(xm, ym, SlimeTypeBlue, false);
break;
case EnemyTypeSlimeViolet:
new SlimeEntity(xm, ym, SlimeTypeViolet, false);
break;
case EnemyTypePumpkin:
new PumpkinEntity(xm, ym, false);
break;
case EnemyTypeWitch:
new WitchEntity(xm, ym, WitchEntity::WitchTypeNormal);
proceedEvent(EventMeetWitches);
break;
case EnemyTypeWitchRed:
new WitchEntity(xm, ym, WitchEntity::WitchTypeRed);
proceedEvent(EventMeetWitches);
break;
case EnemyTypeCauldron:
new CauldronEntity(xm, ym);
break;
case EnemyTypeSpiderEgg:
new SpiderEggEntity(xm, ym, false);
break;
case EnemyTypeSpiderLittle:
new LittleSpiderEntity(xm, ym, false);
break;
case EnemyTypeGhost:
new GhostEntity(xm, ym);
break;
case EnemyTypeZombie:
new ZombieEntity(xm, ym, false);
break;
case EnemyTypeZombieDark:
new ZombieDarkEntity(xm, ym);
break;
case EnemyTypeSpiderEgg_invocated:
new SpiderEggEntity(xm, ym, true);
break;
case EnemyTypeSpiderLittle_invocated:
new LittleSpiderEntity(xm, ym, true);
break;
case EnemyTypeBubble:
new BubbleEntity(xm, ym, BubbleStandard, 0);
break;
case EnemyTypeBubbleIce:
new BubbleEntity(xm, ym, BubbleIce, 0);
break;
case EnemyTypeBubbleGreater:
new BubbleEntity(xm, ym, BubbleTriple, 0);
break;
case EnemyTypeButcher:
new ButcherEntity(xm, ym);
break;
case EnemyTypeSlimeBoss:
new GiantSlimeEntity(xm, ym);
break;
case EnemyTypeCyclops:
new CyclopsEntity(xm, ym);
break;
case EnemyTypeRatKing:
new KingRatEntity(xm, ym);
break;
case EnemyTypeSpiderGiant:
new GiantSpiderEntity(xm, ym);
break;
case EnemyTypeFrancky:
new FranckyEntity(xm, ym);
break;
default:
std::cout << "[WARNING] Enemy (" << monsterType << ") not handled in switch.\n";
}
}
void WitchBlastGame::findPlaceMonsters(enemyTypeEnum monsterType, int amount)
{
// find a suitable place
bool isMonsterFlying = monsterType == EnemyTypeBat
|| monsterType == EnemyTypeImpBlue
|| monsterType == EnemyTypeImpRed;
bool bOk;
int xm, ym;
float xMonster, yMonster;
for (int index = 0; index < amount; index++)
{
bOk = false;
int watchdog = 200;
while (!bOk && watchdog > 0)
{
bOk = true;
watchdog--;
xm = 1 +rand() % (MAP_WIDTH - 3);
ym = 1 +rand() % (MAP_HEIGHT - 3);
if (monsterArray[xm][ym])
{
bOk = false;
}
if (bOk && !isMonsterFlying && !currentMap->isWalkable(xm, ym))
{
bOk = false;
}
if (bOk && isMonsterFlying && !currentMap->isFlyable(xm, ym))
{
bOk = false;
}
if (bOk)
{
xMonster = xm * TILE_WIDTH + TILE_WIDTH * 0.5f;
yMonster = ym * TILE_HEIGHT+ TILE_HEIGHT * 0.5f;
float dist2 = (xMonster - player->getX())*(xMonster - player->getX()) + (yMonster - player->getY())*(yMonster - player->getY());
if ( dist2 < 75000.0f)
{
bOk = false;
}
else
{
addMonster(monsterType, xMonster, yMonster);
monsterArray[xm][ym] = true;
}
}
}
}
}
void WitchBlastGame::generateStandardMap()
{
initMonsterArray();
saveInFight.monsters.clear();
generateStandardRoom(level);
}
item_equip_enum WitchBlastGame::getRandomEquipItem(bool toSale = false, bool noFairy = false)
{
std::vector<int> bonusSet;
int setSize = 0;
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool itemOk = true;
int eq = i + FirstEquipItem;
if (player->isEquiped(i)) itemOk = false;
// TODO item already in floor
if (itemOk && toSale && !items[eq].canBeSold) itemOk = false;
if (itemOk && !toSale && !items[eq].canBeFound) itemOk = false;
if (itemOk && items[eq].level > level) itemOk = false;
if (itemOk && isItemLocked((enumItemType)eq)) { itemOk = false; std::cout << items[eq].name << " locked!\n"; }
if (itemOk && items[eq].requirement >= FirstEquipItem
&& !player->isEquiped(items[eq].requirement - FirstEquipItem)) itemOk = false;
if (itemOk && (items[eq].specialShot != ShotTypeStandard && items[eq].level < 3) && player->canGetNewShot(false))
itemOk = false;
if (itemOk && (items[eq].specialShot != ShotTypeStandard && items[eq].level >= 3) && player->canGetNewShot(true))
itemOk = false;
if (itemOk && i == EQUIP_BOOK_DUAL && (player->isEquiped(EQUIP_BOOK_DUAL_QUICK) || player->isEquiped(EQUIP_RAPID_SHOT)))
itemOk = false;
if (itemOk && i == EQUIP_BOOK_DUAL_QUICK && (player->isEquiped(EQUIP_BOOK_DUAL) || player->isEquiped(EQUIP_RAPID_SHOT)))
itemOk = false;
if (itemOk && i == EQUIP_RAPID_SHOT && (player->isEquiped(EQUIP_BOOK_DUAL_QUICK) || player->isEquiped(EQUIP_BOOK_DUAL)))
itemOk = false;
if (itemOk && noFairy && items[eq].familiar != FamiliarNone) itemOk = false;
if (itemOk)
{
int n = 0;
switch (items[eq].rarity)
{
case RarityCommon:
n = 4;
break;
case RarityUncommon:
n = 2;
break;
case RarityRare:
n = 1;
break;
}
for (int j = 0; j < n; j++)
{
bonusSet.push_back(i);
setSize++;
}
}
}
int bonusType = 0;
if (setSize > 0) bonusType = bonusSet[rand() % setSize];
return (item_equip_enum) bonusType;
}
enumItemType WitchBlastGame::getItemSpell()
{
bool ok = false;
enumItemType item = ItemMagicianHat;
while (!ok)
{
enumCastSpell n = (enumCastSpell)(rand() % SPELL_MAX);
if (player->getActiveSpell().spell != n) ok = true;
if (ok)
{
switch (n)
{
case SpellNone:
case SpellTeleport:
item = ItemSpellTeleport;
break;
case SpellSlimeExplode:
item = ItemSpellSlimeExplode;
break;
case SpellFireball:
item = ItemSpellFireball;
break;
case SpellFreeze:
item = ItemSpellFreeze;
break;
case SpellEarthquake:
item = ItemSpellEarthquake;
break;
case SpellProtection:
item = ItemSpellProtection;
break;
case SpellWeb:
item = ItemSpellWeb;
break;
case SpellFlower:
item = ItemSpellFlower;
break;
case SpellFairy:
item = ItemSpellFairy;
break;
}
ok = !isItemLocked(item);
}
}
return item;
}
void WitchBlastGame::generateChallengeBonus(float x, float y)
{
// loot
if (player->getActiveSpell().spell == SpellNone || rand() % 2 == 0)
{
ItemEntity* newItem = new ItemEntity(getItemSpell(), x, y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
ItemEntity* healthItem1 = new ItemEntity(ItemHealthVerySmall, x, y);
healthItem1->setVelocity(Vector2D(100.0f + rand()% 250));
healthItem1->setViscosity(0.96f);
ItemEntity* healthItem2 = new ItemEntity(ItemHealthVerySmallPoison, x, y);
healthItem2->setVelocity(Vector2D(100.0f + rand()% 250));
healthItem2->setViscosity(0.96f);
}
else
{
ItemEntity* newItem = new ItemEntity(ItemBonusHealth, x, y);
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
int gold = 2 + rand() % 9;
for (int i = 0; i < gold; i++)
{
ItemEntity* newItem = new ItemEntity(ItemCopperCoin, x, y);
newItem->setVelocity(Vector2D(90.0f + rand()% 150));
newItem->setViscosity(0.96f);
}
}
}
void WitchBlastGame::checkInteraction()
{
interaction.active = false;
if (player->getPlayerStatus() != PlayerEntity::playerStatusPlaying) return;
if (currentMap->getRoomType() == roomTypeTemple)
{
int divinity = currentMap->getDivinity(player->getX() / TILE_WIDTH, player->getZ() / TILE_HEIGHT);
if (divinity > -1)
{
interaction.active = true;
interaction.type = InteractionTypeTemple;
interaction.id = divinity;
std::stringstream ss;
ss << "[" << keyToString(input[KeyInteract]) << "] - ";
if (player->getDivinity().divinity == divinity)
{
ss << tools::getLabel("interact_donate");
if (player->getGold() < 10)
{
ss << " ";
ss << tools::getLabel("interact_donate_fail");
}
}
else
{
ss << tools::getLabel("interact_worship");
ss << " ";
ss << tools::getLabel(divinityLabel[divinity] + "_0");
}
interaction.label = ss.str();
}
}
else if (player->getItemToBuy() != NULL)
{
interaction.active = true;
interaction.type = InteractionTypeMerchandise;
interaction.id = player->getItemToBuy()->getItemType();
std::stringstream ss;
ss << tools::getLabel(items[interaction.id].name);
ss << ": ";
ss << tools::getLabel(items[interaction.id].description);
if (player->getItemToBuy()->canBePickedUp())
{
ss << std::endl;
ss << "[" << keyToString(input[KeyInteract]) << "] - ";
ss << tools::getLabel("interact_shop");
}
interaction.label = ss.str();
}
}
void WitchBlastGame::verifyDoorUnlocking()
{
int collidingDirection = (player->getCollidingDirection());
if (collidingDirection > 0 && currentMap->isCleared() && !bossRoomOpened && player->isEquiped(EQUIP_BOSS_KEY))
{
int xt = (player->getX()) / TILE_WIDTH;
int yt = (player->getY()) / TILE_HEIGHT;
if (yt <= 1 && xt >= MAP_WIDTH / 2 - 1 && xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourUp() == 2)
{
doorEntity[0]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, 0, 0);
SoundManager::getInstance().playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (yt >= MAP_HEIGHT - 2 && xt >= MAP_WIDTH / 2 - 1 &&xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourDown() == 2)
{
doorEntity[2]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, 0);
SoundManager::getInstance().playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt <= 1 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourLeft() == 2)
{
doorEntity[1]->openDoor();
currentMap->setTile(0, MAP_HEIGHT / 2, 0);
SoundManager::getInstance().playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt >= MAP_WIDTH - 2 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourRight() == 2)
{
doorEntity[3]->openDoor();
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, 0);
SoundManager::getInstance().playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
}
}
void WitchBlastGame::playMusic(musicEnum musicChoice)
{
music.stop();
if (parameters.musicVolume <= 0) return;
music.setLoop(true);
music.setVolume(parameters.musicVolume);
bool ok = false;
switch (musicChoice)
{
case MusicDungeon:
if (rand() % 2 == 0)
{
ok = music.openFromFile("media/sound/game_Fantasy_Theme_Of_Elvarim.ogg");
}
else
{
ok = music.openFromFile("media/sound/game_Marching_United.ogg");
}
break;
case MusicEnding:
ok = music.openFromFile("media/sound/ending_Music_Is_His_Only_Friend.ogg");
music.setVolume(parameters.musicVolume * 50 / 100);
break;
case MusicBoss:
if (rand() % 2 == 0)
{
ok = music.openFromFile("media/sound/boss_The_Spider_Machine.ogg");
}
else
{
ok = music.openFromFile("media/sound/boss_Pub_Stomp_Deluxe.ogg");
}
break;
case MusicChallenge:
ok = music.openFromFile("media/sound/challenge_Under_Siege.ogg");
break;
case MusicIntro:
ok = music.openFromFile("media/sound/menu_Our_Ship_To_Candletown.ogg");
music.setVolume(parameters.musicVolume * 60 / 100);
break;
}
if (ok)
music.play();
}
void WitchBlastGame::updateMusicVolume()
{
if (music.getStatus() == sf::Music::Playing)
{
if (parameters.musicVolume == 0)
music.stop();
else
music.setVolume(parameters.musicVolume * 60 / 100);
}
else
{
if (parameters.musicVolume > 0)
{
bool ok = music.openFromFile("media/sound/menu_Our_Ship_To_Candletown.ogg");
music.setVolume(parameters.musicVolume * 60 / 100);
if (ok) music.play();
}
}
}
void WitchBlastGame::makeShake(float duration)
{
xGame[xGameTypeShake].active = true;
xGame[xGameTypeShake].timer = duration;
}
void WitchBlastGame::makeColorEffect(int color, float duration)
{
xGame[xGameTypeFadeColor].active = true;
xGame[xGameTypeFadeColor].param = color;
xGame[xGameTypeFadeColor].timer = duration;
xGame[xGameTypeFadeColor].duration = duration;
}
void WitchBlastGame::saveGame()
{
if (player->getPlayerStatus() == PlayerEntity::playerStatusAcquire)
player->acquireItemAfterStance();
std::ofstream file(SAVE_FILE.c_str(), std::ios::out | std::ios::trunc);
int i, j, k, l;
if (file)
{
// version (for compatibility check)
file << SAVE_VERSION << std::endl;
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
file << (now->tm_year + 1900) << '-';
if (now->tm_mon < 9) file << "0";
file << (now->tm_mon + 1) << '-';
if (now->tm_mday < 9) file << "0";
file << now->tm_mday
<< std::endl;
if (now->tm_hour <= 9) file << "0";
file << (now->tm_hour) << ':';
if (now->tm_min <= 9) file << "0";
file << (now->tm_min) << std::endl;
// floor
file << level << " " << challengeLevel << std::endl;
// game age
file << (int)gameTime << std::endl;
// player equip
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++) file << player->isEquiped(i) << " ";
file << std::endl;
file << player->getShotType() << std::endl;
int nbRooms = 0;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
file << currentFloor->getRoom(i,j) << " ";
if (currentFloor->getRoom(i,j) > 0) nbRooms++;
}
file << std::endl;
}
// kill stats
for (i = 0; i < NB_ENEMY; i++) file << killedEnemies[i] << " ";
file << std::endl;
// maps
if (currentMap->isCleared())
saveMapItems();
file << nbRooms << std::endl;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
if (currentFloor->getRoom(i,j) > 0)
{
file << i << " " << j << " "
<< currentFloor->getMap(i, j)->getRoomType() << " "
<< currentFloor->getMap(i, j)->isKnown() << " "
<< currentFloor->getMap(i, j)->isVisited() << " "
<< currentFloor->getMap(i, j)->isCleared() << std::endl;
if (currentFloor->getMap(i, j)->isVisited())
{
for (l = 0; l < MAP_HEIGHT; l++)
{
for (k = 0; k < MAP_WIDTH; k++)
{
int tile = currentFloor->getMap(i, j)->getTile(k, l);
if (tile == MAP_DOOR && !(k > 0 && k < MAP_WIDTH - 1 && l > 0 && l < MAP_HEIGHT - 1)) tile = 0;
file << tile << " ";
}
file << std::endl;
}
// items, etc...
std::list<DungeonMap::itemListElement> itemList = currentFloor->getMap(i, j)->getItemList();
file << itemList.size() << std::endl;
std::list<DungeonMap::itemListElement>::iterator it;
for (it = itemList.begin (); it != itemList.end ();)
{
DungeonMap::itemListElement ilm = *it;
it++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.merch << std::endl;
}
// chests
std::list<DungeonMap::chestListElement> chestList = currentFloor->getMap(i, j)->getChestList();
file << chestList.size() << std::endl;
std::list<DungeonMap::chestListElement>::iterator itc;
for (itc = chestList.begin (); itc != chestList.end ();)
{
DungeonMap::chestListElement ilm = *itc;
itc++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.state << std::endl;
}
// sprites
std::list<DungeonMap::spriteListElement> spriteList = currentFloor->getMap(i, j)->getSpriteList();
file << spriteList.size() << std::endl;
std::list<DungeonMap::spriteListElement>::iterator its;
for (its = spriteList.begin (); its != spriteList.end ();)
{
DungeonMap::spriteListElement ilm = *its;
its++;
file << ilm.type << " " << ilm.frame << " " << ilm.x << " " << ilm.y << " " << ilm.scale << std::endl;
}
}
}
}
file << std::endl;
}
// game
file << floorX << " " << floorY << std::endl;
file << bossRoomOpened << std::endl;
// boss door !
// fight ?
if (currentMap->isCleared())
{
file << false << std::endl;
}
else
{
file << true << std::endl;
file << saveInFight.x << " " << saveInFight.y << " " << saveInFight.direction << std::endl;
file << saveInFight.monsters.size();
for (auto monster : saveInFight.monsters)
file << " " << monster.id << " " << monster.x << " " << monster.y;
file << std::endl;
}
// player
file << player->getHp() << " " << player->getHpMax() << " " << player->getGold() << std::endl;
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++) file << player->isEquiped(i) << " ";
file << std::endl;
file << player->getX() << " " << player->getY() << std::endl;
file << player->getShotIndex();
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++) file << " " << player->getShotType(i) << std::endl;
file << player->getActiveSpell().spell << std::endl;
// divinity
file << player->getDivinity().divinity << " " << player->getDivinity().piety << " "
<< player->getDivinity().level << " " << player->getDivinity().interventions << std::endl;
// events
for (i = 0; i < NB_EVENTS; i++) file << worldEvent[i] << " ";
file.close();
}
else
{
std::cerr << "[ERROR] Saving the game..." << std::endl;
}
}
bool WitchBlastGame::loadGame()
{
saveInFight.monsters.clear();
std::ifstream file(SAVE_FILE.c_str(), std::ios::in);
if (file)
{
int i, j, k, n;
// version
std::string v;
file >> v;
if (v != SAVE_VERSION)
{
file.close();
remove(SAVE_FILE.c_str());
return false;
}
// date an time
file >> v;
file >> v;
// floor
file >> level;
file >> challengeLevel;
file >> gameTime;
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool eq;
file >> eq;
}
file >> n;
currentFloor = new GameFloor(level);
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
int n;
file >> n;
currentFloor->setRoom(i, j, (roomTypeEnum)n);
}
}
// kill stats
for (int i = 0; i < NB_ENEMY; i++) file >> killedEnemies[i];
// maps
int nbRooms;
file >> nbRooms;
for (k = 0; k < nbRooms; k++)
{
file >> i;
file >> j;
file >> n;
DungeonMap* iMap = new DungeonMap(currentFloor, i, j);
currentFloor->setMap(i, j, iMap);
iMap->setRoomType((roomTypeEnum)n);
bool flag;
file >> flag;
iMap->setKnown(flag);
file >> flag;
iMap->setVisited(flag);
file >> flag;
iMap->setCleared(flag);
if (iMap->isVisited())
{
for (j = 0; j < MAP_HEIGHT; j++)
{
for (i = 0; i < MAP_WIDTH; i++)
{
file >> n;
iMap->setTile(i, j, n);
}
}
// items int the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool merc;
file >> t >> x >> y >> merc;
iMap->addItem(t, x, y, merc);
}
// chests in the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool state;
file >> t >> x >> y >> state;
iMap->addChest(t, state, x, y);
}
// sprites in the map
file >> n;
for (i = 0; i < n; i++)
{
int t, f;
float x, y, scale;
file >> t >> f >> x >> y >> scale;
iMap->addSprite(t, f, x, y, scale);
}
}
}
// game
file >> floorX >> floorY;
currentMap = currentFloor->getMap(floorX, floorY);
file >> bossRoomOpened;
// fight ?
file >> saveInFight.isFight;
if (saveInFight.isFight)
{
currentMap->setCleared(false);
file >> saveInFight.x;
file >> saveInFight.y;
file >> saveInFight.direction;
file >> n;
for (i = 0; i < n; i++)
{
StructMonster monster;
file >> j;
monster.id = (enemyTypeEnum)j;
file >> monster.x;
file >> monster.y;
saveInFight.monsters.push_back(monster);
}
}
// player
int hp, hpMax, gold;
file >> hp >> hpMax >> gold;
player = new PlayerEntity((TILE_WIDTH * MAP_WIDTH * 0.5f),
(TILE_HEIGHT * MAP_HEIGHT * 0.5f));
player->setHp(hp);
player->setHpMax(hpMax);
player->setGold(gold);
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool eq;
file >> eq;
player->setEquiped(i, eq);
}
float x, y;
file >> x >> y;
if (saveInFight.isFight)
{
x = saveInFight.x;
y = saveInFight.y;
player->move(saveInFight.direction);
player->setEntering();
}
player->moveTo(x, y);
file >> n;
player->setShotIndex(n);
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
file >> n;
player->setShotType(i, (enumShotType)n);
}
file >> n;
player->setActiveSpell((enumCastSpell)n, saveInFight.isFight);
// divinity
{
int divinityId, piety, divLevel, interventions;
file >> divinityId;
file >> piety;
file >> divLevel;
file >> interventions;
player->loadDivinity(divinityId, piety, divLevel, interventions);
}
// events
for (i = 0; i < NB_EVENTS; i++)
{
bool event;
file >> event;
worldEvent[i] = event;
}
player->computePlayer();
file.close();
remove(SAVE_FILE.c_str());
}
else
{
return false;
}
return true;
}
WitchBlastGame::saveHeaderStruct WitchBlastGame::loadGameHeader()
{
saveHeaderStruct saveHeader;
saveHeader.ok = true;
std::ifstream file(SAVE_FILE.c_str(), std::ios::in);
if (file)
{
// version
std::string v;
file >> v;
if (v != SAVE_VERSION)
{
file.close();
remove(SAVE_FILE.c_str());
saveHeader.ok = false;
}
else
{
// date an time
file >> saveHeader.date;
file >> saveHeader.time;
// floor
file >> saveHeader.level;
int challengeLevel;
file >> challengeLevel;
file >> saveHeader.gameTime;
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
file >> equipToDisplay[i];
file >> saveHeader.shotType;
}
}
else
{
saveHeader.ok = false;
}
return saveHeader;
}
void WitchBlastGame::saveGameData()
{
// TODO
std::ofstream file(SAVE_DATA_FILE.c_str(), std::ios::out | std::ios::trunc);
if (file)
{
// version (for compatibility check)
file << SAVE_VERSION << std::endl;
int i;
// tuto
for (i = 0; i < NB_MESSAGES; i++)
{
messageStruct msg = getMessage((EnumMessages)i);
if (msg.messageType == MessageTypeTutorial)
{
file << gameMessagesToSkip[i] << " ";
}
else file << "0 ";
}
file << std::endl;
// achievements
for (i = 0; i < NB_ACHIEVEMENTS; i++)
{
if (achievementState[i] == AchievementDone) file << "1 ";
else file << "0 ";
}
file << std::endl;
// monsters
for (i = 0; i < NB_ENEMY; i++)
{
file << globalData.killedMonster[i] << " ";
}
file << std::endl;
file.close();
}
else
{
std::cout << "[ERROR] Impossible to open save data file.\n";
}
}
void WitchBlastGame::loadGameData()
{
std::ifstream file(SAVE_DATA_FILE.c_str(), std::ios::in);
int i;
if (file)
{
// version
std::string v;
file >> v;
if (v != SAVE_VERSION)
{
file.close();
remove(SAVE_DATA_FILE.c_str());
return;
}
// tuto
for (i = 0; i < NB_MESSAGES; i++)
{
file >> gameMessagesToSkip[i];
}
}
// Achievements
for (i = 0; i < NB_ACHIEVEMENTS; i++)
{
int n;
file >> n;
if (n == 1) achievementState[i] = AchievementDone;
else achievementState[i] = AchievementUndone;
}
// Monsters
for (i = 0; i < NB_ENEMY; i++)
file >> globalData.killedMonster[i];
}
void WitchBlastGame::addKey(int logicInput, std::string key)
{
int iKey = config.findInt(key);
if (iKey >= 0)
{
sf::Keyboard::Key k = (sf::Keyboard::Key)iKey;
input[logicInput] = k;
}
}
void WitchBlastGame::saveConfigurationToFile()
{
std::map<std::string, std::string> newMap;
// parameters
newMap["language"] = intToString(parameters.language);
newMap["player_name"] = parameters.playerName;
// audio volume
newMap["volume_sound"] = intToString(parameters.soundVolume);
newMap["volume_music"] = intToString(parameters.musicVolume);
newMap["zoom_enabled"] = parameters.zoom ? "1" : "0";
newMap["vsync_enabled"] = parameters.vsync ? "1" : "0";
newMap["blood_spreading"] = parameters.bloodSpread ? "1" : "0";
newMap["fullscreen"] = parameters.fullscreen ? "1" : "0";
// Keys
newMap["keyboard_move_up"] = intToString(input[KeyUp]);
newMap["keyboard_move_down"] = intToString(input[KeyDown]);
newMap["keyboard_move_left"] = intToString(input[KeyLeft]);
newMap["keyboard_move_right"] = intToString(input[KeyRight]);
newMap["keyboard_fire_up"] = intToString(input[KeyFireUp]);
newMap["keyboard_fire_down"] = intToString(input[KeyFireDown]);
newMap["keyboard_fire_left"] = intToString(input[KeyFireLeft]);
newMap["keyboard_fire_right"] = intToString(input[KeyFireRight]);
newMap["keyboard_spell"] = intToString(input[KeySpell]);
newMap["keyboard_interact"] = intToString(input[KeyInteract]);
newMap["keyboard_fire"] = intToString(input[KeyFire]);
newMap["keyboard_time_control"] = intToString(input[KeyTimeControl]);
newMap["keyboard_fire_select"] = intToString(input[KeyFireSelect]);
config.saveToFile(CONFIG_FILE, newMap);
}
void WitchBlastGame::configureFromFile()
{
// default
parameters.language = 0; // english
parameters.zoom = true;
parameters.vsync = true;
parameters.bloodSpread = true;
parameters.fullscreen = false;
parameters.musicVolume = 60;
parameters.soundVolume = 100;
parameters.playerName = "";
input[KeyUp] = sf::Keyboard::W;
input[KeyDown] = sf::Keyboard::S;
input[KeyLeft] = sf::Keyboard::A;
input[KeyRight] = sf::Keyboard::D;
input[KeyFireUp] = sf::Keyboard::Up;
input[KeyFireDown] = sf::Keyboard::Down;
input[KeyFireLeft] = sf::Keyboard::Left;
input[KeyFireRight] = sf::Keyboard::Right;
input[KeyFire] = sf::Keyboard::RControl;
input[KeySpell] = sf::Keyboard::Space;
input[KeyInteract] = sf::Keyboard::E;
input[KeyFireSelect] = sf::Keyboard::Tab;
input[KeyTimeControl] = sf::Keyboard::RShift;
// from file
addKey(KeyUp, "keyboard_move_up");
addKey(KeyDown, "keyboard_move_down");
addKey(KeyLeft, "keyboard_move_left");
addKey(KeyRight, "keyboard_move_right");
addKey(KeyFireUp, "keyboard_fire_up");
addKey(KeyFireDown, "keyboard_fire_down");
addKey(KeyFireLeft, "keyboard_fire_left");
addKey(KeyFireRight, "keyboard_fire_right");
addKey(KeyFire, "keyboard_fire");
addKey(KeySpell, "keyboard_spell");
addKey(KeyTimeControl, "keyboard_time_control");
addKey(KeyFireSelect, "keyboard_fire_select");
int i = config.findInt("language");
if (i >= 0) parameters.language = i;
i = config.findInt("volume_sound");
if (i >= 0) parameters.soundVolume = i;
i = config.findInt("volume_music");
if (i >= 0) parameters.musicVolume = i;
i = config.findInt("vsync_enabled");
if (i >= 0) parameters.vsync = i;
i = config.findInt("zoom_enabled");
if (i >= 0) parameters.zoom = i;
i = config.findInt("blood_spreading");
if (i >= 0) parameters.bloodSpread = i;
i = config.findInt("fullscreen");
if (i >= 0) parameters.fullscreen = i;
std::string playerName = config.findString("player_name");
if (playerName.size() > 0) parameters.playerName = playerName;
tools::setLanguage(languageString[parameters.language]);
}
parameterStruct WitchBlastGame::getParameters()
{
return parameters;
}
void WitchBlastGame::buildMenu(bool rebuild)
{
menuMain.items.clear();
menuConfig.items.clear();
menuFirst.items.clear();
if (!rebuild)
{
menuState = MenuStateMain;
menuMain.age = 0.0f;
menuConfig.age = 0.0f;
menuConfig.index = 0;
}
saveHeader = loadGameHeader();
menuItemStuct itemName;
itemName.label = tools::getLabel("player_name");
itemName.description = tools::getLabel("player_name_desc");
itemName.id = MenuPlayerName;
menuMain.items.push_back(itemName);
if (saveHeader.ok)
{
menuItemStuct itemStart;
itemStart.label = tools::getLabel("start_new_game");
itemStart.description = tools::getLabel("start_desc");
itemStart.id = MenuStartNew;
menuMain.items.push_back(itemStart);
menuItemStuct itemLoad;
itemStart.label = tools::getLabel("restore");
std::ostringstream oss;
oss << saveHeader.date << " " << tools::getLabel("at") << " " << saveHeader.time << " - " << tools::getLabel("level") << " " << saveHeader.level;
itemStart.description = oss.str();
itemStart.id = MenuStartOld;
menuMain.items.push_back(itemStart);
if (!rebuild) menuMain.index = 2;
}
else
{
menuItemStuct itemStart;
itemStart.label = tools::getLabel("start_new_game");
itemStart.description = tools::getLabel("begin_journey");
itemStart.id = MenuStartNew;
menuMain.items.push_back(itemStart);
if (!rebuild) menuMain.index = 1;
}
if (parameters.playerName.compare("") == 0 && menuState == MenuStateMain)
{
menuMain.index = 0;
menuState = MenuStateChangeName;
}
menuItemStuct itemConfig;
itemConfig.label = tools::getLabel("configure_game");
itemConfig.description = tools::getLabel("configure_game_desc");
itemConfig.id = MenuConfig;
menuMain.items.push_back(itemConfig);
menuItemStuct itemAchiev;
std::ostringstream oss;
oss << tools::getLabel("menu_achievements");
oss << " (" << getAchievementsPercents() << "%)";
itemAchiev.label = oss.str();
itemAchiev.description = tools::getLabel("menu_achievements_desc");
itemAchiev.id = MenuAchievements;
menuMain.items.push_back(itemAchiev);
if (scores.size() > 0)
{
menuItemStuct itemHiScores;
itemHiScores.label = tools::getLabel("hi_scores");
itemHiScores.description = tools::getLabel("hi_scores_desc");
itemHiScores.id = MenuHiScores;
menuMain.items.push_back(itemHiScores);
}
menuItemStuct itemCredits;
itemCredits.label = tools::getLabel("credits");
itemCredits.description = tools::getLabel("credits_desc");
itemCredits.id = MenuCredits;
menuMain.items.push_back(itemCredits);
menuItemStuct itemExit;
itemExit.label = tools::getLabel("exit_game");
itemExit.description = tools::getLabel("return_to_desktop");
itemExit.id = MenuExit;
menuMain.items.push_back(itemExit);
// configuration
menuItemStuct itemKeys;
itemKeys.label = tools::getLabel("config_keys");
itemKeys.description = tools::getLabel("redef_input");
itemKeys.id = MenuKeys;
menuConfig.items.push_back(itemKeys);
menuItemStuct itemLanguage;
itemLanguage.label = tools::getLabel("config_lang");
itemLanguage.description = tools::getLabel("config_lang_desc");
itemLanguage.id = MenuLanguage;
menuConfig.items.push_back(itemLanguage);
menuItemStuct itemVolumeSound;
itemVolumeSound.label = tools::getLabel("volume_sound");
itemVolumeSound.description = tools::getLabel("volume_sound_desc");
itemVolumeSound.id = MenuVolumeSound;
menuConfig.items.push_back(itemVolumeSound);
menuItemStuct itemVolumeMusic;
itemVolumeMusic.label = tools::getLabel("volume_music");
itemVolumeMusic.description = tools::getLabel("volume_sound_desc");
itemVolumeMusic.id = MenuVolumeMusic;
menuConfig.items.push_back(itemVolumeMusic);
menuItemStuct itemTutoReset;
itemTutoReset.label = tools::getLabel("tuto_reset");
itemTutoReset.description = tools::getLabel("tuto_reset_desc");
itemTutoReset.id = MenuTutoReset;
menuConfig.items.push_back(itemTutoReset);
menuItemStuct itemConfigBack;
itemConfigBack.label = tools::getLabel("config_back");
itemConfigBack.description = tools::getLabel("config_back_desc");
itemConfigBack.id = MenuConfigBack;
menuConfig.items.push_back(itemConfigBack);
//first time screen
menuFirst.items.push_back(itemLanguage);
}
void WitchBlastGame::buildInGameMenu()
{
menuInGame.items.clear();
menuItemStuct itemContinue;
itemContinue.label = tools::getLabel("menu_continue");
itemContinue.description = tools::getLabel("menu_continue_desc");
itemContinue.id = MenuContinue;
menuInGame.items.push_back(itemContinue);
menuItemStuct itemSaveQuit;
itemSaveQuit.label = tools::getLabel("menu_save_quit");
itemSaveQuit.description = tools::getLabel("menu_save_quit_desc");
itemSaveQuit.id = MenuSaveAndQuit;
menuInGame.items.push_back(itemSaveQuit);
menuItemStuct itemQuit;
itemQuit.label = tools::getLabel("menu_quit");
itemQuit.description = tools::getLabel("menu_quit_desc");
itemQuit.id = MenuExit;
menuInGame.items.push_back(itemQuit);
menuInGame.index = 0;
}
void WitchBlastGame::resetKilledEnemies()
{
for (int i = 0; i < NB_ENEMY; i++) killedEnemies[i] = 0;
}
void WitchBlastGame::addKilledEnemy(enemyTypeEnum enemyType, enumShotType hurtingType)
{
if(!player->isDead())
{
if (enemyType == NB_ENEMY)
std::cout << "[ERROR] No enemy type";
else
{
killedEnemies[enemyType]++;
globalData.killedMonster[enemyType]++;
player->offerMonster(enemyType, hurtingType);
// achievements
- if (enemyType == EnemyTypeSlimeBoss) registerAchievement(AchievementGiantSlime);
+ if (enemyType == EnemyTypeButcher) registerAchievement(AchievementButcher);
+ else if (enemyType == EnemyTypeSlimeBoss) registerAchievement(AchievementGiantSlime);
else if (enemyType == EnemyTypeCyclops) registerAchievement(AchievementCyclops);
else if (enemyType == EnemyTypeRatKing) registerAchievement(AchievementRatKing);
else if (enemyType == EnemyTypeSpiderGiant) registerAchievement(AchievementGiantSpider);
else if (enemyType == EnemyTypeFranckyHead) registerAchievement(AchievementFrancky);
else if ((enemyType == EnemyTypeRat || enemyType == EnemyTypeRatHelmet
|| enemyType == EnemyTypeRatBlack || enemyType == EnemyTypeRatBlackHelmet))
+ {
if (globalData.killedMonster[EnemyTypeRat] + globalData.killedMonster[EnemyTypeRatHelmet]
- + globalData.killedMonster[EnemyTypeRatBlack] + globalData.killedMonster[EnemyTypeRatBlackHelmet] >= 10)
+ + globalData.killedMonster[EnemyTypeRatBlack] + globalData.killedMonster[EnemyTypeRatBlackHelmet] >= 250)
registerAchievement(AchievementRats);
+ }
+ else if (enemyType == EnemyTypeWitch || enemyType == EnemyTypeWitchRed)
+ {
+ if (globalData.killedMonster[EnemyTypeWitch] + globalData.killedMonster[EnemyTypeWitchRed] >= 50)
+ registerAchievement(AchievementWitches);
+ }
+ else if (enemyType == EnemyTypeSpiderEgg || enemyType == EnemyTypeSpiderEgg_invocated)
+ {
+ if (globalData.killedMonster[EnemyTypeSpiderEgg] + globalData.killedMonster[EnemyTypeSpiderEgg_invocated] >= 100)
+ registerAchievement(AchievementEggs);
+ }
}
}
}
void WitchBlastGame::registerLanguage()
{
// default keys
if (parameters.language == 1)
{
// french keyboard
input[KeyUp] = sf::Keyboard::Z;
input[KeyLeft] = sf::Keyboard::Q;
}
else
{
// QWERT / QWERTZ keyboard
input[KeyUp] = sf::Keyboard::W;
input[KeyLeft] = sf::Keyboard::A;
}
input[KeyDown] = sf::Keyboard::S;
input[KeyRight] = sf::Keyboard::D;
input[KeyFireUp] = sf::Keyboard::Up;
input[KeyFireDown] = sf::Keyboard::Down;
input[KeyFireLeft] = sf::Keyboard::Left;
input[KeyFireRight] = sf::Keyboard::Right;
input[KeyFire] = sf::Keyboard::RControl;
input[KeyFireSelect] = sf::Keyboard::Tab;
input[KeyTimeControl] = sf::Keyboard::RShift;
input[KeySpell] = sf::Keyboard::Space;
saveConfigurationToFile();
}
int WitchBlastGame::getAchievementsPercents()
{
int n = 0;
for (int i = 0; i < NB_ACHIEVEMENTS; i++)
if (achievementState[i] == AchievementDone) n++;
return (n * 100) / NB_ACHIEVEMENTS;
}
void WitchBlastGame::testAndAddMessageToQueue(EnumMessages type)
{
if (gameMessagesToSkip[type] == false)
{
if (messagesQueue.empty()) SoundManager::getInstance().playSound(SOUND_MESSAGE);
messageStruct msg = getMessage(type);
if (type == MsgInfoDivGift || type == MsgInfoDivIntervention)
{
std::stringstream ss;
ss << tools::getLabel(divinityLabel[player->getDivinity().divinity] + "_0");
ss << " ";
if (type == MsgInfoDivGift)
ss << tools::getLabel("divinity_gift_1");
else // (type == MsgInfoDivIntervention)
ss << tools::getLabel("divinity_intervention_1");
msg.message[1] = ss.str();
msg.icon = 2 + player->getDivinity().divinity;
}
messagesQueue.push(msg);
if (msg.messageType == MessageTypeTutorial)
{
gameMessagesToSkip[type] = true;
saveGameData();
}
}
}
void WitchBlastGame::initEvents()
{
for (int i = 0; i < NB_EVENTS; i++)
worldEvent[i] = false;
}
void WitchBlastGame::proceedEvent(EnumWorldEvents event)
{
// achievements
if (event == EventGetCoin)
{
if (!achievementState[Achievement100] && player->getGold() > 100)
registerAchievement(Achievement100);
}
else if (event == EventPietyMax)
{
if (!achievementState[AchievementPietyMax]) registerAchievement(AchievementPietyMax);
}
else if (event == EventTripleHit)
{
if (!achievementState[Achievement3Hits]) registerAchievement(Achievement3Hits);
}
else if (event == EventCompleteSet)
{
if (!achievementState[AchievementCompleteSet]) registerAchievement(AchievementCompleteSet);
}
// message ?
if (worldEvent[event]) return;
worldEvent[event] = true;
testAndAddMessageToQueue(eventToMessage[event]);
}
void WitchBlastGame::renderPlayer(float x, float y,
bool equip[NUMBER_EQUIP_ITEMS], int shotType,
int frame, int spriteDy)
{
bool isMirroring = false;
sf::Sprite sprite;
if (equip[EQUIP_FAIRY_FIRE])
{
sprite.setPosition(x - 35, y - 25);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
sprite.setTextureRect(sf::IntRect( 0, 144, 48, 60));
app->draw(sprite);
}
if (equip[EQUIP_FAIRY_ICE])
{
sprite.setPosition(x - 5, y - 25);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
sprite.setTextureRect(sf::IntRect( 0, 216, 48, 60));
app->draw(sprite);
}
if (equip[EQUIP_FAIRY])
{
sprite.setPosition(x - 40, y);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
sprite.setTextureRect(sf::IntRect( 0, 0, 48, 60));
app->draw(sprite);
}
if (equip[EQUIP_FAIRY_TARGET])
{
sprite.setPosition(x - 10, y);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_FAIRY));
sprite.setTextureRect(sf::IntRect( 0, 72, 48, 60));
app->draw(sprite);
}
sprite.setPosition(x, y);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_0));
int width = 64;
int height = 96;
// body
if (isMirroring)
sprite.setTextureRect(sf::IntRect( frame * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( frame * width, spriteDy * height, width, height));
app->draw(sprite);
if (equip[EQUIP_MAGICIAN_ROBE])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (12 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (12 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
if (equip[EQUIP_DISPLACEMENT_GLOVES])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (21 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (21 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
if (equip[EQUIP_CRITICAL_ADVANCED])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (24 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (24 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
if (equip[EQUIP_RAGE_AMULET])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (18 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (18 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
if (equip[EQUIP_LEATHER_BELT])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (15 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (15 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
// hat
if (equip[EQUIP_MAGICIAN_HAT])
{
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_1));
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (6 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (6 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_0));
}
// boots
if (equip[EQUIP_LEATHER_BOOTS])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (9 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (9 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
// staff
int frameDx = equip[EQUIP_MAHOGANY_STAFF] ? 6 : 3;
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (frameDx + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (frameDx + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
if (equip[EQUIP_BLOOD_SNAKE])
{
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (27 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (27 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
}
if (equip[EQUIP_REAR_SHOT])
{
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_1));
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (frame) * width, spriteDy * height, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_0));
}
// shot type
if (shotType != ShotTypeStandard)
{
switch (shotType)
{
case ShotTypeIce:
sprite.setColor(sf::Color(100, 220, 255, 255));
break;
case ShotTypeStone:
sprite.setColor(sf::Color(120, 120, 150, 255));
break;
case ShotTypeLightning:
sprite.setColor(sf::Color(255, 255, 0, 255));
break;
case ShotTypeIllusion:
sprite.setColor(sf::Color(240, 180, 250, 255));
break;
case ShotTypeStandard:
sprite.setColor(sf::Color(255, 255, 255, 0));
break;
case ShotTypeFire:
sprite.setColor(sf::Color(255, 180, 0, 255));
break;
default:
break;
}
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_1));
if (isMirroring)
sprite.setTextureRect(sf::IntRect( (3 + frame) * width + width, spriteDy * height, -width, height));
else
sprite.setTextureRect(sf::IntRect( (3 + frame) * width, spriteDy * height, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getInstance().getImage(IMAGE_PLAYER_0));
}
}
std::string WitchBlastGame::enemyToString(enemyTypeEnum enemyType)
{
std::string value = "unknown";
switch (enemyType)
{
case EnemyTypeBat_invocated:
case EnemyTypeBat:
value = "enemy_type_bat";
break;
case EnemyTypeRat_invocated:
case EnemyTypeRat:
value = "enemy_type_rat";
break;
case EnemyTypeRatBlack:
value = "enemy_type_rat_black";
break;
case EnemyTypeRatHelmet_invocated:
case EnemyTypeRatHelmet:
value = "enemy_type_rat_helmet";
break;
case EnemyTypeRatBlackHelmet:
value = "enemy_type_rat_black_helmet";
break;
case EnemyTypeEvilFlower:
value = "enemy_type_evil_flower";
break;
case EnemyTypeEvilFlowerIce:
value = "enemy_type_evil_flower_ice";
break;
case EnemyTypeEvilFlowerFire:
value = "enemy_type_evil_flower_fire";
break;
case EnemyTypeSnake_invocated:
case EnemyTypeSnake:
value = "enemy_type_snake";
break;
case EnemyTypeSnakeBlood_invocated:
case EnemyTypeSnakeBlood:
value = "enemy_type_snake_blood";
break;
case EnemyTypeSlime_invocated:
case EnemyTypeSlime:
value = "enemy_type_slime";
break;
case EnemyTypeSlimeRed_invocated:
case EnemyTypeSlimeRed:
value = "enemy_type_slime_red";
break;
case EnemyTypeSlimeBlue_invocated:
case EnemyTypeSlimeBlue:
value = "enemy_type_slime_blue";
break;
case EnemyTypeSlimeViolet_invocated:
case EnemyTypeSlimeViolet:
value = "enemy_type_slime_violet";
break;
case EnemyTypeImpBlue:
value = "enemy_type_imp_blue";
break;
case EnemyTypeImpRed:
value = "enemy_type_imp_red";
break;
case EnemyTypePumpkin_invocated:
case EnemyTypePumpkin:
value = "enemy_type_pumpkin";
break;
case EnemyTypeWitch:
value = "enemy_type_witch";
break;
case EnemyTypeWitchRed:
value = "enemy_type_witch_red";
break;
case EnemyTypeCauldron:
value = "enemy_type_cauldron";
break;
case EnemyTypeGhost:
value = "enemy_type_ghost";
break;
case EnemyTypeZombie_invocated:
case EnemyTypeZombie:
value = "enemy_type_zombie";
break;
case EnemyTypeZombieDark:
value = "enemy_type_zombie_dark";
break;
// mini boss
case EnemyTypeBubble:
value = "enemy_type_bubble";
break;
case EnemyTypeBubbleIce:
value = "enemy_type_bubble_ice";
break;
case EnemyTypeBubbleGreater:
value = "enemy_type_bubble_greater";
break;
// boss
case EnemyTypeButcher:
value = "enemy_type_boss_butcher";
break;
case EnemyTypeSlimeBoss:
value = "enemy_type_boss_slime_giant";
break;
case EnemyTypeCyclops:
value = "enemy_type_boss_cyclops";
break;
case EnemyTypeRatKing:
value = "enemy_type_boss_rat_king";
break;
case EnemyTypeSpiderGiant:
value = "enemy_type_boss_spider_giant";
break;
case EnemyTypeFranckyHand:
case EnemyTypeFranckyHead:
case EnemyTypeFranckyFoot:
case EnemyTypeFrancky:
value = "enemy_type_francky";
break;
// invocated
case EnemyTypeRatGreen:
value = "enemy_type_green_rat";
break;
case EnemyTypeRockFalling:
value = "enemy_type_rock_falling";
break;
case EnemyTypeRockMissile:
value = "enemy_type_rock_missile";
break;
case EnemyTypeSpiderEgg:
case EnemyTypeSpiderEgg_invocated:
value = "enemy_type_spider_egg";
break;
case EnemyTypeSpiderLittle:
case EnemyTypeSpiderLittle_invocated:
value = "enemy_type_spider_little";
break;
case EnemyTypeSpiderWeb:
value = "enemy_type_spider_web";
break;
case EnemyTypeNone:
value = "enemy_type_himself";
break;
case NB_ENEMY:
break;
}
return value;
}
std::string WitchBlastGame::sourceToString(sourceTypeEnum sourceType, enemyTypeEnum enemyType)
{
std::string value = "unknown";
switch (sourceType)
{
case SourceTypeBolt:
case SourceTypeMelee:
value = tools::getLabel(enemyToString(enemyType));
break;
case SourceTypeExplosion:
value = tools::getLabel("source_explosion");
break;
case SourceTypePoison:
value = tools::getLabel("source_poison");
}
return value;
}
void WitchBlastGame::saveHiScores()
{
std::ofstream file(HISCORES_FILE.c_str(), std::ios::out | std::ios::trunc);
if (file)
{
// version (for compatibility check)
file << SAVE_VERSION << std::endl;
file << scores.size() << std::endl;
// tuto
for (unsigned int i = 0; i < scores.size() && i < SCORES_MAX; i++)
{
file << scores[i].name << " ";
file << scores[i].level << " ";
file << scores[i].score << " ";
file << scores[i].shotType << " ";
// player equip
for (int j = 0; j < NUMBER_EQUIP_ITEMS; j++)
file << scores[i].equip[j] << " ";
file << std::endl;
}
file << std::endl;
file.close();
}
else
{
std::cout << "[ERROR] Impossible to open hi-scores file.\n";
}
}
void WitchBlastGame::loadHiScores()
{
scores.clear();
std::ifstream file(HISCORES_FILE.c_str(), std::ios::in);
if (file)
{
// version
std::string v;
file >> v;
if (v != SAVE_VERSION)
{
file.close();
remove(SAVE_DATA_FILE.c_str());
return;
}
int nbScores;
file >> nbScores;
for (int i = 0; i < nbScores; i++)
{
StructScore score;
file >> score.name;
file >> score.level;
file >> score.score;
file >> score.shotType;
for (int j = 0; j < NUMBER_EQUIP_ITEMS; j++)
file >> score.equip[j];
scores.push_back(score);
}
}
}
void WitchBlastGame::revealFloor()
{
currentFloor->reveal();
refreshMinimap();
}
void WitchBlastGame::activateKeyRoomEffect(bool withColorEffect)
{
dungeonEntity->activateKeyRoomEffect();
if (withColorEffect) makeColorEffect(X_GAME_COLOR_VIOLET, 0.35f);
SoundManager::getInstance().playSound(SOUND_FORCE_FIELD);
}
void WitchBlastGame::generateStar(sf::Color starColor, float xStar, float yStar)
{
SpriteEntity* spriteStar = new SpriteEntity(
ImageManager::getInstance().getImage(IMAGE_STAR_2),
xStar, yStar);
spriteStar->setScale(0.8f, 0.8f);
spriteStar->setZ(1000.0f);
spriteStar->setSpin(-100 + rand()%200);
spriteStar->setVelocity(Vector2D(10 + rand()%40));
spriteStar->setWeight(-150);
spriteStar->setFading(true);
spriteStar->setAge(-0.8f);
spriteStar->setLifetime(0.1f + (rand() % 100) * 0.003f );
spriteStar->setColor(starColor);
spriteStar->setType(ENTITY_EFFECT);
}
void WitchBlastGame::registerAchievement(enumAchievementType achievement)
{
if (achievementState[achievement] == AchievementUndone)
{
achievementState[achievement] = AchievementPending;
achievementStruct ach;
ach.type = achievement;
ach.message = tools::getLabel(achievements[achievement].label);
ach.timer = ACHIEVEMENT_DELAY_MAX;
ach.hasStarted = false;
achievementsQueue.push(ach);
}
}
bool WitchBlastGame::isItemLocked(enumItemType item)
{
for (int i = 0; i < NB_ACHIEVEMENTS; i++)
{
if (achievementState[i] == AchievementUndone)
{
if (achievements[i].unlockType == UnlockItem)
if (achievements[i].unlock == (int)item) return true;
}
}
return false;
}
WitchBlastGame &game()
{
return *gameptr;
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Jan 30, 3:42 PM (5 d, 2 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55499
Default Alt Text
(249 KB)

Event Timeline