+msgid "Now you'll need to help your shadow cross.\n"
+msgstr "Nå må du hjelpe til med å få skyggen din over.\n"
+
+#: tutorial\tut10.map:19
+msgid "You can save your progress in a level with\ncheckpoints. You can restore them at any\ntime using the F3 button."
+msgstr ""
+"Du kan lagre fremdriften ditt på et nivå med\n"
+"sjekkpunkter. Du kan gjenopprette dem\n"
+"når som helst med F3-tasten."
+
+#: tutorial\tut18.map:14
+#, fuzzy
+msgid "This trigger will deactivate the moving block.\nTry to stop it at the right moment.\nYou can only do this once, so if it fails you'll\nhave to reset the level with the 'R' key."
+msgstr ""
+"Denne utløseren vil deaktivere den bevegende blokken.\n"
+"Du kan stoppe den på akkurat rett tid.\n"
+"Du kan kun gjøre dette én gang, slik at hvis det mislykkes\n"
+"vil du måtte tilbakestille nivået med R-tasten."
+
+#: tutorial\tut21.map:49
+msgid "If your shadow falls down here you will have to restart.\nPress 'R' to restart the level."
+msgstr ""
+"Hvis skyggen din faller ned her vil du måtte starte på ny.\n"
+"Trykk \"R\" for å starte nivået på nytt."
+
+#: tutorial\levels.lst:1
+msgid "tutorial"
+msgstr "veiledning"
+
+#: tutorial\tut23.map:1
+msgid "Collecting Keys"
+msgstr "Nøkkelinnsamling"
+
+#: tutorial\tut10.map:46
+msgid "You've chosen the right way."
+msgstr "Du har valgt rett vei"
+
+#: tutorial\tut22.map:1
+msgid "Shadow swap"
+msgstr "Skyggebytte"
+
+#: tutorial\tut20.map:187
+msgid "A dead end, you'd better go back and choose\nthe other portal."
+msgstr ""
+"En bomvei, du må gå tilbake og velge\n"
+"den andre portalen."
+
+#: tutorial\tut03.map:13
+msgid "See those gaps over there?\nReach the finish without falling."
+msgstr ""
+"Ser du fallgruvene der borte?\n"
+"Nå slutten uten å falle."
+
+#: tutorial\tut07.map:33
+msgid "If your shadow dies you'll have to restart.\nRestart the game by pressing the 'R' key."
+msgstr ""
+"Hvis skyggen din dør må du starte igjen.\n"
+"Start spillet igjen ved å trykke på R-tasten."
+
+#: tutorial\tut02.map:18
+#, fuzzy
+msgid "You can jump using the up key.\nTry jumping over these blocks."
+msgstr ""
+"Du kan hoppe med ↑-tasten.\n"
+"Prøv å hoppe over disse blokkene."
+
+#: tutorial\tut07.map:1
+msgid "Shadow challenge"
+msgstr "Skyggeutfordring"
+
+#: tutorial\tut20.map:1
+msgid "Portal mayhem"
+msgstr "Portalkaos"
+
+#: tutorial\tut02.map:1
+msgid "First jumps"
+msgstr "Første hopp"
+
+#: tutorial\tut20.map:16
+msgid "Portals point to another portal or to nothing.\nTry to reach the exit in this portal mayhem."
+msgstr ""
+"Portaler peker til en annen portal eller gjør ingenting.\n"
+"Prøv å nå slutten i dette portalkaoset."
+
+#: tutorial\tut05.map:32
+msgid "TIP:\nThink what moves your shadow has to make.\nThen let your character record those moves.\nYou can break it down into smaller recordings."
+msgstr ""
+"TIPS:\n"
+"Tenk på hvilke bevegelser skyggen din må gjøre.\n"
+"La så karakteren din ta opp disse bevegelsene.\n"
+"Du kan bryte det ned i mindre opptak."
+
+#: tutorial\tut11.map:17
+msgid "Until now the levels were static.\nThere are however moving blocks."
+msgstr ""
+"Til nå har nivåene vært statiske.\n"
+"Nå finnes det bevegelige blokker."
+
+#: tutorial\tut10.map:32
+msgid "Save your progress here."
+msgstr "Lagre din fremdrift her."
+
+#: tutorial\tut13.map:1
+msgid "Moving spikes"
+msgstr "Bevegelige tagger"
+
+#: tutorial\tut13.map:18
+msgid "Watch out for the moving spikes."
+msgstr "Se opp for de bevegelige taggene."
+
+#: tutorial\tut16.map:1
+msgid "The switch"
+msgstr "Bryteren"
+
+#: tutorial\tut25.map:13
+msgid "The very best of luck!"
+msgstr "Lykke til!"
+
+#: tutorial\tut20.map:156
+msgid "Now choose one of the two."
+msgstr "Velg én av de to."
+
+#: tutorial\tut19.map:42
+#, fuzzy
+msgid "NOTE:\nYou can go back by entering this portal.\nIt is however a bit different, you don't have to\npress the down key, it will activate when you walk in it."
+msgstr ""
+"MERK:\n"
+"Du kan gå tilbake ved å gå inn i denne portalen.\n"
+"Det er dog litt annerledes, du må ikke\n"
+"trykke på ↓-tasten, den vil aktiveres når du går inn i den."
+
+#: tutorial\tut15.map:20
+msgid "This gap is impossible to jump over.\nStep on the button next of you."
+msgstr ""
+"Fallgruven er umulig å hoppe over.\n"
+"Tre opp på knappen ved siden av deg."
+
+#: tutorial\tut06.map:1
+msgid "Shadow walk"
+msgstr "Skyggegange"
+
+#: tutorial\tut10.map:54
+#, fuzzy
+msgid "This is the wrong way.\nGo back to the previous checkpoint by pressing F3."
+msgstr ""
+"Dette er feil vei.\n"
+"Gå tilbake til forrige sjekkpunkt ved å trykke F3."
+
+#: tutorial\tut25.map:318
+msgid "You have made it!"
+msgstr "Du har klart det!"
+
+#: tutorial\tut17.map:1
+msgid "Toggle trigger"
+msgstr "Veksle utløser"
+
+#: tutorial\tut24.map:1
+msgid "Warning"
+msgstr "Advarsel"
+
+#: tutorial\tut05.map:1
+msgid "Shadow"
+msgstr "Skygge"
+
+#: tutorial\tut06.map:23
+msgid "NOTE:\nAlthough you can't jump on those blocks\nyou can record the jumps for your shadow."
+msgstr ""
+"MERK:\n"
+"Selv om du ikke kan hoppe på de blokkene\n"
+"kan du ta opp hoppene for skyggen din."
+
+#: tutorial\tut19.map:39
+msgid "Now it's time to check out the portals.\nTo get to the exit you'll have to take the portal.\nWalk to it and press the down arrow to\nactivate."
+msgstr ""
+"Nå er det på tide å sjekke ut portalene.\n"
+"For å finne rett utgang må du ta portalen.\n"
+"Gå til den og trykk ↓-pilen for å aktivere."
+
+#: tutorial\tut18.map:1
+msgid "Stop trigger"
+msgstr "Stopper"
+
+#: tutorial\tut01.map:1
+msgid "Walk in the park"
+msgstr "En tur i parken"
+
+#: tutorial\tut09.map:14
+msgid "Those blocks are fragile.\nIf you step on them too often they'll break."
+msgstr ""
+"Disse blokkene er skjøre.\n"
+"Hvis du trår på dem for ofte vil de gå istykker."
+
+#: tutorial\tut19.map:1
+msgid "First portals"
+msgstr "Første portaler"
+
+#: tutorial\tut25.map:1
+msgid "Final"
+msgstr "Finale"
+
+#: tutorial\tut04.map:1
+msgid "First spikes"
+msgstr "Første tagger"
+
+#: tutorial\tut12.map:1
+msgid "Moving shadow blocks"
+msgstr "Bevegelige skyggeblokker"
+
+#: tutorial\tut22.map:22
+#, fuzzy
+msgid "You need your shadow to reach the exit.\nMake use of the swapper to get him down (or \nto get yourself down)."
+msgstr ""
+"Du trenger skyggen din for å nå utgangen.\n"
+"Gjør bruk av bytteren for å få den ned (eller \n"
+"for å få deg selv ned)."
+
+#: tutorial\tut21.map:8
+#, fuzzy
+msgid "Now it's time for something completely\ndifferent: swappoints. When you or your\nshadow activate them you'll swap places."
+msgstr ""
+"Nå er det på tide med noe helt annet:\n"
+"Byttingspunkter. Når du eller din skygge\n"
+"aktiverer dem bytter dere sted."
+
+#: tutorial\tut06.map:27
+msgid "Only your shadow can stand on those shadow\nblocks. Try to get him up there."
+msgstr ""
+"Kun skyggen din kan stå på de skyggeblokkene.\n"
+"Prøv å få den opp dit."
+
+#: tutorial\tut17.map:14
+#, fuzzy
+msgid "You've only seen triggers that activate other\nblocks, but they can also deactivate or toggle\nthem."
+msgstr ""
+"Du har kun sett utløsere som aktiverer andre\n"
+"blokker, men de kan også deaktivere eller\n"
+"veksle dem."
+
+#: tutorial\tut14.map:68
+msgid "When standing on conveyor belts you'll\nmove without walking."
+msgstr ""
+"Når du står på samlebåndet vil du\n"
+"flytte deg uten å gå."
+
+#: tutorial\tut25.map:46
+msgid "TIP:\nTry to get your shadow in front of the shadow\nwall. If he falls down you'd better restart."
+msgstr ""
+"TIPS:\n"
+"Prøv å få skyggen din foran skyggeveggen.\n"
+"Hvis skyggen faller ned bør du starte på ny."
+
+#: tutorial\tut22.map:33
+#, fuzzy
+msgid "TIP:\nWhen your shadow is trapped stand on the\nright side of the shadow blocks. Now record \nthe down key and let your shadow mimic."
+msgstr ""
+"TIPS:\n"
+"Når skyggen er fanget, stå på høyre\n"
+"siden av skyggeblokkene. Ta så opp\n"
+"↓-tasten og la din skygge etterligne."
+
+#: tutorial\tut08.map:1
+msgid "Teamwork"
+msgstr "Lagarbeid"
+
+#: tutorial\tut14.map:71
+msgid "Let the shadow finish the level by walking to\nthe finish. But don't stand still because your\nshadow will move all the way back."
+msgstr ""
+"La skyggen fullføre nivået ved å gå til\n"
+"utgangen. Men ikke stå stille fordi\n"
+"da vil skyggen gå hele veien tilbake."
+
+#: tutorial\tut21.map:1
+msgid "Swappoints"
+msgstr "Byttingspunkter"
+
+#: tutorial\tut23.map:18
+#, fuzzy
+msgid "One thing you need to know before you're ready are keys.\nSometimes there are keys spread around the level.\nThe exit is locked until you get all the keys."
+msgstr ""
+"En ting du må ta rede på før du er klar er nøkler.\n"
+"Noen ganger er nøkler spredt rundt omrking på nivået.\n"
+"Utgangen er låst til du finner alle."
+
+#: tutorial\tut03.map:34
+msgid "Good job!"
+msgstr "Godt gjort!"
+
+#: tutorial\tut16.map:14
+#, fuzzy
+msgid "There's another type of trigger: the switch.\nUse the switch to activate the elevator so that you\ncan reach the exit."
+msgstr ""
+"Det finnes en annen type utløser: Bryteren.\n"
+"Bruk den for å aktivere heisen, slik at du kan\n"
+"nå utgangen."
+
+#: tutorial\tut09.map:1
+msgid "Fragile"
+msgstr "Skjør"
+
+#: tutorial\tut24.map:18
+msgid "That's all there is.\nNow it's time to put your skills to the test.\nEnter the exit to go to the last level.\nGood luck!"
+msgstr ""
+"Det er alt.\n"
+"Nå er det på tide å sette ferdighetene dine ut i livet.\n"
+"Gå inn i utgangen for å gå til siste nivå.\n"
+"Lykke til!"
+
+#: tutorial\tut25.map:459
+msgid "Where could your shadow be?"
+msgstr "Hvor kan skyggen din være?"
+
+#: tutorial\tut01.map:18
+#, fuzzy
+msgid "Welcome to Me and My Shadow.\nYou can use the arrow keys to walk to the exit.\n\nGood luck!"
+msgstr ""
+"Velkommen til meg og min skygge.\n"
+"Du kan bruke piltastene for å gå til utgangen.\n"
+"\n"
+"Lykke til!"
+
+#: tutorial\tut15.map:1
+msgid "Triggering"
+msgstr "Utløsing"
+
+#: tutorial\tut03.map:1
+msgid "Jumping around"
+msgstr "Hopping rund omkring"
+
+#: tutorial\tut10.map:1
+msgid "Checkpoints"
+msgstr "Sjekkpunkter"
+
+#: tutorial\tut07.map:19
+msgid "Spikes are not only deadly for you,\nbut also for your shadow."
+msgstr ""
+"Tagger er ikke bare dødlig for deg,\n"
+"men også skyggen din."
+
+#: tutorial\tut08.map:21
+msgid "You and your shadow need to work together.\nMove your shadow towards the wall and jump\non him so that you can jump over the wall."
+msgstr ""
+"Du og din skygge må jobbe sammen.\n"
+"Flytt den mot veggen og hopp på den,\n"
+"slik at du kan hoppe over veggen."
+
+#: tutorial\tut04.map:19
+msgid "Spikes are deadly.\nDon't touch them!"
+msgstr ""
+"Tagger er dødlige.\n"
+"Ikke rør dem!"
+
+#: tutorial\levels.lst:3
+msgid "Step by step introduction"
+msgstr "Stegvis instroduksjon"
+
+#: tutorial\tut11.map:1
+msgid "Moving blocks"
+msgstr "Bevegelige blokker"
+
+#: tutorial\tut14.map:1
+msgid "Conveyor madness"
+msgstr "Samlebåndsgalskap"
+
+#: tutorial\tut05.map:29
+#, fuzzy
+msgid "You can't reach the exit, but your shadow can.\nPress space to record your moves.\nPress space once again to let your shadow\nmimic your recording."
+msgstr ""
+"Du kan ikke nå utgangen, men skyggen din kan.\n"
+"Trykk mellomrom for å ta opp bevegelsene dine.\n"
If this subnode is set, the picture will be randomly used according to the given probability.
##### 1.1.1.3 editorPicture subnode
~~~
editorPicture(<file name>,<x>,<y>,<w>,<h>)
~~~
If this subnode is set, the picture will be used instead in the level editor.
##### 1.1.1.4 positioning subnode
~~~
positioning(<xalign>,<yalign>)
~~~
-* xalign: 'left', 'centre' (NOTE: not 'center'), 'right' or 'repeat' or 'stretch'
+* xalign: 'left', 'centre' (same as 'center'), 'right' or 'repeat' or 'stretch'
* yalign: 'top', 'middle', 'bottom' or 'repeat' or 'stretch'
##### 1.1.1.5 offset subnode
~~~
offset(<x>,<y>[,<w>[,<h>]])
~~~
-Shift the top,left,right,bottom of the destination rectangle by x,y,-w,-h.
+Shift the left,top,right,bottom of the destination rectangle by x,y,-w,-h.
NOTE: w,h are only used when the corresponding positioning modes are 'repeat' or 'stretch'.
##### 1.1.1.6 pictureAnimation subnode
~~~
pictureAnimation(<file name>){
point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
...
}
~~~
NOTE: picture and pictureAnimation are mutually exclusive. (?)
NOTE: The default value of frame_count and the display_time_of_each_frame are 1.
The source rectangle (x,y,w,h) is animated by the following way:
- (x,y,w,h)=point[0] is displayed for time display_time[0]
- for i=1,2,3... the following sequences of pictures are displayed:
- for r=1/frame_count[i],2/frame_count[i],...,1
the (x,y,w,h)=point[i-1]*(1-r)+point[i]*r is displayed for time display_time[i]
##### 1.1.1.7 offsetAnimation subnode
~~~
offsetAnimation{
- point(<x>,<y>[,<frame count>[,<display time of each frame>]])
- point(<x>,<y>[,<frame count>[,<display time of each frame>]])
+ point(<x>,<y>[,<frame count>[,<display time of each frame>[,<w>[,<h>]]]])
+ point(<x>,<y>[,<frame count>[,<display time of each frame>[,<w>[,<h>]]]])
...
}
~~~
This is similar to pictureAnimation subnode, but this time it animates the offset.
+Notice that the w,h are the last two arguments.
+
### 1.2 editorPicture subnode
Syntax:
~~~
editorPicture(<file name>,<x>,<y>,<w>,<h>) //specifies the picture shows in editor
~~~
This subnode is required (?) for block and scenery.
2 background subnode
--------------------
Specifies the background of level.
There can be multiple background subnodes.
Each subnode is a layer of background.
Syntax:
~~~
background(<file name>){
srcSize=<x>,<y>,<w>,<h> //Specifies the source size and offset of picture (optional, default value=image size)
destSize=<x>,<y>,<w>,<h> //Specifies the destination size and offset of picture (optional, default value=size of game window WHEN THE THEME FILE IS LOADED (!!!))
scaleToScreen=<0 or 1> //Specifies the destination should be scale to screen. (optional, default is 1)
repeat=<repeat x>,<repeat y> //Repeat in x,y direction? (0 or 1) (optional, default value=1,1)
speed=<speed x>,<speed y> //Specifies the moving speed (pixel/frame, a real number) (optional, default=0,0)
cameraSpeed=<x>,<y> //The speed of following camera (a real number, typically in 0-1) (optional, default=0,0)
}
~~~
3 character subnode
-------------------
Specifies the appearance of player and shadow.
Syntax:
~~~
character(Player){
...
}
~~~
or
~~~
character(Shadow){
...
}
~~~
The other format is the same as the block subnode.
Here are the states for character which should be implemented.
Unless otherwise specified, all of them should be of size 23x40.
{"tutorial",__("Graduate"),"gfx/medals.png",{30,0,30,30},__("Complete the tutorial level pack."),ACHIEVEMENT_PROGRESS,nullptr},
{"tutorialGold",__("Outstanding graduate"),"gfx/medals.png",{60,0,30,30},__("Complete the tutorial level pack with gold for all levels."),ACHIEVEMENT_PROGRESS,nullptr},
{"addicted",__("Hooked"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Play Me and My Shadow for more than 2 hours."),ACHIEVEMENT_TITLE,nullptr},
{"loyalFan",__("Loyal fan of Me and My Shadow"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Play Me and My Shadow for more than 24 hours."),ACHIEVEMENT_HIDDEN,nullptr},
{"constructor",__("Constructor"),"gfx/gui.png",{112,16,16,16},__("Use the level editor for more than 2 hours."),ACHIEVEMENT_HIDDEN,nullptr},
{"constructor2",__("The creator"),"gfx/gui.png",{112,16,16,16},__("Use the level editor for more than 24 hours."),ACHIEVEMENT_HIDDEN,nullptr},
{"create1",__("Look, cute level!"),"gfx/addon1.png",{0,0,64,64},__("Create a level for the first time."),ACHIEVEMENT_ALL,nullptr},
{"die1000",__("Expert of trial and error"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Die 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
{"squash1",__("Keep an eye for moving blocks!"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Get squashed for the first time."),ACHIEVEMENT_HIDDEN,nullptr},
{"doubleKill",__("Double kill"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Get both the player and the shadow dead."),ACHIEVEMENT_HIDDEN,nullptr},
{"die5in5",__("Bad luck"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Die 5 times in under 5 seconds."),ACHIEVEMENT_TITLE,nullptr},
{"die10in5",__("This level is too dangerous"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Die 10 times in under 5 seconds."),ACHIEVEMENT_HIDDEN,nullptr},
{"forget",__("You forgot your friend"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Finish the level with the player or the shadow dead."),ACHIEVEMENT_HIDDEN,nullptr},
{"jit",__("Just in time"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Reach the exit with the player and the shadow simultaneously."),ACHIEVEMENT_TITLE,nullptr},
{"switch100",__("Switch puller"),"themes/Cloudscape/tiles/tiles.png",{0,100,50,50},__("Pull the switch 100 times."),ACHIEVEMENT_PROGRESS,nullptr},
{"switch1k",__("The switch is broken!"),"themes/Cloudscape/tiles/tiles.png",{0,100,50,50},__("Pull the switch 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
- {"swap1k",__("Player to shadow to player to shadow..."),"themes/Cloudscape/tiles/swap.png",{0,0,50,50},__("Swap 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
+ // {"swap1k",__("Player to shadow to player to shadow..."),"themes/Cloudscape/tiles/swap.png",{0,0,50,50},__("Swap 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
{"save1k",__("Play it save"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Save 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
{"load1k",__("This game is too hard"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Load the game 1000 times."),ACHIEVEMENT_HIDDEN,nullptr},
{ "withoutsave", __("No, thanks"), "themes/Cloudscape/characters/player.png", { 0, 0, 23, 40 }, __("Complete a level with checkpoint, but without saving."), ACHIEVEMENT_TITLE, nullptr },
{"panicSave",__("Panic save"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Save twice in 1 second."),ACHIEVEMENT_HIDDEN,nullptr},
{"panicLoad",__("Panic load"),"themes/Cloudscape/characters/player.png",{0,0,23,40},__("Load twice in 1 second."),ACHIEVEMENT_HIDDEN,nullptr},
{"loadAndDie",__("Bad saving position"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Load the game and die within 1 second."),ACHIEVEMENT_TITLE,nullptr},
{"loadAndDie100",__("This level is too hard"),"themes/Cloudscape/characters/deathright.png",{0,14,23,40},__("Load the same save and die 100 times."),ACHIEVEMENT_HIDDEN,nullptr},
{"quickswap",__("Quick swap"),"themes/Cloudscape/tiles/swap.png",{0,0,50,50},__("Swap twice in under a second."),ACHIEVEMENT_HIDDEN,nullptr},
//ripped from Achievements Unlocked
{"horizontal",__("Horizontal confusion"),"gfx/emotions.png",{0,0,23,40},__("Press left and right simultaneously."),ACHIEVEMENT_HIDDEN,nullptr},
cerr<<"WARNING: Levelpack directory '"<<dir<<"' appears to have been removed already."<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Levelpack directory '%s' appears to have been removed already."),dir),MsgBoxOKOnly,_("Addon error"));
continue;
}
//Remove the directory.
if(!removeDirectory(dir.c_str())){
cerr<<"ERROR: Unable to remove levelpack directory '"<<dir<<"'!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("ERROR: Unable to remove levelpack directory '%s'!"),dir),MsgBoxOKOnly,_("Addon error"));
continue;
}
//Also remove the levelpack from the levelpackManager.
msgBox(imageManager,renderer,_("ERROR: Addon is missing metadata!"),MsgBoxOKOnly,_("Addon error"));
return;
}
//Read the metadata from the addon.
TreeStorageNode obj;
{
POASerializer objSerializer;
if(!objSerializer.readNode(metadata,&obj,true)){
//NOTE: We keep the console output English so we put the string literal here twice.
cerr<<"ERROR: Invalid file format for metadata file!"<<endl;
msgBox(imageManager,renderer,_("ERROR: Invalid file format for metadata file!"),MsgBoxOKOnly,_("Addon error"));
return;
}
}
//Loop through the subNodes.
for(unsigned int i=0;i<obj.subNodes.size();i++){
//Check for the content subNode (there should only be one).
if(obj.subNodes[i]->name=="content"){
TreeStorageNode* obj1=obj.subNodes[i];
//Loop through the subNodes of that.
for(unsigned int j=0;j<obj1->subNodes.size();j++){
TreeStorageNode* obj2=obj1->subNodes[j];
//This code happens for all types of content.
string source=tmpDir+"addon/content/";
if(obj2->value.size()>0)
source+=obj2->value[0];
//The destination MUST be in the user data path.
string dest=getUserPath(USER_DATA);
if(obj2->value.size()>1)
dest+=obj2->value[1];
//Check what the content type is.
if(obj2->name=="file" && obj2->value.size()==2){
//Now copy the file.
if(fileExists(dest.c_str())){
cerr<<"WARNING: File '"<<dest<<"' already exists, addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: File '%s' already exists, addon may be broken or not working!"),dest),MsgBoxOKOnly,_("Addon error"));
continue;
}
if(!copyFile(source.c_str(),dest.c_str())){
cerr<<"WARNING: Unable to copy file '"<<source<<"' to '"<<dest<<"', addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Unable to copy file '%s' to '%s', addon may be broken or not working!"),source,dest),MsgBoxOKOnly,_("Addon error"));
//The dest must NOT exist, otherwise it will fail.
if(dirExists(dest.c_str())){
cerr<<"WARNING: Destination directory '"<<dest<<"' already exists, addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Destination directory '%s' already exists, addon may be broken or not working!"),dest),MsgBoxOKOnly,_("Addon error"));
continue;
}
//FIXME: Copy the directory instead of renaming it, in case the same folder/parts of the folder are needed in different places.
cerr<<"WARNING: Unable to move directory '"<<source<<"' to '"<<dest<<"', addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Unable to move directory '%s' to '%s', addon may be broken or not working!"),source,dest),MsgBoxOKOnly,_("Addon error"));
//The destination MUST be in the levels folder in the user data path.
dest+="levels/"+fileNameFromPath(source);
//Now copy the file.
if(fileExists(dest.c_str())){
cerr<<"WARNING: Level '"<<dest<<"' already exists, addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Level '%s' already exists, addon may be broken or not working!"),dest),MsgBoxOKOnly,_("Addon error"));
continue;
}
if(!copyFile(source.c_str(),dest.c_str())){
cerr<<"WARNING: Unable to copy level '"<<source<<"' to '"<<dest<<"', addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Unable to copy level '%s' to '%s', addon may be broken or not working!"),source,dest),MsgBoxOKOnly,_("Addon error"));
//TODO: Check if the source contains a trailing slash.
//The destination MUST be in the user data path.
dest+="levelpacks/"+fileNameFromPath(source);
//The dest must NOT exist, otherwise it will fail.
if(dirExists(dest.c_str())){
cerr<<"WARNING: Levelpack directory '"<<dest<<"' already exists, addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Levelpack directory '%s' already exists, addon may be broken or not working!"),dest),MsgBoxOKOnly,_("Addon error"));
continue;
}
//FIXME: Copy the directory instead of renaming it, in case the same folder/parts of the folder are needed in different places.
cerr<<"WARNING: Unable to move directory '"<<source<<"' to '"<<dest<<"', addon may be broken or not working!"<<endl;
msgBox(imageManager,renderer,tfm::format(_("WARNING: Unable to move directory '%s' to '%s', addon may be broken or not working!"),source,dest),MsgBoxOKOnly,_("Addon error"));
continue;
}
//It's a levelpack so add it to the levelpack manager.
auto tex=SharedTexture(textureFromText(renderer, *fontText, newText.c_str(), objThemes.getTextColor(true)));
// Make sure we don't create any empty textures.
if(!tex) {
std::cerr << "WARNING: Failed to update texture at index" << index << " \"" << newText << "\"" << std::endl;
return;
}
images.at(index)=tex;
} else {
return;
}
item.at(index)=newText;
+ itemSelectable.at(index) = selectable;
updateScrollbar=true;
}
std::string GUIListBox::getItem(int index){
return item.at(index);
}
GUISingleLineListBox::GUISingleLineListBox(ImageManager& imageManager, SDL_Renderer& renderer, int left, int top, int width, int height, bool enabled, bool visible, int gravity):
* 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 GUILISTBOX_H
#define GUILISTBOX_H
#include "GUIObject.h"
#include "GUIScrollBar.h"
//GUIObject that displays a list.
//It extends GUIObject because it's a special GUIObject.
class GUIListBox:public GUIObject{
public:
//Vector containing the entries of the list.
std::vector<std::string> item;
std::vector<SharedTexture> images;
std::vector<bool> itemSelectable;
//Boolean if the whole list is selectable.
//If it's false then all the items are not selectable, otherwise itemSelectable is checked further.
bool selectable;
//Boolean if the listbox should send click events.
bool clickEvents;
private:
//Scrollbar used when there are more entries than fit on the screen.
GUIScrollBar* scrollBar;
int firstItemY;
//Boolean if update for scrollbar is needed.
bool updateScrollbar;
public:
//Constructor.
//left: The relative x location of the GUIListBox.
//top: The relative y location of the GUIListBox.
//witdh: The width of the GUIListBox.
//height: The height of the GUIListBox.
//enabled: Boolean if the GUIListBox is enabled or not.
//visible: Boolean if the GUIListBox is visisble or not.
GUIListBox(ImageManager& imageManager, SDL_Renderer& renderer, int left=0, int top=0, int width=0, int height=0, bool enabled=true, bool visible=true, int gravity=GUIGravityLeft);
//Destructor
~GUIListBox();
//Method to remove all items and clear cache.
void clearItems();
//Method to add an item to the widget.
//name: Text of the item.
//texture: Custom image for the widget, if NULL the image will be generated from name string.
std::string s = _("NOTE: the layers are sorted by name alphabetically.\nThe layer is background layer if its name is < 'f'\nby dictionary order, otherwise it's foreground layer.");
for (int lps = 0;;) {
size_t lpe = s.find_first_of('\n', lps);
GUIObject *obj = new GUILabel(imageManager, renderer, 40, yy, 520, 36,
//NOTE: The PlayerIsOn event must be handled here so that the script can change the location of a block without interfering with the collision detection.
//Handlingin it here also guarantees that this event will only be called once for one block per update.