Crash landing intro/dialogues/outro improved for storyline integration.

issue1247
Sven Eberhardt 2014-08-26 16:06:53 +02:00
parent faa9667b66
commit addac19062
12 changed files with 357 additions and 73 deletions

View File

@ -8,6 +8,9 @@
#include Library_Goal
local is_fulfilled = false;
local is_outro_stated = false;
protected func Initialize()
{
return inherited(...);
@ -15,6 +18,9 @@ protected func Initialize()
public func IsFulfilled()
{
// already done?
if (is_fulfilled || is_outro_stated) return is_fulfilled;
// not done yet. do fulfillment check
var cabin = FindObject(Find_ID(WoodenCabin));
if (!cabin)
return false;
@ -22,9 +28,14 @@ public func IsFulfilled()
if (!plane)
return false;
// Plane has to be brought to the wooden cabin.
if (ObjectDistance(plane, cabin) < 80)
return true;
return false;
if (ObjectDistance(plane, cabin) < 200)
{
is_outro_stated = true;
StartSequence("Outro", 0, this, plane);
// wait for end of outro for fulfillment
return false;
}
return false;
}
public func GetDescription(int plr)
@ -51,5 +62,11 @@ public func GetShortDescription(int plr)
return "{{Plane}}"; // TODO
}
public func SetFulfilled()
{
is_fulfilled = true;
return true;
}
/*-- Proplist --*/
local Name = "$Name$";

View File

@ -35,6 +35,11 @@ MapWidth=200,0,64,10000
MapHeight=175,0,40,10000
NewStyleLandscape=2
NoScan=1
AutoScanSideOpen=0
LeftOpen=450
RightOpen=0
TopOpen=1
BottomOpen=0
[Weather]
Climate=0,10,0,100

View File

@ -5,7 +5,7 @@
@authors Sven2, Maikel, ck
*/
static g_is_initialized;
static g_is_initialized, g_has_bought_plans, npc_pyrit;
func DoInit(int first_player)
{
@ -68,6 +68,9 @@ func InitializePlayer(int plr)
crew->SetPosition(x , y);
}
}
// Extra plans from merchant to newly joined players
if (g_has_bought_plans) GiveExtraPlans(plr);
// Give clonks initial tools
for(var index = 0; crew = GetCrew(plr, index); ++index)
@ -83,3 +86,18 @@ func InitializePlayer(int plr)
return true;
}
func OnGameOver()
{
GainMissionAccess("S2Crash");
return true;
}
func GiveExtraPlans(int plr)
{
SetPlrKnowledge(plr, Pump);
SetPlrKnowledge(plr, Pipe);
SetPlrKnowledge(plr, Catapult);
SetPlrKnowledge(plr, Cannon);
return true;
}

View File

