From b11b8b0fb5e8f0e8202838a794aab0ea815782e2 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 01:51:08 +0100 Subject: [PATCH 01/36] Finish German translation of Tutorial 3. --- .../Tutorials.ocf/Tutorial03.ocs/DescDE.txt | 8 +-- .../Tutorial03.ocs/System.ocg/StringTblDE.txt | 60 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt index 54c6786e7..de8966760 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt @@ -1,7 +1,7 @@ -Carry & Construct +Transport & Aufbau -Roger has lead you to Wipfville, a small village full of wipfs. Finally he has found his friends and is happy. However, the villagers of Wipfville are less so. Their village has been under attack by an evil faction threatening to capture their wipf population. The first attack they could fend off, but has lead to lots of damage to the village. You decide to stay and help the villagers, because the Roger can make a lot of friends here. +Rüdiger hat dich zu einem Ort namens Wipfdort geführt, ein kleines Dorf voller Wipfe. Endlich hat er seine Freunde gefunden und ist fröhlich. Die Dorfbewohner von Wipfdorf aber brauchen Hilfe. Ihr Dorf wurde von einer dunklen Fraktion angegriffen, die gedroht hat, all ihre Wipfe zu entführen. Den ersten Angriff konnten Sie abwehren, aber ihr Dorf wurde dabei zerstört. Du hast dich entschlossen, den Bewohnern zu helfen, da Rüdiger sich hier wohl zu fühlen scheint. -Goal: Help the villagers rebuild there village. +Ziel: Hilf den Dorfbewohner ihr Dorf wieder aufzubauen. -Tutorial explains: constructing buildings, basic materials (metal, wood, rock) and mining. +Lernrunde erklärt: Errichten von Gebäuden, Standardmaterial (Metall, Holz, Stein) und Bergbau. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial03.ocs/System.ocg/StringTblDE.txt index 6ca1ad2a0..4e447c6ba 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/System.ocg/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/System.ocg/StringTblDE.txt @@ -1,41 +1,41 @@ # Dialogue: Lumberjack -DlgLumberjackHello=Hello I am %s, the lumberjack of this small village. -DlgLumberjackReply=My name is %s, you seem sad. -DlgLumberjackSawmill=Yes, indeed. My sawmill got destroyed and I can't find any rock to rebuild it. Can you help me? -DlgLumberjackRock=Yes, I'll find you some rock. -DlgLumberjackWellDone=Thanks a lot, for constructing the sawmill. Can I do anything for you? -DlgLumberjackFavor=Actually you can, I need wood, do you happen to have an axe? -DlgLumberjackMines=No, I don't, but I have dropped my axe in the mines when I was hiding there during the attack. -DlgLumberjackLook=Ok, I'll have a look. +DlgLumberjackHello=Hallo, ich bin %s, die Holzfällerin des Dorfes. +DlgLumberjackReply=Ich heiße %s. Du schaust traurig aus. +DlgLumberjackSawmill=Ja, das stimmt. Mein Sägewerk wurde zerstört und ich finde keine Steine, um es wieder aufzubauen. Kannst du mir helfen? +DlgLumberjackRock=Ja, ich werde dir Steine finden. +DlgLumberjackWellDone=Danke vielmals, dass du das Sägewerk aufgebaut hast. Kann ich irgendwas für dich tun? +DlgLumberjackFavor=Tatsächlich kannst du das, ja. Ich brauche Holz, du hast nicht zufällig eine Axt? +DlgLumberjackMines=Nein, leider nicht. Ich habe meine Axt in der Mine fallen gelassen, als ich mich während des Angriffes versteckt habe. +DlgLumberjackLook=Na gut, dann suche ich die Axt. # Dialogue: Fireman -DlgFiremanOutOfWay=Fire! Out of my way! -DlgFiremanLastFire=Phew that was the last fire! -DlgFiremanGoodJob=Good job, have you been under attack? -DlgFiremanEvilGuys=Yes our village has been, the evil guys took some of our wipfs. -DlgFiremanFurryFriend=That is bad, I hope they won't take my little furry friend! How can I help? -DlgFiremanFlagpole=We need to construct a new flag pole, to reconnect the power supply in our village. +DlgFiremanOutOfWay=Feuer! Aus dem Weg! +DlgFiremanLastFire=Ein Glück, das war das letzte Feuer! +DlgFiremanGoodJob=Gut gemacht. Wurdet ihr angegriffen? +DlgFiremanEvilGuys=Ja, das ganze Dorf wurde attackiert. Die bösen Typen haben einige unserer Wipfe gestohlen. +DlgFiremanFurryFriend=Das ist schlimm. Ich hoffe, dass sie meinen kleinen Freund nicht bekommen! Kann ich irgendwie helfen? +DlgFiremanFlagpole=Wir müssen eine neue Flagge errichten, damit die Stromzufuhr wieder hergestellt ist. # Dialogue: Builder -DlgBuilderHello=Hi there, my name is %s and I am a builder. -DlgBuilderReply=Then you have lots of work. Do you need a hand? -DlgBuilderFlagpole=Yes, can you construct a flagpole over here? -DlgBuilderWhyHere=Of course, but why over here? -DlgBuilderConnect=Because then the flagpole will provide a power connection between the wind generator and the elevator. +DlgBuilderHello=Hallo du, mein Name ist %s. Ich bin hier der Baumeister. +DlgBuilderReply=Dann hast du sicherlich viel zu tun. Brauchst du Hilfe? +DlgBuilderFlagpole=Ja, kannst du hier drüben vielleicht eine Flagge errichten? +DlgBuilderWhyHere=Na klar, aber warum gerade dort drüben? +DlgBuilderConnect=Weil die Flagge dann Strom zwischen dem Windkraftwerk und dem Fahrstuhl leiten kann. # Dialogue: Farmer -DlgFarmerHello=Hi, is my wipf safe here? -DlgFarmerYesSafe=Yes it is, I will look after it. Are you helping us rebuild? -DlgFarmerRebuild=I am! +DlgFarmerHello=Huhu, ist mein Wipf sicher hier? +DlgFarmerYesSafe=Ja, das ist er. Ich bewache ihn. Hilfst du uns beim Wiederaufbau? +DlgFarmerRebuild=Das tue ich! # Dialogue: Lookout -DlgLookoutHello=Hello, why are you standing over here? -DlgLookoutProtecting=I am on the lookout for attacks from the evil faction. -DlgLookoutMusket=Is that why you are carrying a musket? -DlgLookoutNoChance=Yes, but I don't think I have any chance against those evil guys. -DlgLookoutNoShow=Then let's hope they don't come again. +DlgLookoutHello=Hallo, warum stehst du hier oben? +DlgLookoutProtecting=Dies ist mein Posten. Ich halte Ausschau, für den Fall, dass die dunkle Fraktion wieder angreift. +DlgLookoutMusket=Trägst du deshalb die Muskete? +DlgLookoutNoChance=Ja, aber ich denke nicht, dass ich gegen diese Typen eine Chance habe. +DlgLookoutNoShow=Dann lass uns hoffen, dass sie nicht wiederkommen! # Dialogue: Village head -DlgVillageHeadHello=I am the head of this village. -DlgVillageHeadHere=Why are you down here? -DlgVillageHeadOverview=I am making an overview of the damages. Come back later, I'll have an assignment for you. \ No newline at end of file +DlgVillageHeadHello=Hallo. Ich bin das Dorfoberhaupt von Wipfdorf. +DlgVillageHeadHere=Warum bist du denn hier unten? +DlgVillageHeadOverview=Ich schaue mir die Beschädigungen hier an. Komm doch später noch einmal vorbei, dann habe ich sicher eine Aufgabe für dich. \ No newline at end of file From e762e66a6587f78356218b164c9af74388d2fed6 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 01:51:28 +0100 Subject: [PATCH 02/36] German translation for Tutorial 4. --- .../Tutorials.ocf/Tutorial04.ocs/DescDE.txt | 6 +- .../Tutorial04.ocs/StringTblDE.txt | 28 +++--- .../Tutorial04.ocs/StringTblUS.txt | 2 +- .../Tutorial04.ocs/System.ocg/StringTblDE.txt | 96 +++++++++---------- .../Tutorial04.ocs/System.ocg/StringTblUS.txt | 2 +- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial04.ocs/DescDE.txt index 81b6c7725..e1834f46a 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial04.ocs/DescDE.txt @@ -1,7 +1,7 @@ Bergbauwerkzeuge -Wipfville has been reconstructed, but the villagers have used all their building materials in the process. To get back to their normal day lives the need their tools back again for mining, farming, wood cutting and other activities. Help the villagers with producing some new tools. +Wipfdorf wurde wieder aufgebaut, aber die Dorfbewohner haben ihr gesamtes Material dafür verbraucht. Damit sie wieder ihre Arbeit aufnehmen können, brauchen sie neue Werkzeuge für den Bergbau, Landwirtschaft, Holzproduktion und andere Aufgaben. Hilf den Dorfbewohnern neue Werkzeuge herzustellen. -Ziel: Produziere neuen Werkzeugen. +Ziel: Produziere neue Werkzeuge. -Lernrunde erklärt: Produktion, Lehm, Spitzhacke. +Lernrunde erklärt: Produktion, Lehmbrücken, Spitzhacke. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial04.ocs/StringTblDE.txt index bd234ff41..f95b2aaf0 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial04.ocs/StringTblDE.txt @@ -1,6 +1,6 @@ # Goal Description -MsgGoalName=Tool Production -MsgGoalDescription=Help the villagers produce tools essential to operate their village. +MsgGoalName=Werkzeugproduktion +MsgGoalDescription=Hilf den Dorfbewohnern Werkzeuge herzustellen, die sie dringend brauchen. # Dialogue options MsgNextTutorial=&Nächste Lernrunde @@ -9,18 +9,18 @@ MsgRepeatRound=&Lernrunde wiederholen MsgRepeatRoundDesc=Diese Lernrunde wiederholen. # Tutorial messages -MsgTutorialVillageHead=The buildings in Wipfville have been repaired again, but it seems the villagers are lacking tools to continue with their work. Descend into the mines and talk to the village head to let him know you want to help out. Take the elevator down into the mines, stand on the elevator case and press [%s] to grab the case, then press [%s] and [%s] to go up and down. -MsgTutorialLoamProduction=To move the lorry to the elevator case you need a piece of loam to cross this gap over here. Go to the foundry and grab the bucket, to produce loam you need water and earth. Earth is collected in the bucket whilst you are digging with your shovel. -MsgTutorialFillBucket=Now that you have both the shovel and the bucket in your inventory you can dig out earth. Dig out some earth to the right of the foundry and the bucket will fill itself automatically. -MsgTutorialGetBarrel=Good, the bucket is filled, put it back into the foundry and now take out the barrel. -MsgTutorialFillBarrel=The barrel is a heavy object which needs to be carried with both hands. While carrying the barrel you can't use any of your other inventory items. The barrel will fill itself automatically with once it is submerged in liquid. Find a body of water and swim in it with the barrel, then put the barrel back in the foundry. -MsgTutorialProduceLoam=Now produce a piece of loam (in the interaction menu opened with [%s]) and take it back to the lorry. -MsgTutorialMakeLoamBridge=Now stand as close to the edge as possible and close the gap with loam. Select the loam in your inventory and press [%s] in the direction you want to construct the bridge. Then grab the lorry with [%s] and move it to the workshop. -MsgTutorialProducePickaxe=Transfer the contents of the lorry to the workshop using the interaction menu (open with [%s]). Select the lorry and the workshop and then click the \"transfer all\" button in the middle of the menu. Then produce a pickaxe in the workshop, the rest of the materials will be used by the village head to produce other tools. -MsgTutorialMineOre=Take the pickaxe and make your way to the ore mine below the foundry. Hack out three pieces of ore. The pickaxe is an alternative to explosives and can be used to mine harder materials like iron ore or gold. To use the pickaxe select it and point your mouse cursor are solid material close to the clonk, then press [%s]. -MsgTutorialPutOre=Collect the three pieces of ore and put them into the foundry. Then talk to the village head. -MsgTutorialCompleted=Well, you helped the village head and completed this tutorial. But the villagers seem in trouble and Rüdiger got kidnapped... Time to make plans against the evil faction in the next tutorial. +MsgTutorialVillageHead=Die Gebäude in Wipfdorf wurden zwar repariert, aber damit die Bewohner von Wipfdorf wieder arbeiten können, brauchen sie Werkzeuge. Steige in die Minen hinab und berichte mit dem Dorfoberhaupt, dass du helfen willst. Nimm den Fahrstuhl, um damit in die Minen herunterzufahren. Stell dich dafür auf den Fahrstuhlkorb und drücke [%s] um diesen anzufassen, danach [%s] und [%s] um hinauf oder hinunter zu fahren. +MsgTutorialLoamProduction=Um die Lore zum Fahrstuhlkorb zu schaffen, brauchst du ein Stück Lehm um damit diese Lücke zu schließen. Lehm kann mit Hilfe des Hochofens hergestellt werden, doch brauchst du dafür Erde und Wasser. Nimm den Eimer aus dem Hochofen, wenn du dort bist. Ein Eimer wird automatisch mit Erde gefüllt, wenn du die Schaufel zum Graben benutzt. +MsgTutorialFillBucket=Mit der Schaufel und dem Eimer im Inventar kannst du jetzt Erde ausgraben. Benutze die Schaufel gleich rechts vom Hochofen und der Eimer wird sich automatisch mit Erde füllen. +MsgTutorialGetBarrel=Gut, der Eimer ist jetzt gefüllt. Hole jetzt das Fass aus dem Hochofen. +MsgTutorialFillBarrel=Ein Fass ist ein schweres Objekt und muss deswegen mit beiden Händen getragen werden. Während du ein solches bei dir hast, kannst du keine anderen Gegenstände aus deinem Inventar benutzen. Das Fass wird automatisch mit Wasser gefüllt, wenn es untergetaucht wird. Finde etwas Wasser und spring mit dem Fass hinein. Bringe das Fass danach zum Hochofen zurück. +MsgTutorialProduceLoam=Stelle jetzt ein Stück Lehm her (benutze dazu das Interaktionsmenü, welches du mit [%s] öffnen kannst) und bringe es zur Lore. +MsgTutorialMakeLoamBridge=Stelle dich nun so nah wie möglich an die Kante und schließe die Lücke mit Lehm. Wähle dazu den Lehmklumpen in deinem Inventar aus und drücke [%s] in die Richtung, in die du eine Lehmbrücke errichten willst. Fasse danach die Lore mit [%s] an und schiebe sie zur Werkstatt. +MsgTutorialProducePickaxe=Mit dem Interaktionsmenü kannst du den Inhalt der Lore in die Werkstatt verschieben (öffne das Menü mit [%s]). Wähle im Menü auf der einen Seite die Lore und auf der anderen die Werkstatt aus und drücke dann den \"Alles verschieben\"-Knopf in der Mitte des Menüs. Stelle danach eine Spitzhacke her (ebenfalls im Interaktionsmenü). Die restlichen Materialien brauchen die Dorfbewohner zur Herstellung anderer Werkzeuge. +MsgTutorialMineOre=Nimm die Spitzhacke mit und laufe dann zurück zum Erz in der Mine. Schürfe drei Erzklumpen mit der Spitzhacke. Die Spitzhacke kann alternativ statt Sprengstoffen zum Abbau von harten Materialien, wie Eisenerz oder Gold, verwendet werden. Um die Spitzhacke zu verwenden, ziele mit der Maus auf festen Material nahe des Clonks und halte [%s] gedrückt. +MsgTutorialPutOre=Sammle die drei Erzklumpen ein und bringe sie zum Hochofen. Sprich danach mit dem Dorfoberhaupt. +MsgTutorialCompleted=Du hast den Dorfbewohnern geholfen und damit diese Lernrunde abgeschlossen. Aber die Dorfbewohner wurden angegriffen und Rüdiger entführt...Zeit, in der nächsten Lernrunde Pläne gegen die dunkle Fraktion zu schmieden. # Wipf name WipfName=Rüdiger -WipfDescription=Your furry little friend. \ No newline at end of file +WipfDescription=Dein felliger kleiner Freund. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/StringTblUS.txt b/planet/Tutorials.ocf/Tutorial04.ocs/StringTblUS.txt index faf0ad9ee..4c88be9ce 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/StringTblUS.txt +++ b/planet/Tutorials.ocf/Tutorial04.ocs/StringTblUS.txt @@ -17,7 +17,7 @@ MsgTutorialFillBarrel=The barrel is a heavy object which needs to be carried wit MsgTutorialProduceLoam=Now produce a piece of loam (in the interaction menu opened with [%s]) and take it back to the lorry. MsgTutorialMakeLoamBridge=Now stand as close to the edge as possible and close the gap with loam. Select the loam in your inventory and press [%s] in the direction you want to construct the bridge. Then grab the lorry with [%s] and move it to the workshop. MsgTutorialProducePickaxe=Transfer the contents of the lorry to the workshop using the interaction menu (open with [%s]). Select the lorry and the workshop and then click the \"transfer all\" button in the middle of the menu. Then produce a pickaxe in the workshop, the rest of the materials will be used by the village head to produce other tools. -MsgTutorialMineOre=Take the pickaxe and make your way to the ore mine below the foundry. Hack out three pieces of ore. The pickaxe is an alternative to explosives and can be used to mine harder materials like iron ore or gold. To use the pickaxe select it and point your mouse cursor are solid material close to the clonk, then press [%s]. +MsgTutorialMineOre=Take the pickaxe and make your way to the ore mine below the foundry. Hack out three pieces of ore. The pickaxe is an alternative to explosives and can be used to mine harder materials like iron ore or gold. To use the pickaxe select it and point your mouse cursor at solid material close to the clonk, then press [%s]. MsgTutorialPutOre=Collect the three pieces of ore and put them into the foundry. Then talk to the village head. MsgTutorialCompleted=Well, you helped the village head and completed this tutorial. But the villagers seem in trouble and Roger got kidnapped... Time to make plans against the evil faction in the next tutorial. diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblDE.txt index 3fc97d919..911d5155f 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblDE.txt @@ -1,63 +1,63 @@ # Dialogue: Lumberjack -DlgLumberjackForest=Where are all the trees? -DlgLumberjackCutDown=I have processed them all into logs for the reconstruction of our village. -DlgLumberjackNoWood=So you ran out of wood completely? -DlgLumberjackSupply=No we have a small supply in the mines, hidden from the evil faction. +DlgLumberjackForest=Wo sind die Bäume hin? +DlgLumberjackCutDown=Die habe ich alle zu Holz verarbeitet, damit wir unser Dorf wieder aufbauen können. +DlgLumberjackNoWood=Das heißt, dass jetzt kein Holz mehr übrig ist? +DlgLumberjackSupply=Doch. Wir haben einen kleinen Vorrat tief in der Mine, versteckt vor der dunklen Fraktion. # Dialogue: Fireman -DlgFiremanWhereBarrel=Hi, where did you leave that big barrel you used to extinguish fires? -DlgFiremanFoundry=I put it back into the foundry below, where we use it to produce loam, which requires water. -DlgFiremanWhereWater=Where do you get the water from then? -DlgFiremanDive=Oh, I just dive into any small lake I see with the barrel. There are some underground in the mines we have. +DlgFiremanWhereBarrel=Hey, wo hast du dieses große Fass gelassen, mit dem du die Feuer gelöscht hast? +DlgFiremanFoundry=Ich habe es nach unten in die Mine gebracht, wo wir Lehm herstellen. Die Herstellung von Lehm benötigt Wasser. +DlgFiremanWhereWater=Woher bekommst du das Wasser? +DlgFiremanDive=Oh, ich tauche in jeden See den ich finden kann. Im Untergrund in den Minen sind ein paar. # Dialogue: Builder -DlgBuilderThanks=Thank you for constructing that flagpole. -DlgBuilderNoProblem=No problem. -DlgBuilderPowerConnection=With that flagpole the elevator is not connected to the power sources of our village, as you can see. +DlgBuilderThanks=Danke, dass du die Flagge gebaut hast. +DlgBuilderNoProblem=Kein Problem. +DlgBuilderPowerConnection=Wie du siehst, ist durch die Flagge der Fahrstuhl jetzt mit der Energieversorgung des Dorfes verbunden. # Dialogue: Farmer -DlgFarmerWipf=Hi, how is my wipf doing? -DlgFarmerDoingWell=It is getting along with our wipfs very well. -DlgFarmerPleasure=That is a pleasure to hear! +DlgFarmerWipf=Hey, wie geht es meinem Wipf? +DlgFarmerDoingWell=Er versteht sich gut mit unseren Wipfen. +DlgFarmerPleasure=Das hört sich gut an! # Dialogue: Lookout -DlgLookoutNewAttack=Hello, any signs for a new attack? -DlgLookoutNo=No, not at the moment. +DlgLookoutNewAttack=Hallo, gibt es Anzeichen für einen Angriff? +DlgLookoutNo=Nein, derzeit nicht. # Dialogue: Village head -DlgVillageHeadThank=Thank you for your help with repairing our buildings. Are you willing to help more? -DlgVillageHeadHelp=Yes, of course, as long as my wipf can stay with the other wipfs. How can I help? -DlgVillageHeadTools=Well, we are lacking tools and I was about to take this lorry with materials to the workshop to produce them, but you see there is a problem. -DlgVillageHeadProblem=What problem? -DlgVillageHeadGap=There is this gap which we need to cross with the lorry to make it to the elevator shaft. -DlgVillageHeadFix=Ah I see, I'll fix that for you! -DlgVillageHeadPickaxe=Cool, maybe you can then produce a pickaxe and mine some iron ore for us? We are a bit low on explosives. -DlgVillageHeadYes=Yes, no problem. -DlgVillageHeadPutOre=Please put three pieces of iron ore in the foundry. -DlgVillageHeadThanks=Thanks a lot for helping out again. +DlgVillageHeadThank=Danke, dass du uns geholfen hast, die Gebäude zu reparieren. Möchtest du noch mehr helfen? +DlgVillageHeadHelp=Ja, natürlich. Wenn mein Wipf länger bei euren Wipfen bleiben darf. Wie kann ich helfen? +DlgVillageHeadTools=Gut. Uns fehlen Werkzeuge. Ich wollte gerade diese Lore mit Material zur Werkstatt bringen. Aber siehst du das Problem? +DlgVillageHeadProblem=Was für ein Problem? +DlgVillageHeadGap=Diese Lücke hier müssen wir überwinden, damit wir die Lore zum Fahrstuhlschacht schieben können. +DlgVillageHeadFix=Ich verstehe. Das schaffe ich! +DlgVillageHeadPickaxe=Toll. Kannst du vielleicht danach eine Spitzhacke herstellen und etwas Erz abbauen? Uns fehlt leider Sprengstoff für einen schnelleren Abbau. +DlgVillageHeadYes=Ja klar, kein Problem. +DlgVillageHeadPutOre=Bitte bring die drei Erzklumpen in den Hochofen. +DlgVillageHeadThanks=Danke noch mal für deine Hilfe. # Sequence: Outro dialogue -MsgVillageHeadNoise=What is that noise? -MsgFarmerAirplanes=Oh no that must be the airplanes of the evil faction again. -MsgEvilLeaderItsUs=Yes, it's us again! Resistance is futile, so tell your guard to stand down! -MsgVillageHeadWhy=Why are you here again? You just destroyed our village... -MsgEvilLeaderWipfs=I started a new hobby, I collect wipfs now. -MsgVillageHeadManiac=You are a maniac, can't you leave us alone? -MsgEvilLeader=I'll leave you be after I kidnapped all your wipfs. -MsgPlayerDontTakeWipf=Please, don't take Roger... -MsgEvilLeaderBegging=Oh little kid, begging is useless, my men are not prone to crying. Your wipf will be mine and it is best to forget about him, cause you won't see him again. -MsgEvilLeaderBye=Okay, we are done here. Time to say goodbye to your pet friends... muhaha +MsgVillageHeadNoise=Was ist das für ein Geräusch? +MsgFarmerAirplanes=Oh nein! Das sind bestimmt die Flugzeuge der dunklen Fraktion! +MsgEvilLeaderItsUs=Ja, wir sind es wieder. Widerstand ist zwecklos. Gebt auf! +MsgVillageHeadWhy=Wieso seid ihr zurückgekommen? Ihr habt unser Dorf doch bereits einmal zerstört... +MsgEvilLeaderWipfs=Ich habe jetzt ein neues Hobby: Wipfe sammeln. +MsgVillageHeadManiac=Du bist völlig verrückt! Kannst du uns nicht in Ruhe lassen? +MsgEvilLeader=Ich verschwinde gleich wieder, aber erst will ich alle Wipfe haben. +MsgPlayerDontTakeWipf=Bitte nehmt Rüdiger nicht! +MsgEvilLeaderBegging=Ach, du Kleinkind. Betteln hilft dir nicht, meine Leute sind immun gegenüber Geweine. Dein Wipf gehört mir und am besten vergisst du, dass es ihn jemals gab. Wiedersehen wirst du ihn nicht! +MsgEvilLeaderBye=Gut, wir sind hier fertig. Sagt euren Tierchen auf Wiedersehen...muhaha # Sequence: Outro messages -MsgHenchman3DropMusket=You better drop that musket! -MsgLookoutSurrender=Yes, I surrender. -MsgHenchman1RunGirl=Run girl, or we shoot! -MsgHenchman2Wipfs=Your wipfs are ours now, muhaha. -MsgFarmerComment=You are evil. -MsgKidnapperGotThem=We have got them! -MsgHenchman1SeeYa=I am off now! -MsgHenchman2SeeYa=Bye! -MsgHenchman3SeeYa=See Ya! -MsgHenchmanGotWipf1=I got one! -MsgHenchmanGotWipf2=Wipf ahoy! -MsgHenchmanGotWipf3=It'll be a nice ride. +MsgHenchman3DropMusket=Lass die Muskete fallen! +MsgLookoutSurrender=Ich gebe auf! +MsgHenchman1RunGirl=Verschwinde Mädchen oder wir schießen! +MsgHenchman2Wipfs=Eure Wipfe gehören uns, muhaha. +MsgFarmerComment=Ihr seid böse. +MsgKidnapperGotThem=Wir haben sie. +MsgHenchman1SeeYa=Ich bin jetzt weg. +MsgHenchman2SeeYa=Tschüss! +MsgHenchman3SeeYa=Bis bald! +MsgHenchmanGotWipf1=Ich hab einen. +MsgHenchmanGotWipf2=Wipf kommt! +MsgHenchmanGotWipf3=Keine Sorge, das wird ein sanfter Flug. diff --git a/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblUS.txt b/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblUS.txt index 3fc97d919..f97efaba1 100644 --- a/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblUS.txt +++ b/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/StringTblUS.txt @@ -13,7 +13,7 @@ DlgFiremanDive=Oh, I just dive into any small lake I see with the barrel. There # Dialogue: Builder DlgBuilderThanks=Thank you for constructing that flagpole. DlgBuilderNoProblem=No problem. -DlgBuilderPowerConnection=With that flagpole the elevator is not connected to the power sources of our village, as you can see. +DlgBuilderPowerConnection=With that flagpole the elevator is now connected to the power sources of our village, as you can see. # Dialogue: Farmer DlgFarmerWipf=Hi, how is my wipf doing? From bd4551c6d4c0b593fab5d3aa8887f01839774fb1 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Mon, 11 Jan 2016 18:07:00 -0800 Subject: [PATCH 03/36] Disable gamepad controls (#1536) Gamepad support is currently not working properly as many menus cannot be navigated with a gamepad. Simply don't load any control assignment sets that have gamepad enabled. --- src/control/C4PlayerControl.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/control/C4PlayerControl.cpp b/src/control/C4PlayerControl.cpp index 9df38e25e..205eb9fdd 100644 --- a/src/control/C4PlayerControl.cpp +++ b/src/control/C4PlayerControl.cpp @@ -734,6 +734,21 @@ void C4PlayerControlAssignmentSets::CompileFunc(StdCompiler *pComp) } pComp->Value(mkNamingAdapt(clear_previous, "ClearPrevious", false)); pComp->Value(mkSTLContainerAdapt(Sets, StdCompiler::SEP_NONE)); + + // Remove all sets that have gamepad controls, since gamepad + // support is broken at the moment. Disable this once we have gamepad + // support again! + if (pComp->isCompiler()) + { + AssignmentSetList::iterator iter = Sets.begin(); + for (AssignmentSetList::iterator iter = Sets.begin(); iter != Sets.end(); ) + { + if (iter->HasGamepad()) + iter = Sets.erase(iter); + else + ++iter; + } + } } bool C4PlayerControlAssignmentSets::operator ==(const C4PlayerControlAssignmentSets &cmp) const From 7e19070ef3c5a4453d7db66ba11759a4e20a18ba Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Mon, 11 Jan 2016 18:28:23 -0800 Subject: [PATCH 04/36] Allow to only select a single player in the menu (#1529) Due to the lack of gamepad support, splitscreen support is somewhat pointless at the moment. --- src/gui/C4StartupPlrSelDlg.cpp | 8 ++++++-- src/gui/C4StartupPlrSelDlg.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/C4StartupPlrSelDlg.cpp b/src/gui/C4StartupPlrSelDlg.cpp index 05747cb46..663c0523c 100644 --- a/src/gui/C4StartupPlrSelDlg.cpp +++ b/src/gui/C4StartupPlrSelDlg.cpp @@ -730,6 +730,10 @@ void C4StartupPlrSelDlg::OnItemCheckChange(C4GUI::Element *pCheckBox) switch (eMode) { case PSDM_Player: + // Deselect all other players + for (ListItem* pEl = static_cast(pPlrListBox->GetFirst()); pEl != NULL; pEl = pEl->GetNext()) + if (pCheckBox && pEl != pCheckBox->GetParent()) + pEl->SetActivated(false); // update Config.General.Participants UpdateActivatedPlayers(); break; @@ -769,7 +773,7 @@ void C4StartupPlrSelDlg::OnActivateBtn(C4GUI::Control *btn) if (!pSel) return; pSel->SetActivated(!pSel->IsActivated()); // update stuff - OnItemCheckChange(NULL); + OnItemCheckChange(pSel->GetCheckBox()); } void C4StartupPlrSelDlg::DoBack() @@ -934,7 +938,7 @@ void C4StartupPlrSelDlg::SelectItem(const StdStrBuf &Filename, bool fActivate) { pPlrItem->SetActivated(true); // player activation updates - OnItemCheckChange(NULL); + OnItemCheckChange(pPlrItem->GetCheckBox()); } // max one return; diff --git a/src/gui/C4StartupPlrSelDlg.h b/src/gui/C4StartupPlrSelDlg.h index e8b9f8db3..a91b2834c 100644 --- a/src/gui/C4StartupPlrSelDlg.h +++ b/src/gui/C4StartupPlrSelDlg.h @@ -66,6 +66,7 @@ private: void SetFilename(const StdStrBuf &sNewFN); public: + C4GUI::CheckBox *GetCheckBox() const { return pCheck; } ListItem *GetNext() const { return static_cast(BaseClass::GetNext()); } virtual uint32_t GetColorDw() const = 0; // get drawing color for portrait bool IsActivated() const { return pCheck->GetChecked(); } From bb3959771165b04af5ca0ec2de7cd1094e5bba42 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Mon, 11 Jan 2016 18:33:08 -0800 Subject: [PATCH 05/36] main menu: limit player selection to one player (#1529) --- src/gui/C4StartupMainDlg.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/C4StartupMainDlg.cpp b/src/gui/C4StartupMainDlg.cpp index e7d1885bb..320e7c7f8 100644 --- a/src/gui/C4StartupMainDlg.cpp +++ b/src/gui/C4StartupMainDlg.cpp @@ -154,7 +154,9 @@ C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextRemove(C4GUI::Element *p void C4StartupMainDlg::OnPlayerSelContextAddPlr(C4GUI::Element *pTarget, const StdCopyStrBuf &rsFilename) { - SAddModule(Config.General.Participants, rsFilename.getData()); + // De-select all other players for now (see #1529) + SCopy(rsFilename.getData(), Config.General.Participants); + //SAddModule(Config.General.Participants, rsFilename.getData()); UpdateParticipants(); } From 190b4bbae392e70f374b7b05de40995ce0a78f62 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Mon, 11 Jan 2016 18:40:59 -0800 Subject: [PATCH 06/36] Instruct to start a network game when starting a round with >=2 MinPlayers Instead of asking the user to activate more players, which is no longer possible as of #1529. --- planet/System.ocg/LanguageDE.txt | 2 +- planet/System.ocg/LanguageUS.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/System.ocg/LanguageDE.txt b/planet/System.ocg/LanguageDE.txt index fcf6e97e0..62808c74d 100644 --- a/planet/System.ocg/LanguageDE.txt +++ b/planet/System.ocg/LanguageDE.txt @@ -620,7 +620,7 @@ IDS_MSG_TEAMDIST_HOST=Per &Host IDS_MSG_TEAMDIST_NONE=&Keine IDS_MSG_TEAMDIST_RND=&Zufällig IDS_MSG_TEAMDIST_RNDINV=Zufällig und &Unsichtbar -IDS_MSG_TOOFEWPLAYERS=Dieses Szenario ist auf mindestens %i Teilnehmer ausgelegt. Bitte in der Spielerauswahl die entsprechenden Teilnehmer auswählen und aktivieren. +IDS_MSG_TOOFEWPLAYERS=Dieses Szenario ist auf mindestens %i Teilnehmer ausgelegt. Bitte starte das Szenario als Netzwerkspiel und warte auf weitere Teilnehmer aus dem Netzwerk. IDS_MSG_TOOFEWPLAYERSNET=Der Spielmodus dieses Szenarios ist auf mehr Spieler ausgelegt, als auf diesem Rechner aktiviert sind. Beim Start der Runde muss auf weitere Teilnehmer aus dem Netzwerk gewartet werden. IDS_MSG_TOOMANYPLAYERS=Dieses Szenario ist auf maximal %i Teilnehmer ausgelegt. IDS_MSG_TOPICIN=Thema in %s: %s diff --git a/planet/System.ocg/LanguageUS.txt b/planet/System.ocg/LanguageUS.txt index 319bc391e..026ce8b63 100644 --- a/planet/System.ocg/LanguageUS.txt +++ b/planet/System.ocg/LanguageUS.txt @@ -620,7 +620,7 @@ IDS_MSG_TEAMDIST_HOST=by &Host IDS_MSG_TEAMDIST_NONE=&none IDS_MSG_TEAMDIST_RND=&random IDS_MSG_TEAMDIST_RNDINV=&surprise random! -IDS_MSG_TOOFEWPLAYERS=This scenario is designed for a minimum of %i players. Please go to the Player Selection dialog and activate the participants for this round. +IDS_MSG_TOOFEWPLAYERS=This scenario is designed for a minimum of %i players. Please start the round as a network game and wait for additional players to join. IDS_MSG_TOOFEWPLAYERSNET=This scenario is set for more participants than are activated on this computer. On start, you will have to wait for additional players to join from the network. IDS_MSG_TOOMANYPLAYERS=This scenario is designed for a maximum of %i players. IDS_MSG_TOPICIN=Topic in %s: %s From b29631f0038ac17159fddbc6b902109f97b54c93 Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Mon, 11 Jan 2016 22:02:26 -0500 Subject: [PATCH 07/36] Make relaunch weapon selection menu unclosable #1577 --- .../Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c index 53285f895..2e7518f11 100644 --- a/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/LastManStanding.ocd/Relaunch.ocd/Script.c @@ -63,7 +63,7 @@ private func OpenWeaponMenu(object clonk) menu = CreateObject(MenuStyle_Default, nil, nil, clonk->GetOwner()); menu->SetPermanent(); menu->SetTitle(Format("$MsgWeapon$", time / 36)); - clonk->SetMenu(menu); + clonk->SetMenu(menu, true); for (var weapon in weapons) menu->AddItem(weapon, weapon->GetName(), nil, this, "OnWeaponSelected", weapon); From 7784a2617ebe73a988034216f692803f26e05e24 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 12 Jan 2016 09:48:46 +0100 Subject: [PATCH 08/36] fix showing rocks in tutorial 3 (#1594) --- planet/Tutorials.ocf/Tutorial03.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt | 2 +- planet/Tutorials.ocf/Tutorial03.ocs/StringTblUS.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/Script.c b/planet/Tutorials.ocf/Tutorial03.ocs/Script.c index a62ddf1ca..c2d3a0455 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial03.ocs/Script.c @@ -538,7 +538,7 @@ protected func OnGuideMessageShown(int plr, int index) if (index == 4) { var clonk = FindObject(Find_OCF(OCF_CrewMember), Find_Owner(plr)); - var rock = FindObject(Find_ID(Rock), Sort_Distance(clonk->GetX(), clonk->GetY())); + var rock = FindObject(Find_ID(Rock), Find_NoContainer(), Find_OCF(OCF_InFree), Find_Distance(60, clonk->GetX(), clonk->GetY()), Sort_Distance(clonk->GetX(), clonk->GetY())); TutArrowShowTarget(rock); } // Show the sawmill construction site. diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt index b567fc653..e22cc1d20 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt @@ -13,7 +13,7 @@ MsgTutorialWipfville=Auf dem Wegweiser steht Wipfdorf - wahrscheinlich der Grund MsgTutorialFindRock=Okay, wir müssen etwas Stein finden um das Sägewerk da fertig zu stellen. Lass uns einen Blick in die Minen des Dorfes werfen. Vielleicht finden wir da etwas. MsgTutorialDynamiteLorry=Da steht eine Lore voll mit Dynamit! Du kommst an den Inhalt von vielen Fahrzeugen und Gebäuden heran, indem du [%s] drückst um das Interaktionsmenü zu öffnen. Du kannst mit einem Klick Gegenstände hin- und hertauschen. Hol dir etwas Dynamit! MsgTutorialBlastRock=Perfekt, mit Dynamit kannst du den Stein an der Decke sprengen. Stein wird als Baumaterial gebraucht. Hangel dich an den Stein und wähle das Dynamit aus. Drücke dann die linke Maustaste einmal um das Dynamit zu zünden und dann ziele auf den Stein und klicke noch einmal um das Dynamit in die Wand zu stecken. Dann hau ab! -MsgTutorialPickUpRock=Schön! Sammel drei Steine, so dass du das Sägewerk fertig bauen kannst. +MsgTutorialPickUpRock=Schön! Sammel drei Steine, so dass du das Sägewerk fertig bauen kannst. Note that the explosion could have flung some pieces of rock into the lorry. MsgTutorialSawmill=Geh hoch zur Baustelle und tue die drei Steine mit dem Interaktionsmenü in die Baustelle (drücke dazu [%s]). Die Baustelle wird automatisch vollendet, sobald alles Baumaterial da ist. MsgTutorialTalkToFireman=Die Dorfbewohner brauchen noch mehr Hilfe. Rede mit dem Feuerwehrmann neben der verbrannten Hütte und mit dem Bauarbeiter beim Mineneingang. MsgTutorialConstructFlagpole=Hol dir den Hammer aus der Kiste und benutze ihn um das Baumenü zu öffnen. Im Baumenü kannst du ein Gebäude auswählen und danach platzieren. Wähle die Flagge aus und platziere sie an der markierten Position. diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblUS.txt b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblUS.txt index e4e063d67..774a73253 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblUS.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblUS.txt @@ -13,7 +13,7 @@ MsgTutorialWipfville=This guidepost reads Wipfville, probably the reason why Rog MsgTutorialFindRock=Okay, we need to find some rock to finish the construction of this sawmill over here. Let's have a look at the mines of this village, maybe we can find something there. MsgTutorialDynamiteLorry=There is a lorry filled with dynamite. You can access the contents of many vehicles and buildings by pressing [%s], which opens the interaction menu. You can interchange items between different containers by clicking them. Grab a stick of dynamite! MsgTutorialBlastRock=Perfect, with dynamite you can blast the rock at the ceiling, rock is used as a construction material. Hang onto the rock material and select one of the dynamite sticks, press the left mouse button once to fuse it and press it another time in the direction of the rock to stick it into the wall. Then jump off and run! -MsgTutorialPickUpRock=Great, pick up three pieces of rock, so that you can finish the sawmill construction. +MsgTutorialPickUpRock=Great, pick up three pieces of rock, so that you can finish the sawmill construction. Note that the explosion could have flung some pieces of rock into the lorry. MsgTutorialSawmill=Go up to the sawmill construction site and put the three pieces of rock into construction site via the interaction menu (press [%s] to open). If all building materials are put into a construction site the building will be constructed automatically. MsgTutorialTalkToFireman=The villagers seem to need a little more help, talk to the fireman standing next to the burned hut and to the builder next to the mine entrance. MsgTutorialConstructFlagpole=Get the hammer from the chest, then use it to open the construction menu. From the construction menu you can select a building you wish to construct, select the flagpole and place it at the indicated position. From 8f71fa8a7a5fb45bed065fb2c63eee1d2b6ebe61 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 19:50:59 +0100 Subject: [PATCH 09/36] Tutorial 3: Translated new hint (#1594). --- planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt index e22cc1d20..fa9707f72 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/StringTblDE.txt @@ -13,7 +13,7 @@ MsgTutorialWipfville=Auf dem Wegweiser steht Wipfdorf - wahrscheinlich der Grund MsgTutorialFindRock=Okay, wir müssen etwas Stein finden um das Sägewerk da fertig zu stellen. Lass uns einen Blick in die Minen des Dorfes werfen. Vielleicht finden wir da etwas. MsgTutorialDynamiteLorry=Da steht eine Lore voll mit Dynamit! Du kommst an den Inhalt von vielen Fahrzeugen und Gebäuden heran, indem du [%s] drückst um das Interaktionsmenü zu öffnen. Du kannst mit einem Klick Gegenstände hin- und hertauschen. Hol dir etwas Dynamit! MsgTutorialBlastRock=Perfekt, mit Dynamit kannst du den Stein an der Decke sprengen. Stein wird als Baumaterial gebraucht. Hangel dich an den Stein und wähle das Dynamit aus. Drücke dann die linke Maustaste einmal um das Dynamit zu zünden und dann ziele auf den Stein und klicke noch einmal um das Dynamit in die Wand zu stecken. Dann hau ab! -MsgTutorialPickUpRock=Schön! Sammel drei Steine, so dass du das Sägewerk fertig bauen kannst. Note that the explosion could have flung some pieces of rock into the lorry. +MsgTutorialPickUpRock=Schön! Sammle drei Steine ein, so dass du damit das Sägewerk fertig bauen kannst. Beachte, dass einige Stein durch die Explosion in der Lore gelandet sein könnten. MsgTutorialSawmill=Geh hoch zur Baustelle und tue die drei Steine mit dem Interaktionsmenü in die Baustelle (drücke dazu [%s]). Die Baustelle wird automatisch vollendet, sobald alles Baumaterial da ist. MsgTutorialTalkToFireman=Die Dorfbewohner brauchen noch mehr Hilfe. Rede mit dem Feuerwehrmann neben der verbrannten Hütte und mit dem Bauarbeiter beim Mineneingang. MsgTutorialConstructFlagpole=Hol dir den Hammer aus der Kiste und benutze ihn um das Baumenü zu öffnen. Im Baumenü kannst du ein Gebäude auswählen und danach platzieren. Wähle die Flagge aus und platziere sie an der markierten Position. From 07e912bac62df719ca7ea563887eb4e8c07d36d3 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 19:51:29 +0100 Subject: [PATCH 10/36] Tutorial 5: German translation. --- .../Tutorials.ocf/Tutorial05.ocs/DescDE.txt | 4 +- .../Tutorial05.ocs/StringTblDE.txt | 18 ++++---- .../Tutorial05.ocs/System.ocg/StringTblDE.txt | 44 +++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial05.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial05.ocs/DescDE.txt index 42105663d..8b0f0f31e 100644 --- a/planet/Tutorials.ocf/Tutorial05.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial05.ocs/DescDE.txt @@ -1,7 +1,7 @@ Räuberhöhle -Archibald the head of the village takes you with him on a journey to a neighbouring village to ask for help. On your way you stumble upon a guy who lost his house to robbers. To make your way to the other village you need to pass through the cave where these robbers hide. +Archibald, das Dorfoberhaupt, hat dich auf seine Reise zu einem benachbarten Dorf mitgenommen. Dort möchte er Hilfe suchen. Auf dem Weg trefft ihr auf jemanden, der sein Haus durch Räuber verloren hat. Um zu dem anderen Dorf zu gelangen, müsst ihr die Höhle durchqueren, in denen die Räuber Zuflucht gesucht haben. -Ziel: Battle your way through the robber's cave. +Ziel: Kämpfe dich durch die Räuberhöhle. Lernrunde erklärt: Waffen wie Bogen, Speed, Schwert und Schild. diff --git a/planet/Tutorials.ocf/Tutorial05.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial05.ocs/StringTblDE.txt index 3501186c6..5a76d7c03 100644 --- a/planet/Tutorials.ocf/Tutorial05.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial05.ocs/StringTblDE.txt @@ -1,6 +1,6 @@ # Goal Description -MsgGoalName=Reach the village -MsgGoalDescription=Traverse the cave and reach the village on the other side together with the village head. +MsgGoalName=Erreiche das nächste Dorf +MsgGoalDescription=Durchquere zusammen mit dem Dorfoberhaupt die Höhle bis zum nächsten Dorf. # Dialogue options MsgNextTutorial=&Nächste Lernrunde @@ -9,10 +9,10 @@ MsgRepeatRound=&Lernrunde wiederholen MsgRepeatRoundDesc=Diese Lernrunde wiederholen. # Tutorial messages -MsgTutorialTalkToHead=You need to enter the cave and take down the robbers. Talk to the village head first, hopefully he has some idea on how to do this. -MsgTutorialNotHelpful=That was not very helpful, but at least you have a weapon. You can test the axe on the straw men in the grain field, press [%s] to use axe and destroy the straw men. -MsgTutorialFirstEnemy=The first robber in the cave has a bow and shoots arrows at you, maybe there is another way to approach him instead of engaging him head-on. Kill your enemy, if you die in the process you will respawn, so you can try multiple times. -MsgTutorialOnRespawn=Okay, that did not work, maybe you can reach that chest over there by digging through the earth. Then take whatever is in the chest and use that to kill the robber. Some weapons can be thrown, just aim your mouse cursor at where you want to throw that weapon. -MsgTutorialKilledFirst=Well done, that guy is eliminated. You can take his weapons and proceed to explore the cave and find more robbers. The bow can be used to shoot enemies over larger distance, aim with the mouse cursor in the direction you want to shoot. -MsgTutorialKilledSecond=And another one down, you are getting the hang of it! He dropped some bread, pick it up and press [%s] to eat it. Then continue along the cave's path. -MsgTutorialCompleted=Well done! Now you are a trained fighter. There are many more weapons in this game which you can try out in later tutorials or in other rounds. \ No newline at end of file +MsgTutorialTalkToHead=Du musst die Höhle betreten und dich den Räubern stellen. Sprich zunächst mit dem Dorfoberhaupt, vielleicht hat er Ideen, die dir helfen können. +MsgTutorialNotHelpful=Das war nicht sonderlich hilfreich, aber immerhin hast du eine Waffe. Diese kannst du erst mal an den Strohpuppen im Kornfeld testen. Drücke [%s] um die Axt zu benutzen und die Strohpuppen zu zerstören. +MsgTutorialFirstEnemy=Der erste Räuber in der Höhle hat Pfeil und Bogen und kann dich aus der Ferne bekämpfen. Blindlings voranstürmen, wird dir nicht helfen. Vielleicht findest du eine Möglichkeit, ihn besser anzugreifen. Sollte dein Clonk beim Kampf umkommen, gibt es einen Respawn so oft wie nötig. +MsgTutorialOnRespawn=Hm, das hat nicht so gut funktioniert. Vielleicht kannst du die Kiste da drüben erreichen, wenn du durch die Erde gräbst. Nimm, was auch immer in der Kiste ist zum Kämpfen. Manche Waffen können geworfen werden. Ziele einfach mit der Maus in die Richtung, in die du werfen möchtest. +MsgTutorialKilledFirst=Gut gemacht, der ist erledigt. Nimm dir seine Waffe und gehe tiefer in die Höhle, wo sicher noch mehr Räuber sind. Mit dem Bogen lassen sich Feinde aus großer Entfernung bekämpfen. Ziele einfach mit der Maus in die Richtung, in die du schießen willst. +MsgTutorialKilledSecond=Und noch einer weg! So langsam kriegst du den Dreh raus. Dieser hier hat etwas Brot fallen gelassen. Nimm das Brot und drücke [%s] um es zu essen. So füllst deine Lebensenergie wieder auf. Laufe danach weiter den Pfad entlang. +MsgTutorialCompleted=Ausgezeichnet! Jetzt bist du ein ausgebildeter Kämpfer. Es gibt noch weitere Waffen in diesem Spiele, die du in späteren Lernrunden oder anderen Szenarien ausprobieren kannst. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial05.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial05.ocs/System.ocg/StringTblDE.txt index 2b39c86dc..680732856 100644 --- a/planet/Tutorials.ocf/Tutorial05.ocs/System.ocg/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial05.ocs/System.ocg/StringTblDE.txt @@ -1,29 +1,29 @@ # Dialogue: homeless -DlgHomelessFood=Hey, you have got some food for a poor man? -DlgHomelessNo=No, have nothing on me. -DlgHomelessShame=That's a shame. -DlgHomelessYes=Yes, here is some %s. -DlgHomelessReward=Ah, thanks. I have this old club you can have, it might help against those robbers. +DlgHomelessFood=Hast du etwas zu essen für einen armen Mann? +DlgHomelessNo=Nein, ich habe nichts dabei. +DlgHomelessShame=Schade. +DlgHomelessYes=Ja, hier ist etwas %s. +DlgHomelessReward=Vielen Dank! Ich habe diese alte Keule hier, vielleicht hilft sie dir gegen die Räuber. # Dialogue: village head -DlgVillageHeadHowToAttack=How can I stand a chance against these evil robbers? -DlgVillageHeadNoIdea=I have no idea about combat. I can give you this axe, but it is not really a weapon. -DlgVillageHeadThanks=Well thanks, I'll give it a try then. -DlgVillageHeadGoodLuck=Good luck, let me know when it is safe to enter the cave. +DlgVillageHeadHowToAttack=Wie soll ich denn alleine gegen die Räuber kämpfen? +DlgVillageHeadNoIdea=Vom Kämpfen habe ich leider keine Ahnung. Ich kann dir diese Axt hier geben, aber eine gute Waffe ist das nicht. +DlgVillageHeadThanks=Na gut, danke trotzdem. Ich versuche mein Bestes. +DlgVillageHeadGoodLuck=Viel Glück! Sag Bescheid, wenn die Höhle sicher ist. # Sequence: intro -MsgVillageHeadAnnoyed=I am really annoyed by the evil faction, we have to strike back. -MsgClonkHowToStrike=How can we strike back? They are many and armed to the teeth. -MsgVillageHeadOrganize=We have to organize ourselves with another village, that is where we are heading. -MsgClonkPoorGuy=Look at this poor guy, his cabin burned down. What has happened? -MsgHomelessRobbers=Some robbers stole my goods and burned down my cabin. -MsgClonkWhere=That is terrible. Do you know where they are? -MsgHomelessLocation=Well they went into the cave ahead, where they also came from. -MsgVillageHeadTeachThem=Well, %s here will teach them a lesson. -MsgHomelessHappy=That would make me very happy. +MsgVillageHeadAnnoyed=Die dunkle Fraktion ist zu weit gegangen. Wir müssen zurückschlagen. +MsgClonkHowToStrike=Wie sollen wir zurückschlagen? Das sind so viele und die sind bis an die Zähne bewaffnet. +MsgVillageHeadOrganize=Wir müssen uns mit anderen Dörfern zusammenschließen. Deshalb sind wir jetzt unterwegs zu einem. +MsgClonkPoorGuy=Schau dir diesen armen Kerl an. Seine Hütte ist abgebrannt. Was ist passiert? +MsgHomelessRobbers=Räuber haben mir alles genommen und mein Haus in Brand gesetzt. +MsgClonkWhere=Wie schrecklich. Weißt du, wo die Räuber jetzt sind? +MsgHomelessLocation=Die verstecken sich in der Höhle, wo sonst auch. +MsgVillageHeadTeachThem=Nun, %s hier wird denen eine Lektion erteilen. +MsgHomelessHappy=Das wäre toll. # Sequence: outro -MsgClonkSafe=%s it is safe down here! -MsgVillageHeadComing=Okay, I am coming down. -MsgVillageHeadTakeElevator=Let's take this elevator up to the surface. -MsgVillageHeadPassedCave=Thanks to you we manage to pass this cave and we can safely make it to the other village! \ No newline at end of file +MsgClonkSafe=%s, es ist jetzt sicher hier unten! +MsgVillageHeadComing=Gut, ich bin auf dem Weg. +MsgVillageHeadTakeElevator=Lass uns mit dem Fahrstuhl zur Oberfläche fahren. +MsgVillageHeadPassedCave=Dank dir sind wir sicher durch diese Höhle gekommen und können nun sicher zum nächsten Dorf gelangen! \ No newline at end of file From 4f7688810b2a7744e72d9cec6c20d02090d60a4b Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 20:34:49 +0100 Subject: [PATCH 11/36] Tutorial 3: Used the title from Title.txt. --- planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt index de8966760..0bd0c688e 100644 --- a/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial03.ocs/DescDE.txt @@ -1,4 +1,4 @@ -Transport & Aufbau +Tragen & Bauen Rüdiger hat dich zu einem Ort namens Wipfdort geführt, ein kleines Dorf voller Wipfe. Endlich hat er seine Freunde gefunden und ist fröhlich. Die Dorfbewohner von Wipfdorf aber brauchen Hilfe. Ihr Dorf wurde von einer dunklen Fraktion angegriffen, die gedroht hat, all ihre Wipfe zu entführen. Den ersten Angriff konnten Sie abwehren, aber ihr Dorf wurde dabei zerstört. Du hast dich entschlossen, den Bewohnern zu helfen, da Rüdiger sich hier wohl zu fühlen scheint. From b30fea4f7d935b0aed851fc5179a0f55ec27e11f Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 20:35:02 +0100 Subject: [PATCH 12/36] Tutorial 7: German translation. --- .../Tutorials.ocf/Tutorial07.ocs/DescDE.txt | 8 ++++---- .../Tutorial07.ocs/StringTblDE.txt | 14 ++++++------- .../Tutorial07.ocs/System.ocg/StringTblDE.txt | 20 +++++++++---------- planet/Tutorials.ocf/Tutorial07.ocs/Title.txt | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial07.ocs/DescDE.txt index 1338813b6..ff34a45f1 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial07.ocs/DescDE.txt @@ -1,7 +1,7 @@ -Airborne Mining +Luftbergbau -Up high in the skies, far above the stronghold of the evil wipf faction, one of the villagers has an airbase. The head of Wipfville has asked you to help him mine gems from the sky islands over there. The clunkers can help the villagers hire some men in their fight against the evil faction. +Weit oben im Himmel, weit über der Feste der Dunkelwipf-Fraktion, hat einer der Dorfbewohner eine Himmelsbasis. Das Dorfoberhaupt hat dich gebeten, beim Abbau der Edelsteine auf diesen Inseln zu helfen. Die dadurch erwirtschafteten Clunker können helfen, einige Clonks zum Kampf geben die Dunkelwipf-Fraktion anzuwerben. -Goal: Mine some gems from the sky islands. +Ziel: Baue Edelsteine von den Himmelsinseln ab. -Tutorial explains: Airship, rope ladder, selling valuables. +Lernrunde erklärt: Luftschiff, Strickleiter, Verkauf von Wertsachen. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial07.ocs/StringTblDE.txt index 0a2856cd5..d57077616 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial07.ocs/StringTblDE.txt @@ -1,6 +1,6 @@ # Goal Description MsgGoalName=Edelsteine abbauen -MsgGoalDescription=Find and mine the gem stalactite, then sell the gems at the flagpole. +MsgGoalDescription=Finde den Edelstein-Stalaktit, baue Edelsteine ab und verkaufe sie bei der Flagge. # Dialogue options MsgNextTutorial=&Nächste Lernrunde @@ -9,9 +9,9 @@ MsgRepeatRound=&Lernrunde wiederholen MsgRepeatRoundDesc=Diese Lernrunde wiederholen. # Tutorial messages -MsgTutorialFindRubies=You are high up in the sky in an area with several sky islands. Talk to the pilot for some advice about the area and then take the airship and find the ruby stalactite hanging from one of the islands. You can grab the airship with [%s] and then steer it with %s. -MsgTutorialParkAirship=Ah you found the ruby stalactite. Now it is time to blast it to gems! Park your airship in front of the rope ladders over there. -MsgTutorialLadderJump=Good, now your companion will control the airship and you can jump to the ruby stalactite. Jump towards a hanging rope ladder and you will automatically grab it. You can switch sides or let go of the ladder by pressing the movement keys [%s]/[%s]. Instead of letting go you can also jump off the ladder if you press the movement key corresponding to the side your a hanging on while climbing up. -MsgTutorialBlastGems=Okay, you can now plant some dynamite sticks on the stalactite and get back on board of the airship. Then fuse the dynamite to blast the stalactite. -MsgTutorialCollectGems=Perfect blast! Now collect at least five gems and sell them back at the flagpole, you can sell them by transfering them into the flagpole using the interaction menu. If you are lazy you can use the teleglove to pick up the gems from the sky island below. -MsgTutorialCompleted=Well done, you have stolen enough rubies from the evil wipf faction to hire some clonks for your attack on the faction's stronghold. \ No newline at end of file +MsgTutorialFindRubies=Schau an, du bist weit oben auf einigen Himmelsinseln. Sprich mit dem Piloten und frag ihn nach Hinweisen über diese Gegend. Nimm danach das Luftschiff und such den Edelstein-Stalaktit, der von einer Himmelsinsel hängen soll. Du kannst das Luftschiff mit [%s] anfassen und mit %s steuern. +MsgTutorialParkAirship=Ah, du hast den Stalaktit gefunden. Es ist Zeit, Edelsteine herauszusprengen! Parke das Luftschiff vor den Strickleitern dort. +MsgTutorialLadderJump=Gut. Dein Kollege wird ab jetzt das Luftschiff steuern. Du kannst bist zum Rubingestein springen. Springe an eine Strickleiter und dein Clonk wird sich automatisch festhalten. Mit den Bewegungstasten ([%s]/[%s]) kannst du an den Leitern die Seiten wechseln oder sie loslassen. Wenn du nach oben kletterst und die Richtungstasten der Richtung drückst, an der du gerade an einer Leiter hängst, kannst du auch abspringen. +MsgTutorialBlastGems=Gut, jetzt kannst du einige Dynamitstangen an dem Stalaktit befestigen und danach zum Luftschiff zurückkehren. Drück danach den Zünder, um den Stalaktiten zu sprengen. +MsgTutorialCollectGems=Eine perfekte Sprengung! Sammle jetzt wenigstens fünf Edelsteine und verkaufe sie an der Flagge. Du kannst Dinge verkaufen, indem du sie im Interaktionsmenü in die Flage ablegst. Wenn du keine Lust hast, alle Edelsteine vom Boden zu sammeln, kannst du auch den Telehandschuh aus der Lore verwenden, um die Brocken von der Himmelsinsel zu heben. +MsgTutorialCompleted=Gut gemacht. Du hast genug Rubine von der Dunkelwipf-Fraktion gestohlen, um damit Clonks für einen Angriff auf die Feste anzuheuern. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial07.ocs/System.ocg/StringTblDE.txt index 08b7f8511..f75e817fc 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/System.ocg/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial07.ocs/System.ocg/StringTblDE.txt @@ -1,13 +1,13 @@ # Dialogue: Pilot -DlgPilotHello=Hello I am %s, have you seen sky islands before? -DlgPilotReply=No, but I have been told they are home to gem stalactites. -DlgPilotBats=Yes, indeed. But you have to be careful, they are also home to bats which become active during night. -DlgPilotAgainstBats=Oh, what can I do against bats? -DlgPilotBowArrow=Well, if they attack you... You can fend them off using the bow and arrows. -DlgPilotHaveBow=I see, well, do you have a bow for me? -DlgPilotArmory=I think you can produce one in the armory together with arrows, I have built an armory on the island to the lower right from here. +DlgPilotHello=Hallo, ich bin %s. Hast du schon einmal Himmelsinseln gesehen? +DlgPilotReply=Nein, aber mir wurde gesagt, dass es hier Edelstein-Stalaktiten gibt. +DlgPilotBats=Ja, das stimmt. Aber ebenso gibt es hier nachtaktive Fledermäuse, vor denen man sich in Acht nehmen muss. +DlgPilotAgainstBats=Oh. Kann man etwas gegen die Fledermäuse tun? +DlgPilotBowArrow=Nun ja, wenn sie angreifen...mit Pfeil und Bogen könntest du sie abwehren. +DlgPilotHaveBow=Ich verstehe. Hast du einen Bogen für mich? +DlgPilotArmory=Nein, aber in der Waffenschmiede kannst du einen Bogen und Pfeile herstellen. Ich habe eine Waffenschmiede auf einer unten rechts von hier gebaut. # Messages: Pilot -DlgPilotGem0=Yeah a gem! -DlgPilotGem1=I'll take that gem! -DlgPilotGem2=That gem is mine! \ No newline at end of file +DlgPilotGem0=Yeah, ein Edelstein! +DlgPilotGem1=Den Stein nehme ich! +DlgPilotGem2=Der Stein gehört mir! \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/Title.txt b/planet/Tutorials.ocf/Tutorial07.ocs/Title.txt index 41907eefe..6cdbcd8d4 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/Title.txt +++ b/planet/Tutorials.ocf/Tutorial07.ocs/Title.txt @@ -1,2 +1,2 @@ -DE:Luftmine +DE:Luftbergbau US:Airborne Mining \ No newline at end of file From 05b714a75828601a6976514a43971802a52bc39e Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 20:35:12 +0100 Subject: [PATCH 13/36] Tutorial 8: German translation. --- .../Tutorials.ocf/Tutorial08.ocs/DescDE.txt | 8 ++-- .../Tutorial08.ocs/StringTblDE.txt | 26 ++++++------ .../Tutorial08.ocs/System.ocg/StringTblDE.txt | 42 +++++++++---------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial08.ocs/DescDE.txt b/planet/Tutorials.ocf/Tutorial08.ocs/DescDE.txt index d7ed3bc6b..a7fd29ef8 100644 --- a/planet/Tutorials.ocf/Tutorial08.ocs/DescDE.txt +++ b/planet/Tutorials.ocf/Tutorial08.ocs/DescDE.txt @@ -1,7 +1,7 @@ Wasserwerk - -You were sent to the mine where the villagers of Wipfville get their metal supplies. Unfortunately the mine got flooded as a dike broke during a recent disaster. The chief of the mining operation tells you the mine is still in operation, but they have trouble getting the metal out of the mine. This is where you come in: help the miners salvage their lorries filled with metal. -Goal: Salvage the lorry from the flooded mine. +Du wurdest zu der Mine geschickt, aus der die Bewohner von Wipfdorf ihre Metallvorräte beziehen. Dummerweise wurde die Mine bei einem katastrophalen Dammbruch geflutet. Der Vorarbeiter der Minenarbeiter berichtet, dass die Mine noch in Betrieb ist, aber das Metall nicht mehr aus der Mine geschafft werden kann. Hier ist deine Aufgabe: Hilf den Minenarbeitern die Loren mit dem Metall zu bergen. -Tutorial explains: Pump and liquids, elevator, wall kits. +Ziel: Berge die Loren aus der überfluteten Mine. + +Lernrunde erklärt: Pumpe und Flüssigkeiten, Fahrstuhl, Wandbausatz. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial08.ocs/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial08.ocs/StringTblDE.txt index ac6358816..182c0a4f2 100644 --- a/planet/Tutorials.ocf/Tutorial08.ocs/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial08.ocs/StringTblDE.txt @@ -1,6 +1,6 @@ # Goal description -MsgGoalName=Salvage lorry -MsgGoalDescription=Locate the lorry with metal and transport it back to the surface. +MsgGoalName=Lorenbergung +MsgGoalDescription=Finde die Lore mit Metall und bringe sie zur Oberfläche. # Dialogue options MsgNextTutorial=&Nächste Lernrunde @@ -9,14 +9,14 @@ MsgRepeatRound=&Lernrunde wiederholen MsgRepeatRoundDesc=Diese Lernrunde wiederholen. # Tutorial messages -MsgTutorialFloodedMines=You are right in front of the mine entrance. Talk to the mine operator standing in front of the pump to find out how you can help. -MsgTutorialConnectPipe=Get a pipe from the chest. Pipes can be connected to the pump by using them in front of the pump, the first pipe will be the source and the second pipe will be the drain. Connect the pipe to the pump. More options for the pump are found in the interaction menu. -MsgTutorialFindMetalLorry=Good, this way the pump will take water from the pipe and drop it right in front of itself since no drain pipe is connected. You can then keep the pipe in your inventory and use it to pump water from the mine. Now enter the mine by following the path of the elevator and locate the lorry with the metal. Remember to catch your breath every once in a while. -MsgTutorialMoveLorry=Okay, let's move the lorry out of the mine to the flooded elevator shaft. Push it into the water, maybe it will make its way to where the elevator case would touch the shaft's ground. -MsgTutorialCallElevator=Hm, that did not work. Swim to the place where the elevator case would reach the ground and call it by pressing [%s]. It will take a few seconds for it to make its way down. In the meanwhile talk to the NPC standing in front of the chemical lab, maybe he has some idea. -MsgTutorialProduceWallKit=That was not very helpful. The problem seems to be getting the lorry onto the elevator case. If one could somehow close of a small part around the elevator case to remove the water with the pump. Wait a second... One could use a wall kit for this. Produce one in the workshop. -MsgTutorialCloseMineShaft=Take the wall kit and a dynamite box from the chemical lab. Then make sure the elevator is at the bottom of the flooded shaft and close off the gap above the elevator with wall kits. To place a wall kit, select it in the inventory and hold the left mouse button. Then position the wall kit by moving the mouse cursor and place it by releasing the button. -MsgTutorialWaitAndMoveLorry=Perfect, now place the pipe in near the elevator case and wait for the lower part of the shaft to be drained, then move the lorry into the case. -MsgTutorialBlastWall=Good, now that the lorry is in the elevator case we can blast the the wall again to allow the elevator to move up to the surface. Take a dynamite box from the chemical lab and place all five dynamite sticks at the indicated location, then move a way and use the igniter to blast it. -MsgTutorialSwimUp=Now you can swim back up to the surface again and call the elevator case when you are at the top. Then move the metal lorry to the chief of the mine and talk to him. -MsgTutorialCompleted=Well done, you see that in this game you sometimes need nifty tricks to solve difficult problems! Now the villagers have enough metal to produce weapons and you are one step closer to mounting an attack against the evil faction. \ No newline at end of file +MsgTutorialFloodedMines=Du befindest direkt vor dem Mineneingang. Sprich mit dem Vorarbeiter, der vor der Pumpe steht und finde heraus, wie du helfen kannst. +MsgTutorialConnectPipe=Nimm ein Rohr aus der Kiste. Rohre können mit Pumpen verbunden werden, indem man sie benutzt, während man vor der Pumpe steht. Das erste angeschlossene Rohr ist der Zulauf, das zweite der Ablauf. Verbinde das Rohr jetzt mit der Pumpe. Weitere Optionen der Pumpe kannst du im Interaktionsmenü finden. +MsgTutorialFindMetalLorry=Gut. Jetzt wird die Pumpe Wasser aus dem Zulauf pumpen und direkt vor sich herauspumpen, da noch kein Ablauf verbunden ist. Du kannst das Rohr im Inventar behalten und es benutzen, um Wasser aus der Mine zu pumpen. Tauche jetzt hinunter zur Mine, indem du dem Pfad des Fahrstuhls folgst. Mach die Lore mit dem Metall ausfindig. Denke auch daran, regelmäßig Luft zu holen! +MsgTutorialMoveLorry=Gut, bringe die Lore jetzt aus der Mine in den gefluteten Fahrstuhlschacht. Schiebe die Lore ins Wasser, vielleicht rollt sie ja genau dorthin, wo der Fahrstuhlkorb den Schachtboden erreicht. +MsgTutorialCallElevator=Hm, das hat nicht funktioniert. Schwimme zu dem Ort, wo der Fahrstuhlkorb den Schachtboden erreichen würde und rufe den Korb, indem du [%s] drückst. Der Korb wird einige Zeit brauchen, bis der Boden des Schachtes erreicht hat. Währenddessen könntest du mit dem Clonk vor dem Chemielabor reden, vielleicht hat der ja noch Ideen. +MsgTutorialProduceWallKit=Das war nicht sehr hilfreich. Das Problem hier, dass die Lore in den Fahrstuhlkorb hinein muss. Wenn es nur irgendwie möglich wäre, den kleinen Bereich um den Fahrstuhlkorb zu versiegeln und das Wasser mit der Pumpe zu entfernen. Warte mal kurz...dafür wäre ein Wandbausatz genau das richtige. Du solltest davon einen in der Werkstatt herstellen. +MsgTutorialCloseMineShaft=Nimm den Wandbausatz und die Dynamitkiste aus dem Chemielabor. Versichere dich, dass der Fahrstuhlkorb wirklich am Boden des gefluteten Schachtes ist. Benutze dann den Wandbausatz, um den Schacht zu verschließen. Wähle dazu den Wandbausatz in deinem Inventar aus und halte die linke Maustaste gedrückt. Positioniere die Wand, indem du den Mauszeiger bewegst und erstelle sie durch Loslassen der Taste. +MsgTutorialWaitAndMoveLorry=Perfekt! Bring den Zulauf der Pumpe jetzt zum Fahrstuhlkorb und warte, bis der Schacht leergepumpt wurde. Danach kannst du die Lore auf den Fahrstuhlkorb schieben. +MsgTutorialBlastWall=Gut, jetzt wo die Lore auf dem Korb steht, kannst du die Wand nach oben wieder aufsprengen, damit der Fahrstuhl an die Oberfläche zurückkehren kann. Nimm die Dynamitkiste (aus dem Chemielabor) und platziere die Dynamitstangen an der angezeigten Stelle. Gehe danach in Sicherheit und zünde das Dynamit! +MsgTutorialSwimUp=Jetzt kannst du an die Oberfläche zurückschwimmen. Wenn du oben angelangt bist, rufe den Fahrstuhlkorb. Schiebe die Lore zum Vorarbeiter und sprich mit ihm. +MsgTutorialCompleted=Sehr gut. Wie du siehst, braucht man manchmal ein paar geschickte Tricks, um Probleme in diesem Spiel zu lösen. Jetzt wo die Dorfbewohner genug Metall haben, bist du einen Schritt näher, um die Dunkelwipffraktion anzugreifen. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial08.ocs/System.ocg/StringTblDE.txt b/planet/Tutorials.ocf/Tutorial08.ocs/System.ocg/StringTblDE.txt index 04bcc107c..3fe27cadb 100644 --- a/planet/Tutorials.ocf/Tutorial08.ocs/System.ocg/StringTblDE.txt +++ b/planet/Tutorials.ocf/Tutorial08.ocs/System.ocg/StringTblDE.txt @@ -1,26 +1,26 @@ # Dialogue: Chief -DlgChiefHello=Hello I am chief of operations of the mines below. But we had a disaster and our dike protecting us from the sea broke, and now the mine is flooded. -DlgChiefReply=Oh that is terrible, I came here to buy some metal from you. -DlgChiefNoMetal=Well, we don't have any metal available as we can't transport it out of the mine. My miners are even stuck below. -DlgChiefHelp=Well, what if I help you get the metal out of the mine? -DlgChiefAppreciation=That would be wonderful! You can use this pump I have just built, unfortunately it is not strong enough to empty the sea here, but it may be of help. -DlgChiefReward=Can I get some reward for this? -DlgChiefMetal=Yes, of course. The metal you can get to the surface you may keep, if you tell me how you did it! -DlgChiefLorry=I got the lorry with metal up to the surface! -DlgChiefKeepLorry=That's great, now we can use your method to keep excavating the mine! You may keep the lorry and its contents. -DlgChiefReally=You can really keep the lorry and the metal. +DlgChiefHello=Hallo, ich bin der Vorarbeiter dieser Minenoperation. Es gab eine schlimme Katastrophe, der Damm zum Meer ist gebrochen und die Mine geflutet. +DlgChiefReply=Oh nein, wie schrecklich. Ich bin gekommen, um Metall zu kaufen. +DlgChiefNoMetal=Nun, wir haben gerade kein Metall da. Unser Transportweg aus der Mine ist geflutet. Ich habe noch Leute, die da unten festsitzen. +DlgChiefHelp=Was ist, wenn ich euch helfe, das Metall aus der Mine zu bringen? +DlgChiefAppreciation=Das wäre wundervoll. Du kannst diese Pumpe hier benutzen. Leider ist sie nicht stark genug, um alles Wasser hier wegzupumpen, aber vielleicht ist sie trotzdem nützlich. +DlgChiefReward=Kriege ich eine Belohnung? +DlgChiefMetal=Ja, natürlich. Du darfst alles Metall behalten, wenn du nach hier oben bringst. Wenn du mir sagst, wie du das geschafft hast! +DlgChiefLorry=Hier ist die Lore mit dem Metall! +DlgChiefKeepLorry=Klasse gemacht. Wir können jetzt die gleiche Methode anwenden, um die Mine weiter auszubeuten. Du kannst alles Metall behalten. +DlgChiefReally=Du kannst wirklich die Lore und das Metall behalten. # Dialogue: Miner -DlgMinerGreeting=Hi, I am %s, are you one of the miners? -DlgMinerYes=Yes, I am %s. I have been locked down here for more than a day now. Do you have some food? -DlgMinerNoFood=No, I am sorry. If I find something I'll be back. -DlgMinerYesFood=Yes, I have a %s, you can have it. -DlgMinerEatFood=Thank you for the food. How did you get in here? Do you know a way out? -DlgMinerWayOut=Yes, you can just swim up, along the original path of the elevator. +DlgMinerGreeting=Hallo, ich bin %s. Bist du einer der Minenleute hier? +DlgMinerYes=Ja. Mein Name ist %s. Ich bin jetzt seit über einem Tag hier unten eingesperrt. Hast du vielleicht etwas zu essen? +DlgMinerNoFood=Nein, tut mir leid. Wenn ich etwas finde, komme ich wieder. +DlgMinerYesFood=Ja, ich habe hier etwas %s. Kannst du haben. +DlgMinerEatFood=Danke für das Essen! Wie bist du eigentlich hier herunter gekommen? Gibt es einen Weg nach oben? +DlgMinerWayOut=Ja, man kann einfach nach oben schwimmen, entlang des Fahrstuhlschachtes. # Dialogue: Explosive Expert -DlgExpertHello=Hi I am looking for a way to get lorries out of this mine. Can you help? -DlgExpertNoHelp=I have no clue how to achieve that. I only know about explosives. -DlgExpertWhatExplosives=Oh explosives! What kind do you have and can I use them? -DlgExpertUseExplosives=I have dynamite. Please use whatever you can find in the chemical lab or the workshop for your endeavour. -DlgExpertThanks=Thanks a lot. +DlgExpertHello=Hallo, ich suche nach einer Möglichkeit, um Loren an die Oberfläche zu bringen. Kannst du mir helfen? +DlgExpertNoHelp=Dazu fällt mir gar nichts ein. Ich bin hier für Sprengstoffe zuständig. +DlgExpertWhatExplosives=Oh, Sprengstoffe! Hast du welche, die ich verwenden kann? +DlgExpertUseExplosives=Dynamit ist da. Nimm das, was du im Chemielabor oder in der Werkstatt findest. +DlgExpertThanks=Vielen Dank. From f0a03b303bc75a93804f690d5a3566d33d51d117 Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Tue, 12 Jan 2016 22:01:47 +0100 Subject: [PATCH 14/36] Fixed ownership of buildings. I must be mad. This script failed a lot of times. I had to add those brackets. Even then, the first run failed, the buildings were still ownerless. What is this sorcery. --- planet/Worlds.ocf/Clonkomotive.ocs/Script.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/planet/Worlds.ocf/Clonkomotive.ocs/Script.c b/planet/Worlds.ocf/Clonkomotive.ocs/Script.c index e06559156..e0f25b1d1 100644 --- a/planet/Worlds.ocf/Clonkomotive.ocs/Script.c +++ b/planet/Worlds.ocf/Clonkomotive.ocs/Script.c @@ -76,15 +76,17 @@ public func InitializePlayer(plr) GivePlayerAirKnowledge(plr); GivePlayerSpecificKnowledge(plr, [WoodenBridge]); RemovePlayerSpecificKnowledge(plr, [WallKit]); - + // Give the player the elementary base materials and some tools. GivePlayerElementaryBaseMaterial(plr); GivePlayerToolsBaseMaterial(plr); // Take over small village at the start of the map. - for (var structure in FindObjects(Find_Func("IsFlagpole"))) - structure->SetOwner(plr); - + for (var building in FindObjects(Find_Or(Find_ID(Sawmill), Find_ID(WindGenerator), Find_ID(ToolsWorkshop)))) + { + building->SetOwner(plr); + } + // Set zoom range. SetPlayerZoomByViewRange(plr, 600, nil, PLRZOOM_Direct | PLRZOOM_LimitMax); SetPlayerViewLock(plr, true); From 82b090c7ca8bc68cdf8c79cf9eb1a73eecd1f6d6 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 12 Jan 2016 22:17:32 +0100 Subject: [PATCH 15/36] producer library does not request power if producer is not a consumer (#1602) --- .../Structures.ocd/Producer.ocd/Script.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/planet/Objects.ocd/Libraries.ocd/Structures.ocd/Producer.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Structures.ocd/Producer.ocd/Script.c index 717448f60..5c377311c 100644 --- a/planet/Objects.ocd/Libraries.ocd/Structures.ocd/Producer.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Structures.ocd/Producer.ocd/Script.c @@ -619,8 +619,10 @@ protected func FxProcessProductionStart(object target, proplist effect, int temp // But first hold the production until the power system gives it ok. // Always register the power request even if power need is zero. The // power network handles this correctly and a producer may decide to - // change its power need during production. - RegisterPowerRequest(this->PowerNeed()); + // change its power need during production. Only do this for producers + // which are power consumers. + if (this->~IsPowerConsumer()) + RegisterPowerRequest(this->PowerNeed()); return FX_OK; } @@ -659,8 +661,6 @@ protected func FxProcessProductionTimer(object target, proplist effect, int time // Add effect interval to production duration. effect.Duration += effect.Interval; - //Log("Production in progress on %i, %d frames, %d time", effect.Product, effect.Duration, time); - // Check if production time has been reached. if (effect.Duration >= ProductionTime(effect.Product)) return FX_Execute_Kill; @@ -673,21 +673,20 @@ protected func FxProcessProductionStop(object target, proplist effect, int reaso if (temp) return FX_OK; - // no need to consume power anymore - // always unregister even if there's a queue left to process, because OnNotEnoughPower relies on it - // and it gives other producers the chance to get some power - UnregisterPowerRequest(); + // No need to consume power anymore. Always unregister even if there's a queue left to + // process, because OnNotEnoughPower relies on it and it gives other producers the chance + // to get some power. Do not unregister if this producer does not consumer power. + if (this->~IsPowerConsumer()) + UnregisterPowerRequest(); if (reason != 0) return FX_OK; // Callback to the producer. - //Log("Production finished on %i after %d frames", effect.Product, effect.Duration); this->~OnProductionFinish(effect.Product); // Create product. var product = CreateObject(effect.Product); OnProductEjection(product); - return FX_OK; } From ba2cf8f096344d689636a5630a4a66fd3b498cfa Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Tue, 12 Jan 2016 22:18:18 +0100 Subject: [PATCH 16/36] fix incorrect clipping in script GUI windows (#1592) I am not sure why the 'isMainWindow' was there. It wasn't there in 7319f7b3cc5f1ffb1fea28fd7ca84b482c6052ff and got introduced in the major rework in 049088be78db99b3aa6833847801c8e8c13ae2d7 - I guess it was just an oversight that was not noticed because usually the UI windows have the text or other things that need to scroll on a deeper level. Anyway, checking whether the window is a script-root window does not make any sense as far as I can see now. --- src/gui/C4ScriptGuiWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/C4ScriptGuiWindow.cpp b/src/gui/C4ScriptGuiWindow.cpp index a7e8dd1df..785e16844 100644 --- a/src/gui/C4ScriptGuiWindow.cpp +++ b/src/gui/C4ScriptGuiWindow.cpp @@ -1893,7 +1893,7 @@ bool C4ScriptGuiWindow::Draw(C4TargetFacet &cgo, int32_t player, C4Rect *current bool C4ScriptGuiWindow::GetClippingRect(int32_t &left, int32_t &top, int32_t &right, int32_t &bottom) { const int32_t &style = props[C4ScriptGuiWindowPropertyName::style].GetInt(); - if (IsRoot() || isMainWindow || (style & C4ScriptGuiWindowStyleFlag::NoCrop)) + if (IsRoot() || (style & C4ScriptGuiWindowStyleFlag::NoCrop)) return false; if (pScrollBar->IsVisible()) From aec5184cf24ae26e96056c67e680841b4adc6e21 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 12 Jan 2016 22:43:35 +0100 Subject: [PATCH 17/36] locomotive in clonkomotive accepts metal barrels as well --- planet/Worlds.ocf/Clonkomotive.ocs/Locomotive.ocd/Script.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/planet/Worlds.ocf/Clonkomotive.ocs/Locomotive.ocd/Script.c b/planet/Worlds.ocf/Clonkomotive.ocs/Locomotive.ocd/Script.c index 3fda40e66..f1019aa67 100644 --- a/planet/Worlds.ocf/Clonkomotive.ocs/Locomotive.ocd/Script.c +++ b/planet/Worlds.ocf/Clonkomotive.ocs/Locomotive.ocd/Script.c @@ -138,8 +138,8 @@ private func UpdateFuel() private func GetBarrel() { - for (var barrel in FindObjects(Find_ID(Barrel), Find_Container(this))) - if (barrel->GetFillLevel()) + for (var barrel in FindObjects(Find_Func("IsBarrel"), Find_Container(this))) + if (barrel->GetFillLevel() > 0) return barrel; return; } @@ -177,7 +177,7 @@ public func IsContainer() { return true; } protected func RejectCollect(id object_id) { - if (object_id == Coal || object_id == Barrel) + if (object_id == Coal || object_id == Barrel || object_id == MetalBarrel) return false; return true; } From a7da208d851d1c970ab78ab7d507e2e6e5acaada Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 12 Jan 2016 23:07:36 +0100 Subject: [PATCH 18/36] fix next mission for tutorials 5 and 8 --- planet/Tutorials.ocf/Tutorial05.ocs/Script.c | 2 +- planet/Tutorials.ocf/Tutorial08.ocs/Script.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial05.ocs/Script.c b/planet/Tutorials.ocf/Tutorial05.ocs/Script.c index a964d4935..ca98f1ed7 100644 --- a/planet/Tutorials.ocf/Tutorial05.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial05.ocs/Script.c @@ -36,7 +36,7 @@ protected func OnGoalsFulfilled() // Achievement: Tutorial completed. GainScenarioAchievement("TutorialCompleted", 3); // Dialogue options -> next round. - SetNextMission("Tutorials.ocf\\Tutorial06.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); + SetNextMission("Tutorials.ocf\\Tutorial07.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); // Normal scenario ending by goal library. return false; } diff --git a/planet/Tutorials.ocf/Tutorial08.ocs/Script.c b/planet/Tutorials.ocf/Tutorial08.ocs/Script.c index 7520452e9..4279d75bc 100644 --- a/planet/Tutorials.ocf/Tutorial08.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial08.ocs/Script.c @@ -37,7 +37,7 @@ protected func OnGoalsFulfilled() // Achievement: Tutorial completed. GainScenarioAchievement("TutorialCompleted", 3); // Dialogue options -> next round. - SetNextMission("Tutorials.ocf\\Tutorial09.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); + //SetNextMission("Tutorials.ocf\\Tutorial09.ocs", "$MsgNextTutorial$", "$MsgNextTutorialDesc$"); // Normal scenario ending by goal library. return false; } From 46ad28ea652fad34814a866f3b9c305aa7cc6faa Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Tue, 12 Jan 2016 23:16:57 +0100 Subject: [PATCH 19/36] tutorial guide: don't scroll portrait with text ..by putting the text into another subwindow. Might be good to "fix" (it's intended but possibly not wise) that in the engine, but not right now before the release, because it could introduce new bugs. --- .../Tutorial.ocd/TutorialGuide.ocd/Script.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial.ocd/TutorialGuide.ocd/Script.c b/planet/Tutorials.ocf/Tutorial.ocd/TutorialGuide.ocd/Script.c index 024618b29..969f927c9 100644 --- a/planet/Tutorials.ocf/Tutorial.ocd/TutorialGuide.ocd/Script.c +++ b/planet/Tutorials.ocf/Tutorial.ocd/TutorialGuide.ocd/Script.c @@ -145,11 +145,15 @@ private func InitializeMenu() }; var prop_text = { - Target = this, - ID = 2, Left = Format("0%%%s", ToEmString(10 * menu_height + text_margin)), Right = Format("100%%%s", ToEmString(- 5 * menu_height - text_margin)), - Text = nil, + // Wrap the text again to scroll only one window instead of also scrolling e.g. the portrait. + text = + { + Target = this, + ID = 2, + Text = nil, + } }; prop_next = { @@ -218,8 +222,8 @@ private func ShowGuideMenu(int index) private func UpdateGuideMenu(string guide_message, bool has_next, bool has_prev, bool has_close) { // Update the text message entry. - prop_menu.text.Text = guide_message; - GuiUpdate(prop_menu.text, id_menu, prop_menu.text.ID, this); + prop_menu.text.text.Text = guide_message; + GuiUpdateText(guide_message, id_menu, prop_menu.text.text.ID, this); // Update the next/close button. if (has_next || has_close) From 2ce04aa48529636b33dfb4b9a2356f3439d28da9 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Tue, 12 Jan 2016 23:25:24 +0100 Subject: [PATCH 20/36] tell player to park airship a bit higher in tutorial 7 (#1598) --- planet/Tutorials.ocf/Tutorial07.ocs/Script.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/planet/Tutorials.ocf/Tutorial07.ocs/Script.c b/planet/Tutorials.ocf/Tutorial07.ocs/Script.c index 0676bed23..2f85f229d 100644 --- a/planet/Tutorials.ocf/Tutorial07.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial07.ocs/Script.c @@ -257,8 +257,8 @@ global func FxTutorialFindStalactiteTimer(object target, proplist effect, int ti global func FxTutorialAirshipParkedTimer(object target, proplist effect, int timer) { - var clonk = FindObject(Find_ID(Clonk), Find_Distance(30, 700, 230)); - var airship = FindObject(Find_ID(Airship), Find_Distance(30, 700, 230)); + var clonk = FindObject(Find_ID(Clonk), Find_Distance(30, 688, 200)); + var airship = FindObject(Find_ID(Airship), Find_Distance(30, 688, 200)); if (clonk && airship) { var plr = clonk->GetOwner(); @@ -299,7 +299,7 @@ protected func OnGuideMessageShown(int plr, int index) { // Show airship parking space. if (index == 1) - TutArrowShowPos(700, 240, 135); + TutArrowShowPos(688, 220, 135); // Show dynamite placement location. if (index == 3) TutArrowShowPos(800, 200, 60); From 9208f32d16d61160f5995ff80a44e2b53ffd4fbd Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Tue, 12 Jan 2016 18:19:41 -0800 Subject: [PATCH 21/36] Denumerate attached meshes recursively (#1603) Since mesh instances can now be attached to attached definitions, attached definitions need to denumerate pointers recursively to make sure that the reference to the mesh instance is restored correctly. --- src/lib/StdMesh.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/StdMesh.cpp b/src/lib/StdMesh.cpp index e0e1d30a0..c0184980e 100644 --- a/src/lib/StdMesh.cpp +++ b/src/lib/StdMesh.cpp @@ -1030,6 +1030,9 @@ void StdMeshInstance::AttachedMesh::DenumeratePointers() Child->AttachParent = this; MapBonesOfChildToParent(Parent->GetMesh().GetSkeleton(), Child->GetMesh().GetSkeleton()); + + if(OwnChild) + Child->DenumeratePointers(); } bool StdMeshInstance::AttachedMesh::ClearPointers(class C4Object* pObj) From 4357004dbf142030df5dd831d4badc29d8c20583 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Wed, 13 Jan 2016 23:13:44 +0100 Subject: [PATCH 22/36] prevent picking up heavy objects when on grapple rope and draw in rope when picking up heavy object (#1521) Maybe there are other places where the controls libraries should make callbacks to control effects. But that is for the future. --- .../GrappleBow.ocd/Hook.ocd/Script.c | 22 ++++++++++++--- .../CarryHeavyControl.ocd/Script.c | 27 +++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c index 536dcdc3e..85d069449 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/GrappleBow.ocd/Hook.ocd/Script.c @@ -167,7 +167,7 @@ public func OnRopeBreak() /*-- Grapple rope controls --*/ -public func FxIntGrappleControlControl(object target, proplist effect, int ctrl, int x, int y, int strength, repeat, release) +public func FxIntGrappleControlControl(object target, proplist effect, int ctrl, int x, int y, int strength, repeat, release) { // Cancel this effect if clonk is now attached to something. if (target->GetProcedure() == "ATTACH") @@ -337,9 +337,20 @@ public func FxIntGrappleControlTimer(object target, proplist effect, int time) return FX_OK; } -private func Trans_RotX(int rotation, int ox, int oy) +public func FxIntGrappleControlOnCarryHeavyPickUp(object target, proplist effect, object heavy_object) { - return Trans_Mul(Trans_Translate(-ox, -oy), Trans_Rotate(rotation, 0, 0, 1), Trans_Translate(ox, oy)); + // Remove the control effect when a carry-heavy object is picked up. + // The rope will then be drawn in automatically. + RemoveEffect(nil, target, effect); + return; +} + +public func FxIntGrappleControlRejectCarryHeavyPickUp(object target, proplist effect, object heavy_object) +{ + // Block picking up carry-heavy objects when this clonk is hanging on a rope. + if (rope->PullObjects()) + return true; + return false; } public func FxIntGrappleControlStop(object target, proplist effect, int reason, int tmp) @@ -361,6 +372,11 @@ public func FxIntGrappleControlStop(object target, proplist effect, int reason, return FX_OK; } +private func Trans_RotX(int rotation, int ox, int oy) +{ + return Trans_Mul(Trans_Translate(-ox, -oy), Trans_Rotate(rotation, 0, 0, 1), Trans_Translate(ox, oy)); +} + public func RejectWindbagForce() { return true; } // Only the grappler is stored. diff --git a/planet/Objects.ocd/Libraries.ocd/CarryHeavyControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/CarryHeavyControl.ocd/Script.c index 33e3aee76..03c608e85 100644 --- a/planet/Objects.ocd/Libraries.ocd/CarryHeavyControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/CarryHeavyControl.ocd/Script.c @@ -18,10 +18,24 @@ protected func RejectCollect(id objid, object obj) // Carry heavy only gets picked up if none held already if(this.inventory.force_collection && obj->~IsCarryHeavy()) { - // collection of that object magically disabled? + // Collection of that object magically disabled? if(GetEffect("NoCollection", obj)) return true; + + // Do callbacks to control effects to see if the effect blocks picking up a carry heavy object. + var block_carry_heavy = false; + var count = GetEffectCount("*Control*", this), control_effect; + while (count--) + { + control_effect = GetEffect("*Control*", this, count); + if (control_effect && EffectCall(this, control_effect, "RejectCarryHeavyPickUp", obj)) + { + block_carry_heavy = true; + break; + } + } - if(IsCarryingHeavy()) + // Don't pick up if already carrying a heavy object or if it is blocked. + if (IsCarryingHeavy() || block_carry_heavy) { CustomMessage("$TxtHandsFull$", this, this->GetController(), 0, 0, 0xff0000); return true; @@ -120,6 +134,15 @@ public func CarryHeavy(object target) // Update attach stuff this->~OnSlotFull(); + + // Do callbacks to control effects for this clonk that a carry heavy object has been picked up. + var count = GetEffectCount("*Control*", this), control_effect; + while (count--) + { + control_effect = GetEffect("*Control*", this, count); + if (control_effect) + EffectCall(this, control_effect, "OnCarryHeavyPickUp", target); + } return true; } From 4493bfc3ab395789841a5853c4d0ceaacf1da660 Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Thu, 14 Jan 2016 13:03:18 +0100 Subject: [PATCH 23/36] interaction menu: disallow interaction with outside world when contained (#1541) The interaction with IsContainer objects is still flawed in a way: when a lorry is inside a (IsContainer-)hut, you can take the lorry into your hands. Since we don't have that possibility in the normal game, I leave it unchanged for now. However, it is now possible to add a Chest (or a cupboard!) into a WoodenCabin and then store stuff inside of it. --- planet/Objects.ocd/Clonk.ocd/Script.c | 8 ++++++-- .../HUD.ocd/ObjectInteractionMenu.ocd/Script.c | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/planet/Objects.ocd/Clonk.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Script.c index 6a917356d..02f3362e7 100644 --- a/planet/Objects.ocd/Clonk.ocd/Script.c +++ b/planet/Objects.ocd/Clonk.ocd/Script.c @@ -510,8 +510,12 @@ public func OnInteractionMenuOpen(object menu) { _inherited(menu, ...); - var surrounding = CreateObject(Helper_Surrounding); - surrounding->InitFor(this, menu); + // Allow picking up stuff from the surrounding only if not in a container itself. + if (!Contained()) + { + var surrounding = CreateObject(Helper_Surrounding); + surrounding->InitFor(this, menu); + } } /* Mesh transformations */ diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c index f8c81be75..36bdfa26a 100644 --- a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c @@ -147,7 +147,16 @@ func FxIntCheckObjectsStart(target, effect fx, temp) func FxIntCheckObjectsTimer(target, effect fx) { - var new_objects = FindObjects(Find_AtRect(target->GetX() - 5, target->GetY() - 10, 10, 20), Find_NoContainer(), Find_Layer(target->GetObjectLayer()), + // If contained, leave the search area intact, because otherwise we'd have to pass a "nil" parameter to FindObjects (which needs additional hacks). + // This is a tiny bit slower (because the area AND the container have to be checked), but the usecase of contained Clonks is rare anyway. + var container_restriction = Find_NoContainer(); + var container = target->Contained(); + if (container) + { + container_restriction = Find_Or(Find_Container(container), Find_InArray([container])); + } + + var new_objects = FindObjects(Find_AtRect(target->GetX() - 5, target->GetY() - 10, 10, 20), container_restriction, Find_Layer(target->GetObjectLayer()), // Find all containers and objects with a custom menu. Find_Or(Find_Func("IsContainer"), Find_Func("HasInteractionMenu")), // Do not show objects with an extra slot though - even if they are containers. They count as items here. From 579cb7e66ccb7949a980fb90292659dbb1bc1925 Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Thu, 14 Jan 2016 21:40:42 -0500 Subject: [PATCH 24/36] Reset action targets on procedure change #1552 --- src/object/C4Object.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index fbeb3fec1..c46f40048 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -2872,10 +2872,12 @@ bool C4Object::SetAction(C4PropList * Act, C4Object *pTarget, C4Object *pTarget2 if (Act!=LastAction) { Action.Time=0; - // reset action data if procedure is changed + // reset action data and targets if procedure is changed if ((Act ? Act->GetPropertyP(P_Procedure) : -1) != (LastAction ? LastAction->GetPropertyP(P_Procedure) : -1)) Action.Data = 0; + Action.Target = NULL; + Action.Target2 = NULL; } // Set new action From 27f5cdc46100709dadcf5fa190fbe279c9723b0c Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Thu, 14 Jan 2016 21:51:30 -0500 Subject: [PATCH 25/36] Fix black waves when swim timer is executed in same frame as clonk leaves the water. --- .../Clonk.ocd/Animations.ocd/Script.c | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c index fb047a334..236ab4ee0 100644 --- a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c +++ b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c @@ -1022,29 +1022,32 @@ func FxIntSwimTimer(pTarget, effect, iTime) // Swimming else if(!GBackSemiSolid(0, -5)) { - var percent = GetAnimationPosition(GetRootAnimation(5))*200/GetAnimationLength("Swim"); - percent = (percent%100); - if( percent < 40 ) + if (GBackLiquid()) // re-check water background before effects to prevent waves in wrong color { - if(iTime%5 == 0) + var percent = GetAnimationPosition(GetRootAnimation(5)) * 200 / GetAnimationLength("Swim"); + percent = (percent % 100); + if (percent < 40) { - var phases = PV_Linear(0, 7); - if (GetDir() == 1) phases = PV_Linear(8, 15); - var color = GetAverageTextureColor(GetTexture(0, 0)); - var particles = + if (iTime % 5 == 0) { - Size = 16, - Phase = phases, - CollisionVertex = 750, - OnCollision = PC_Die(), - R = (color >> 16) & 0xff, - G = (color >> 8) & 0xff, - B = (color >> 0) & 0xff, - Attach = ATTACH_Front, - }; - CreateParticle("Wave", 0, -4, (RandomX(-5,5)-(-1+2*GetDir())*4)/4, 0, 16, particles); + var phases = PV_Linear(0, 7); + if (GetDir() == 1) phases = PV_Linear(8, 15); + var color = GetAverageTextureColor(GetTexture(0, 0)); + var particles = + { + Size = 16, + Phase = phases, + CollisionVertex = 750, + OnCollision = PC_Die(), + R = (color >> 16) & 0xff, + G = (color >> 8) & 0xff, + B = (color >> 0) & 0xff, + Attach = ATTACH_Front, + }; + CreateParticle("Wave", 0, -4, (RandomX(-5, 5) - (-1 + 2 * GetDir()) * 4) / 4, 0, 16, particles); + } + Sound("Liquids::Splash?"); } - Sound("Liquids::Splash?"); } // Animation speed by X if(effect.animation_name != "Swim") From cd63c06aaf19c54fb14e901ea20d18d8b8884607 Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Thu, 14 Jan 2016 22:25:45 -0500 Subject: [PATCH 26/36] Fix crash when starting tabbed out. --- src/landscape/fow/C4FoWRegion.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/landscape/fow/C4FoWRegion.cpp b/src/landscape/fow/C4FoWRegion.cpp index b4b4d8cf5..62ab400a7 100644 --- a/src/landscape/fow/C4FoWRegion.cpp +++ b/src/landscape/fow/C4FoWRegion.cpp @@ -118,6 +118,9 @@ bool C4FoWRegion::BindFramebuf() pBackSurface->Unlock(); } + // Cannot bind empty surface + if (!pSurface->iTexSize) return false; + // Generate frame buffer object if (!hFrameBufDraw) { From 71b96bc5de57c9fb8b5c1bad0f4f53cdf9834840 Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Thu, 14 Jan 2016 22:30:55 -0500 Subject: [PATCH 27/36] Fix nil pointer access when recovering from over-full inventory --- planet/Objects.ocd/Libraries.ocd/Inventory.ocd/Script.c | 1 + 1 file changed, 1 insertion(+) diff --git a/planet/Objects.ocd/Libraries.ocd/Inventory.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/Inventory.ocd/Script.c index 55c7d5c19..ee3e00e9d 100644 --- a/planet/Objects.ocd/Libraries.ocd/Inventory.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/Inventory.ocd/Script.c @@ -407,6 +407,7 @@ func Ejection(object obj) for(var c = 0; c < ContentsCount(); ++c) { var o = Contents(c); + if (!o) continue; // safety in case callbacks delete some objects if(o->~IsCarryHeavy()) continue; if (GetItemPos(o) == nil) From c8a76ce4509f4d5625492da3816490366b73c42a Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Thu, 14 Jan 2016 22:32:54 -0500 Subject: [PATCH 28/36] Use less annoying swim sounds when swimming on the surface. The "splash" sounded more like the clonk was jumping into the water. --- .../Clonk.ocd/Animations.ocd/Script.c | 2 +- planet/Sound.ocg/Liquids.ocg/Swim1.ogg | Bin 0 -> 17037 bytes planet/Sound.ocg/Liquids.ocg/Swim2.ogg | Bin 0 -> 11198 bytes planet/Sound.ocg/Liquids.ocg/Swim3.ogg | Bin 0 -> 22703 bytes planet/Sound.ocg/authors.txt | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 planet/Sound.ocg/Liquids.ocg/Swim1.ogg create mode 100644 planet/Sound.ocg/Liquids.ocg/Swim2.ogg create mode 100644 planet/Sound.ocg/Liquids.ocg/Swim3.ogg diff --git a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c index 236ab4ee0..8af8202bc 100644 --- a/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c +++ b/planet/Objects.ocd/Clonk.ocd/Animations.ocd/Script.c @@ -1046,7 +1046,7 @@ func FxIntSwimTimer(pTarget, effect, iTime) }; CreateParticle("Wave", 0, -4, (RandomX(-5, 5) - (-1 + 2 * GetDir()) * 4) / 4, 0, 16, particles); } - Sound("Liquids::Splash?"); + Sound("Liquids::Swim?"); } } // Animation speed by X diff --git a/planet/Sound.ocg/Liquids.ocg/Swim1.ogg b/planet/Sound.ocg/Liquids.ocg/Swim1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..830425217877db8d9d7db9ea0e61933549f46ec1 GIT binary patch literal 17037 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 Ae*gdg literal 0 HcmV?d00001 diff --git a/planet/Sound.ocg/authors.txt b/planet/Sound.ocg/authors.txt index 803c85429..5c20db36b 100644 --- a/planet/Sound.ocg/authors.txt +++ b/planet/Sound.ocg/authors.txt @@ -31,7 +31,7 @@ Stickinthemud - Clonk (http://www.freesound.org/people/Stickinthemud/sounds/27 Toby Knowles - Fanfare (http://www.freesound.org/people/tobyk/sounds/26198/) ERH - WindLoop (http://www.freesound.org/people/ERH/sounds/34338/) TicTacShutUp - Click (http://www.freesound.org/people/TicTacShutUp/sounds/406/), UI::Confirmed (modified) -CGEffex - Splash1-3 (http://www.freesound.org/people/CGEffex/sounds/98335/) +CGEffex - Splash1-3 (http://www.freesound.org/people/CGEffex/sounds/98335/), Swim1-3 (modified by Sven2 from Splash1-3) Mirors_ - Pshshsh (http://www.freesound.org/people/Mirors_/sounds/81205/) juskiddink - SoftHit1 (http://www.freesound.org/people/juskiddink/sounds/108617/) jenc - BlastMetal (http://www.freesound.org/people/jenc/sounds/511/) From cc613c01f4495f6916421a872adfb6e1197fc3ca Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Fri, 15 Jan 2016 08:14:46 -0500 Subject: [PATCH 29/36] Fix action target reset on same procedure only. --- src/object/C4Object.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index c46f40048..ade3229c6 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -2874,10 +2874,12 @@ bool C4Object::SetAction(C4PropList * Act, C4Object *pTarget, C4Object *pTarget2 Action.Time=0; // reset action data and targets if procedure is changed if ((Act ? Act->GetPropertyP(P_Procedure) : -1) - != (LastAction ? LastAction->GetPropertyP(P_Procedure) : -1)) + != (LastAction ? LastAction->GetPropertyP(P_Procedure) : -1)) + { Action.Data = 0; - Action.Target = NULL; - Action.Target2 = NULL; + Action.Target = NULL; + Action.Target2 = NULL; + } } // Set new action From 4eddeba9aa211eee3df3c21cb533e81a7406b19a Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Fri, 15 Jan 2016 08:53:00 -0500 Subject: [PATCH 30/36] Fix crash when drawing zero-sized viewports (may happen during editor viewport initialization) --- src/game/C4Viewport.cpp | 16 ++++++++++++++-- src/landscape/fow/C4FoWRegion.cpp | 11 ++++++----- src/landscape/fow/C4FoWRegion.h | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/game/C4Viewport.cpp b/src/game/C4Viewport.cpp index d78a3990d..934a84eed 100644 --- a/src/game/C4Viewport.cpp +++ b/src/game/C4Viewport.cpp @@ -240,9 +240,21 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawGame, bool fDrawOverlay) // Region in which the light is calculated // At the moment, just choose integer coordinates to surround the viewport const C4Rect lightRect(vpRect); - pFoW->Update(lightRect, vpRect); + if (!lightRect.Wdt || !lightRect.Hgt) + { + // Do not bother initializing FoW on empty region; would cause errors in drawing proc + pFoW = NULL; + } + else + { + pFoW->Update(lightRect, vpRect); - pFoW->Render(); + if (!pFoW->Render()) + { + // If FoW init fails, do not set it for further drawing + pFoW = NULL; + } + } } pDraw->SetFoW(pFoW); diff --git a/src/landscape/fow/C4FoWRegion.cpp b/src/landscape/fow/C4FoWRegion.cpp index 62ab400a7..fe0ae785c 100644 --- a/src/landscape/fow/C4FoWRegion.cpp +++ b/src/landscape/fow/C4FoWRegion.cpp @@ -181,7 +181,7 @@ void C4FoWRegion::Update(C4Rect r, const FLOAT_RECT& vp) ViewportRegion = vp; } -void C4FoWRegion::Render(const C4TargetFacet *pOnScreen) +bool C4FoWRegion::Render(const C4TargetFacet *pOnScreen) { #ifndef USE_CONSOLE // Update FoW at interesting location @@ -191,24 +191,24 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen) if (pOnScreen) { pFoW->Render(this, pOnScreen, pPlayer, pGL->GetProjectionMatrix()); - return; + return true; } // Set up shader. If this one doesn't work, we're really in trouble. C4Shader *pShader = pFoW->GetFramebufShader(); assert(pShader); - if (!pShader) return; + if (!pShader) return false; // Create & bind the frame buffer pDraw->StorePrimaryClipper(); if(!BindFramebuf()) { pDraw->RestorePrimaryClipper(); - return; + return false; } assert(pSurface && hFrameBufDraw); if (!pSurface || !hFrameBufDraw) - return; + return false; // Set up a clean context glViewport(0, 0, pSurface->Wdt, pSurface->Hgt); @@ -321,6 +321,7 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen) OldRegion = Region; #endif + return true; } void C4FoWRegion::GetFragTransform(const C4Rect& clipRect, const C4Rect& outRect, float lightTransform[6]) const diff --git a/src/landscape/fow/C4FoWRegion.h b/src/landscape/fow/C4FoWRegion.h index f9d82eee6..dc365c9d6 100644 --- a/src/landscape/fow/C4FoWRegion.h +++ b/src/landscape/fow/C4FoWRegion.h @@ -53,7 +53,7 @@ public: #endif void Update(C4Rect r, const FLOAT_RECT& vp); - void Render(const C4TargetFacet *pOnScreen = NULL); + bool Render(const C4TargetFacet *pOnScreen = NULL); // Fills a 2x3 matrix to transform fragment coordinates to light texture coordinates void GetFragTransform(const C4Rect& clipRect, const C4Rect& outRect, float lightTransform[6]) const; From 26084af5021b071d81a4df4c0ebe5ac29733a24f Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Fri, 15 Jan 2016 08:54:03 -0500 Subject: [PATCH 31/36] Fix crash when grab target is lost. --- src/object/C4Object.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index ade3229c6..dbb8a807e 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -2882,7 +2882,6 @@ bool C4Object::SetAction(C4PropList * Act, C4Object *pTarget, C4Object *pTarget2 } } // Set new action - SetProperty(P_Action, C4VPropList(Act)); Action.Phase=Action.PhaseDelay=0; // Set target if specified @@ -3019,12 +3018,10 @@ int32_t C4Object::GetProcedure() const return pActionDef->GetPropertyP(P_Procedure); } -void GrabLost(C4Object *cObj) +void GrabLost(C4Object *cObj, C4Object *prev_target) { // Grab lost script call on target (quite hacky stuff...) - cObj->Action.Target->Call(PSF_GrabLost); - // Also, delete the target from the clonk's action (Newton) - cObj->Action.Target = NULL; + if (prev_target && prev_target->Status) prev_target->Call(PSF_GrabLost); // Clear commands down to first PushTo (if any) in command stack for (C4Command *pCom=cObj->Command; pCom; pCom=pCom->Next) if (pCom->Next && pCom->Next->Command==C4CMD_PushTo) @@ -3042,6 +3039,7 @@ void C4Object::NoAttachAction() if (GetAction()) { int32_t iProcedure = GetProcedure(); + C4Object *prev_target = Action.Target; // Scaling upwards: corner scale if (iProcedure == DFA_SCALE && Action.ComDir != COMD_Stop && ComDirLike(Action.ComDir, COMD_Up)) if (ObjectActionCornerScale(this)) return; @@ -3058,7 +3056,7 @@ void C4Object::NoAttachAction() { if (ObjectActionJump(this,itofix(-1),Fix0,false)) return; } } // Pushing: grab loss - if (iProcedure==DFA_PUSH) GrabLost(this); + if (iProcedure==DFA_PUSH) GrabLost(this, prev_target); // Else jump ObjectActionJump(this,xdir,ydir,false); } @@ -3773,10 +3771,11 @@ void C4Object::ExecAction() if (!Inside(GetX()-sax,-iPushRange,sawdt-1+iPushRange) || !Inside(GetY()-say,-iPushRange,sahgt-1+iPushRange)) { + C4Object *prev_target = Action.Target; // Wait command (why, anyway?) StopActionDelayCommand(this); // Grab lost action - GrabLost(this); + GrabLost(this, prev_target); // Done return; } @@ -3847,10 +3846,12 @@ void C4Object::ExecAction() if (!Inside(GetX()-sax,-iPushRange,sawdt-1+iPushRange) || !Inside(GetY()-say,-iPushRange,sahgt-1+iPushRange)) { + // Remember target. Will be lost on changing action. + C4Object *prev_target = Action.Target; // Wait command (why, anyway?) StopActionDelayCommand(this); // Grab lost action - GrabLost(this); + GrabLost(this, prev_target); // Lose target Action.Target=NULL; // Done From 44f913d0e5c3f8ae07b6cd4fa3a75dcfd26b07fb Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Fri, 15 Jan 2016 08:54:50 -0500 Subject: [PATCH 32/36] Do not display grab interaction when swimming (unless clonk returns true on CanGrabUnderwater callback) --- .../Libraries.ocd/ClonkInteractionControl.ocd/Script.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/planet/Objects.ocd/Libraries.ocd/ClonkInteractionControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/ClonkInteractionControl.ocd/Script.c index 70ac0e0df..1815f63da 100644 --- a/planet/Objects.ocd/Libraries.ocd/ClonkInteractionControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/ClonkInteractionControl.ocd/Script.c @@ -378,6 +378,10 @@ func GetInteractableObjects(array sort) if (interactable->GetOCF() & OCF_Grab) { var priority = 19; + // not if swimming because the grab command cannot really fix that (unlike e.g. scale/hangle) + if (GetProcedure() == "SWIM") + if (!this->~CanGrabUnderwater(interactable)) // unless it's a special clonk that can grab underwater. It needs to define a callback then. + continue; // high priority if already grabbed if (GetActionTarget() == interactable) priority = 0; From 343fb1bb8cced8bfe4b0dcfbbc48150b815a45e6 Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Fri, 15 Jan 2016 19:11:49 +0100 Subject: [PATCH 33/36] set version extra string to false for release --- Version.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Version.txt b/Version.txt index 790b58ad9..0ba51d6c2 100644 --- a/Version.txt +++ b/Version.txt @@ -26,5 +26,5 @@ SET(C4XVER1 7) SET(C4XVER2 0) # Set this variable to any string for pre-release versions, like "alpha" or -# "rc1". Don't supply a value for release versions. -SET(C4VERSIONEXTRA "alpha0") +# "rc1". Don't supply a value (FALSE) for release versions. +SET(C4VERSIONEXTRA FALSE) From 21d8a2a64ad5ed8150353bbe40a5b19571796ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Brammer?= Date: Fri, 15 Jan 2016 20:13:52 +0100 Subject: [PATCH 34/36] Use 32 bit math for +1, ++, -1, etc. in script (#1389) The engine has a few more usages of the operators, but they don't look prone to overflowing. The other operators in Script already used SetInt, which always truncates to 32 bit. --- src/script/C4AulExec.cpp | 4 ++-- src/script/C4Value.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/script/C4AulExec.cpp b/src/script/C4AulExec.cpp index c08120637..43a33c03f 100644 --- a/src/script/C4AulExec.cpp +++ b/src/script/C4AulExec.cpp @@ -295,11 +295,11 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors) break; case AB_Inc: // ++ CheckOpPar(C4V_Int, "++"); - ++(*pCurVal); + pCurVal->SetInt(pCurVal->_getInt() + 1); break; case AB_Dec: // -- CheckOpPar(C4V_Int, "--"); - --(*pCurVal); + pCurVal->SetInt(pCurVal->_getInt() - 1); break; // postfix case AB_Pow: // ** diff --git a/src/script/C4Value.h b/src/script/C4Value.h index 0d34cc461..d2f1634b5 100644 --- a/src/script/C4Value.h +++ b/src/script/C4Value.h @@ -114,7 +114,7 @@ public: void Set(const C4Value &nValue) { Set(nValue.Data, nValue.Type); } - void SetInt(int i) { C4V_Data d; d.Int = i; Set(d, C4V_Int); } + void SetInt(int32_t i) { C4V_Data d; d.Int = i; Set(d, C4V_Int); } void SetBool(bool b) { C4V_Data d; d.Int = b; Set(d, C4V_Bool); } void SetString(C4String * Str) { C4V_Data d; d.Str = Str; Set(d, C4V_String); } void SetArray(C4ValueArray * Array) { C4V_Data d; d.Array = Array; Set(d, C4V_Array); } @@ -129,6 +129,7 @@ public: bool IsIdenticalTo(const C4Value &cmp) const { return GetType()==cmp.GetType() && GetData()==cmp.GetData(); } // Change and set Type to int in case it was nil or bool before + // Use with care: These don't handle int32_t overflow C4Value & operator += (int32_t by) { Data.Int += by; Type=C4V_Int; return *this; } C4Value & operator -= (int32_t by) { Data.Int -= by; Type=C4V_Int; return *this; } C4Value & operator *= (int32_t by) { Data.Int *= by; Type=C4V_Int; return *this; } From 675b9ee050b0ada1617da7f11301d1c3a835846a Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Fri, 15 Jan 2016 21:56:37 +0100 Subject: [PATCH 35/36] Fix weapons not buyable in Gidl/Guardians (#1611). Switch2Items() is probably broken but luckily not used. --- planet/Defense.ocf/Defense.ocd/Homebase.ocd/Script.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/planet/Defense.ocf/Defense.ocd/Homebase.ocd/Script.c b/planet/Defense.ocf/Defense.ocd/Homebase.ocd/Script.c index a7f8d2853..05039318f 100644 --- a/planet/Defense.ocf/Defense.ocd/Homebase.ocd/Script.c +++ b/planet/Defense.ocf/Defense.ocd/Homebase.ocd/Script.c @@ -210,13 +210,13 @@ public func OnBuySelection(int callback_idx) else { // Regular item: Buy into inventory - // Get rid of current item (unless it's the same we already want) + // Get rid of current item + if (last_item) + SellItem(last_item); var item; // Create item if (!item) item = cursor->CreateContents(entry.item); - if (!item) return false; - cursor->Switch2Items(cursor->GetItemPos(last_item), cursor->GetItemPos(item)); - if (last_item) SellItem(last_item); + if (!item) return false; // ??? // for later sale item.GidlValue = entry.cost; // ammo up! From c54d917f7e85cabebe447259f46ca0092469284e Mon Sep 17 00:00:00 2001 From: Clonkonaut Date: Fri, 15 Jan 2016 21:56:57 +0100 Subject: [PATCH 36/36] Deactivate cheats in Gidl/Guardians. We didn't forget!!! --- planet/Defense.ocf/FightForGidl.ocs/Script.c | 8 ++++---- planet/Defense.ocf/Windmill.ocs/Script.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/planet/Defense.ocf/FightForGidl.ocs/Script.c b/planet/Defense.ocf/FightForGidl.ocs/Script.c index f1c9020bc..149d2b368 100644 --- a/planet/Defense.ocf/FightForGidl.ocs/Script.c +++ b/planet/Defense.ocf/FightForGidl.ocs/Script.c @@ -25,10 +25,10 @@ static shared_wealth_remainder; func Initialize() { // dev stuff (we will forget to turn this off for release) - AddMsgBoardCmd("waveinfo", "GameCall(\"ShowWaveInfo\")"); - AddMsgBoardCmd("next", "GameCall(\"SetNextWave\", \"%s\")"); - AddMsgBoardCmd("nextwait", "GameCall(\"SetNextWave\", \"%s\", true)"); - AddMsgBoardCmd("scrooge", "GameCall(\"DoWealthForAll\", 1000000000)"); + //AddMsgBoardCmd("waveinfo", "GameCall(\"ShowWaveInfo\")"); + //AddMsgBoardCmd("next", "GameCall(\"SetNextWave\", \"%s\")"); + //AddMsgBoardCmd("nextwait", "GameCall(\"SetNextWave\", \"%s\", true)"); + //AddMsgBoardCmd("scrooge", "GameCall(\"DoWealthForAll\", 1000000000)"); // Init door dummies g_doorleft.dummy_target = g_doorleft->CreateObject(DoorDummy, -6, 6); g_doorright.dummy_target = g_doorright->CreateObject(DoorDummy, +6, 6); diff --git a/planet/Defense.ocf/Windmill.ocs/Script.c b/planet/Defense.ocf/Windmill.ocs/Script.c index c8fc562b6..c457d2716 100644 --- a/planet/Defense.ocf/Windmill.ocs/Script.c +++ b/planet/Defense.ocf/Windmill.ocs/Script.c @@ -27,10 +27,10 @@ static shared_wealth_remainder; func Initialize() { // dev stuff (we will forget to turn this off for release) - AddMsgBoardCmd("waveinfo", "GameCall(\"ShowWaveInfo\")"); - AddMsgBoardCmd("next", "GameCall(\"SetNextWave\", \"%s\")"); - AddMsgBoardCmd("nextwait", "GameCall(\"SetNextWave\", \"%s\", true)"); - AddMsgBoardCmd("scrooge", "GameCall(\"DoWealthForAll\", 1000000000)"); + //AddMsgBoardCmd("waveinfo", "GameCall(\"ShowWaveInfo\")"); + //AddMsgBoardCmd("next", "GameCall(\"SetNextWave\", \"%s\")"); + //AddMsgBoardCmd("nextwait", "GameCall(\"SetNextWave\", \"%s\", true)"); + //AddMsgBoardCmd("scrooge", "GameCall(\"DoWealthForAll\", 1000000000)"); // Wealth shown at all time GUI_Controller->ShowWealth(); // static variable init