openclonk/planet/Tutorials.ocf/Tutorial04.ocs/System.ocg/SeqOutro.c

446 lines
14 KiB
C

// Outro sequence for this tutorial.
#appendto Sequence
public func Outro_Init(int for_plr)
{
this.plr = for_plr;
// Store villagers.
this.village_head = Dialogue->FindByName("VillageHead")->GetDialogueTarget();
this.farmer = Dialogue->FindByName("Farmer")->GetDialogueTarget();
this.lookout = Dialogue->FindByName("Lookout")->GetDialogueTarget();
this.lumberjack = Dialogue->FindByName("Lumberjack")->GetDialogueTarget();
this.fireman = Dialogue->FindByName("Fireman")->GetDialogueTarget();
this.builder = Dialogue->FindByName("Builder")->GetDialogueTarget();
// Create two airplanes with pilots and let them fly from left to right.
this.airplane1 = CreateObject(Airplane, AbsX(40), AbsY(160));
this.pilot1 = CreateObject(Clonk);
this.pilot1->SetSkin(2);
this.pilot1->Enter(this.airplane1);
this.pilot1->SetAction("Walk");
this.pilot1->SetColor(0xff000000);
this.airplane1->FaceRight();
this.airplane1->StartInstantFlight(90, 15);
this.airplane1->SetXDir(12);
this.airplane1->SetYDir(-1);
this.airplane1->MakeInvincible();
this.airplane1->SetColor(0xff000000);
this.airplane1.BorderBound = 0;
this.airplane2 = CreateObject(Airplane, AbsX(0), AbsY(190));
this.pilot2 = CreateObject(Clonk);
this.pilot2->SetSkin(2);
this.pilot2->Enter(this.airplane2);
this.pilot2->SetAction("Walk");
this.pilot2->SetColor(0xff000000);
this.airplane2->FaceRight();
this.airplane2->StartInstantFlight(90, 15);
this.airplane2->SetXDir(12);
this.airplane2->SetYDir(-1);
this.airplane2->MakeInvincible();
this.airplane2->SetColor(0xff000000);
this.airplane2.BorderBound = 0;
// Each plane has a henchman which will kidnap the wipfs.
this.henchman1 = CreateObject(Clonk);
this.henchman1->SetAlternativeSkin("Leather");
this.henchman1->Enter(this.airplane1);
this.henchman1->SetAction("Walk");
this.henchman1->SetColor(0xff000000);
this.henchman1->CreateContents(Musket)->CreateContents(LeadShot);
this.henchman2 = CreateObject(Clonk);
this.henchman2->SetAlternativeSkin("Leather");
this.henchman2->Enter(this.airplane2);
this.henchman2->SetAction("Walk");
this.henchman2->SetColor(0xff000000);
this.henchman2->CreateContents(Musket)->CreateContents(LeadShot);
// Another henchman which will control the lookout.
this.henchman3 = CreateObject(Clonk);
this.henchman3->SetAlternativeSkin("Leather");
this.henchman3->Enter(this.airplane2);
this.henchman3->SetAction("Walk");
this.henchman3->SetColor(0xff000000);
this.henchman3->CreateContents(Musket)->CreateContents(LeadShot);
// The faction leader which will do the talking.
this.leader = CreateObject(Clonk);
this.leader->SetAlternativeSkin("Doctor");
this.leader->SetName("Gotham");
this.leader->Enter(this.airplane1);
this.leader->SetAction("Walk");
this.leader->SetColor(0xff000000);
this.leader->CreateContents(Musket)->CreateContents(LeadShot);
// There is also a kidnapper on an airship with a lorry to collect the wipfs.
// The third henchman shoots down the balloons.
this.airship = CreateObject(Airship, AbsX(20), AbsY(280));
this.lorry = CreateObject(Lorry, AbsX(32), AbsY(280));
this.kidnapper = CreateObject(Clonk, AbsX(30), AbsY(280));
this.kidnapper->SetSkin(3);
this.kidnapper->SetAction("Walk");
this.kidnapper->SetCommand("Grab", this.airship);
this.kidnapper->SetColor(0xff000000);
this.airship->ControlRight(this.kidnapper);
return true;
}
public func Outro_JoinPlayer(int plr)
{
SetPlayerZoomByViewRange(plr, LandscapeWidth(), nil, PLRZOOM_Set | PLRZOOM_LimitMax);
return;
}
public func Outro_Start()
{
return ScheduleNext(4);
}
public func Outro_1()
{
MessageBox("$MsgVillageHeadNoise$", GetCrew(this.plr, 0), this.village_head, this.plr, true);
return ScheduleNext(72);
}
public func Outro_2()
{
MessageBox("$MsgFarmerAirplanes$", GetCrew(this.plr, 0), this.farmer, this.plr, true);
// Fireman and lumberjack flee into wooden cabin.
this.fireman->SetCommand("Enter", this.fireman->FindObject(Find_ID(WoodenCabin), Find_AnyLayer(), Sort_Distance()));
this.lumberjack->SetCommand("Enter", this.lumberjack->FindObject(Find_ID(WoodenCabin), Find_AnyLayer(), Sort_Distance()));
// Builder flees into the mine.
this.builder->SetCommand("MoveTo", this.builder->FindObject(Find_ID(Foundry), Find_AnyLayer(), Sort_Distance()));
return ScheduleNext(36);
}
public func Outro_3()
{
// Exit the leader from the airplane on a balloon.
this.leader->Exit();
var balloon = this.leader->CreateContents(Balloon);
balloon->ControlUseStart(this.leader);
this.leader->GetActionTarget()->ControlDown(this.leader);
return ScheduleNext(36);
}
public func Outro_4()
{
// Exit henchman from the airplanes on balloons.
this.henchman1->Exit();
var balloon = this.henchman1->CreateContents(Balloon);
balloon->ControlUseStart(this.henchman1);
this.henchman1->GetActionTarget()->ControlDown(this.henchman1);
this.henchman2->Exit();
var balloon = this.henchman2->CreateContents(Balloon);
balloon->ControlUseStart(this.henchman2);
this.henchman2->GetActionTarget()->ControlDown(this.henchman2);
// Let henchmen aim at the farmer.
AddEffect("AimMusketAt", this.henchman1, 100, 1, this, nil, this.farmer, 356);
AddEffect("AimMusketAt", this.henchman2, 100, 1, this, nil, this.farmer, 356);
// Let leader aim at the village head.
AddEffect("AimMusketAt", this.leader, 100, 1, this, nil, this.village_head);
return ScheduleNext(78);
}
public func Outro_5()
{
MessageBox("$MsgEvilLeaderItsUs$", GetCrew(this.plr, 0), this.leader, this.plr, true);
// Exit a third henchman from the airplane on a balloon.
this.henchman3->Exit();
var balloon = this.henchman3->CreateContents(Balloon);
balloon->ControlUseStart(this.henchman3);
this.henchman3->GetActionTarget()->ControlDown(this.henchman3);
return ScheduleNext(20);
}
public func Outro_6()
{
// Third henchman aims at lookout
AddEffect("AimMusketAt", this.henchman3, 100, 1, this, nil, this.lookout, 280);
return ScheduleNext(100);
}
public func Outro_7()
{
return ScheduleNext(36);
}
public func Outro_8()
{
MessageBox("$MsgVillageHeadWhy$", GetCrew(this.plr, 0), this.village_head, this.plr, true);
return ScheduleNext(36);
}
public func Outro_9()
{
// Third henchman tells lookout to drop the weapon.
this.henchman3->Message("$MsgHenchman3DropMusket$");
return ScheduleNext(18);
}
public func Outro_10()
{
// First and second henchman scare off farmer.
this.henchman1->Message("$MsgHenchman1RunGirl$");
this.henchman2->Message("$MsgHenchman2Wipfs$");
return ScheduleNext(18);
}
public func Outro_11()
{
// Lookout surrenders.
this.lookout->Message("$MsgLookoutSurrender$");
this.lookout->SetCommand("Drop", this.lookout->Contents());
return ScheduleNext(18);
}
public func Outro_12()
{
// Farmer runs off into the mines.
this.farmer->SetCommand("MoveTo", this.farmer->FindObject(Find_ID(ToolsWorkshop), Find_AnyLayer(), Sort_Distance()));
this.farmer->Message("$MsgFarmerComment$");
return ScheduleNext(100);
}
public func Outro_13()
{
MessageBox("$MsgEvilLeaderWipfs$", GetCrew(this.plr, 0), this.leader, this.plr, true);
this.airship->ControlStop(this.kidnapper);
AddEffect("TieWipfToBalloon", this.henchman1, 100, 5, this);
AddEffect("TieWipfToBalloon", this.henchman2, 100, 5, this);
return ScheduleNext(108);
}
public func Outro_14()
{
MessageBox("$MsgVillageHeadManiac$", GetCrew(this.plr, 0), this.village_head, this.plr, true);
ScheduleCall(this, "MessageBox", 108, 0, "$MsgEvilLeader$", GetCrew(this.plr, 0), this.leader, this.plr, true);
ScheduleCall(this, "MessageBox", 216, 0, "$MsgPlayerDontTakeWipf$", GetCrew(this.plr, 0), GetCrew(this.plr, 0), this.plr, true);
ScheduleCall(this, "MessageBox", 356, 0, "$MsgEvilLeaderBegging$", GetCrew(this.plr, 0), this.leader, this.plr, true);
return ScheduleNext(4);
}
public func Outro_15()
{
// Wait until all wipfs are up then move airship.
if (!FindObject(Find_ID(Wipf), Find_InRect(AbsX(632), AbsY(280), 216, 112), Find_AnyLayer()))
{
AddEffect("MoveAirshipToWipf", this.kidnapper, 100, 5, this);
return ScheduleNext(10);
}
return ScheduleSame(10);
}
public func Outro_16()
{
if (FindObject(Find_ID(Wipf), Find_NoContainer(), Find_InRect(AbsX(632), AbsY(0), 216, 352), Find_Property("tied_up")))
return ScheduleSame(10);
return ScheduleNext(10);
}
public func Outro_17()
{
this.airship->ControlRight(this.kidnapper);
this.airship->ControlUp(this.kidnapper);
this.kidnapper->Message("$MsgKidnapperGotThem$");
ScheduleCall(this.kidnapper, "RemoveObject", 300, 0);
ScheduleCall(this.airship, "RemoveObject", 300, 0);
ScheduleCall(this.lorry, "RemoveObject", 300, 0);
var boompack = this.henchman3->CreateContents(Boompack);
boompack->SetFuel(10000);
boompack->ControlUse(this.henchman3, -8, -40);
boompack->SetDirectionDeviation();
this.henchman3->Message("$MsgHenchman3SeeYa$");
RemoveAll(Find_Container(this.henchman3));
ScheduleCall(this.henchman3, "RemoveObject", 120, 0);
ScheduleCall(boompack, "RemoveObject", 120, 0);
this.henchman1->SetCommand("MoveTo", nil, 632, 382);
this.henchman2->SetCommand("MoveTo", nil, 632, 382);
return ScheduleNext(70);
}
public func Outro_18()
{
var boompack = this.henchman2->CreateContents(Boompack);
boompack->SetFuel(10000);
boompack->ControlUse(this.henchman2, -10, -40);
boompack->SetDirectionDeviation();
this.henchman2->Message("$MsgHenchman3SeeYa$");
RemoveAll(Find_Container(this.henchman2));
ScheduleCall(this.henchman2, "RemoveObject", 100, 0);
ScheduleCall(boompack, "RemoveObject", 100, 0);
return ScheduleNext(10);
}
public func Outro_19()
{
MessageBox("$MsgEvilLeaderBye$", GetCrew(this.plr, 0), this.leader, this.plr, true);
var boompack = this.henchman1->CreateContents(Boompack);
boompack->SetFuel(10000);
boompack->ControlUse(this.henchman1, -10, -40);
boompack->SetDirectionDeviation();
this.henchman1->Message("$MsgHenchman3SeeYa$");
RemoveAll(Find_Container(this.henchman1));
ScheduleCall(this.henchman1, "RemoveObject", 120, 0);
ScheduleCall(boompack, "RemoveObject", 120, 0);
RemoveEffect("AimMusketAt", this.leader);
return ScheduleNext(36);
}
public func Outro_20()
{
var boompack = this.leader->CreateContents(Boompack);
boompack->SetFuel(10000);
boompack->ControlUse(this.leader, -8, -40);
boompack->SetDirectionDeviation();
RemoveAll(Find_Container(this.leader));
ScheduleCall(this.leader, "RemoveObject", 120, 0);
ScheduleCall(boompack, "RemoveObject", 120, 0);
return ScheduleNext(188);
}
public func Outro_21()
{
// Show last guide message and then stop the sequence and fulfill the goal.
GameCall("ShowLastGuideMessage");
return ScheduleNext(108);
}
public func Outro_22()
{
return Stop();
}
public func Outro_Stop()
{
// Fulfill the tutorial goal.
var goal = FindObject(Find_ID(Goal_Tutorial));
if (goal)
goal->Fulfill();
return true;
}
/*-- Effects --*/
public func FxAimMusketAtStart(object target, proplist effect, int temp, object aim, int length)
{
if (temp)
return FX_OK;
effect.aim_target = aim;
effect.aim_length = length;
effect.musket = FindObject(Find_ID(Musket), Find_Container(target));
effect.musket.loaded = true;
effect.musket->ControlUseStart(target, effect.aim_target->GetX() - target->GetX(), effect.aim_target->GetY() - target->GetY());
return FX_OK;
}
public func FxAimMusketAtTimer(object target, proplist effect, int time)
{
effect.musket->ControlUseHolding(target, effect.aim_target->GetX() - target->GetX(), effect.aim_target->GetY() - target->GetY());
if (effect.aim_length != nil && time >= effect.aim_length)
return FX_Execute_Kill;
return FX_OK;
}
public func FxAimMusketAtStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
effect.musket->ControlUseCancel(target, effect.aim_target->GetX() - target->GetX(), effect.aim_target->GetY() - target->GetY());
return FX_OK;
}
public func FxTieWipfToBalloonStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
effect.wait_time = 0;
return FX_OK;
}
public func FxTieWipfToBalloonTimer(object target, proplist effect, int time)
{
if (effect.wait_time > 0)
{
effect.wait_time -= effect.Interval;
return FX_OK;
}
if (!effect.wipf)
{
effect.wipf = target->FindObject(Find_ID(Wipf), Find_InRect(target->AbsX(632), target->AbsY(260), 216, 132), Find_AnyLayer(), Find_Not(Find_Or(Find_Property("tied_up"), Find_Property("tie_target"))), Sort_Distance());
if (!effect.wipf)
return FX_Execute_Kill;
effect.wipf.tie_target = true;
}
if (ObjectDistance(target, effect.wipf) < 10)
{
effect.wipf->SetObjectLayer();
effect.wipf.Collectible = true;
var balloon = effect.wipf->CreateContents(Balloon);
balloon->HangWipfOnBalloon(effect.wipf);
target->Message(Translate(Format("MsgHenchmanGotWipf%d", 1 + Random(3))));
effect.wipf.tied_up = true;
effect.wipf = nil;
effect.wait_time = 36;
return FX_OK;
}
target->SetCommand("MoveTo", nil, effect.wipf->GetX(), effect.wipf->GetY());
return FX_OK;
}
public func FxTieWipfToBalloonStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
return FX_OK;
}
public func FxMoveAirshipToWipfStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
return FX_OK;
}
public func FxMoveAirshipToWipfTimer(object target, proplist effect, int time)
{
var right_wipf = FindObject(Find_ID(Wipf), Find_NoContainer(), Find_InRect(AbsX(616), AbsY(0), 248, 280), Find_Property("tied_up"), Sort_Reverse(Sort_Func("GetX")));
if (!right_wipf)
return FX_Execute_Kill;
if (Abs(this.airship->GetX() - right_wipf->GetX()) < 8)
{
this.airship->ControlStop(this.kidnapper);
// Shoot musket.
if (!right_wipf.shot)
{
var musket = FindObject(Find_ID(Musket), Find_Container(this.henchman3));
musket.loaded = true;
musket->ControlUseStart(target, right_wipf->GetX() - this.henchman3->GetX(), right_wipf->GetY() - this.henchman3->GetY() - 24);
musket->ControlUseHolding(target, right_wipf->GetX() - this.henchman3->GetX(), right_wipf->GetY() - this.henchman3->GetY() - 24);
musket->ControlUseStop(target, right_wipf->GetX() - this.henchman3->GetX(), right_wipf->GetY() - this.henchman3->GetY() - 24);
right_wipf.shot = true;
}
return FX_OK;
}
if (this.airship->GetX() > right_wipf->GetX())
this.airship->ControlLeft(this.kidnapper);
else
this.airship->ControlRight(this.kidnapper);
return FX_OK;
}
public func FxMoveAirshipToWipfStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
return FX_OK;
}