openclonk/planet/Worlds.ocf/HorridHighway.ocs/LocomotiveHighway.ocd/Script.c

173 lines
3.6 KiB
C

/**
Locomotive Highway
Construct and protect the locomotive highway.
@author Maikel
*/
#include Library_Goal
#include Library_SwitchTarget
/*-- Control --*/
// Reaction to operation by a switch.
public func OnSetInputSignal(object operator, object switch, bool right)
{
if (!right)
{
if (!GetEffect("FxRunLocomotives", this) && !FindObject(Find_ID(Locomotive)))
CreateEffect(FxRunLocomotives, 100, 36, this);
switch->ControlSwitchDir(nil, -1);
}
_inherited(operator, switch, right, ...);
}
local FxRunLocomotives = new Effect
{
Construction = func(object goal)
{
this.goal = goal;
this.Interval = 36;
this.train_int = 15;
this.train_start = 1;
this.goal->SetPassed(0);
return FX_OK;
},
Timer = func(int time)
{
if (time > this.Interval * this.train_int * Target.LocomotiveGoal)
return FX_Execute_Kill;
// Launch a locomotive.
if ((time / this.Interval) % this.train_int == this.train_start)
{
var loco = CreateObjectAbove(Locomotive, 12, LandscapeHeight() / 2 - 3);
loco->SetEntrance(false);
loco.IsContainer = Goal_LocomotiveHighway.FxRunLocomotives.NoContainer;
loco.HasInteractionMenu = Goal_LocomotiveHighway.FxRunLocomotives.NoInteractions;
loco->SetDir(DIR_Right);
loco->CreateContents(Coal, 100);
loco.LiquidCapacity = 100000;
loco->PutLiquid(Water, 100000);
loco->ContainedRight();
loco->CreateEffect(Target.FxCheckLocomotive, 100, 2, this.goal);
}
return FX_OK;
},
NoContainer = func()
{
return false;
},
NoInteractions = func()
{
return false;
}
};
local FxCheckLocomotive = new Effect
{
Construction = func(object goal)
{
this.goal = goal;
// The allowed time means that no obstacles must be in the way.
// The train moves roughly at a pace of 1.3-1.4 pixels per frame.
this.time_allowed = 4 * LandscapeWidth() / 5;
this.Interval = 2;
return FX_OK;
},
Timer = func(int time)
{
if (Target->GetX() > LandscapeWidth() - 14)
{
if (time <= this.time_allowed)
this.goal->DoPassed(1);
Target->RemoveObject();
return FX_Execute_Kill;
}
if (time > this.time_allowed)
{
Target->FadeOut(18, true);
return FX_Execute_Kill;
}
return FX_OK;
}
};
/*-- Goal interface --*/
local nr_passed = 0;
public func SetPassed(int to_passed)
{
nr_passed = to_passed;
return;
}
public func GetPassed() { return nr_passed; }
public func DoPassed(int add_passed)
{
SetPassed(GetPassed() + add_passed);
return;
}
public func IsFulfilled()
{
return nr_passed >= this.LocomotiveGoal;
}
public func GetDescription(int plr)
{
var message;
if (IsFulfilled())
{
message = "$MsgGoalFulfilled$";
}
else
{
if (GetEffect("FxRunLocomotives", this) || FindObject(Find_ID(Locomotive)))
message = Format("$MsgGoalRunning$", GetPassed(), this.LocomotiveGoal);
else
message = "$MsgGoalUnfulfilled$";
}
return message;
}
// Shows or hides a message window with information.
public func Activate(int plr)
{
// If goal message open -> hide it.
if (GetEffect("GoalMessage", this))
{
CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter);
RemoveEffect("GoalMessage", this);
return;
}
// Otherwise open a new message.
AddEffect("GoalMessage", this, 100, 0, this);
var message;
if (IsFulfilled())
{
message = "@$MsgGoalFulfilled$";
}
else
{
if (GetEffect("FxRunLocomotives", this) || FindObject(Find_ID(Locomotive)))
message = Format("@$MsgGoalRunning$", GetPassed(), this.LocomotiveGoal);
else
message = "@$MsgGoalUnfulfilled$";
}
CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter);
return;
}
protected func FxGoalMessageStart() {}
/*-- Proplist --*/
local Name = "$Name$";
local LocomotiveGoal = 12;