@ -2,49 +2,119 @@
#appendto Dialogue
static g_has_bought_plans;
private func Dlg_Merchant_1(object clonk)
func Dlg_Merchant_1(object clonk)
{
MessageBox("$MsgSellPlans$", clonk);
return;
MessageBox("$Merchant1$", clonk);
return true;
}
private func Dlg_Merchant_2(object clonk)
func Dlg_Merchant_2(object clonk)
{
var options = [["$MerchantQPlane$", "Dlg_Merchant_Plane"]];
var i = GetLength(options);
if (g_has_bought_plans)
{
options[i++] = ["$MerchantQPump$", "Dlg_Merchant_Pump"];
options[i++] = ["$MerchantQCatapult$", "Dlg_Merchant_Catapult"];
}
else
{
options[i++] = ["$MerchantQLake$", "Dlg_Merchant_Lake"];
}
options[i++] = ["$MerchantQDone$", "StopDialogue()"];
MessageBox("", clonk, clonk, false, nil, options);
SetDialogueProgress(1);
return true;
}
func Dlg_Merchant_Lake(object clonk)
{
if (g_has_bought_plans) return StopDialogue(); // in case multiple players initiate the dialogue at the same time
MessageBox("$MerchantSellPlans$", clonk);
SetDialogueProgress(10);
return true;
}
func Dlg_Merchant_10(object clonk)
{
if (g_has_bought_plans) return StopDialogue(); // in case multiple players initiate the dialogue at the same time
var plr = clonk->GetOwner();
var wealth = GetWealth(plr);
if (wealth >= 150)
{
MessageBox("$AnsBuyPlans$", clonk, clonk);
MessageBox("$MerchantBuyPlans$", clonk, clonk);
}
else
{
MessageBox("$AnsNoMoney$", clonk, clonk);
SetDialogueProgress(0);
SetDialogueStatus(DLG_Status_Stop);
MessageBox("$MerchantNoMoney$", clonk, clonk);
SetDialogueProgress(2);
}
return;
return true;
}
private func Dlg_Merchant_3(object clonk)
func Dlg_Merchant_11(object clonk)
{
MessageBox("$MsgGivePlans$", clonk);
DoWealth(clonk->GetOwner(), -150);
for (var i = 0; i < GetPlayerCount(); i++)
// prevent race conditions
if (g_has_bought_plans) return StopDialogue();
var plr = clonk->GetOwner();
var wealth = GetWealth(plr);
if (wealth < 150)
{
var plr = GetPlayerByIndex(i);
SetPlrKnowledge(plr, Pump);
SetPlrKnowledge(plr, Pipe);
SetPlrKnowledge(plr, Catapult);
SetPlrKnowledge(plr, Cannon);
}
SetDialogueStatus(DLG_Status_Stop);
return;
MessageBox("$MerchantNoMoney$", clonk, clonk);
SetDialogueProgress(2);
}
// do transaction.
MessageBox("$MerchantGivePlans$", clonk);
DoWealth(clonk->GetOwner(), -150);
for (var i = 0; i < GetPlayerCount(); i++) GameCall("GiveExtraPlans", GetPlayerByIndex(i));
g_has_bought_plans = true;
SetDialogueProgress(2);
return true;
}
private func Dlg_Merchant_4(object clonk)
func Dlg_Merchant_Plane(object clonk)
{
MessageBox("$MsgLeaveVillage$", clonk);
SetDialogueStatus(DLG_Status_Stop);
return;
MessageBox("$MerchantAPlane1$", clonk);
SetDialogueProgress(20);
return true;
}
func Dlg_Merchant_20(object clonk)
{
MessageBox("$MerchantAPlane2$", clonk);
SetDialogueProgress(2);
return true;
}
func Dlg_Merchant_Pump(object clonk)
{
MessageBox("$MerchantAPump1$", clonk);
SetDialogueProgress(30);
return true;
}
func Dlg_Merchant_30(object clonk)
{
MessageBox("$MerchantAPump2$", clonk);
SetDialogueProgress(2);
return true;
}
func Dlg_Merchant_Catapult(object clonk)
{
MessageBox("$MerchantACatapult1$", clonk);
SetDialogueProgress(40);
return true;
}
func Dlg_Merchant_40(object clonk)
{
MessageBox("$MerchantACatapult2$", clonk, clonk);
SetDialogueProgress(2);
return true;
}

View File

@ -3,17 +3,28 @@
#appendto Dialogue
private func Dlg_Pilot_1(object clonk)
func Dlg_Pilot_1(object clonk)
{
MessageBox("$MsgCrashedPlane$", clonk);
return;
return true;
}
private func Dlg_Pilot_2(object clonk)
func Dlg_Pilot_2(object clonk)
{
MessageBox("$AnsCrashedPlane$", clonk, clonk);
var options = [["$PyritQPlane$", "Dlg_Pilot_Plane"], ["$PyritQLake$", "Dlg_Pilot_Lake"], ["$PyritQDone$", "StopDialogue()"]];
MessageBox("$AnsCrashedPlane$", clonk, clonk, nil, false, options);
SetDialogueProgress(1);
SetDialogueStatus(DLG_Status_Stop);
return;
return true;
}
func Dlg_Pilot_Plane(object clonk, q)
{
MessageBox("$PyritAPlane$", clonk);
return StopDialogue();
}
func Dlg_Pilot_Lake(object clonk, q)
{
MessageBox("$PyritALake$", clonk);
return StopDialogue();
}

View File

