Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
111 KB
Referenced Files
None
Subscribers
None
diff --git a/data/locale/it.po b/data/locale/it.po
index 7cbdba9..355dca0 100644
--- a/data/locale/it.po
+++ b/data/locale/it.po
@@ -1,1081 +1,1507 @@
# Italian translation for Me and My Shadow
# Copyright (C) 2012 Me and My Shadow
# This file is distributed under the same license (GNU GPLv3) as the meandmyshadow package.
# BioHazardX <dhamp90@aol.com>, 2012
#
msgid ""
msgstr ""
"Project-Id-Version: meandmyshadow 0.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-03 16:20+0200\n"
-"PO-Revision-Date: 2012-07-14 14:21+0100\n"
+"POT-Creation-Date: 2013-02-22 15:23+0100\n"
+"PO-Revision-Date: 2013-03-09 17:02+0100\n"
"Last-Translator: BioHazardX <dhamp90@aol.com>\n"
"Language-Team: \n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
-#: ../src/Addons.cpp:40
-#: ../src/TitleMenu.cpp:50
+#: ../src/Addons.cpp:46 ../src/TitleMenu.cpp:52
msgid "Addons"
msgstr "Estensioni"
-#: ../src/Addons.cpp:58
+#: ../src/Addons.cpp:65
msgid "Unable to initialize addon menu:"
msgstr "Impossibile inizializzare il menu delle estensioni:"
-#: ../src/Addons.cpp:66
-#: ../src/Addons.cpp:115
-#: ../src/LevelEditSelect.cpp:69
-#: ../src/LevelSelect.cpp:186
+#: ../src/Addons.cpp:73 ../src/Addons.cpp:122 ../src/LevelEditSelect.cpp:74
+#: ../src/LevelSelect.cpp:201 ../src/StatisticsScreen.cpp:323
+#: ../src/TitleMenu.cpp:812
msgid "Back"
msgstr "Indietro"
-#: ../src/Addons.cpp:97
+#: ../src/Addons.cpp:104
msgid "Levels"
msgstr "Livelli"
-#: ../src/Addons.cpp:98
+#: ../src/Addons.cpp:105
msgid "Level Packs"
msgstr "Pacchetti di livelli"
-#: ../src/Addons.cpp:99
+#: ../src/Addons.cpp:106
msgid "Themes"
msgstr "Temi"
-#: ../src/Addons.cpp:119
-#: ../src/Addons.cpp:595
+#: ../src/Addons.cpp:126 ../src/Addons.cpp:614
msgid "Install"
msgstr "Installa"
-#: ../src/Addons.cpp:123
+#: ../src/Addons.cpp:130
msgid "Update"
msgstr "Aggiorna"
-#: ../src/Addons.cpp:400
-#: ../src/Addons.cpp:417
-#: ../src/Addons.cpp:434
-#: ../src/Addons.cpp:461
-#: ../src/Addons.cpp:478
-#: ../src/Addons.cpp:492
+#: ../src/Addons.cpp:141
+msgid "ERROR: unable to download addons file!"
+msgstr "ERRORE: impossibile scaricare l'estensione!"
+
+#: ../src/Addons.cpp:153
+msgid "ERROR: unable to load addon_list file!"
+msgstr "ERRORE: impossibile caricare addon_list!"
+
+#: ../src/Addons.cpp:164
+msgid "ERROR: Invalid file format of addons file!"
+msgstr "ERRORE: formato dell'estensione invalido!"
+
+#: ../src/Addons.cpp:185
+msgid "ERROR: Unable to create the installed_addons file."
+msgstr "ERRORE: impossibile creare installed_addons."
+
+#: ../src/Addons.cpp:197
+msgid "ERROR: Invalid file format of the installed_addons!"
+msgstr "ERRORE: formato invalido per installed_addons!"
+
+#: ../src/Addons.cpp:419 ../src/Addons.cpp:436 ../src/Addons.cpp:453
+#: ../src/Addons.cpp:480 ../src/Addons.cpp:497 ../src/Addons.cpp:511
msgid "ERROR: Unable to download addon!"
msgstr "ERRORE: impossibile scaricare l'estensione!"
-#: ../src/Addons.cpp:400
-#: ../src/Addons.cpp:417
-#: ../src/Addons.cpp:434
-#: ../src/Addons.cpp:461
-#: ../src/Addons.cpp:478
-#: ../src/Addons.cpp:492
+#: ../src/Addons.cpp:419 ../src/Addons.cpp:436 ../src/Addons.cpp:453
+#: ../src/Addons.cpp:480 ../src/Addons.cpp:497 ../src/Addons.cpp:511
msgid "ERROR:"
msgstr "ERRORE:"
-#: ../src/Addons.cpp:590
+#: ../src/Addons.cpp:609
msgid "Uninstall"
msgstr "Disinstalla"
+#: ../src/Block.cpp:606 ../src/LevelEditor.cpp:172
+msgid "On"
+msgstr "Attivo"
+
+#: ../src/Block.cpp:607 ../src/LevelEditor.cpp:173
+msgid "Off"
+msgstr "Non attivo"
+
# TRANSLATORS: Font used in GUI:
# - Use "knewave" for languages using Latin and Latin-derived alphabets
# - "DroidSansFallback" can be used for non-Latin writing systems
-#: ../src/Functions.cpp:592
-#: ../src/Functions.cpp:593
-#: ../src/Functions.cpp:594
+#: ../src/Functions.cpp:634 ../src/Functions.cpp:635 ../src/Functions.cpp:636
+#: ../src/Functions.cpp:652
msgid "knewave"
msgstr "knewave"
# TRANSLATORS: Font used for normal text:
# - Use "Blokletters-Viltstift" for languages using Latin and Latin-derived alphabets
# - "DroidSansFallback" can be used for non-Latin writing systems
-#: ../src/Functions.cpp:598
+#: ../src/Functions.cpp:640
msgid "Blokletters-Viltstift"
msgstr "Blokletters-Viltstift"
-#: ../src/Functions.cpp:1132
-#: ../src/Functions.cpp:1159
-#: ../src/Functions.cpp:1523
-#: ../src/InputManager.cpp:196
-#: ../src/LevelEditor.cpp:1017
-#: ../src/LevelEditor.cpp:1630
-#: ../src/LevelEditor.cpp:1687
-#: ../src/LevelEditor.cpp:1750
-#: ../src/LevelEditor.cpp:1830
-#: ../src/LevelEditor.cpp:1936
-#: ../src/LevelEditor.cpp:1996
-#: ../src/LevelEditSelect.cpp:175
-#: ../src/LevelEditSelect.cpp:215
-#: ../src/LevelEditSelect.cpp:263
+#: ../src/Functions.cpp:754
+msgid "Loading..."
+msgstr "In caricamento..."
+
+#: ../src/Functions.cpp:1330 ../src/Functions.cpp:1357
+#: ../src/Functions.cpp:1695 ../src/InputManager.cpp:233
+#: ../src/LevelEditor.cpp:353 ../src/LevelEditor.cpp:458
+#: ../src/LevelEditor.cpp:514 ../src/LevelEditor.cpp:1777
+#: ../src/LevelEditSelect.cpp:232 ../src/LevelEditSelect.cpp:264
+#: ../src/LevelEditSelect.cpp:300
msgid "OK"
msgstr "OK"
-#: ../src/Functions.cpp:1133
-#: ../src/Functions.cpp:1145
-#: ../src/Functions.cpp:1155
-#: ../src/Functions.cpp:1527
-#: ../src/LevelEditor.cpp:1021
-#: ../src/LevelEditor.cpp:1634
-#: ../src/LevelEditor.cpp:1691
-#: ../src/LevelEditor.cpp:1754
-#: ../src/LevelEditor.cpp:1834
-#: ../src/LevelEditor.cpp:1940
-#: ../src/LevelEditor.cpp:2000
-#: ../src/LevelEditSelect.cpp:179
-#: ../src/LevelEditSelect.cpp:219
-#: ../src/LevelEditSelect.cpp:267
-#: ../src/TitleMenu.cpp:451
+#: ../src/Functions.cpp:1331 ../src/Functions.cpp:1343
+#: ../src/Functions.cpp:1353 ../src/Functions.cpp:1699
+#: ../src/LevelEditor.cpp:357 ../src/LevelEditor.cpp:462
+#: ../src/LevelEditor.cpp:518 ../src/LevelEditor.cpp:1781
+#: ../src/LevelEditSelect.cpp:236 ../src/LevelEditSelect.cpp:268
+#: ../src/LevelEditSelect.cpp:304 ../src/TitleMenu.cpp:493
msgid "Cancel"
msgstr "Indietro"
-#: ../src/Functions.cpp:1137
+#: ../src/Functions.cpp:1335
msgid "Abort"
msgstr "Rinuncia"
-#: ../src/Functions.cpp:1138
-#: ../src/Functions.cpp:1154
+#: ../src/Functions.cpp:1336 ../src/Functions.cpp:1352
msgid "Retry"
msgstr "Riprova"
-#: ../src/Functions.cpp:1139
+#: ../src/Functions.cpp:1337
msgid "Ignore"
msgstr "Ignora"
-#: ../src/Functions.cpp:1143
-#: ../src/Functions.cpp:1149
+#: ../src/Functions.cpp:1341 ../src/Functions.cpp:1347
msgid "Yes"
msgstr "Sì"
-#: ../src/Functions.cpp:1144
-#: ../src/Functions.cpp:1150
+#: ../src/Functions.cpp:1342 ../src/Functions.cpp:1348
msgid "No"
msgstr "No"
# TRANSLATORS: Filename is coming before this text
-#: ../src/Functions.cpp:1291
+#: ../src/Functions.cpp:1466
#, c-format
msgid ""
"%s already exists.\n"
"Do you want to overwrite it?"
msgstr ""
"%s esiste già.\n"
"Vuoi sovrascriverlo?"
-#: ../src/Functions.cpp:1291
+#: ../src/Functions.cpp:1466
msgid "Overwrite Prompt"
-msgstr "Prompt di sovrascrizione"
+msgstr "Messaggio di sovrascrizione"
-#: ../src/Functions.cpp:1312
-#: ../src/Functions.cpp:1330
+#: ../src/Functions.cpp:1487 ../src/Functions.cpp:1505
#, c-format
msgid "Can't open file %s."
-msgstr "Impossibile aprire il file %s"
+msgstr "Impossibile aprire il file %s."
-#: ../src/Functions.cpp:1312
-#: ../src/Functions.cpp:1330
+#: ../src/Functions.cpp:1487 ../src/Functions.cpp:1505
msgid "Error"
msgstr "Errore"
-#: ../src/Functions.cpp:1464
+#: ../src/Functions.cpp:1636
msgid "Save File"
msgstr "Salva il file"
-#: ../src/Functions.cpp:1464
+#: ../src/Functions.cpp:1636
msgid "Load File"
msgstr "Carica il file"
-#: ../src/Functions.cpp:1468
+#: ../src/Functions.cpp:1640
msgid "Search In"
msgstr "Cerca"
-#: ../src/Functions.cpp:1478
+#: ../src/Functions.cpp:1650
msgid "File Name"
-msgstr "Nome file"
+msgstr "Nome del file"
# TRANSLATORS: Please do not remove %s or %d from your translation:
# - %d means the level number in a levelpack
# - %s means the name of current level
-#: ../src/Game.cpp:233
-#: ../src/Game.cpp:830
+#: ../src/Game.cpp:266 ../src/Game.cpp:951
#, c-format
msgid "Level %d %s"
msgstr "Livello %d %s"
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with current action key
-#: ../src/Game.cpp:657
+#: ../src/Game.cpp:771
#, c-format
msgid "Press %s key to save the game."
msgstr "Premi il tasto %s per salvare il gioco."
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with current action key
-#: ../src/Game.cpp:662
+#: ../src/Game.cpp:776
#, c-format
msgid "Press %s key to swap the position of player and shadow."
-msgstr "Premi il tasto %s per scambiare la posizione del giocatore con quella dell'ombra."
+msgstr ""
+"Premi il tasto %s per scambiare la posizione del giocatore con quella "
+"dell'ombra."
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with current action key
-#: ../src/Game.cpp:667
+#: ../src/Game.cpp:781
#, c-format
msgid "Press %s key to activate the switch."
msgstr "Premi il tasto %s per attivare l'interruttore."
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with current action key
-#: ../src/Game.cpp:672
+#: ../src/Game.cpp:786
#, c-format
msgid "Press %s key to teleport."
msgstr "Premi il tasto %s per teletrasportarti."
# TRANSLATORS: Please do not remove %s from your translation:
# - first %s means currently configured key to restart game
# - Second %s means configured key to load from last save
-#: ../src/Game.cpp:713
+#: ../src/Game.cpp:827
#, c-format
msgid "Press %s to restart current level or press %s to load the game."
-msgstr "Premi %s per ricominciare il livello corrente o %s per caricare il gioco."
+msgstr ""
+"Premi %s per ricominciare il livello corrente o %s per caricare il gioco."
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with currently configured key to restart game
-#: ../src/Game.cpp:725
+#: ../src/Game.cpp:839
#, c-format
msgid "Press %s to restart current level."
msgstr "Premi il tasto %s per ricominciare il livello corrente."
-#: ../src/Game.cpp:739
+#: ../src/Game.cpp:853
msgid "Your shadow has died."
msgstr "La tua ombra è morta."
-#: ../src/Game.cpp:782
+#: ../src/Game.cpp:904
#, c-format
msgid "%d recordings"
-msgstr "%d registrazione"
+msgstr "%d registrazioni"
# TRANSLATORS: This is caption for finished level
-#: ../src/Game.cpp:822
+#: ../src/Game.cpp:943
msgid "You've finished:"
msgstr "Hai completato:"
# TRANSLATORS: Please do not remove %-.2f from your translation:
# - %-.2f means time in seconds
# - s is shortened form of a second. Try to keep it so.
-#: ../src/Game.cpp:1002
+#: ../src/Game.cpp:1129
#, c-format
msgid "Time: %-.2fs"
msgstr "Tempo: %-.2fs"
# TRANSLATORS: Please do not remove %-.2f from your translation:
# - %-.2f means time in seconds
# - s is shortened form of a second. Try to keep it so.
-#: ../src/Game.cpp:1011
+#: ../src/Game.cpp:1138
#, c-format
msgid "Best time: %-.2fs"
msgstr "Tempo migliore: %-.2fs"
-#: ../src/Game.cpp:1022
+#: ../src/Game.cpp:1149
#, c-format
msgid "Target time: %-.2fs"
-msgstr "Tempo obiettivo: %-.2fs"
+msgstr "Tempo richiesto: %-.2fs"
# TRANSLATORS: Please do not remove %d from your translation:
# - %d means the number of recordings user has made
-#: ../src/Game.cpp:1043
+#: ../src/Game.cpp:1170
#, c-format
msgid "Recordings: %d"
-msgstr "Registrazione: %d"
+msgstr "Registrazioni: %d"
# TRANSLATORS: Please do not remove %d from your translation:
# - %d means the number of recordings user has made
-#: ../src/Game.cpp:1051
+#: ../src/Game.cpp:1178
#, c-format
msgid "Best recordings: %d"
-msgstr "Registrazione migliore: %d"
+msgstr "Registrazioni migliori: %d"
-#: ../src/Game.cpp:1061
+#: ../src/Game.cpp:1188
#, c-format
msgid "Target recordings: %d"
-msgstr "Registrazione obiettivo: %d"
+msgstr "Registrazioni richieste: %d"
# TRANSLATORS: Please do not remove %s from your translation:
# - %s will be replaced with name of a prize medal (gold, silver or bronze)
-#: ../src/Game.cpp:1074
+#: ../src/Game.cpp:1201
#, c-format
msgid "You earned the %s medal"
msgstr "Hai guadagnato la medaglia di %s"
-#: ../src/Game.cpp:1074
+#: ../src/Game.cpp:1201
msgid "GOLD"
msgstr "ORO"
-#: ../src/Game.cpp:1074
+#: ../src/Game.cpp:1201
msgid "SILVER"
msgstr "ARGENTO"
-#: ../src/Game.cpp:1074
+#: ../src/Game.cpp:1201
msgid "BRONZE"
msgstr "BRONZO"
# TRANSLATORS: used as return to the level selector menu
-#: ../src/Game.cpp:1089
+#: ../src/Game.cpp:1216
msgid "Menu"
msgstr "Menu"
# TRANSLATORS: used as restart level
-#: ../src/Game.cpp:1096
-#: ../src/InputManager.cpp:41
+#: ../src/Game.cpp:1223 ../src/InputManager.cpp:44
msgid "Restart"
msgstr "Ricomincia"
# TRANSLATORS: used as next level
-#: ../src/Game.cpp:1103
+#: ../src/Game.cpp:1230
msgid "Next"
msgstr "Prossimo"
-#: ../src/Game.cpp:1146
+#: ../src/Game.cpp:1288
msgid "Game replay is done."
msgstr "Il replay di gioco è completato."
-#: ../src/Game.cpp:1146
+#: ../src/Game.cpp:1288
msgid "Game Replay"
msgstr "Replay di gioco"
-#: ../src/Game.cpp:1303
-#: ../src/Game.cpp:1305
+#: ../src/Game.cpp:1512 ../src/Game.cpp:1514
msgid "Congratulations"
msgstr "Congratulazioni"
-#: ../src/Game.cpp:1305
+#: ../src/Game.cpp:1514
msgid "You have finished the levelpack!"
msgstr "Hai completato il pacchetto di livelli!"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Up (in menu)"
msgstr "Su (dal menu)"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Down (in menu)"
msgstr "Giù (dal menu)"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Left"
msgstr "Sinistra"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Right"
msgstr "Destra"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Jump"
msgstr "Salta"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Action"
msgstr "Azione"
-#: ../src/InputManager.cpp:40
+#: ../src/InputManager.cpp:43
msgid "Space (Record)"
msgstr "Spazio (registra)"
-#: ../src/InputManager.cpp:41
+#: ../src/InputManager.cpp:43
+msgid "Cancel recording"
+msgstr "Annulla la registrazione"
+
+#: ../src/InputManager.cpp:44
msgid "Escape"
msgstr "Esci"
-#: ../src/InputManager.cpp:41
+#: ../src/InputManager.cpp:44
msgid "Tab (View shadow/Level prop.)"
msgstr "Tab (visualizza ombra/proprietà livello)"
-#: ../src/InputManager.cpp:41
+#: ../src/InputManager.cpp:44
msgid "Save game (in editor)"
-msgstr "Salva gioco (dall'editor)"
+msgstr "Salva il gioco (dall'editor)"
-#: ../src/InputManager.cpp:41
+#: ../src/InputManager.cpp:44
msgid "Load game"
-msgstr "Carica gioco"
+msgstr "Carica il gioco"
-#: ../src/InputManager.cpp:41
+#: ../src/InputManager.cpp:44
msgid "Swap (in editor)"
msgstr "Scambia (dall'editor)"
-#: ../src/InputManager.cpp:42
+#: ../src/InputManager.cpp:45
msgid "Teleport (in editor)"
msgstr "Teletrasporta (dall'editor)"
-#: ../src/InputManager.cpp:42
+#: ../src/InputManager.cpp:45
msgid "Suicide (in editor)"
msgstr "Suicidio (dall'editor)"
-#: ../src/InputManager.cpp:42
+#: ../src/InputManager.cpp:45
msgid "Shift (in editor)"
msgstr "Sposta (dall'editor)"
-#: ../src/InputManager.cpp:42
+#: ../src/InputManager.cpp:45
msgid "Next block type (in Editor)"
-msgstr "Tipo di blocco successivo(dall'editor)"
+msgstr "Tipo di blocco successivo (dall'editor)"
-#: ../src/InputManager.cpp:43
+#: ../src/InputManager.cpp:46
msgid "Previous block type (in editor)"
msgstr "Tipo di blocco precedente (dall'editor)"
-#: ../src/InputManager.cpp:43
+#: ../src/InputManager.cpp:46
msgid "Select (in menu)"
msgstr "Seleziona (dal menu)"
-#: ../src/InputManager.cpp:163
-#: ../src/TitleMenu.cpp:430
+#: ../src/InputManager.cpp:204 ../src/TitleMenu.cpp:472
msgid "Config Keys"
msgstr "Configura i tasti"
-#: ../src/InputManager.cpp:166
+#: ../src/InputManager.cpp:207
msgid "Select an item and press a key to config it."
-msgstr "Seleziona una voce e premi un tasto per configurare."
+msgstr "Seleziona una voce e premi un tasto per configurarla."
-#: ../src/InputManager.cpp:179
+#: ../src/InputManager.cpp:221
msgid "Primary key"
msgstr "Tasti primari"
-#: ../src/InputManager.cpp:180
+#: ../src/InputManager.cpp:222
msgid "Alternative key"
msgstr "Tasti alternativi"
-#: ../src/InputManager.cpp:186
+#: ../src/InputManager.cpp:228
msgid "Unset the key"
msgstr "Rimuovi il tasto"
-#: ../src/InputManager.cpp:300
+#: ../src/InputManager.cpp:299
msgid "(Not set)"
msgstr "(non configurato)"
-#: ../src/LevelEditor.cpp:121
-msgid "Toolbox"
-msgstr "Toolbox"
-
-#: ../src/LevelEditor.cpp:180
+#: ../src/LevelEditor.cpp:64
msgid "Block"
msgstr "Blocco"
-#: ../src/LevelEditor.cpp:180
+#: ../src/LevelEditor.cpp:64
msgid "Player Start"
msgstr "Punto d'inizio giocatore"
-#: ../src/LevelEditor.cpp:180
+#: ../src/LevelEditor.cpp:64
msgid "Shadow Start"
msgstr "Punto d'inizio ombra"
-#: ../src/LevelEditor.cpp:181
+#: ../src/LevelEditor.cpp:65
msgid "Exit"
msgstr "Uscita"
-#: ../src/LevelEditor.cpp:181
+#: ../src/LevelEditor.cpp:65
msgid "Shadow Block"
msgstr "Blocco-ombra"
-#: ../src/LevelEditor.cpp:181
+#: ../src/LevelEditor.cpp:65
msgid "Spikes"
msgstr "Spuntoni"
-#: ../src/LevelEditor.cpp:182
+#: ../src/LevelEditor.cpp:66
msgid "Checkpoint"
msgstr "Checkpoint"
-#: ../src/LevelEditor.cpp:182
-#: ../src/LevelEditSelect.cpp:258
+#: ../src/LevelEditor.cpp:66 ../src/LevelEditSelect.cpp:295
msgid "Swap"
msgstr "Scambio"
-#: ../src/LevelEditor.cpp:182
-#: ../src/LevelEditor.cpp:1976
+#: ../src/LevelEditor.cpp:66
msgid "Fragile"
msgstr "Fragile"
-#: ../src/LevelEditor.cpp:183
+#: ../src/LevelEditor.cpp:67
msgid "Moving Block"
msgstr "Blocco mobile"
-#: ../src/LevelEditor.cpp:183
+#: ../src/LevelEditor.cpp:67
msgid "Moving Shadow Block"
msgstr "Blocco-ombra mobile"
-#: ../src/LevelEditor.cpp:183
+#: ../src/LevelEditor.cpp:67
msgid "Moving Spikes"
msgstr "Spuntoni mobili"
-#: ../src/LevelEditor.cpp:184
+#: ../src/LevelEditor.cpp:68
msgid "Teleporter"
msgstr "Teletrasporto"
-#: ../src/LevelEditor.cpp:184
-#: ../src/LevelEditor.cpp:1884
+#: ../src/LevelEditor.cpp:68
msgid "Button"
msgstr "Pulsante"
-#: ../src/LevelEditor.cpp:184
-#: ../src/LevelEditor.cpp:1886
+#: ../src/LevelEditor.cpp:68
msgid "Switch"
msgstr "Interruttore"
-#: ../src/LevelEditor.cpp:185
+#: ../src/LevelEditor.cpp:69
msgid "Conveyor Belt"
msgstr "Nastro trasportatore"
-#: ../src/LevelEditor.cpp:185
+#: ../src/LevelEditor.cpp:69
msgid "Shadow Conveyor Belt"
msgstr "Nastro-ombra trasportatore"
-#: ../src/LevelEditor.cpp:185
+#: ../src/LevelEditor.cpp:69
msgid "Notification Block"
msgstr "Blocco di notifica"
-#: ../src/LevelEditor.cpp:185
+#: ../src/LevelEditor.cpp:69
msgid "Collectable"
msgstr "Oggetto da collezione"
-#: ../src/LevelEditor.cpp:529
-msgid "Are you sure you want to quit?"
-msgstr "Sei sicuro di volere uscire?"
-
-#: ../src/LevelEditor.cpp:529
-msgid "Quit prompt"
-msgstr "Prompt di uscita"
+#: ../src/LevelEditor.cpp:69
+msgid "Puhsable"
+msgstr "Spingibile"
-#: ../src/LevelEditor.cpp:957
-#: ../src/LevelEditor.cpp:959
-#: ../src/LevelEditor.cpp:2609
-#: ../src/LevelEditor.cpp:2611
-#, c-format
-msgid "Level \"%s\" saved"
-msgstr "Livello \"%s\" salvato"
+#: ../src/LevelEditor.cpp:174
+msgid "Toggle"
+msgstr "Attiva/disattiva"
-#: ../src/LevelEditor.cpp:957
-#: ../src/LevelEditor.cpp:959
-#: ../src/LevelEditor.cpp:2609
-#: ../src/LevelEditor.cpp:2611
-msgid "Saved"
-msgstr "Salvato"
+#: ../src/LevelEditor.cpp:177
+msgid "Complete"
+msgstr "Intero"
-#: ../src/LevelEditor.cpp:972
-#: ../src/LevelEditor.cpp:2732
-msgid "Level settings"
-msgstr "Impostazioni del livello"
+#: ../src/LevelEditor.cpp:178
+msgid "One step"
+msgstr "Calpestato una volta"
-#: ../src/LevelEditor.cpp:976
-#: ../src/LevelEditSelect.cpp:154
-msgid "Name:"
-msgstr "Nome:"
+#: ../src/LevelEditor.cpp:179
+msgid "Two steps"
+msgstr "Calpestato due volte"
-#: ../src/LevelEditor.cpp:982
-msgid "Theme:"
-msgstr "Tema:"
+#: ../src/LevelEditor.cpp:180
+msgid "Gone"
+msgstr "Consumato"
-#: ../src/LevelEditor.cpp:997
-msgid "Target time (s):"
-msgstr "Tempo obiettivo (s):"
+#: ../src/LevelEditor.cpp:190
+msgid "Move"
+msgstr "Muovi"
-#: ../src/LevelEditor.cpp:1008
-msgid "Target recordings:"
-msgstr "Registrazione obiettivo:"
+#: ../src/LevelEditor.cpp:191 ../src/LevelEditor.cpp:744
+#: ../src/LevelEditor.cpp:2843
+msgid "Delete"
+msgstr "Cancella"
-#: ../src/LevelEditor.cpp:1576
-#: ../src/LevelEditor.cpp:1793
-msgid "Defined"
-msgstr "Definito"
+#: ../src/LevelEditor.cpp:196
+msgid "Link"
+msgstr "Link"
-#: ../src/LevelEditor.cpp:1579
-#: ../src/LevelEditor.cpp:1796
-#: ../src/LevelEditor.cpp:1878
-msgid "None"
-msgstr "Niente"
+#: ../src/LevelEditor.cpp:197
+msgid "Remove Links"
+msgstr "Rimuovi i link"
-#: ../src/LevelEditor.cpp:1586
-msgid "Moving block"
-msgstr "Blocco mobile"
+# TRANSLATORS: as detect user's language automatically
+#: ../src/LevelEditor.cpp:201 ../src/LevelEditor.cpp:400
+msgid "Automatic"
+msgstr "Automatico"
-#: ../src/LevelEditor.cpp:1589
-msgid "Moving shadow block"
-msgstr "Blocco-ombra mobile"
+#: ../src/LevelEditor.cpp:214
+msgid "Path"
+msgstr "Percorso"
-#: ../src/LevelEditor.cpp:1592
-msgid "Moving spikes"
-msgstr "Spuntoni mobili"
+#: ../src/LevelEditor.cpp:215
+msgid "Remove Path"
+msgstr "Rimuovi il percorso"
-#: ../src/LevelEditor.cpp:1599
-#: ../src/LevelEditor.cpp:1736
+#: ../src/LevelEditor.cpp:218 ../src/LevelEditor.cpp:224
+#: ../src/LevelEditor.cpp:378
msgid "Enabled"
msgstr "Attivo"
-#: ../src/LevelEditor.cpp:1605
-msgid "Loop"
+#: ../src/LevelEditor.cpp:219 ../src/LevelEditor.cpp:389
+msgid "Looping"
msgstr "Ripetizione"
-#: ../src/LevelEditor.cpp:1611
-msgid "Path"
-msgstr "Percorso"
+#: ../src/LevelEditor.cpp:225
+msgid "Speed"
+msgstr "Velocità"
+
+#: ../src/LevelEditor.cpp:235
+msgid "Message"
+msgstr "Messaggio"
+
+#: ../src/LevelEditor.cpp:237 ../src/LevelEditor.cpp:476
+msgid "Scripting"
+msgstr "Scripting"
-#: ../src/LevelEditor.cpp:1671
+#: ../src/LevelEditor.cpp:335
msgid "Notification block"
msgstr "Blocco di notifica"
-#: ../src/LevelEditor.cpp:1674
+#: ../src/LevelEditor.cpp:340
msgid "Enter message here:"
msgstr "Inserisci qui il messaggio:"
-#: ../src/LevelEditor.cpp:1728
-msgid "Shadow Conveyor belt"
-msgstr "Nastro-ombra trasportatore"
-
-#: ../src/LevelEditor.cpp:1730
-msgid "Conveyor belt"
-msgstr "Nastro trasportatore"
+#: ../src/LevelEditor.cpp:445
+msgid "Conveyor belt speed"
+msgstr "Velocità nastro trasportatore"
-#: ../src/LevelEditor.cpp:1742
+#: ../src/LevelEditor.cpp:450
msgid "Enter speed here:"
msgstr "Inserisci qui la velocità:"
-#: ../src/LevelEditor.cpp:1800
-msgid "Portal"
-msgstr "Portale"
-
-#: ../src/LevelEditor.cpp:1803
-msgid "Activate on touch"
-msgstr "Attivabile manualmente"
+#: ../src/LevelEditor.cpp:481
+msgid "Id:"
+msgstr "Id:"
-#: ../src/LevelEditor.cpp:1809
-#: ../src/LevelEditor.cpp:1914
-msgid "Targets:"
-msgstr "Obiettivi:"
+#: ../src/LevelEditor.cpp:729 ../src/LevelEditor.cpp:2837
+msgid "Select"
+msgstr "Seleziona"
-#: ../src/LevelEditor.cpp:1875
-#, c-format
-msgid "%d Defined"
-msgstr "%d definito"
+#: ../src/LevelEditor.cpp:759
+msgid "Configure"
+msgstr "Configura"
-#: ../src/LevelEditor.cpp:1891
-msgid "Behaviour:"
-msgstr "Comportamento:"
+#: ../src/LevelEditor.cpp:1159
+msgid "Are you sure you want to quit?"
+msgstr "Sei sicuro di volere uscire?"
-#: ../src/LevelEditor.cpp:1897
-msgid "On"
-msgstr "Attivo"
+#: ../src/LevelEditor.cpp:1159
+msgid "Quit prompt"
+msgstr "Messaggio di uscita"
-#: ../src/LevelEditor.cpp:1898
-msgid "Off"
-msgstr "Non attivo"
+#: ../src/LevelEditor.cpp:1266 ../src/LevelEditor.cpp:1268
+#: ../src/LevelEditor.cpp:1727 ../src/LevelEditor.cpp:1729
+#, c-format
+msgid "Level \"%s\" saved"
+msgstr "Livello \"%s\" salvato"
-#: ../src/LevelEditor.cpp:1899
-msgid "Toggle"
-msgstr "Attiva/disattiva"
+#: ../src/LevelEditor.cpp:1266 ../src/LevelEditor.cpp:1268
+#: ../src/LevelEditor.cpp:1727 ../src/LevelEditor.cpp:1729
+msgid "Saved"
+msgstr "Salvato"
-#: ../src/LevelEditor.cpp:1979
-msgid "State:"
-msgstr "Stato:"
+#: ../src/LevelEditor.cpp:1736 ../src/LevelEditor.cpp:2849
+msgid "Level settings"
+msgstr "Impostazioni del livello"
-#: ../src/LevelEditor.cpp:1985
-msgid "Complete"
-msgstr "Completo"
+#: ../src/LevelEditor.cpp:1742 ../src/LevelEditSelect.cpp:205
+msgid "Name:"
+msgstr "Nome:"
-#: ../src/LevelEditor.cpp:1986
-msgid "One step"
-msgstr "Un passo"
+#: ../src/LevelEditor.cpp:1748
+msgid "Theme:"
+msgstr "Tema:"
-#: ../src/LevelEditor.cpp:1987
-msgid "Two steps"
-msgstr "Due passi"
+#: ../src/LevelEditor.cpp:1756
+msgid "Target time (s):"
+msgstr "Tempo richiesto (s):"
-#: ../src/LevelEditor.cpp:1988
-msgid "Gone"
-msgstr "Finito"
+#: ../src/LevelEditor.cpp:1765
+msgid "Target recordings:"
+msgstr "Registrazioni richieste:"
-#: ../src/LevelEditor.cpp:2717
-msgid "Select"
-msgstr "Seleziona"
+#: ../src/LevelEditor.cpp:2804 ../src/LevelEditor.cpp:2810
+#, c-format
+msgid "Movespeed: %s"
+msgstr "Velocità di movimento: %s"
-#: ../src/LevelEditor.cpp:2720
+#: ../src/LevelEditor.cpp:2840
msgid "Add"
msgstr "Aggiungi"
-#: ../src/LevelEditor.cpp:2723
-msgid "Delete"
-msgstr "Cancella"
-
-#: ../src/LevelEditor.cpp:2726
-msgid "Configure"
-msgstr "Configura"
-
-#: ../src/LevelEditor.cpp:2729
-#: ../src/LevelPlaySelect.cpp:65
-#: ../src/TitleMenu.cpp:47
+#: ../src/LevelEditor.cpp:2846 ../src/LevelPlaySelect.cpp:69
+#: ../src/TitleMenu.cpp:49
msgid "Play"
msgstr "Gioca"
-#: ../src/LevelEditor.cpp:2735
+#: ../src/LevelEditor.cpp:2852
msgid "Save level"
-msgstr "Salva livello"
+msgstr "Salva il livello"
-#: ../src/LevelEditor.cpp:2738
+#: ../src/LevelEditor.cpp:2855
msgid "Back to menu"
msgstr "Ritorna al menu"
-#: ../src/LevelEditor.cpp:2776
-#: ../src/LevelEditor.cpp:2782
-#, c-format
-msgid "Movespeed: %s"
-msgstr "Velocità di movimento: %s"
-
-#: ../src/LevelEditSelect.cpp:41
-#: ../src/TitleMenu.cpp:49
+#: ../src/LevelEditSelect.cpp:46 ../src/TitleMenu.cpp:51
msgid "Map Editor"
msgstr "Editor di mappe"
-#: ../src/LevelEditSelect.cpp:78
+#: ../src/LevelEditSelect.cpp:83
msgid "New Levelpack"
msgstr "Nuovo pacchetto di livelli"
-#: ../src/LevelEditSelect.cpp:83
+#: ../src/LevelEditSelect.cpp:88
msgid "Pack Properties"
msgstr "Proprietà del pacchetto"
-#: ../src/LevelEditSelect.cpp:88
+#: ../src/LevelEditSelect.cpp:93
msgid "Remove Pack"
-msgstr "Rimuovi pacchetto"
+msgstr "Rimuovi il pacchetto"
-#: ../src/LevelEditSelect.cpp:93
+#: ../src/LevelEditSelect.cpp:98
msgid "Move Map"
-msgstr "Sposta mappa"
+msgstr "Sposta la mappa"
-#: ../src/LevelEditSelect.cpp:99
+#: ../src/LevelEditSelect.cpp:106
msgid "Remove Map"
-msgstr "Rimuovi mappa"
+msgstr "Rimuovi la mappa"
-#: ../src/LevelEditSelect.cpp:104
+#: ../src/LevelEditSelect.cpp:111
msgid "Edit Map"
-msgstr "Edita mappa"
+msgstr "Modifica la mappa"
-#: ../src/LevelEditSelect.cpp:151
+#: ../src/LevelEditSelect.cpp:202
msgid "Properties"
msgstr "Proprietà"
-#: ../src/LevelEditSelect.cpp:161
+#: ../src/LevelEditSelect.cpp:214
msgid "Description:"
msgstr "Descrizione:"
-#: ../src/LevelEditSelect.cpp:168
+#: ../src/LevelEditSelect.cpp:223
msgid "Congratulation text:"
msgstr "Messaggio di congratulazioni:"
-#: ../src/LevelEditSelect.cpp:203
-#: ../src/LevelEditSelect.cpp:371
+#: ../src/LevelEditSelect.cpp:252 ../src/LevelEditSelect.cpp:407
msgid "Add level"
-msgstr "Aggiungi livello"
+msgstr "Aggiungi il livello"
-#: ../src/LevelEditSelect.cpp:206
+#: ../src/LevelEditSelect.cpp:255
msgid "File name:"
-msgstr "Nome file:"
+msgstr "Nome del file:"
-#: ../src/LevelEditSelect.cpp:243
+#: ../src/LevelEditSelect.cpp:280
msgid "Move level"
-msgstr "Sposta livello"
+msgstr "Sposta il livello"
-#: ../src/LevelEditSelect.cpp:246
+#: ../src/LevelEditSelect.cpp:283
msgid "Level: "
msgstr "Livello:"
-#: ../src/LevelEditSelect.cpp:256
+#: ../src/LevelEditSelect.cpp:293
msgid "Before"
msgstr "Prima"
-#: ../src/LevelEditSelect.cpp:257
+#: ../src/LevelEditSelect.cpp:294
msgid "After"
msgstr "Dopo"
-#: ../src/LevelEditSelect.cpp:439
+#: ../src/LevelEditSelect.cpp:470
msgid "Are you sure?"
msgstr "Sei sicuro?"
-#: ../src/LevelEditSelect.cpp:439
+#: ../src/LevelEditSelect.cpp:470
msgid "Remove prompt"
-msgstr "Prompt di rimozione"
+msgstr "Messaggio di rimozione"
-#: ../src/LevelEditSelect.cpp:579
+#: ../src/LevelEditSelect.cpp:615
msgid "No file name given for the new level."
-msgstr "Nessun nome file dato per il nuovo livello."
+msgstr "Nessun nome dato al nuovo livello."
-#: ../src/LevelEditSelect.cpp:579
+#: ../src/LevelEditSelect.cpp:615
msgid "Missing file name"
-msgstr "Nome file mancante"
+msgstr "Nome del file mancante"
+
+#: ../src/LevelEditSelect.cpp:672
+msgid "ERROR: Unable to add level to Levels levelpack"
+msgstr "ERRORE: impossibile aggiungere il livello nel pacchetto"
-#: ../src/LevelEditSelect.cpp:656
+#: ../src/LevelEditSelect.cpp:706
msgid "The entered level number isn't valid!"
-msgstr "Il numero livello inserito non è valido!"
+msgstr "Il numero di livello inserito non è valido!"
-#: ../src/LevelEditSelect.cpp:656
+#: ../src/LevelEditSelect.cpp:706
msgid "Illegal number"
msgstr "Numero incorretto"
-#: ../src/LevelPlaySelect.cpp:43
+#: ../src/LevelPlaySelect.cpp:47
msgid "Select Level"
-msgstr "Seleziona livello"
+msgstr "Seleziona il livello"
-#: ../src/LevelPlaySelect.cpp:92
+#: ../src/LevelPlaySelect.cpp:96
msgid "Choose a level"
msgstr "Scegli un livello"
-#: ../src/LevelPlaySelect.cpp:93
-#: ../src/LevelPlaySelect.cpp:231
-#: ../src/LevelPlaySelect.cpp:242
+#: ../src/LevelPlaySelect.cpp:97
msgid "Time:"
msgstr "Tempo:"
-#: ../src/LevelPlaySelect.cpp:94
-#: ../src/LevelPlaySelect.cpp:240
-#: ../src/LevelPlaySelect.cpp:243
+#: ../src/LevelPlaySelect.cpp:98 ../src/StatisticsScreen.cpp:166
msgid "Recordings:"
-msgstr "Registrazione:"
+msgstr "Registrazioni:"
-#: ../src/TitleMenu.cpp:48
+#: ../src/StatisticsManager.cpp:393
+msgid "New achievement:"
+msgstr "Nuovo obiettivo:"
+
+#: ../src/StatisticsManager.cpp:401
+#, c-format
+msgid "Achieved at %s"
+msgstr "Sbloccato in %s"
+
+#: ../src/StatisticsManager.cpp:407
+msgid "Unknown achievement"
+msgstr "Obiettivo sconosciuto"
+
+#: ../src/StatisticsManager.cpp:413
+#, c-format
+msgid "Achieved %0.1f%%"
+msgstr "Sbloccato %0.1f%%"
+
+#: ../src/StatisticsManager.cpp:417
+msgid "Not achieved"
+msgstr "Non sbloccato"
+
+#: ../src/StatisticsScreen.cpp:135 ../src/TitleMenu.cpp:203
+msgid "Achievements and Statistics"
+msgstr "Obiettivi e statistiche"
+
+#: ../src/StatisticsScreen.cpp:147
+msgid "Total"
+msgstr "Totale"
+
+#: ../src/StatisticsScreen.cpp:156
+msgid "Traveling distance (m)"
+msgstr "Distanza percorsa (m)"
+
+#: ../src/StatisticsScreen.cpp:157
+msgid "Jump times"
+msgstr "Numero di salti"
+
+#: ../src/StatisticsScreen.cpp:158
+msgid "Die times"
+msgstr "Numero di morti"
+
+#: ../src/StatisticsScreen.cpp:159
+msgid "Squashed times"
+msgstr "Numero di schiacciamenti"
+
+#: ../src/StatisticsScreen.cpp:166
+msgid "Switch pulled times:"
+msgstr "Numero di interruttori premuti:"
+
+#: ../src/StatisticsScreen.cpp:167
+msgid "Swap times:"
+msgstr "Numero di scambi:"
+
+#: ../src/StatisticsScreen.cpp:168
+msgid "Save times:"
+msgstr "Numero di salvataggi:"
+
+#: ../src/StatisticsScreen.cpp:168
+msgid "Load times:"
+msgstr "Numero di caricamenti:"
+
+#: ../src/StatisticsScreen.cpp:175
+msgid "Completed levels:"
+msgstr "Livelli completati:"
+
+#: ../src/StatisticsScreen.cpp:217
+msgid "In-game time:"
+msgstr "Tempo di gioco:"
+
+#: ../src/StatisticsScreen.cpp:230
+msgid "Level editing time:"
+msgstr "Durata editing di livello:"
+
+#: ../src/StatisticsScreen.cpp:242
+msgid "Created levels:"
+msgstr "Livelli creati:"
+
+#: ../src/StatisticsScreen.cpp:330
+msgid "Achievements"
+msgstr "Obiettivi"
+
+#: ../src/StatisticsScreen.cpp:331
+msgid "Statistics"
+msgstr "Statistiche"
+
+#: ../src/TitleMenu.cpp:50
msgid "Options"
msgstr "Opzioni"
-#: ../src/TitleMenu.cpp:51
+#: ../src/TitleMenu.cpp:53
msgid "Quit"
msgstr "Esci"
-#: ../src/TitleMenu.cpp:109
+#: ../src/TitleMenu.cpp:129
msgid "Enable internet in order to install addons."
msgstr "Abilita la rete internet per installare le estensioni."
-#: ../src/TitleMenu.cpp:109
+#: ../src/TitleMenu.cpp:129
msgid "Internet disabled"
msgstr "Non connesso a internet"
-#: ../src/TitleMenu.cpp:188
+#: ../src/TitleMenu.cpp:201 ../src/TitleMenu.cpp:709
+msgid "Credits"
+msgstr "Riconoscimenti"
+
+#: ../src/TitleMenu.cpp:234
msgid "Settings"
msgstr "Impostazioni"
-#: ../src/TitleMenu.cpp:236
+#: ../src/TitleMenu.cpp:278
msgid "Music"
msgstr "Musica"
-#: ../src/TitleMenu.cpp:244
+#: ../src/TitleMenu.cpp:286
msgid "Sound"
msgstr "Suono"
-#: ../src/TitleMenu.cpp:252
+#: ../src/TitleMenu.cpp:294
msgid "Fullscreen"
msgstr "Schermo intero"
-#: ../src/TitleMenu.cpp:257
+#: ../src/TitleMenu.cpp:299
msgid "Resolution"
msgstr "Risoluzione"
-#: ../src/TitleMenu.cpp:339
+#: ../src/TitleMenu.cpp:381
msgid "Language"
msgstr "Lingua"
# TRANSLATORS: as detect user's language automatically
-#: ../src/TitleMenu.cpp:348
+#: ../src/TitleMenu.cpp:390
msgid "Auto-Detect"
-msgstr "Rilevamento automatico"
+msgstr "Automatico"
-#: ../src/TitleMenu.cpp:376
+#: ../src/TitleMenu.cpp:418
msgid "Theme"
msgstr "Tema"
-#: ../src/TitleMenu.cpp:409
+#: ../src/TitleMenu.cpp:451
msgid "Level themes"
-msgstr "Temi del livello"
+msgstr "Tema dei livelli"
-#: ../src/TitleMenu.cpp:414
+#: ../src/TitleMenu.cpp:456
msgid "Internet"
msgstr "Internet"
-#: ../src/TitleMenu.cpp:420
+#: ../src/TitleMenu.cpp:462
msgid "Internet proxy"
msgstr "Internet proxy"
# TRANSLATORS: Used for button which clear any level progress like unlocked levels and highscores.
-#: ../src/TitleMenu.cpp:437
+#: ../src/TitleMenu.cpp:479
msgid "Clear Progress"
-msgstr "Cancella progresso"
+msgstr "Cancella il progresso"
-#: ../src/TitleMenu.cpp:456
+#: ../src/TitleMenu.cpp:498
msgid "Save Changes"
-msgstr "Salva cambiamenti"
+msgstr "Salva i cambiamenti"
-#: ../src/TitleMenu.cpp:564
+#: ../src/TitleMenu.cpp:610
msgid "Do you really want to reset level progress?"
-msgstr "Vuoi davvero cancellare tutto il progresso dei livelli?"
+msgstr "Vuoi davvero cancellare l'intero progresso dei livelli?"
-#: ../src/TitleMenu.cpp:564
+#: ../src/TitleMenu.cpp:610
msgid "Warning"
msgstr "Attenzione"
+#: ../src/AchievementList.h:38
+msgid "Newbie"
+msgstr "Principiante"
+
+#: ../src/AchievementList.h:38
+msgid "Complete a level."
+msgstr "Completato un livello."
+
+#: ../src/AchievementList.h:39
+msgid "Experienced player"
+msgstr "Giocatore esperto"
+
+#: ../src/AchievementList.h:39
+msgid "Complete 50 levels."
+msgstr "Completa 50 livelli."
+
+#: ../src/AchievementList.h:40
+msgid "Good job!"
+msgstr "Ottimo lavoro!"
+
+#: ../src/AchievementList.h:40
+msgid "Receive a gold medal."
+msgstr "Ricevuta una medaglia d'oro."
+
+#: ../src/AchievementList.h:41
+msgid "Expert"
+msgstr "Esperto"
+
+#: ../src/AchievementList.h:41
+msgid "Earn 50 gold medal."
+msgstr "Guadagnato 50 medaglie d'oro."
+
+#: ../src/AchievementList.h:43
+msgid "Graduate"
+msgstr "Promosso"
+
+#: ../src/AchievementList.h:43
+msgid "Complete the tutorial level pack."
+msgstr "Completati tutti i livelli del tutorial."
+
+#: ../src/AchievementList.h:44
+msgid "Outstanding graduate"
+msgstr "Promosso con lode"
+
+#: ../src/AchievementList.h:44
+msgid "Complete the tutorial level pack with gold for all levels."
+msgstr ""
+"Completati tutti i livelli del tutorial con ogni medaglia d'oro per ciascuno."
+
+#: ../src/AchievementList.h:46
+msgid "Hooked"
+msgstr "Preso"
+
+#: ../src/AchievementList.h:46
+msgid "Play Me and My Shadow for more than 2 hours."
+msgstr "Giocato a Me and My Shadow per più di due ore."
+
+#: ../src/AchievementList.h:47
+msgid "Loyal fan of Me and My Shadow"
+msgstr "Fedelissimo di Me and My Shadow"
+
+#: ../src/AchievementList.h:47
+msgid "Play Me and My Shadow for more than 24 hours."
+msgstr "Giocato a Me and My Shadow per più di 24 ore."
+
+#: ../src/AchievementList.h:49
+msgid "Constructor"
+msgstr "Costruttore"
+
+#: ../src/AchievementList.h:49
+msgid "Use the level editor for more than 2 hours."
+msgstr "Usato l'editor di livelli per più di 2 ore."
+
+#: ../src/AchievementList.h:50
+msgid "The creator"
+msgstr "Il creatore"
+
+#: ../src/AchievementList.h:50
+msgid "Use the level editor for more than 24 hours."
+msgstr "Usato l'editor di livelli per più di 24 ore."
+
+#: ../src/AchievementList.h:52
+msgid "Look, cute level!"
+msgstr "Che bel livello!"
+
+#: ../src/AchievementList.h:52
+msgid "Create a level for the first time."
+msgstr "Creato un livello per la prima volta."
+
+#: ../src/AchievementList.h:53
+msgid "The level museum"
+msgstr "Il museo dei livelli"
+
+#: ../src/AchievementList.h:53
+msgid "Create 50 levels."
+msgstr "Creato 50 livelli."
+
+#: ../src/AchievementList.h:55
+msgid "Frog"
+msgstr "Rana"
+
+#: ../src/AchievementList.h:55
+msgid "Jump 1000 times."
+msgstr "Saltato 1000 volte."
+
+#: ../src/AchievementList.h:57
+msgid "Wanderer"
+msgstr "Vagabondo"
+
+#: ../src/AchievementList.h:57
+msgid "Travel 100 meters."
+msgstr "Percorsi 100 metri."
+
+#: ../src/AchievementList.h:58
+msgid "Runner"
+msgstr "Corridore"
+
+#: ../src/AchievementList.h:58
+msgid "Travel 1 kilometer."
+msgstr "Percorso 1 chilometro."
+
+#: ../src/AchievementList.h:59
+msgid "Long distance runner"
+msgstr "Fondista"
+
+#: ../src/AchievementList.h:59
+msgid "Travel 10 kilometers."
+msgstr "Percorsi 10 chilometri."
+
+#: ../src/AchievementList.h:60
+msgid "Marathon runner"
+msgstr "Maratoneta"
+
+#: ../src/AchievementList.h:60
+msgid "Travel 42,195 meters."
+msgstr "Percorsi 42195 metri."
+
+#: ../src/AchievementList.h:62
+msgid "Be careful!"
+msgstr "Fai attenzione!"
+
+#: ../src/AchievementList.h:62
+msgid "Die for the first time."
+msgstr "Morto per la prima volta."
+
+#: ../src/AchievementList.h:63
+msgid "It doesn't matter..."
+msgstr "Non importa..."
+
+#: ../src/AchievementList.h:63
+msgid "Die 50 times."
+msgstr "Morto 50 volte."
+
+#: ../src/AchievementList.h:64
+msgid "Expert of trial and error"
+msgstr "Esperto in tentativi ed errori"
+
+#: ../src/AchievementList.h:64
+msgid "Die 1000 times."
+msgstr "Morto 1000 volte."
+
+#: ../src/AchievementList.h:66
+msgid "Keep an eye for moving blocks!"
+msgstr "Tieni d'occhio i blocchi mobili!"
+
+#: ../src/AchievementList.h:66
+msgid "Get squashed for the first time."
+msgstr "Schiacciato per la prima volta."
+
+#: ../src/AchievementList.h:67
+msgid "Potato masher"
+msgstr "Schiacciapatate"
+
+#: ../src/AchievementList.h:67
+msgid "Get squashed 50 times."
+msgstr "Schiacciato 50 volte."
+
+#: ../src/AchievementList.h:69
+msgid "Double kill"
+msgstr "Doppia uccisione"
+
+#: ../src/AchievementList.h:69
+msgid "Get both the player and the shadow dead."
+msgstr "Sia il giocatore che l'ombra sono morti."
+
+#: ../src/AchievementList.h:71
+msgid "Bad luck"
+msgstr "Disgrazia"
+
+#: ../src/AchievementList.h:71
+msgid "Die 5 times in under 5 seconds."
+msgstr "Morto 5 volte in meno di 5 secondi."
+
+#: ../src/AchievementList.h:72
+msgid "This level is too dangerous"
+msgstr "Questo livello è troppo pericoloso"
+
+#: ../src/AchievementList.h:72
+msgid "Die 10 times in under 5 seconds."
+msgstr "Morto 10 volte in meno di 5 secondi."
+
+#: ../src/AchievementList.h:74
+msgid "You forgot your friend"
+msgstr "Hai dimenticato il tuo amico"
+
+#: ../src/AchievementList.h:74
+msgid "Finish the level with the player or the shadow dead."
+msgstr "Terminato il livello con il giocatore o l'ombra morti."
+
+#: ../src/AchievementList.h:75
+msgid "Just in time"
+msgstr "Appena in tempo"
+
+#: ../src/AchievementList.h:75
+msgid "Reach the exit with the player and the shadow simultaneously."
+msgstr "Raggiunta contemporaneamente l'uscita con il giocatore e l'ombra."
+
+#: ../src/AchievementList.h:77
+msgid "Recorder"
+msgstr "Registratore"
+
+#: ../src/AchievementList.h:77
+msgid "Record 100 times."
+msgstr "Registrato 100 volte."
+
+#: ../src/AchievementList.h:78
+msgid "Shadowmaster"
+msgstr "Maestro delle ombre"
+
+#: ../src/AchievementList.h:78
+msgid "Record 1000 times."
+msgstr "Registrato 1000 volte."
+
+#: ../src/AchievementList.h:80
+msgid "Switch puller"
+msgstr "Premitore d'interruttori"
+
+#: ../src/AchievementList.h:80
+msgid "Pull the switch 100 times."
+msgstr "Premuto l'interruttore 100 volte."
+
+#: ../src/AchievementList.h:81
+msgid "The switch is broken!"
+msgstr "L'interruttore è guasto!"
+
+#: ../src/AchievementList.h:81
+msgid "Pull the switch 1000 times."
+msgstr "Premuto l'interruttore 1000 volte."
+
+#: ../src/AchievementList.h:83
+msgid "Swapper"
+msgstr "Scambiatore"
+
+#: ../src/AchievementList.h:83
+msgid "Swap 100 times."
+msgstr "Scambiato 100 volte."
+
+#: ../src/AchievementList.h:84
+msgid "Player to shadow to player to shadow..."
+msgstr "Giocatore con ombra, ombra con giocatore..."
+
+#: ../src/AchievementList.h:84
+msgid "Swap 1000 times."
+msgstr "Scambiato 1000 volte."
+
+#: ../src/AchievementList.h:86
+msgid "Play it save"
+msgstr "Gioca sicuro"
+
+#: ../src/AchievementList.h:86
+msgid "Save 1000 times."
+msgstr "Salvato 1000 volte."
+
+#: ../src/AchievementList.h:87
+msgid "This game is too hard"
+msgstr "Questo gioco è troppo difficile"
+
+#: ../src/AchievementList.h:87
+msgid "Load the game 1000 times."
+msgstr "Caricato il gioco 1000 volte."
+
+#: ../src/AchievementList.h:89
+msgid "Panic save"
+msgstr "Salvataggio da paura"
+
+#: ../src/AchievementList.h:89
+msgid "Save twice in 1 second."
+msgstr "Salvato due volte in 1 secondo."
+
+#: ../src/AchievementList.h:90
+msgid "Panic load"
+msgstr "Caricamento da paura"
+
+#: ../src/AchievementList.h:90
+msgid "Load twice in 1 second."
+msgstr "Caricato due volte in 1 secondo."
+
+#: ../src/AchievementList.h:92
+msgid "Bad saving position"
+msgstr "Brutta posizione per salvare"
+
+#: ../src/AchievementList.h:92
+msgid "Load the game and die within 1 second."
+msgstr "Caricato il gioco e per essere morto in meno di 1 secondo."
+
+#: ../src/AchievementList.h:93
+msgid "This level is too hard"
+msgstr "Questo livello è troppo difficile"
+
+#: ../src/AchievementList.h:93
+msgid "Load the same save and die 100 times."
+msgstr "Caricato lo stesso livello per morire 100 volte."
+
+#: ../src/AchievementList.h:95
+msgid "Quick swap"
+msgstr "Scambio veloce"
+
+#: ../src/AchievementList.h:95
+msgid "Swap twice in under a second."
+msgstr "Scambiato due volte in meno di un secondo."
+
+#: ../src/AchievementList.h:98
+msgid "Horizontal confusion"
+msgstr "Confusione orizzontale"
+
+#: ../src/AchievementList.h:98
+msgid "Press left and right simultaneously."
+msgstr "Premuti destra e sinistra contemporaneamente."
+
+#: ../src/AchievementList.h:100
+msgid "Programmer"
+msgstr "Programmatore"
+
+#: ../src/AchievementList.h:100
+msgid "Play the development version of Me and My Shadow."
+msgstr "Giocata la versione di sviluppo di Me and My Shadow"
+
# TRANSLATORS: name of a key
msgid "backspace"
msgstr "backspace"
# TRANSLATORS: name of a key
msgid "tab"
msgstr "tab"
# TRANSLATORS: name of a key
msgid "clear"
msgstr "annulla"
# TRANSLATORS: name of a key
msgid "return"
msgstr "invio"
# TRANSLATORS: name of a key
msgid "pause"
msgstr "pausa"
# TRANSLATORS: name of a key
msgid "escape"
msgstr "escape"
# TRANSLATORS: name of a key
msgid "space"
msgstr "spazio"
# TRANSLATORS: name of a key
msgid "delete"
msgstr "cancella"
# TRANSLATORS: name of a key
msgid "enter"
msgstr "invio"
# TRANSLATORS: name of a key
msgid "equals"
msgstr "equals"
# TRANSLATORS: name of a key
msgid "up"
msgstr "su"
# TRANSLATORS: name of a key
msgid "down"
msgstr "giù"
# TRANSLATORS: name of a key
msgid "right"
msgstr "destra"
# TRANSLATORS: name of a key
msgid "left"
msgstr "sinistra"
# TRANSLATORS: name of a key
msgid "insert"
msgstr "inserimento"
# TRANSLATORS: name of a key
msgid "home"
msgstr "home"
# TRANSLATORS: name of a key
msgid "end"
msgstr "fine"
# TRANSLATORS: name of a key
msgid "page up"
msgstr "pagina su"
# TRANSLATORS: name of a key
msgid "page down"
msgstr "pagina giù"
# TRANSLATORS: name of a key
msgid "numlock"
msgstr "blocco numeri"
# TRANSLATORS: name of a key
msgid "caps lock"
msgstr "blocco maiuscole"
# TRANSLATORS: name of a key
msgid "scroll lock"
msgstr "blocco scorrimento"
# TRANSLATORS: name of a key
msgid "right shift"
msgstr "shift destro"
# TRANSLATORS: name of a key
msgid "left shift"
msgstr "shift sinistro"
# TRANSLATORS: name of a key
msgid "right ctrl"
msgstr "ctrl destro"
# TRANSLATORS: name of a key
msgid "left ctrl"
msgstr "ctrl sinistro"
# TRANSLATORS: name of a key
msgid "right alt"
msgstr "alt destro"
# TRANSLATORS: name of a key
msgid "left alt"
msgstr "alt sinistro"
# TRANSLATORS: name of a key
msgid "right meta"
msgstr "meta destro"
# TRANSLATORS: name of a key
msgid "left meta"
msgstr "meta sinistro"
# TRANSLATORS: name of a key
msgid "left super"
msgstr "super sinistro"
# TRANSLATORS: name of a key
msgid "right super"
msgstr "super destro"
# TRANSLATORS: name of a key
msgid "alt gr"
msgstr "alt gr"
# TRANSLATORS: name of a key
msgid "compose"
msgstr "componi"
# TRANSLATORS: name of a key
msgid "help"
msgstr "aiuto"
# TRANSLATORS: name of a key
msgid "print screen"
msgstr "stampa schermo"
# TRANSLATORS: name of a key
msgid "sys req"
msgstr "sys req"
# TRANSLATORS: name of a key
msgid "break"
msgstr "interrompi"
# TRANSLATORS: name of a key
msgid "menu"
msgstr "menu"
# TRANSLATORS: name of a key
msgid "power"
msgstr "power"
# TRANSLATORS: name of a key
msgid "euro"
msgstr "euro"
# TRANSLATORS: name of a key
msgid "undo"
msgstr "undo"
-msgid "Credits"
-msgstr "Crediti"
+#~ msgid "Toolbox"
+#~ msgstr "Toolbox"
+
+#~ msgid "Defined"
+#~ msgstr "Definito"
+
+#~ msgid "None"
+#~ msgstr "Niente"
+
+#~ msgid "Moving block"
+#~ msgstr "Blocco mobile"
+
+#~ msgid "Moving shadow block"
+#~ msgstr "Blocco-ombra mobile"
+
+#~ msgid "Moving spikes"
+#~ msgstr "Spuntoni mobili"
+
+#~ msgid "Shadow Conveyor belt"
+#~ msgstr "Nastro-ombra trasportatore"
+
+#~ msgid "Portal"
+#~ msgstr "Portale"
+
+#~ msgid "Activate on touch"
+#~ msgstr "Attivabile manualmente"
+
+#~ msgid "Targets:"
+#~ msgstr "Obiettivi:"
+
+#~ msgid "%d Defined"
+#~ msgstr "%d definito"
+
+#~ msgid "Behaviour:"
+#~ msgstr "Comportamento:"
+#~ msgid "State:"
+#~ msgstr "Stato:"
diff --git a/data/themes/Cloudscape/theme.mnmstheme b/data/themes/Cloudscape/theme.mnmstheme
index 676a8b3..4e493c8 100644
--- a/data/themes/Cloudscape/theme.mnmstheme
+++ b/data/themes/Cloudscape/theme.mnmstheme
@@ -1,484 +1,484 @@
name="Cloudscape"
background(background.png){
repeat=0,0
}
block(Block){
editorPicture(tiles/tiles.png,0,0,50,50)
state(default){
object{
picture(tiles/tiles.png,0,0,50,50)
optionalPicture(tiles/tiles.png,50,0,50,50,0.15)
optionalPicture(tiles/tiles.png,100,0,50,50,0.15)
}
}
}
block(ShadowBlock){
editorPicture(tiles/tiles.png,0,50,50,50)
state(default){
object{
picture(tiles/tiles.png,0,50,50,50)
}
}
}
character(Player){
state(standleft){
object{
picture(characters/player.png,115,0,23,40)
}
}
state(standright){
object{
picture(characters/player.png,0,0,23,40)
}
}
state(walkleft){
object{
animation=20,0
pictureAnimation(characters/player.png){
point(138,0,23,40,1,5)
point(230,0,23,40,4,5)
}
}
}
state(walkright){
object{
animation=20,0
pictureAnimation(characters/player.png){
point(23,0,23,40,1,5)
point(115,0,23,40,4,5)
}
}
}
state(jumpleft){
object{
picture(characters/player.png,276,0,23,40)
}
}
state(fallleft){
object{
picture(characters/player.png,299,0,23,40)
}
}
state(jumpright){
object{
picture(characters/player.png,230,0,23,40)
}
}
state(fallright){
object{
picture(characters/player.png,253,0,23,40)
}
}
state(holding){
object{
picture(characters/player.png,322,0,23,40)
}
}
state(line){
object{
picture(characters/line.png,0,0,5,5)
}
}
state(dieright){
oneTimeAnimation=8,dead
object{
offset(0,-14)
animation=8,0
pictureAnimation(characters/deathright.png){
point(0,0,23,54,1,2)
point(92,0,23,54,4,2)
}
}
}
state(dieleft){
oneTimeAnimation=8,dead
object{
offset(0,-14)
animation=8,0
pictureAnimation(characters/deathleft.png){
point(0,0,23,54,1,2)
point(92,0,23,54,4,2)
}
}
}
state(dead){
object{
picture(characters/player.png,0,0,23,40)
invisibleAtRunTime=1
}
}
}
character(Shadow){
state(standleft){
object{
picture(characters/shadow.png,115,0,23,40)
}
}
state(standright){
object{
picture(characters/shadow.png,0,0,23,40)
}
}
state(walkleft){
object{
animation=20,0
pictureAnimation(characters/shadow.png){
point(138,0,23,40,1,5)
point(230,0,23,40,4,5)
}
}
}
state(walkright){
object{
animation=20,0
pictureAnimation(characters/shadow.png){
point(23,0,23,40,1,5)
point(115,0,23,40,4,5)
}
}
}
state(jumpleft){
object{
picture(characters/shadow.png,276,0,23,40)
}
}
state(fallleft){
object{
picture(characters/shadow.png,299,0,23,40)
}
}
state(jumpright){
object{
picture(characters/shadow.png,230,0,23,40)
}
}
state(fallright){
object{
picture(characters/shadow.png,253,0,23,40)
}
}
state(holding){
object{
picture(characters/shadow.png,322,0,23,40)
}
}
state(line){
object{
picture(characters/line.png,0,0,5,5)
}
}
state(dieright){
oneTimeAnimation=8,dead
object{
offset(0,-14)
animation=8,0
pictureAnimation(characters/shadowdeathright.png){
point(0,0,23,54,1,2)
point(92,0,23,54,4,2)
}
}
}
state(dieleft){
oneTimeAnimation=8,dead
object{
offset(0,-14)
animation=8,0
pictureAnimation(characters/shadowdeathleft.png){
point(0,0,23,54,1,2)
point(92,0,23,54,4,2)
}
}
}
state(dead){
object{
picture(characters/player.png,0,0,23,40)
invisibleAtRunTime=1
}
}
}
block(Fragile){
editorPicture(tiles/tiles.png,150,0,50,50)
state(default){
object{
picture(tiles/tiles.png,150,0,50,50)
}
}
transitionState(default,fragile1){
oneTimeAnimation=20,fragile1
object{
oneTimeAnimation=20,6
pictureAnimation(tiles/tiles.png){
point(200,0,50,50,1,5)
point(250,0,50,50,1,5)
}
}
}
state(fragile1){
object{
picture(tiles/tiles.png,250,0,50,50)
}
}
transitionState(fragile1,fragile2){
oneTimeAnimation=20,fragile2
object{
oneTimeAnimation=20,6
pictureAnimation(tiles/tiles.png){
point(300,0,50,50,1,5)
point(350,0,50,50,1,5)
}
}
}
state(fragile2){
object{
picture(tiles/tiles.png,350,0,50,50)
}
}
state(fragile3){
oneTimeAnimation=6,fragile3_1
object{
animation=20,0
pictureAnimation(tiles/tiles.png){
point(150,50,50,100,1,2)
point(250,50,50,100,2,2)
}
}
}
state(fragile3_1){
object{
picture(tiles/tiles.png,250,50,50,100)
invisibleAtRunTime=1
}
}
}
block(MovingBlock){
editorPicture(tiles/tiles.png,350,200,50,50)
state(default){
object{
picture(tiles/tiles.png,0,0,50,50)
optionalPicture(tiles/tiles.png,50,0,50,50,0.15)
optionalPicture(tiles/tiles.png,100,0,50,50,0.15)
editorPicture(tiles/tiles.png,350,200,50,50)
}
}
}
block(MovingShadowBlock){
editorPicture(tiles/tiles.png,300,200,50,50)
state(default){
object{
picture(tiles/tiles.png,0,50,50,50)
editorPicture(tiles/tiles.png,300,200,50,50)
}
}
}
block(Exit){
editorPicture(tiles/tiles.png,150,200,50,50)
state(default){
object{
picture(tiles/tiles.png,150,200,50,50)
}
}
state(closed){
object{
picture(tiles/tiles.png,0,200,50,50)
}
}
transitionState(closed,default){
oneTimeAnimation=6,open
object{
animation=80,0
pictureAnimation(tiles/tiles.png){
point(50,200,50,50,1,2)
point(150,200,50,50,2,2)
}
}
}
}
block(Spikes){
editorPicture(tiles/tiles.png,450,0,50,50)
state(default){
object{
picture(tiles/tiles.png,450,0,50,50)
optionalPicture(tiles/tiles.png,450,50,50,50,0.5)
}
}
}
block(MovingSpikes){
editorPicture(tiles/tiles.png,400,200,50,50)
state(default){
object{
editorPicture(tiles/tiles.png,400,200,50,50)
picture(tiles/tiles.png,450,0,50,50)
optionalPicture(tiles/tiles.png,450,50,50,50,0.5)
}
}
}
block(Checkpoint){
editorPicture(tiles/tiles.png,50,50,50,50)
state(default){
object{
picture(tiles/tiles.png,50,50,50,50)
}
}
state(activated){
object{
animation=16,0
picture(tiles/tiles.png,100,50,50,50)
offsetAnimation{
point(0,0)
point(0,-4,4,1)
point(0,4,8,1)
point(0,0,4,1)
}
}
}
}
block(Swap){
editorPicture(tiles/swap.png,0,0,50,50)
state(default){
object{
picture(tiles/swap.png,0,0,50,50)
}
}
state(activated){
oneTimeAnimation=24,default
object{
animation=12,0
pictureAnimation(tiles/swap.png){
point(0,0,50,50)
point(600,0,50,50,12,1)
}
}
}
}
block(Teleporter){
editorPicture(tiles/tiles.png,300,50,50,50)
state(default){
object{
picture(tiles/tiles.png,300,50,50,50)
}
}
state(activated){
oneTimeAnimation=9,default
object{
animation=3,0
pictureAnimation(tiles/tiles.png){
point(300,50,50,50)
point(450,50,50,50,3,1)
}
}
}
}
block(Switch){
editorPicture(tiles/tiles.png,0,100,50,50)
state(default){
object{
picture(tiles/tiles.png,0,100,50,50)
}
}
transitionState(default,activated){
oneTimeAnimation=3,activated
object{
animation=3,0
pictureAnimation(tiles/tiles.png){
point(0,100,50,50)
point(150,100,50,50,3,1)
}
}
}
state(activated){
object{
picture(tiles/tiles.png,100,100,50,50)
}
}
transitionState(activated,default){
oneTimeAnimation=3,default
object{
animation=3,0
pictureAnimation(tiles/tiles.png){
point(100,100,50,50)
point(-50,100,50,50,3,1)
}
}
}
}
block(Button){
editorPicture(tiles/tiles.png,450,200,50,50)
state(default){
object{
picture(tiles/tiles.png,0,0,50,50)
optionalPicture(tiles/tiles.png,50,0,50,50,0.15)
optionalPicture(tiles/tiles.png,100,0,50,50,0.15)
}
}
state(button){
object{
# TODO:
picture(tiles/tiles.png,300,100,50,16)
}
}
}
block(NotificationBlock){
editorPicture(tiles/tiles.png,350,100,50,50)
state(default){
object{
picture(tiles/tiles.png,350,100,50,50)
}
}
}
block(ConveyorBelt){
editorPicture(tiles/tiles.png,450,100,50,50)
state(default){
object{
picture(tiles/tiles.png,450,100,50,50)
editorPicture(tiles/tiles.png,450,100,50,50)
}
}
}
block(ShadowConveyorBelt){
editorPicture(tiles/tiles.png,400,100,50,50)
state(default){
object{
picture(tiles/tiles.png,400,100,50,50)
}
}
}
block(PlayerStart){
editorPicture(tiles/tiles.png,250,200,50,50)
state(default){
object{
picture(tiles/tiles.png,250,200,50,50)
invisibleAtRunTime=1
}
}
}
block(ShadowStart){
editorPicture(tiles/tiles.png,200,200,50,50)
state(default){
object{
picture(tiles/tiles.png,200,200,50,50)
invisibleAtRunTime=1
}
}
}
block(Collectable){
- editorPicture(tiles/collectable.png,0,0,50,50)
+ editorPicture(tiles/tiles.png,50,150,50,50)
state(inactive){
object{
}
}
state(default){
object{
- picture(tiles/collectable.png,0,0,50,50)
+ picture(tiles/tiles.png,50,150,50,50)
}
}
}
block(Pushable){
- editorPicture(tiles/crate.png,0,0,50,50)
+ editorPicture(tiles/tiles.png,0,150,50,50)
state(default){
object{
- picture(tiles/crate.png,0,0,50,50)
- editorPicture(tiles/crate.png,0,0,50,50)
+ picture(tiles/tiles.png,0,150,50,50)
+ editorPicture(tiles/tiles.png,0,150,50,50)
}
}
}
diff --git a/data/themes/Cloudscape/tiles/collectable.png b/data/themes/Cloudscape/tiles/collectable.png
deleted file mode 100644
index 1bcc238..0000000
Binary files a/data/themes/Cloudscape/tiles/collectable.png and /dev/null differ
diff --git a/data/themes/Cloudscape/tiles/crate.png b/data/themes/Cloudscape/tiles/crate.png
deleted file mode 100644
index 50e1d90..0000000
Binary files a/data/themes/Cloudscape/tiles/crate.png and /dev/null differ
diff --git a/data/themes/Cloudscape/tiles/tiles.png b/data/themes/Cloudscape/tiles/tiles.png
index 6fa5c91..898ae3a 100644
Binary files a/data/themes/Cloudscape/tiles/tiles.png and b/data/themes/Cloudscape/tiles/tiles.png differ
diff --git a/src/Game.cpp b/src/Game.cpp
index 26cadd9..dba698f 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,1570 +1,1568 @@
/*
* Copyright (C) 2011-2013 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow 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.
*
* Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GameState.h"
#include "Globals.h"
#include "Functions.h"
#include "FileManager.h"
#include "GameObjects.h"
#include "ThemeManager.h"
#include "Objects.h"
#include "Game.h"
#include "TreeStorageNode.h"
#include "POASerializer.h"
#include "InputManager.h"
#include "StatisticsManager.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <algorithm>
#include <locale>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libs/tinyformat/tinyformat.h"
using namespace std;
const char* Game::blockName[TYPE_MAX]={"Block","PlayerStart","ShadowStart",
"Exit","ShadowBlock","Spikes",
"Checkpoint","Swap","Fragile",
"MovingBlock","MovingShadowBlock","MovingSpikes",
"Teleporter","Button","Switch",
"ConveyorBelt","ShadowConveyorBelt","NotificationBlock", "Collectable", "Pushable"
};
map<string,int> Game::blockNameMap;
map<int,string> Game::gameObjectEventTypeMap;
map<string,int> Game::gameObjectEventNameMap;
string Game::recordFile;
Game::Game():isReset(false)
,currentLevelNode(NULL)
,customTheme(NULL)
,background(NULL)
,won(false)
,interlevel(false)
,gameTipIndex(0)
,time(0),timeSaved(0)
,recordings(0),recordingsSaved(0)
,shadowCam(false)
,player(this),shadow(this),objLastCheckPoint(NULL),
medalX(0),currentCollectables(0),totalCollectables(0),currentCollectablesSaved(0){
saveStateNextTime=false;
loadStateNextTime=false;
recentSwap=recentSwapSaved=-10000;
recentLoad=recentSave=0;
//Reserve the memory for the GameObject tips.
memset(bmTips,0,sizeof(bmTips));
action=loadImage(getDataPath()+"gfx/actions.png");
medals=loadImage(getDataPath()+"gfx/medals.png");
//Get the collectable image from the theme.
//NOTE: Isn't there a better way to retrieve the image?
- ThemeBlockInstance appearance;
- objThemes.getBlock(TYPE_COLLECTABLE)->createInstance(&appearance);
- collectable=appearance.currentState->parent->themeObjects[0]->picture.picture;
+ objThemes.getBlock(TYPE_COLLECTABLE)->createInstance(&collectable);
//Hide the cursor if not in the leveleditor.
if(stateID!=STATE_LEVEL_EDITOR)
SDL_ShowCursor(SDL_DISABLE);
}
Game::~Game(){
//Simply call our destroy method.
destroy();
//Before we leave make sure the cursor is visible.
SDL_ShowCursor(SDL_ENABLE);
}
void Game::destroy(){
//Loop through the levelObjects and delete them.
for(unsigned int i=0;i<levelObjects.size();i++)
delete levelObjects[i];
//Done now clear the levelObjects vector.
levelObjects.clear();
//Loop through the backgroundLayers and delete them.
std::map<std::string,std::vector<Scenery*> >::iterator it;
for(it=backgroundLayers.begin();it!=backgroundLayers.end();++it){
for(unsigned int i=0;i<it->second.size();i++)
delete it->second[i];
}
backgroundLayers.clear();
//Clear the name and the editor data.
levelName.clear();
levelFile.clear();
editorData.clear();
//Loop through the tips.
for(int i=0;i<TYPE_MAX;i++){
//If it exist free the SDL_Surface.
if(bmTips[i])
SDL_FreeSurface(bmTips[i]);
}
memset(bmTips,0,sizeof(bmTips));
//Remove everything from the themeManager.
background=NULL;
if(customTheme)
objThemes.removeTheme();
customTheme=NULL;
//If there's a (partial) theme bundled with the levelpack remove that as well.
if(levels->customTheme)
objThemes.removeTheme();
//delete current level (if any)
if(currentLevelNode){
delete currentLevelNode;
currentLevelNode=NULL;
}
//Reset the time.
time=timeSaved=0;
recordings=recordingsSaved=0;
recentSwap=recentSwapSaved=-10000;
}
void Game::loadLevelFromNode(TreeStorageNode* obj,const string& fileName){
//Make sure there's nothing left from any previous levels.
//Not needed since loadLevelFromNode is only called from the changeState method, meaning it's a new instance of Game.
//destroy();
//set current level to loaded one.
currentLevelNode=obj;
//Temp var used for block locations.
SDL_Rect box;
//Set the level dimensions to the default, it will probably be changed by the editorData,
//but 800x600 is a fallback.
LEVEL_WIDTH=800;
LEVEL_HEIGHT=600;
currentCollectables=0;
totalCollectables=0;
currentCollectablesSaved=0;
//Load the additional data.
for(map<string,vector<string> >::iterator i=obj->attributes.begin();i!=obj->attributes.end();++i){
if(i->first=="size"){
//We found the size attribute.
if(i->second.size()>=2){
//Set the dimensions of the level.
LEVEL_WIDTH=atoi(i->second[0].c_str());
LEVEL_HEIGHT=atoi(i->second[1].c_str());
}
}else if(i->second.size()>0){
//Any other data will be put into the editorData.
editorData[i->first]=i->second[0];
}
}
//Get the theme.
{
//If a theme is configured then load it.
string theme=processFileName(getSettings()->getValue("theme"));
//Check if level themes are enabled.
if(getSettings()->getBoolValue("leveltheme")) {
//Check for the theme to use.
string &s=editorData["theme"];
if(!s.empty()){
customTheme=objThemes.appendThemeFromFile(processFileName(s)+"/theme.mnmstheme");
}
//Also check for bundled (partial) themes.
if(levels->customTheme){
if(objThemes.appendThemeFromFile(levels->levelpackPath+"/theme/theme.mnmstheme")==NULL){
//The theme failed to load so set the customTheme boolean to false.
levels->customTheme=false;
}
}
}
//Set the Appearance of the player and the shadow.
objThemes.getCharacter(false)->createInstance(&player.appearance);
objThemes.getCharacter(true)->createInstance(&shadow.appearance);
}
for(unsigned int i=0;i<obj->subNodes.size();i++){
TreeStorageNode* obj1=obj->subNodes[i];
if(obj1==NULL) continue;
if(obj1->name=="tile"){
Block* block=new Block(this);
if(!block->loadFromNode(obj1)){
delete block;
continue;
}
//If the type is collectable, increase the number of totalCollectables
if(block->type==TYPE_COLLECTABLE)
totalCollectables++;
//Add the block to the levelObjects vector.
levelObjects.push_back(block);
}else if(obj1->name=="backgroundlayer" && obj1->value.size()==1){
//Loop through the sub nodes.
for(unsigned int j=0;j<obj1->subNodes.size();j++){
TreeStorageNode* obj2=obj1->subNodes[j];
if(obj2==NULL) continue;
if(obj2->name=="object"){
//Load the scenery from node.
Scenery* scenery=new Scenery(this);
if(!scenery->loadFromNode(obj2)){
delete scenery;
continue;
}
backgroundLayers[obj1->value[0]].push_back(scenery);
}
}
}
}
//Close exits if there are collectables
if(totalCollectables>0){
for(unsigned int i=0;i<levelObjects.size();i++){
if(levelObjects[i]->type==TYPE_EXIT){
levelObjects[i]->onEvent(GameObjectEvent_OnSwitchOff);
}
}
}
//Set the levelName to the name of the current level.
levelName=editorData["name"];
levelFile=fileName;
//Some extra stuff only needed when not in the levelEditor.
if(stateID!=STATE_LEVEL_EDITOR){
//We create a text with the text "Level <levelno> <levelName>".
//It will be shown in the left bottom corner of the screen.
string s;
if(levels->getLevelCount()>1){
s=tfm::format(_("Level %d %s"),levels->getCurrentLevel()+1,_C(levels->getDictionaryManager(),editorData["name"]));
}
SDL_Color fg={0,0,0,0};
bmTips[0]=TTF_RenderUTF8_Blended(fontText,s.c_str(),fg);
}
//Get the background
background=objThemes.getBackground(false);
if(background)
background->resetAnimation(true);
//Reset the script environment.
getScriptExecutor()->reset();
//Send GameObjectEvent_OnCreate event to the script
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->onEvent(GameObjectEvent_OnCreate);
}
}
void Game::loadLevel(string fileName){
//Create a TreeStorageNode that will hold the loaded data.
TreeStorageNode *obj=new TreeStorageNode();
{
POASerializer objSerializer;
string s=fileName;
//Parse the file.
if(!objSerializer.loadNodeFromFile(s.c_str(),obj,true)){
cout<<"Can't load level file "<<s<<endl;
delete obj;
return;
}
}
//Now call another function.
loadLevelFromNode(obj,fileName);
}
void Game::saveRecord(const char* fileName){
//check if current level is NULL (which should be impossible)
if(currentLevelNode==NULL) return;
TreeStorageNode obj;
POASerializer objSerializer;
//put current level to the node.
currentLevelNode->name="map";
obj.subNodes.push_back(currentLevelNode);
//serialize the game record using RLE compression.
#define PUSH_BACK \
if(j>0){ \
if(j>1){ \
sprintf(c,"%d*%d",last,j); \
}else{ \
sprintf(c,"%d",last); \
} \
v.push_back(c); \
}
vector<string> &v=obj.attributes["record"];
vector<int> *record=player.getRecord();
char c[64];
int i,j=0,last;
for(i=0;i<(int)record->size();i++){
int currentKey=(*record)[i];
if(j==0 || currentKey!=last){
PUSH_BACK;
last=currentKey;
j=1;
}else{
j++;
}
}
PUSH_BACK;
#undef PUSH_BACK
#ifdef RECORD_FILE_DEBUG
//add record file debug data.
{
obj.attributes["recordKeyPressLog"].push_back(player.keyPressLog());
vector<SDL_Rect> &playerPosition=player.playerPosition();
string s;
char c[32];
sprintf(c,"%d\n",int(playerPosition.size()));
s=c;
for(unsigned int i=0;i<playerPosition.size();i++){
SDL_Rect& r=playerPosition[i];
sprintf(c,"%d %d\n",r.x,r.y);
s+=c;
}
obj.attributes["recordPlayerPosition"].push_back(s);
}
#endif
//save it
objSerializer.saveNodeToFile(fileName,&obj,true,true);
//remove current level from node to prevent delete it.
obj.subNodes.clear();
}
void Game::loadRecord(const char* fileName){
//Create a TreeStorageNode that will hold the loaded data.
TreeStorageNode obj;
{
POASerializer objSerializer;
string s=fileName;
//Parse the file.
if(!objSerializer.loadNodeFromFile(s.c_str(),&obj,true)){
cout<<"Can't load record file "<<s<<endl;
return;
}
}
//find the node named 'map'.
bool loaded=false;
for(unsigned int i=0;i<obj.subNodes.size();i++){
if(obj.subNodes[i]->name=="map"){
//load the level. (fileName=???)
loadLevelFromNode(obj.subNodes[i],"???");
//remove this node to prevent delete it.
obj.subNodes[i]=NULL;
//over
loaded=true;
break;
}
}
if(!loaded){
cout<<"ERROR: Can't find subnode named 'map' from record file"<<endl;
return;
}
//load the record.
{
vector<int> *record=player.getRecord();
record->clear();
vector<string> &v=obj.attributes["record"];
for(unsigned int i=0;i<v.size();i++){
string &s=v[i];
string::size_type pos=s.find_first_of('*');
if(pos==string::npos){
//1 item only.
int i=atoi(s.c_str());
record->push_back(i);
}else{
//contains many items.
int i=atoi(s.substr(0,pos).c_str());
int j=atoi(s.substr(pos+1).c_str());
for(;j>0;j--){
record->push_back(i);
}
}
}
}
#ifdef RECORD_FILE_DEBUG
//load the debug data
{
vector<string> &v=obj.attributes["recordPlayerPosition"];
vector<SDL_Rect> &playerPosition=player.playerPosition();
playerPosition.clear();
if(!v.empty()){
if(!v[0].empty()){
stringstream st(v[0]);
int m;
st>>m;
for(int i=0;i<m;i++){
SDL_Rect r;
st>>r.x>>r.y;
r.w=0;
r.h=0;
playerPosition.push_back(r);
}
}
}
}
#endif
//play the record.
//TODO: tell the level manager don't save the level progress.
player.playRecord();
shadow.playRecord(); //???
}
/////////////EVENT///////////////
void Game::handleEvents(){
//First of all let the player handle input.
player.handleInput(&shadow);
//Check for an SDL_QUIT event.
if(event.type==SDL_QUIT){
//We need to quit so enter STATE_EXIT.
setNextState(STATE_EXIT);
}
//Check for the escape key.
if(inputMgr.isKeyUpEvent(INPUTMGR_ESCAPE)){
//Escape means we go one level up, to the level select state.
setNextState(STATE_LEVEL_SELECT);
//Save the progress.
levels->saveLevelProgress();
//And change the music back to the menu music.
getMusicManager()->playMusic("menu");
}
//Check if 'r' is pressed.
if(inputMgr.isKeyDownEvent(INPUTMGR_RESTART)){
//Only set isReset true if this isn't a replay.
if(!(player.isPlayFromRecord() && !interlevel))
isReset=true;
}
//Check for the next level buttons when in the interlevel popup.
if(inputMgr.isKeyDownEvent(INPUTMGR_SPACE) || (event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_RCTRL))){
if(interlevel){
//The interlevel popup is shown so we need to delete it.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//Now goto the next level.
gotoNextLevel();
}
}
//Check if tab is pressed.
if(inputMgr.isKeyDownEvent(INPUTMGR_TAB)){
shadowCam=!shadowCam;
}
}
/////////////////LOGIC///////////////////
void Game::logic(){
//Check if we should save/load state.
if(saveStateNextTime){
saveState();
}else if(loadStateNextTime){
loadState();
}
saveStateNextTime=false;
loadStateNextTime=false;
//Add one tick to the time.
time++;
//First prepare each gameObject for the new frame.
//This includes resetting dx/dy and xVel/yVel.
for(unsigned int o=0;o<levelObjects.size();o++)
levelObjects[o]->prepareFrame();
//Process any event in the queue.
for(unsigned int idx=0;idx<eventQueue.size();idx++){
//Get the event from the queue.
typeGameObjectEvent &e=eventQueue[idx];
//Check if the it has an id attached to it.
if(e.target){
//NOTE: Should we check if the target still exists???
e.target->onEvent(e.eventType);
}else if(e.flags|1){
//Loop through the levelObjects and give them the event if they have the right id.
for(unsigned int i=0;i<levelObjects.size();i++){
if(e.objectType<0 || levelObjects[i]->type==e.objectType){
if(levelObjects[i]->id==e.id){
levelObjects[i]->onEvent(e.eventType);
}
}
}
}else{
//Loop through the levelObjects and give them the event.
for(unsigned int i=0;i<levelObjects.size();i++){
if(e.objectType<0 || levelObjects[i]->type==e.objectType){
levelObjects[i]->onEvent(e.eventType);
}
}
}
}
//Done processing the events so clear the queue.
eventQueue.clear();
//Loop through the gameobjects to update them.
for(unsigned int i=0;i<levelObjects.size();i++){
//Send GameObjectEvent_OnEnterFrame event to the script
levelObjects[i]->onEvent(GameObjectEvent_OnEnterFrame);
}
for(unsigned int i=0;i<levelObjects.size();i++){
//Let the gameobject handle movement.
levelObjects[i]->move();
}
//Also update the scenery.
{
std::map<std::string,std::vector<Scenery*> >::iterator it;
for(it=backgroundLayers.begin();it!=backgroundLayers.end();++it){
for(unsigned int i=0;i<it->second.size();i++)
it->second[i]->move();
}
}
//Let the player store his move, if recording.
player.shadowSetState();
//Let the player give his recording to the shadow, if configured.
player.shadowGiveState(&shadow);
//Let him move.
player.move(levelObjects);
//And let the camera follow him.
if(!shadowCam){
player.setMyCamera();
}else{
shadow.setMyCamera();
}
//Now let the shadow decide his move, if he's playing a recording.
shadow.moveLogic();
//Let the shadow move.
shadow.move(levelObjects);
//Check collision and stuff for the shadow and player.
player.otherCheck(&shadow);
//Check if we won.
if(won){
//Check if it's playing from record
if(player.isPlayFromRecord() && !interlevel){
recordingEnded();
}else{
//the string to store auto-save record path.
string bestTimeFilePath,bestRecordingFilePath;
//and if we can't get test path.
bool filePathError=false;
//Get current level
LevelPack::Level *level=levels->getLevel();
//Now check if we should update statistics
{
//Get previous and current medal
int oldMedal=level->won?1:0,newMedal=1;
int bestTime=level->time;
int targetTime=level->targetTime;
int bestRecordings=level->recordings;
int targetRecordings=level->targetRecordings;
if(oldMedal){
if(targetTime<0){
oldMedal=3;
}else{
if(targetTime<0 || bestTime<=targetTime)
oldMedal++;
if(targetRecordings<0 || bestRecordings<=targetRecordings)
oldMedal++;
}
}else{
bestTime=time;
bestRecordings=recordings;
}
if(bestTime==-1 || bestTime>time) bestTime=time;
if(bestRecordings==-1 || bestRecordings>recordings) bestRecordings=recordings;
if(targetTime<0){
newMedal=3;
}else{
if(targetTime<0 || bestTime<=targetTime)
newMedal++;
if(targetRecordings<0 || bestRecordings<=targetRecordings)
newMedal++;
}
//Check if we need to update statistics
if(newMedal>oldMedal){
switch(oldMedal){
case 0:
statsMgr.completedLevels++;
break;
case 2:
statsMgr.silverLevels--;
break;
}
switch(newMedal){
case 2:
statsMgr.silverLevels++;
break;
case 3:
statsMgr.goldLevels++;
break;
}
}
}
//Set the current level won.
level->won=true;
if(level->time==-1 || level->time>time){
level->time=time;
//save the best-time game record.
if(bestTimeFilePath.empty()){
getCurrentLevelAutoSaveRecordPath(bestTimeFilePath,bestRecordingFilePath,true);
}
if(bestTimeFilePath.empty()){
cout<<"ERROR: Couldn't get auto-save record file path"<<endl;
filePathError=true;
}else{
saveRecord(bestTimeFilePath.c_str());
}
}
if(level->recordings==-1 || level->recordings>recordings){
level->recordings=recordings;
//save the best-recordings game record.
if(bestRecordingFilePath.empty() && !filePathError){
getCurrentLevelAutoSaveRecordPath(bestTimeFilePath,bestRecordingFilePath,true);
}
if(bestRecordingFilePath.empty()){
cout<<"ERROR: Couldn't get auto-save record file path"<<endl;
filePathError=true;
}else{
saveRecord(bestRecordingFilePath.c_str());
}
}
//Set the next level unlocked if it exists.
if(levels->getCurrentLevel()+1<levels->getLevelCount()){
levels->setLocked(levels->getCurrentLevel()+1);
}
//And save the progress.
levels->saveLevelProgress();
//Now go to the interlevel screen.
replayPlay();
//Update achievements
if(levels->levelpackName=="tutorial") statsMgr.updateTutorialAchievements();
statsMgr.updateLevelAchievements();
//NOTE: We set isReset false to prevent the user from getting a best time of 0.00s and 0 recordings.
}
}
won=false;
//Check if we should reset.
if(isReset)
//NOTE: In case of the interlevel popup the save data needs to be deleted so the restart behaviour is the same for key and button restart.
reset(interlevel);
isReset=false;
}
/////////////////RENDER//////////////////
void Game::render(){
//First of all render the background.
{
//Get a pointer to the background.
ThemeBackground* bg=background;
//Check if the background is null, but there are themes.
if(bg==NULL && objThemes.themeCount()>0){
//Get the background from the first theme in the stack.
bg=objThemes[0]->getBackground(false);
}
//Check if the background isn't null.
if(bg){
//It isn't so draw it.
bg->draw(screen);
//And if it's the loaded background then also update the animation.
//FIXME: Updating the animation in the render method?
if(bg==background)
bg->updateAnimation();
}else{
//There's no background so fill the screen with white.
SDL_Rect r={0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
SDL_FillRect(screen,&r,-1);
}
}
//Now draw the backgroundLayers.
std::map<std::string,std::vector<Scenery*> >::iterator it;
for(it=backgroundLayers.begin();it!=backgroundLayers.end();++it){
for(unsigned int i=0;i<it->second.size();i++)
it->second[i]->show();
}
//Now we draw the levelObjects.
for(unsigned int o=0; o<levelObjects.size(); o++){
levelObjects[o]->show();
}
//Followed by the player and the shadow.
//NOTE: We draw the shadow second because he needs to be behind the player.
shadow.show();
player.show();
//Show the levelName if it isn't the level editor.
if(stateID!=STATE_LEVEL_EDITOR && bmTips[0]!=NULL && !interlevel){
drawGUIBox(-2,SCREEN_HEIGHT-bmTips[0]->h-4,bmTips[0]->w+8,bmTips[0]->h+6,screen,0xFFFFFFFF);
applySurface(2,SCREEN_HEIGHT-bmTips[0]->h,bmTips[0],screen,NULL);
}
//Check if there's a tooltip.
//NOTE: gameTipIndex 0 is used for the levelName, 1 for shadow death, 2 for restart text, 3 for restart+checkpoint.
if(gameTipIndex>3 && gameTipIndex<TYPE_MAX){
//Check if there's a tooltip for the type.
if(bmTips[gameTipIndex]==NULL){
//There isn't thus make it.
string s;
string keyCode=_(inputMgr.getKeyCodeName(inputMgr.getKeyCode(INPUTMGR_ACTION,false)));
transform(keyCode.begin(),keyCode.end(),keyCode.begin(),::toupper);
switch(gameTipIndex){
case TYPE_CHECKPOINT:
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with current action key
s=tfm::format(_("Press %s key to save the game."),keyCode);
break;
case TYPE_SWAP:
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with current action key
s=tfm::format(_("Press %s key to swap the position of player and shadow."),keyCode);
break;
case TYPE_SWITCH:
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with current action key
s=tfm::format(_("Press %s key to activate the switch."),keyCode);
break;
case TYPE_PORTAL:
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with current action key
s=tfm::format(_("Press %s key to teleport."),keyCode);
break;
}
//If we have a string then it's a supported GameObject type.
if(!s.empty()){
SDL_Color fg={0,0,0,0};
bmTips[gameTipIndex]=TTF_RenderUTF8_Blended(fontText,s.c_str(),fg);
}
}
//We already have a gameTip for this type so draw it.
if(bmTips[gameTipIndex]!=NULL){
drawGUIBox(-2,-2,bmTips[gameTipIndex]->w+8,bmTips[gameTipIndex]->h+6,screen,0xFFFFFFFF);
applySurface(2,2,bmTips[gameTipIndex],screen,NULL);
}
}
//Set the gameTip to 0.
gameTipIndex=0;
//Pointer to the sdl surface that will contain a message, if any.
SDL_Surface* bm=NULL;
//Check if the player is dead, meaning we draw a message.
if(player.dead){
//Get user configured restart key
string keyCodeRestart=inputMgr.getKeyCodeName(inputMgr.getKeyCode(INPUTMGR_RESTART,false));
transform(keyCodeRestart.begin(),keyCodeRestart.end(),keyCodeRestart.begin(),::toupper);
//The player is dead, check if there's a state that can be loaded.
if(player.canLoadState()){
//Now check if the tip is already made, if not make it.
if(bmTips[3]==NULL){
//Get user defined key for loading checkpoint
string keyCodeLoad=inputMgr.getKeyCodeName(inputMgr.getKeyCode(INPUTMGR_LOAD,false));
transform(keyCodeLoad.begin(),keyCodeLoad.end(),keyCodeLoad.begin(),::toupper);
//Draw string
SDL_Color fg={0,0,0,0},bg={255,255,255,0};
bmTips[3]=TTF_RenderUTF8_Blended(fontText,
/// TRANSLATORS: Please do not remove %s from your translation:
/// - first %s means currently configured key to restart game
/// - Second %s means configured key to load from last save
tfm::format(_("Press %s to restart current level or press %s to load the game."),
keyCodeRestart,keyCodeLoad).c_str(),
fg);
}
bm=bmTips[3];
}else{
//Now check if the tip is already made, if not make it.
if(bmTips[2]==NULL){
SDL_Color fg={0,0,0,0};
bmTips[2]=TTF_RenderUTF8_Blended(fontText,
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with currently configured key to restart game
tfm::format(_("Press %s to restart current level."),keyCodeRestart).c_str(),
fg);
}
bm=bmTips[2];
}
}
//Check if the shadow has died (and there's no other notification).
//NOTE: We use the shadow's jumptime as countdown, this variable isn't used when the shadow is dead.
if(shadow.dead && bm==NULL && shadow.jumpTime>0){
//Now check if the tip is already made, if not make it.
if(bmTips[1]==NULL){
SDL_Color fg={0,0,0,0},bg={255,255,255,0};
bmTips[1]=TTF_RenderUTF8_Blended(fontText,
_("Your shadow has died."),
fg);
}
bm=bmTips[1];
//NOTE: Logic in the render loop, we substract the shadow's jumptime by one.
shadow.jumpTime--;
//return view to player and keep it there
shadowCam=false;
}
//Draw the tip.
if(bm!=NULL){
int x=(SCREEN_WIDTH-bm->w)/2;
int y=32;
drawGUIBox(x-8,y-8,bm->w+16,bm->h+14,screen,0xFFFFFFFF);
applySurface(x,y,bm,screen,NULL);
}
//Show the number of collectables the user has collected if there are collectables in the level.
//We hide this when interlevel.
if(currentCollectables<=totalCollectables && totalCollectables!=0 && !interlevel && time>0){
//Temp stringstream just to addup all the text nicely
stringstream temp;
temp << currentCollectables << "/" << totalCollectables;
SDL_Rect r;
SDL_Surface* bm=TTF_RenderText_Blended(fontText,temp.str().c_str(),themeTextColorDialog);
//Align the text properly
- r.x=SCREEN_WIDTH-collectable->w-bm->w+22;
+ r.x=SCREEN_WIDTH-50-bm->w+22;
r.y=SCREEN_HEIGHT-bm->h;
//Draw background
drawGUIBox(SCREEN_WIDTH-bm->w-34,SCREEN_HEIGHT-bm->h-4,bm->w+34+2,bm->h+4+2,screen,0xFFFFFFFF);
//Draw the collectable icon
- applySurface(SCREEN_WIDTH-collectable->w+12,SCREEN_HEIGHT-collectable->h+10,collectable,screen,NULL);
+ collectable.draw(screen,SCREEN_WIDTH-50+12,SCREEN_HEIGHT-50+10,NULL);
//Draw text
SDL_BlitSurface(bm,NULL,screen,&r);
SDL_FreeSurface(bm);
}
//show time and records used in level editor.
if(stateID==STATE_LEVEL_EDITOR && time>0){
SDL_Color fg={0,0,0,0},bg={255,255,255,0};
SDL_Surface *bm;
int y=SCREEN_HEIGHT;
bm=TTF_RenderUTF8_Shaded(fontText,tfm::format(_("%d recordings"),recordings).c_str(),fg,bg);
SDL_SetAlpha(bm,SDL_SRCALPHA,160);
y-=bm->h;
applySurface(0,y,bm,screen,NULL);
SDL_FreeSurface(bm);
char c[32];
sprintf(c,"%-.2fs",time/40.0f);
bm=TTF_RenderUTF8_Shaded(fontText,c,fg,bg);
SDL_SetAlpha(bm,SDL_SRCALPHA,160);
y-=bm->h;
applySurface(0,y,bm,screen,NULL);
SDL_FreeSurface(bm);
}
//Draw the current action in the upper right corner.
if(player.record){
applySurface(SCREEN_WIDTH-50,0,action,screen,NULL);
}else if(shadow.state!=0){
SDL_Rect r={50,0,50,50};
applySurface(SCREEN_WIDTH-50,0,action,screen,&r);
}
//if the game is play from record then draw something indicates it
if(player.isPlayFromRecord()){
//Dim the screen if interlevel is true.
if(interlevel){
SDL_BlitSurface(screen,NULL,tempSurface,NULL);
SDL_FillRect(screen,NULL,0);
SDL_SetAlpha(tempSurface, SDL_SRCALPHA,191);
SDL_BlitSurface(tempSurface,NULL,screen,NULL);
//Check if the GUI isn't null.
if(GUIObjectRoot){
//==Create first box==
//Create the title
SDL_Rect r;
/// TRANSLATORS: This is caption for finished level
SDL_Surface* bm=TTF_RenderUTF8_Blended(fontGUI,_("You've finished:"),themeTextColorDialog);
//Recreate the level string.
string s;
if (levels->getLevelCount()>0){
/// TRANSLATORS: Please do not remove %s or %d from your translation:
/// - %d means the level number in a levelpack
/// - %s means the name of current level
s=tfm::format(_("Level %d %s"),levels->getCurrentLevel()+1,_C(levels->getDictionaryManager(),levelName));
}
SDL_Surface* bm2=TTF_RenderUTF8_Blended(fontText,s.c_str(),themeTextColorDialog);
//Now draw the first gui box so that it's bigger than longer text.
int width;
if(bm->w>bm2->w)
width=bm->w+32;
else
width=bm2->w+32;
drawGUIBox((SCREEN_WIDTH-width)/2,4,width,68,screen,0xFFFFFFBF);
// Now draw title.
r.x=(SCREEN_WIDTH-bm->w)/2;
r.y=8-GUI_FONT_RAISE;
SDL_BlitSurface(bm,NULL,screen,&r);
// And then level name.
r.x=(SCREEN_WIDTH-bm2->w)/2;
r.y=44;
SDL_BlitSurface(bm2,NULL,screen,&r);
//Free drawed texts
SDL_FreeSurface(bm);
SDL_FreeSurface(bm2);
//==Create second box==
//Now draw the second gui box.
drawGUIBox(GUIObjectRoot->left,GUIObjectRoot->top,GUIObjectRoot->width,GUIObjectRoot->height,screen,0xFFFFFFBF);
//Draw the medal.
int medal=GUIObjectRoot->value;
r.x=(medal-1)*30;
r.y=0;
r.w=30;
r.h=30;
applySurface(GUIObjectRoot->left+16,GUIObjectRoot->top+92,medals,screen,&r);
applySurface(GUIObjectRoot->left+medalX,GUIObjectRoot->top+92,medals,screen,&r);
}
}else if((time & 0x10)==0x10){
SDL_Rect r={50,0,50,50};
applySurface(0,0,action,screen,&r);
applySurface(0,SCREEN_HEIGHT-50,action,screen,&r);
applySurface(SCREEN_WIDTH-50,SCREEN_HEIGHT-50,action,screen,&r);
}
}else if(player.objNotificationBlock){
//If the player is in front of a notification block show the message.
//And it isn't a replay.
std::string &untranslated_message=player.objNotificationBlock->message;
std::string message=_C(levels->getDictionaryManager(),untranslated_message);
std::vector<char> string_data(message.begin(), message.end());
string_data.push_back('\0');
int maxWidth = 0;
int y = 20;
vector<SDL_Surface*> lines;
//Now process the prompt.
{
//Pointer to the string.
char* lps=&string_data[0];
//Pointer to a character.
char* lp=NULL;
//We keep looping forever.
//The only way out is with the break statement.
for(;;){
//As long as it's still the same sentence we continue.
//It will stop when there's a newline or end of line.
for(lp=lps;*lp!='\n'&&*lp!='\r'&&*lp!=0;lp++);
//Store the character we stopped on. (End or newline)
char c=*lp;
//Set the character in the string to 0, making lps a string containing one sentence.
*lp=0;
//Integer used to center the sentence horizontally.
int x;
TTF_SizeText(fontText,lps,&x,NULL);
//Find out largest width
if(x>maxWidth)
maxWidth=x;
x=(SCREEN_WIDTH-x)/2;
lines.push_back(TTF_RenderUTF8_Blended(fontText,lps,themeTextColorDialog));
//Increase y with 25, about the height of the text.
y+=25;
//Check the stored character if it was a stop.
if(c==0){
//It was so break out of the for loop.
lps=lp;
break;
}
//It wasn't meaning more will follow.
//We set lps to point after the "newline" forming a new string.
lps=lp+1;
}
}
maxWidth+=SCREEN_WIDTH*0.15;
drawGUIBox((SCREEN_WIDTH-maxWidth)/2,SCREEN_HEIGHT-y-25,maxWidth,y+20,screen,0xFFFFFFBF);
while(!lines.empty()){
SDL_Surface* bm=lines[0];
if(bm!=NULL){
applySurface(100+((SCREEN_WIDTH-200-bm->w)/2),SCREEN_HEIGHT-y,bm,screen,NULL);
SDL_FreeSurface(bm);
}
y-=25;
lines.erase(lines.begin());
}
}
}
void Game::resize(){
//Check if the interlevel popup is shown.
if(interlevel && GUIObjectRoot){
GUIObjectRoot->left=(SCREEN_WIDTH-GUIObjectRoot->width)/2;
}
}
void Game::replayPlay(){
//Reset the number of collectables
currentCollectables=currentCollectablesSaved=0;
//We show the interlevel popup so interlevel must be true.
interlevel=true;
//Make the cursor visible when the interlevel popup is up.
SDL_ShowCursor(SDL_ENABLE);
//Create the gui if it isn't already done.
if(!GUIObjectRoot){
GUIObjectRoot=new GUIObject(0,SCREEN_HEIGHT-140,570,135,GUIObjectNone);
//NOTE: We put the medal in the value of the GUIObjectRoot.
//Make child widgets change color properly according to theme.
GUIObjectRoot->inDialog=true;
//The different values.
int bestTime=levels->getLevel()->time;
int targetTime=levels->getLevel()->targetTime;
int bestRecordings=levels->getLevel()->recordings;
int targetRecordings=levels->getLevel()->targetRecordings;
int medal=1;
if(targetTime<0){
medal=3;
}else{
if(targetTime<0 || bestTime<=targetTime)
medal++;
if(targetRecordings<0 || bestRecordings<=targetRecordings)
medal++;
}
//Add it to the GUIObjectRoot.
GUIObjectRoot->value=medal;
int maxWidth=0;
int x=20;
//Is there a target time for this level?
int timeY=0;
bool isTargetTime=true;
if(targetTime<=0){
isTargetTime=false;
timeY=12;
}
//Create the labels with the time and best time.
/// TRANSLATORS: Please do not remove %-.2f from your translation:
/// - %-.2f means time in seconds
/// - s is shortened form of a second. Try to keep it so.
GUIObject* obj=new GUIObject(x,10+timeY,-1,36,GUIObjectLabel,tfm::format(_("Time: %-.2fs"),time/40.0f).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
maxWidth=obj->width;
/// TRANSLATORS: Please do not remove %-.2f from your translation:
/// - %-.2f means time in seconds
/// - s is shortened form of a second. Try to keep it so.
obj=new GUIObject(x,34+timeY,-1,36,GUIObjectLabel,tfm::format(_("Best time: %-.2fs"),bestTime/40.0f).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
if(obj->width>maxWidth)
maxWidth=obj->width;
/// TRANSLATORS: Please do not remove %-.2f from your translation:
/// - %-.2f means time in seconds
/// - s is shortened form of a second. Try to keep it so.
if(isTargetTime){
obj=new GUIObject(x,58,-1,36,GUIObjectLabel,tfm::format(_("Target time: %-.2fs"),targetTime/40.0f).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
if(obj->width>maxWidth)
maxWidth=obj->width;
}
x+=maxWidth+20;
//Is there target recordings for this level?
int recsY=0;
bool isTargetRecs=true;
if(targetRecordings<0){
isTargetRecs=false;
recsY=12;
}
//Now the ones for the recordings.
/// TRANSLATORS: Please do not remove %d from your translation:
/// - %d means the number of recordings user has made
obj=new GUIObject(x,10+recsY,-1,36,GUIObjectLabel,tfm::format(_("Recordings: %d"),recordings).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
maxWidth=obj->width;
/// TRANSLATORS: Please do not remove %d from your translation:
/// - %d means the number of recordings user has made
obj=new GUIObject(x,34+recsY,-1,36,GUIObjectLabel,tfm::format(_("Best recordings: %d"),bestRecordings).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
if(obj->width>maxWidth)
maxWidth=obj->width;
/// TRANSLATORS: Please do not remove %d from your translation:
/// - %d means the number of recordings user has made
if(isTargetRecs){
obj=new GUIObject(x,58,-1,36,GUIObjectLabel,tfm::format(_("Target recordings: %d"),targetRecordings).c_str());
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
if(obj->width>maxWidth)
maxWidth=obj->width;
}
x+=maxWidth;
//The medal that is earned.
/// TRANSLATORS: Please do not remove %s from your translation:
/// - %s will be replaced with name of a prize medal (gold, silver or bronze)
string s1=tfm::format(_("You earned the %s medal"),(medal>1)?(medal==3)?_("GOLD"):_("SILVER"):_("BRONZE"));
obj=new GUIObject(50,92,-1,36,GUIObjectLabel,s1.c_str(),0,true,true,GUIGravityCenter);
GUIObjectRoot->addChild(obj);
obj->render(0,0,false);
if(obj->left+obj->width>x){
x=obj->left+obj->width+30;
}else{
obj->left=20+(x-20-obj->width)/2;
}
medalX=x-24;
//Create the three buttons, Menu, Restart, Next.
/// TRANSLATORS: used as return to the level selector menu
GUIObject* b1=new GUIObject(x,10,-1,36,GUIObjectButton,_("Menu"),0,true,true,GUIGravityCenter);
b1->name="cmdMenu";
b1->eventCallback=this;
GUIObjectRoot->addChild(b1);
b1->render(0,0,true);
/// TRANSLATORS: used as restart level
GUIObject* b2=new GUIObject(x,50,-1,36,GUIObjectButton,_("Restart"),0,true,true,GUIGravityCenter);
b2->name="cmdRestart";
b2->eventCallback=this;
GUIObjectRoot->addChild(b2);
b2->render(0,0,true);
/// TRANSLATORS: used as next level
GUIObject* b3=new GUIObject(x,90,-1,36,GUIObjectButton,_("Next"),0,true,true,GUIGravityCenter);
b3->name="cmdNext";
b3->eventCallback=this;
GUIObjectRoot->addChild(b3);
b3->render(0,0,true);
maxWidth=b1->width;
if(b2->width>maxWidth)
maxWidth=b2->width;
if(b3->width>maxWidth)
maxWidth=b3->width;
b1->left=b2->left=b3->left=x+maxWidth/2;
x+=maxWidth;
GUIObjectRoot->width=x;
GUIObjectRoot->left=(SCREEN_WIDTH-GUIObjectRoot->width)/2;
}
//We only need to reset a few things so we don't call reset().
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->reset(true);
}
//Also reset the background animation, if any.
if(background)
background->resetAnimation(true);
//The script environment.
getScriptExecutor()->reset();
//And call the onCreate scripts.
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->onEvent(GameObjectEvent_OnCreate);
}
//Close exit(s) if there are any collectables
if(totalCollectables>0){
for(unsigned int i=0;i<levelObjects.size();i++){
if(levelObjects[i]->type==TYPE_EXIT){
levelObjects[i]->onEvent(GameObjectEvent_OnSwitchOff);
}
}
}
//Make a copy of the playerButtons.
vector<int> recordCopy=player.recordButton;
player.reset(true);
shadow.reset(true);
player.recordButton=recordCopy;
//Now play the recording.
player.playRecord();
}
void Game::recordingEnded(){
//Check if it's a normal replay, if so just stop.
if(!interlevel){
//Show the cursor so that the user can press the ok button.
SDL_ShowCursor(SDL_ENABLE);
//Now show the message box.
msgBox(_("Game replay is done."),MsgBoxOKOnly,_("Game Replay"));
//Go to the level select menu.
setNextState(STATE_LEVEL_SELECT);
//And change the music back to the menu music.
getMusicManager()->playMusic("menu");
}else{
//Instead of directly replaying we set won true to let the Game handle the replaying at the end of the update cycle.
won=true;
}
}
bool Game::canSaveState(){
return (player.canSaveState() && shadow.canSaveState());
}
bool Game::saveState(){
//Check if the player and shadow can save the current state.
if(player.canSaveState() && shadow.canSaveState()){
//Let the player and the shadow save their state.
player.saveState();
shadow.saveState();
//Save the stats.
timeSaved=time;
recordingsSaved=recordings;
recentSwapSaved=recentSwap;
//Save the current collectables
currentCollectablesSaved=currentCollectables;
//Save other state, for example moving blocks.
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->saveState();
}
//Also save the background animation, if any.
if(background)
background->saveAnimation();
if(!player.isPlayFromRecord() && !interlevel){
//Update achievements
Uint32 t=SDL_GetTicks()+5000; //Add a bias to prevent bugs
if(recentSave+1000>t){
statsMgr.newAchievement("panicSave");
}
recentSave=t;
//Update statistics.
statsMgr.saveTimes++;
//Update achievements
switch(statsMgr.saveTimes){
case 1000:
statsMgr.newAchievement("save1k");
break;
}
}
//Return true.
return true;
}
//We can't save the state so return false.
return false;
}
bool Game::loadState(){
//Check if there's a state that can be loaded.
if(player.canLoadState() && shadow.canLoadState()){
//Let the player and the shadow load their state.
player.loadState();
shadow.loadState();
//Load the stats.
time=timeSaved;
recordings=recordingsSaved;
recentSwap=recentSwapSaved;
//Load the current collactbles
currentCollectables=currentCollectablesSaved;
//Load other state, for example moving blocks.
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->loadState();
}
//Also load the background animation, if any.
if(background)
background->loadAnimation();
if(!player.isPlayFromRecord() && !interlevel){
//Update achievements.
Uint32 t=SDL_GetTicks()+5000; //Add a bias to prevent bugs
if(recentLoad+1000>t){
statsMgr.newAchievement("panicLoad");
}
recentLoad=t;
//Update statistics.
statsMgr.loadTimes++;
//Update achievements
switch(statsMgr.loadTimes){
case 1000:
statsMgr.newAchievement("load1k");
break;
}
}
//Return true.
return true;
}
//We can't load the state so return false.
return false;
}
void Game::reset(bool save){
//We need to reset the game so we also reset the player and the shadow.
player.reset(save);
shadow.reset(save);
saveStateNextTime=false;
loadStateNextTime=false;
//Reset the stats.
time=0;
recordings=0;
recentSwap=-10000;
if(save) recentSwapSaved=-10000;
//Reset the number of collectables
currentCollectables=0;
if(save)
currentCollectablesSaved=0;
//There is no last checkpoint so set it to NULL.
if(save)
objLastCheckPoint=NULL;
//Reset other state, for example moving blocks.
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->reset(save);
}
//Also reset the background animation, if any.
if(background)
background->resetAnimation(save);
//Reset the script environment
getScriptExecutor()->reset();
//Send GameObjectEvent_OnCreate event to the script
for(unsigned int i=0;i<levelObjects.size();i++){
levelObjects[i]->onEvent(GameObjectEvent_OnCreate);
}
//Close exit(s) if there are any collectables
if(totalCollectables>0){
for(unsigned int i=0;i<levelObjects.size();i++){
if(levelObjects[i]->type==TYPE_EXIT){
levelObjects[i]->onEvent(GameObjectEvent_OnSwitchOff);
}
}
}
//Check if interlevel is true, if so we might need to delete the gui.
if(interlevel){
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
}
//Also set interlevel to false.
interlevel=false;
//Hide the cursor (if not the leveleditor).
if(stateID!=STATE_LEVEL_EDITOR)
SDL_ShowCursor(SDL_DISABLE);
}
void Game::broadcastObjectEvent(int eventType,int objectType,const char* id,GameObject* target){
//Create a typeGameObjectEvent that can be put into the queue.
typeGameObjectEvent e;
//Set the event type.
e.eventType=eventType;
//Set the object type.
e.objectType=objectType;
//By default flags=0.
e.flags=0;
//Unless there's an id.
if(id){
//Set flags to 0x1 and set the id.
e.flags|=1;
e.id=id;
}
//Or there's a target given.
if(target)
e.target=target;
else
e.target=NULL;
//Add the event to the queue.
eventQueue.push_back(e);
}
void Game::getCurrentLevelAutoSaveRecordPath(std::string &bestTimeFilePath,std::string &bestRecordingFilePath,bool createPath){
levels->getLevelAutoSaveRecordPath(-1,bestTimeFilePath,bestRecordingFilePath,createPath);
}
void Game::gotoNextLevel(){
//Goto the next level.
levels->nextLevel();
//Check if the level exists.
if(levels->getCurrentLevel()<levels->getLevelCount()){
setNextState(STATE_GAME);
//Don't forget the music.
getMusicManager()->pickMusic();
}else{
if(!levels->congratulationText.empty()){
msgBox(_C(levels->getDictionaryManager(),levels->congratulationText),MsgBoxOKOnly,_("Congratulations"));
}else{
msgBox(_("You have finished the levelpack!"),MsgBoxOKOnly,_("Congratulations"));
}
//Now go back to the levelselect screen.
setNextState(STATE_LEVEL_SELECT);
//And set the music back to menu.
getMusicManager()->playMusic("menu");
}
}
void Game::GUIEventCallback_OnEvent(string name,GUIObject* obj,int eventType){
if(name=="cmdMenu"){
setNextState(STATE_LEVEL_SELECT);
//And change the music back to the menu music.
getMusicManager()->playMusic("menu");
}else if(name=="cmdRestart"){
//Clear the gui.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//And reset the game.
//new: we don't need to clear the save game because
//in level replay the game won't be saved
//TODO: it doesn't work; better leave for next release
reset(/*false*/ true);
}else if(name=="cmdNext"){
//No matter what, clear the gui.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//And goto the next level.
gotoNextLevel();
}
}
diff --git a/src/Game.h b/src/Game.h
index 459eeb4..7fc9f61 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -1,244 +1,245 @@
/*
* Copyright (C) 2011-2013 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow 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.
*
* Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GAME_H
#define GAME_H
#include <SDL/SDL.h>
#ifdef __APPLE__
#include <SDL_mixer/SDL_mixer.h>
#include <SDL_ttf/SDL_ttf.h>
#else
#include <SDL/SDL_mixer.h>
#include <SDL/SDL_ttf.h>
#endif
#include <vector>
#include <map>
#include <string>
#include "GameState.h"
#include "GUIObject.h"
#include "GameObjects.h"
#include "Scenery.h"
#include "Player.h"
#include "Shadow.h"
//This structure contains variables that make a GameObjectEvent.
struct typeGameObjectEvent{
//The type of event.
int eventType;
//The type of object that should react to the event.
int objectType;
//Flags, 0x1 means use the id.
int flags;
//Blocks with this id should react to the event.
std::string id;
//Optional pointer to the block the event should be called on.
GameObject* target;
};
class ThemeManager;
class ThemeBackground;
class TreeStorageNode;
class Game : public GameState,public GUIEventCallback{
private:
//Boolean if the game should reset.
bool isReset;
//contains currently played level.
TreeStorageNode* currentLevelNode;
protected:
//Array containing "tooltips" for certain block types.
//It will be shown in the topleft corner of the screen.
SDL_Surface* bmTips[TYPE_MAX];
//SDL_Surface containing the action images (record, play, etc..)
SDL_Surface* action;
//SDL_Surface containing the medal image.
SDL_Surface* medals;
- //SDL_Surface containing the collectable image.
- SDL_Surface* collectable;
+
+ //ThemeBlockInstance containing the collectable image.
+ ThemeBlockInstance collectable;
//The name of the current level.
std::string levelName;
//The path + file of the current level.
std::string levelFile;
//Editor data containing information like name, size, etc...
std::map<std::string,std::string> editorData;
//Vector used to queue the gameObjectEvents.
std::vector<typeGameObjectEvent> eventQueue;
//The themeManager.
ThemeManager* customTheme;
//The themeBackground.
ThemeBackground* background;
//Load a level from node.
//After calling this function the ownership of
//node will transfer to Game class. So don't delete
//the node after calling this function!
virtual void loadLevelFromNode(TreeStorageNode* obj, const std::string& fileName);
public:
//Array used to convert GameObject type->string.
static const char* blockName[TYPE_MAX];
//Map used to convert GameObject string->type.
static std::map<std::string,int> blockNameMap;
//Map used to convert GameObjectEventType type->string.
static std::map<int,std::string> gameObjectEventTypeMap;
//Map used to convert GameObjectEventType string->type.
static std::map<std::string,int> gameObjectEventNameMap;
//Boolean that is set to true when a game is won.
bool won;
//Boolean that is set to true when we should save game on next logic update.
bool saveStateNextTime;
//Boolean that is set to true when we should load game on next logic update.
bool loadStateNextTime;
//Boolean if the replaying currently done is for the interlevel screen.
bool interlevel;
//X position of second medal in interlevel popup
int medalX;
//Integer containing the current tip index.
int gameTipIndex;
//Integer containing the number of ticks passed since the start of the level.
int time;
//Integer containing the stored value of time.
int timeSaved;
//Integer containing the number of recordings it took to finish.
int recordings;
//Integer containing the stored value of recordings.
int recordingsSaved;
//Integer keeping track of currently obtained collectables
int currentCollectables;
//Integer keeping track of total colletables in the level
int totalCollectables;
//Integer containing the stored value of current collectables
int currentCollectablesSaved;
//Time of recent swap, for achievements. (in game-ticks)
int recentSwap,recentSwapSaved;
//Store time of recent save/load for achievements (in millisecond)
Uint32 recentLoad,recentSave;
//Boolean if the camera should follow the shadow or not.
bool shadowCam;
//Vector containing all the levelObjects in the current game.
std::vector<Block*> levelObjects;
//The background layers for the scenery.
std::map<std::string,std::vector<Scenery*> > backgroundLayers;
//The player...
Player player;
//... and his shadow.
Shadow shadow;
//warning: weak reference only, may point to invalid location
Block* objLastCheckPoint;
//Constructor.
Game();
//If this is not empty then when next Game class is created
//it will play this record file.
static std::string recordFile;
//Destructor.
//It will call destroy();
~Game();
//Method used to clean up the GameState.
void destroy();
//Inherited from GameState.
void handleEvents();
void logic();
void render();
void resize();
//This method will load a level.
//fileName: The fileName of the level.
virtual void loadLevel(std::string fileName);
//Method used to broadcast a GameObjectEvent.
//eventType: The type of event.
//objectType: The type of object that should react to the event.
//id: The id of the blocks that should react.
//target: Pointer to the object
void broadcastObjectEvent(int eventType,int objectType=-1,const char* id=NULL,GameObject* target=NULL);
//Returns if the player and shadow can save the current state.
bool canSaveState();
//Method used to store the current state.
//This is used for checkpoints.
//Returns: True if it succeeds without problems.
bool saveState();
//Method used to load the stored state.
//This is used for checkpoints.
//Returns: True if it succeeds without problems.
bool loadState();
//Method that will reset the GameState to it's initial state.
//save: Boolean if the saved state should also be delted.
void reset(bool save);
//Save current game record to the file.
//fileName: The filename of the destination file.
void saveRecord(const char* fileName);
//Load game record (and its level) from file and play it.
//fileName: The filename of the recording file.
void loadRecord(const char* fileName);
//Method called by the player (or shadow) when he finished.
void replayPlay();
//Method that gets called when the recording has ended.
void recordingEnded();
//get current level's auto-save record path,
//using current level's MD5, file name and other information.
void getCurrentLevelAutoSaveRecordPath(std::string &bestTimeFilePath,std::string &bestRecordingFilePath,bool createPath);
//Method that will prepare the gamestate for the next level and start it.
//If it's the last level it will show the congratulations text and return to the level select screen.
void gotoNextLevel();
//Get the name of the current level.
const std::string& getLevelName(){
return levelName;
}
//GUI event handling is done here.
void GUIEventCallback_OnEvent(std::string name,GUIObject* obj,int eventType);
};
#endif

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 16, 12:04 PM (18 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
64152
Default Alt Text
(111 KB)

Event Timeline