1 /**
2 Locomotive Highway
3 Construct and protect the locomotive highway.
4
5 @author Maikel
6 */
7
8
9 #include Library_Goal
10 #include Library_SwitchTarget
11
12
13 /*-- Control --*/
14
15 // Reaction to operation by a switch.
OnSetInputSignal(object operator,object switch,bool right)16 public func OnSetInputSignal(object operator, object switch, bool right)
17 {
18 if (!right)
19 {
20 if (!GetEffect("FxRunLocomotives", this) && !FindObject(Find_ID(Locomotive)))
21 CreateEffect(FxRunLocomotives, 100, 36, this);
22 switch->ControlSwitchDir(nil, -1);
23 }
24 _inherited(operator, switch, right, ...);
25 }
26
27 local FxRunLocomotives = new Effect
28 {
func(object goal)29 Construction = func(object goal)
30 {
31 this.goal = goal;
32 this.Interval = 36;
33 this.train_int = 15;
34 this.train_start = 1;
35 this.goal->SetPassed(0);
36 return FX_OK;
37 },
38 Timer = func(int time)
39 {
40 if (time > this.Interval * this.train_int * Target.LocomotiveGoal)
41 return FX_Execute_Kill;
42 // Launch a locomotive.
43 if ((time / this.Interval) % this.train_int == this.train_start)
44 {
45 var loco = CreateObjectAbove(Locomotive, 12, LandscapeHeight() / 2 - 3);
46 loco->SetEntrance(false);
47 loco.IsContainer = Goal_LocomotiveHighway.FxRunLocomotives.NoContainer;
48 loco.HasInteractionMenu = Goal_LocomotiveHighway.FxRunLocomotives.NoInteractions;
49 loco->SetDir(DIR_Right);
50 loco->CreateContents(Coal, 100);
51 loco.LiquidCapacity = 100000;
52 loco->PutLiquid(Water, 100000);
53 loco->ContainedRight();
54 loco->CreateEffect(Target.FxCheckLocomotive, 100, 2, this.goal);
55 }
56 return FX_OK;
57 },
58 NoContainer = func()
59 {
60 return false;
61 },
62 NoInteractions = func()
63 {
64 return false;
65 }
66 };
67
68 local FxCheckLocomotive = new Effect
69 {
func(object goal)70 Construction = func(object goal)
71 {
72 this.goal = goal;
73 // The allowed time means that no obstacles must be in the way.
74 // The train moves roughly at a pace of 1.3-1.4 pixels per frame.
75 this.time_allowed = 4 * LandscapeWidth() / 5;
76 this.Interval = 2;
77 return FX_OK;
78 },
79 Timer = func(int time)
80 {
81 if (Target->GetX() > LandscapeWidth() - 14)
82 {
83 if (time <= this.time_allowed)
84 this.goal->DoPassed(1);
85 Target->RemoveObject();
86 return FX_Execute_Kill;
87 }
88 if (time > this.time_allowed)
89 {
90 Target->FadeOut(18, true);
91 return FX_Execute_Kill;
92 }
93 return FX_OK;
94 }
95 };
96
97
98 /*-- Goal interface --*/
99
100 local nr_passed = 0;
101
SetPassed(int to_passed)102 public func SetPassed(int to_passed)
103 {
104 nr_passed = to_passed;
105 return;
106 }
107
GetPassed()108 public func GetPassed() { return nr_passed; }
109
DoPassed(int add_passed)110 public func DoPassed(int add_passed)
111 {
112 SetPassed(GetPassed() + add_passed);
113 return;
114 }
115
IsFulfilled()116 public func IsFulfilled()
117 {
118 return nr_passed >= this.LocomotiveGoal;
119 }
120
GetDescription(int plr)121 public func GetDescription(int plr)
122 {
123 var message;
124 if (IsFulfilled())
125 {
126 message = "$MsgGoalFulfilled$";
127 }
128 else
129 {
130 if (GetEffect("FxRunLocomotives", this) || FindObject(Find_ID(Locomotive)))
131 message = Format("$MsgGoalRunning$", GetPassed(), this.LocomotiveGoal);
132 else
133 message = "$MsgGoalUnfulfilled$";
134 }
135 return message;
136 }
137
138 // Shows or hides a message window with information.
Activate(int plr)139 public func Activate(int plr)
140 {
141 // If goal message open -> hide it.
142 if (GetEffect("GoalMessage", this))
143 {
144 CustomMessage("", nil, plr, nil, nil, nil, nil, nil, MSG_HCenter);
145 RemoveEffect("GoalMessage", this);
146 return;
147 }
148 // Otherwise open a new message.
149 AddEffect("GoalMessage", this, 100, 0, this);
150 var message;
151 if (IsFulfilled())
152 {
153 message = "@$MsgGoalFulfilled$";
154 }
155 else
156 {
157 if (GetEffect("FxRunLocomotives", this) || FindObject(Find_ID(Locomotive)))
158 message = Format("@$MsgGoalRunning$", GetPassed(), this.LocomotiveGoal);
159 else
160 message = "@$MsgGoalUnfulfilled$";
161 }
162 CustomMessage(message, nil, plr, 0, 16 + 64, 0xffffff, GUI_MenuDeco, this, MSG_HCenter);
163 return;
164 }
165
FxGoalMessageStart()166 protected func FxGoalMessageStart() {}
167
168
169 /*-- Proplist --*/
170
171 local Name = "$Name$";
172 local LocomotiveGoal = 12;
173