@ -5,7 +5,7 @@
func Intro_Init()
{
this.plane = CreateObject(Plane, 0, 400);
this.pilot = CreateObject(Clonk, 100, 100, NO_OWNER);
this.pilot = npc_pyrit = CreateObject(Clonk, 100, 100, NO_OWNER);
this.pilot->MakeInvincible();
this.pilot->MakeNonFlammable();
this.pilot->SetSkin(2);
@ -24,7 +24,6 @@ func Intro_Init()
func Intro_Start(object hero)
{
if (!this.plane) Intro_Init();
this.hero = hero;
this.plane->StartInstantFlight(90, 15);
@ -36,7 +35,6 @@ func Intro_Start(object hero)
func Intro_JoinPlayer(int plr)
{
if (!this.plane) Intro_Init();
if (this.intro_closed) return false; // too late for join - just join in village
var crew;
for(var index = 0; crew = GetCrew(plr, index); ++index)
@ -152,40 +150,99 @@ func Intro_16()
{
var x = this.plane->GetX();
var y = this.plane->GetY();
this.pilot->Exit();
Intro_CreateBoompack(RandomX(x-5,x+5), RandomX(y-5,y+5), 160)->Launch(290 + Random(26), this.pilot);
while(this.dialogue->Contents())
Intro_CreateBoompack(RandomX(x-5,x+5), RandomX(y-5,y+5), 160)->Launch(290 + Random(26), this.dialogue->Contents());
SetViewTarget(nil);
for (var i=0; i<GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
SetPlrView(plr, GetCrew(plr));
}
return ScheduleNext(40);
return ScheduleNext(100);
}
func Intro_17()
{
ScheduleCall(nil, this.Intro_PilotDlg, 330, 1, this.pilot);
this.pilot->SetCommand("MoveTo", nil, 120, 860);
for (var i=0; i<GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
var crew = GetCrew(plr);
if (crew)
{
crew->SetCommand("MoveTo", nil, 135+Random(25), 860);
}
}
this.timer=0;
return ScheduleNext(100);
}
func Intro_18()
{
// wait until pilot has arrived in village
if (!Inside(this.pilot->GetX(), 100,140))
{
++this.timer;
if (this.timer < 12) return ScheduleSame(18);
// Pilot didn't arrive on time. Just put him there.
this.pilot->SetPosition(120,860);
}
this.pilot->SetCommand("None");
this.pilot->SetComDir(COMD_Stop);
this.pilot->SetXDir();
return ScheduleNext(30);
}
func Intro_19()
{
// Begin dialogue in village
this.pilot->SetDir(DIR_Right);
MessageBoxAll("$MsgIntro6$", this.pilot, true); // that was close
return ScheduleNext(150);
}
func Intro_20()
{
this.hero->SetDir(DIR_Left);
MessageBoxAll("$MsgIntro7$", this.hero, true); // what now?
return ScheduleNext(150);
}
func Intro_21()
{
MessageBoxAll("$MsgIntro8$", this.pilot, true); // plane crashed into mountain on other side
return ScheduleNext(250);
}
func Intro_22()
{
MessageBoxAll("$MsgIntro9$", this.pilot, true); // u go there n save it
return ScheduleNext(220);
}
func Intro_23()
{
MessageBoxAll("$MsgIntro10$", this.hero, true); // ok
return ScheduleNext(40);
}
func Intro_24()
{
return Stop();
}
func Intro_Stop()
{
// if players got stuck somewhere, unstick them
for (var i=0; i<GetPlayerCount(C4PT_User); ++i)
{
var plr = GetPlayerByIndex(i, C4PT_User);
var crew = GetCrew(plr);
if (crew && !Inside(crew->GetX(),125,170))
{
crew->SetPosition(135+Random(25), 860);
}
crew->Extinguish();
crew->DoEnergy(100);
}
this.dialogue->SetInteraction(true);
this.dialogue->AddAttention();
SetPlayerZoomByViewRange(NO_OWNER, 400,300, PLRZOOM_Set);
return true;
}
func Intro_PilotDlg(object pilot)
{
pilot->SetCommand("MoveTo", nil, 120, 860);
var dialogue = Dialogue->FindByTarget(pilot);
dialogue->SetInteraction(true);
dialogue->AddAttention();
return true;
}

View File

@ -0,0 +1,45 @@
/* Outro sequence */
#appendto Sequence
func Outro_Start(object goal, object plane)
{
this.goal = goal;
this.plane = plane;
this.hero = plane->FindObject(Find_Not(Find_Owner(NO_OWNER)), Find_ID(Clonk), plane->Sort_Distance());
SetViewTarget(this.plane);
MessageBoxAll("$Outro1$", this.hero, true);
return ScheduleNext(150);
}
func Outro_1()
{
MessageBoxAll("$Outro2$", npc_pyrit, true);
return ScheduleNext(220);
}
func Outro_2()
{
MessageBoxAll("$Outro3$", this.hero, true);
return ScheduleNext(180);
}
func Outro_3()
{
MessageBoxAll("$Outro4$", npc_pyrit, true);
return ScheduleNext(150);
}
func Outro_4()
{
return Stop();
}
func Outro_Stop()
{
this.goal->SetFulfilled();
return true;
}

View File

@ -4,15 +4,41 @@ MsgIntro2=Schau, der sch
MsgIntro3=Komm schon, Baby...
MsgIntro4=Oh oh...
MsgIntro5=Schnell! Der Schleudersitz!
MsgIntro6=Puh, das war knapp.
MsgIntro7=Was können wir nun tun?
MsgIntro8=Ich glaube ich habe gesehen, wie das Flugzeug auf der anderen Seite des Vulkans im Schnee gelandet ist.
MsgIntro9=Schnee ist weich. Wenn du dorthin gelangst, kannst du das Flugzeug vielleicht retten.
MsgIntro10=Ich werde es versuchen.
# NPC Pilot
NamePilot=Pilot
MsgCrashedPlane=Und, habt ihr das Flugzeug schon gefunden?
AnsCrashedPlane=Nein, wir suchen noch.
PyritQPlane=Wo ist das Flugzeug?
PyritAPlane=Ich glaube ich habe gesehen, wie das Flugzeug auf der anderen Seite des Vulkans im Schnee gelandet ist.
PyritQLake=Wie überquere ich den See?
PyritALake=Du braucht vermutlich ein paar fortgeschrittene Werkzeuge. Vielleicht geben uns die Dorfbewohner etwas.
PyritQDone=Nichts weiter.
# NPC Merchant
MsgSellPlans=Ich habe hier ein paar interessante Baupläne! Für 150 Clunker würde ich sie dir überlassen.
AnsNoMoney=Da muss ich noch etwas Gold abbauen. Ich komme später wieder.
AnsBuyPlans=Das ist ein guter Deal; hier sind deine Clunker.
MsgGivePlans=Danke! Hier hast du Pläne fuer {{Pump}}, {{Pipe}}, {{Catapult}} und {{Cannon}}. Aber Vorsicht: Die Pumpe ist aus Holz und sollte nicht zum Pumpen von Lava verwendet werden!
MsgLeaveVillage=Bitte verlasse unser verschlafenes Dorf!
Merchant1=Seid gegrüßt, Fremde aus dem Himmel. Wie kann ich euch helfen?
MerchantQPlane=Hast du unser Flugzeug gesehen?
MerchantAPlane1=Der seltame Vogel? Er trudelte über den Vulkan und landere auf der anderen Seite im Schnee.
MerchantAPlane2=Dorthin zu gelangen wird nicht einfach sein.
MerchantQLake=Kannst du uns helfen, den See zu überqueren?
MerchantSellPlans=Ich habe hier ein paar interessante Baupläne! Für 150 Clunker würde ich sie dir überlassen.
MerchantNoMoney=Da muss ich noch etwas Gold abbauen. Ich komme später wieder.
MerchantBuyPlans=Das ist ein guter Deal; hier sind deine Clunker.
MerchantGivePlans=Danke! Hier hast du Pläne fuer {{Pump}}, {{Pipe}}, {{Catapult}} und {{Cannon}}.
MerchantQPump=Wie benutze ich die Pumpe?
MerchantAPump1=Baue zwei Leitungen und benutze sie, während du vor der Pumpe stehst. Die erste Leitung wird das Zuflussrohr und die zweite Leitung das Abflussrohr.
MerchantAPump2=Wirf dann einfach das andere Ende des zuflussrohrs ins Wasser und platziere das Abflussrohr dort, wo die Flüssigkeit hingepumpt werden soll.
MerchantQCatapult=Wozu brauche ich ein Katapult?
MerchantACatapult1=Ein Katapult hat viele Anwendungen. Man kann Dinge wie Leitungsenden durch die Gegend werfen. Und wenn du mutig bist, kannst du selbst ins Katapult steigen und dich über den Lavasee schleudern.
MerchantACatapult2=Das...klingt gefährlich. Das gefällt mir!
MerchantQDone=Tschüss.
# Outro
Outro1=Es ist vollbracht! Das Flugzeug ist zurück.
Outro2=Gut gemacht. Dann lasst uns die Reise fortsetzen. Wir haben noch einen weiten Weg vor uns.
Outro3=Aber diesmal fliegen wir etwas höher, ok?
Outro4=Mal sehen, was ich tun kann.

View File

@ -4,15 +4,42 @@ MsgIntro2=Have a look at that lava lake!
MsgIntro3=Come on old girl, hang in there...
MsgIntro4=Uh oh...
MsgIntro5=Quick! The ejection seats!
MsgIntro6=Phew, that was close.
MsgIntro7=What can we do now?
MsgIntro8=I think I saw the plane crash into the snow on the hill on the other side of the volcano.
MsgIntro9=The snow is soft. Maybe if you get there, you can still salvage the plane.
MsgIntro10=I will try my best
# NPC Pilot
NamePilot=Pilot
MsgCrashedPlane=So, have you found the plane yet?
AnsCrashedPlane=No, we're still searching.
PyritQPlane=Where is the plane?
PyritAPlane=I think I saw it crash into the snow on the hill on the other side of the volcano.
PyritQLake=How can I cross the lake
PyritALake=You probably need some advanced tools. Maybe the villagers can give us something.
PyritQDone=Nevermind.
# NPC Merchant
MsgSellPlans=I know some interesting construction plans, which I can share with you for 150 clunkers.
AnsNoMoney=Then I'll have to mine for gold, I'll be back later.
AnsBuyPlans=That's a good deal, here you go.
MsgGivePlans=Thanks, here are the plans for {{Pump}}, {{Pipe}}, {{Catapult}} and {{Cannon}}. But be careful with the pump; it's made of wood and cannot be used to pump lava!
MsgLeaveVillage=Please leave this quiet village.
Merchant1=Greetings, strangers from the sky. How can I help you?
MerchantQPlane=Have you seen our plane?
MerchantAPlane1=The strange bird? It flew over the turublent volcano and landed on the other side in the snow.
MerchantAPlane2=Getting there might not be that easy.
MerchantQLake=Can you help us cross the lake?
MerchantSellPlans=I know some interesting construction plans, which may help you in this situation. I can share them with you for 150 clunkers.
MerchantNoMoney=Then I'll have to mine for gold, I'll be back later.
MerchantBuyPlans=That's a good deal, here you go.
MerchantGivePlans=Thanks, here are the plans for {{Pump}}, {{Pipe}}, {{Catapult}} and {{Cannon}}.
MerchantQPump=How do I use the pump?
MerchantAPump1=Just use two pipes as you're standing in front of the pump. The first pipe becomes the source pipe from which is pumped and the second pipe is the drain.
MerchantAPump2=Then just throw the source pipe into liquid and the drain pipe to where you want to pump!
MerchantQCatapult=Why do I need the catapult?
MerchantACatapult1=A catapult has many uses. You can fling things like pipe ends. If you're daring, you could even try to catapult yourself over the lava lake!
MerchantACatapult2=That...sounds scary. I like it!
MerchantQDone=Goodbye.
# Outro
Outro1=It's done! The plane is back.
Outro2=Good job. Let's continue our voyage then. We still have a long way ahead of us.
Outro3=But next time we fly a bit higher, ok?
Outro4=I'll see what I can do.
# plane flies up vertically

View File

@ -27,6 +27,8 @@ func Initialize()
{
MakeRuinsOnDamage(); // see System.ocg/Ruins.c
PlaceGrass(40);
SetNextMission("Mission.ocf/Crash.ocs");
return true;
}
func DoInit(int first_player)

View File

@ -318,6 +318,8 @@ private func MessageBox(string message, object clonk, object talker, int for_pla
// Text+Command given
option_text = option[0];
option_command = option[1];
// if only a command is given, the standard parameter is just the clonk
if (!WildcardMatch(option_command, "*(*")) option_command = Format("%s(Object(%d))", option_command, clonk->ObjectNumber());
}
else
{

View File

@ -18,6 +18,10 @@ func Start(string name, int progress, ...)
SetPosition(0,0); // force global coordinates
this.seq_name = name;
this.seq_progress = progress;
// call init function of this scene - difference to start function is that it is called before any player joins
var fn_init = Format("~%s_Init", seq_name);
if (!Call(fn_init, ...))
GameCall(fn_init, this, ...);
// Disable crew of all players
for (var i=0; i<GetPlayerCount(C4PT_User); ++i)
{
@ -181,10 +185,10 @@ private func MessageBox(string message, object clonk, object talker, int for_pla
/* Global helper functions */
global func StartSequence(string name, int progress, object view_target)
global func StartSequence(string name, int progress, ...)
{
var seq = CreateObject(Sequence, 0,0, NO_OWNER);
seq->Start(name, progress, view_target);
seq->Start(name, progress, ...);
return seq;
}