Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F118515
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
111 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 16, 12:04 PM (19 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
64152
Default Alt Text
(111 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline