1 /**
2 Pipe line
3
4 @author ST-DDT, Marky
5 */
6
7 local pipe_kit;
8 local is_air_pipe = false;
9
Initialize()10 private func Initialize()
11 {
12 SetAction("Connect");
13 SetVertexXY(0, GetX(), GetY());
14 SetVertexXY(1, GetX(), GetY());
15 SetNeutral();
16 }
17
18 // Greyish colour
SetNeutral()19 public func SetNeutral()
20 {
21 this.LineColors = [RGB(80, 80, 120), RGB(80, 80, 120)];
22 is_air_pipe = false;
23 }
24
25 // Reddish colour.
26 // Please to not change otherwise people with dyschromatopsia will hunt you down.
SetDrain()27 public func SetDrain()
28 {
29 this.LineColors = [RGB(238, 102, 0), RGB(238, 102, 0)];
30 is_air_pipe = false;
31 }
32
33 // Greenish colour.
34 // Please to not change otherwise people with dyschromatopsia will hunt you down.
SetSource()35 public func SetSource()
36 {
37 this.LineColors = [RGB(102, 136, 34), RGB(102, 136, 34)];
38 is_air_pipe = false;
39 }
40
41 // Blueish colour.
SetAir()42 public func SetAir()
43 {
44 this.LineColors = [RGB(0, 153, 255), RGB(0, 153, 255)];
45 is_air_pipe = true;
46 }
47
48 // Returns true if this object is a functioning pipe.
IsPipeLine()49 public func IsPipeLine()
50 {
51 return GetAction() == "Connect";
52 }
53
IsAirPipe()54 public func IsAirPipe()
55 {
56 return this.is_air_pipe;
57 }
58
59 // Returns whether this pipe is connected to an object.
60 // Returns only actually connected objects if the parameter 'strict' is true.
IsConnectedTo(object obj,bool strict)61 public func IsConnectedTo(object obj, bool strict)
62 {
63 return GetActionTarget(0) == obj || GetActionTarget(1) == obj || (!strict && pipe_kit == obj);
64 }
65
66 // Returns the object which is connected to obj through this pipe.
GetConnectedObject(object obj)67 public func GetConnectedObject(object obj)
68 {
69 if (GetActionTarget(0) == obj)
70 return GetActionTarget(1);
71 if (GetActionTarget(1) == obj)
72 return GetActionTarget(0);
73 return;
74 }
75
76 // Switches connection from connected_to to another obj.
SwitchConnection(object connected_to,object obj)77 public func SwitchConnection(object connected_to, object obj)
78 {
79 var target0 = GetActionTarget(0), target1 = GetActionTarget(1);
80
81 if (target0 == connected_to) target0 = obj;
82 if (target1 == connected_to) target1 = obj;
83
84 SetActionTargets(target0, target1);
85 }
86
87 // Saves the pipe object that created this line.
SetPipeKit(object obj)88 public func SetPipeKit(object obj)
89 {
90 pipe_kit = obj;
91 }
92
GetPipeKit()93 public func GetPipeKit()
94 {
95 if (pipe_kit)
96 {
97 return pipe_kit;
98 }
99 else
100 {
101 FatalError("Unexpected error: This pipe has lost its pipe kit!");
102 }
103 }
104
105
OnLineBreak(bool no_msg)106 private func OnLineBreak(bool no_msg)
107 {
108 Sound("Objects::LineSnap");
109 if (!no_msg)
110 BreakMessage();
111
112 if (GetPipeKit())
113 {
114 GetPipeKit()->SetNeutralPipe();
115 if (GetActionTarget(0)) GetActionTarget(0)->~OnPipeDisconnect(GetPipeKit());
116 if (GetActionTarget(1)) GetActionTarget(1)->~OnPipeDisconnect(GetPipeKit());
117 }
118
119 return;
120 }
121
OnLineChange()122 private func OnLineChange()
123 {
124 // Notify action targets about line change.
125 var act1 = GetActionTarget(0);
126 var act2 = GetActionTarget(1);
127 if (act1) act1->~OnPipeLengthChange(this);
128 if (act2) act2->~OnPipeLengthChange(this);
129 // Break line if it is too long.
130 if (GetPipeLength() > this.PipeMaxLength)
131 {
132 OnLineBreak();
133 RemoveObject();
134 }
135 return;
136 }
137
138 // Returns the length between all the vertices.
GetPipeLength()139 public func GetPipeLength()
140 {
141 var current_length = 0;
142 for (var index = 0; index < GetVertexNum() - 1; index++)
143 current_length += Distance(GetVertex(index, VTX_X), GetVertex(index, VTX_Y), GetVertex(index + 1, VTX_X), GetVertex(index + 1, VTX_Y));
144 return current_length;
145 }
146
Destruction()147 private func Destruction()
148 {
149 if (GetActionTarget(0)) GetActionTarget(0)->~OnPipeLineRemoval();
150 if (GetActionTarget(1)) GetActionTarget(1)->~OnPipeLineRemoval();
151 return;
152 }
153
BreakMessage()154 private func BreakMessage()
155 {
156 var line_end = GetPipeKit();
157 if (line_end) line_end->Report("$TxtPipeBroke$");
158 return;
159 }
160
SaveScenarioObject(props)161 public func SaveScenarioObject(props)
162 {
163 if (!inherited(props, ...)) return false;
164 SaveScenarioObjectAction(props);
165 // Ensure vertices are moved to the action targets to ensure the shortest path length and prevent a line break.
166 if (GetActionTarget()) props->AddCall("VtxX", this, "SetVertexXY", 0, GetActionTarget()->GetX(), GetActionTarget()->GetY());
167 if (GetActionTarget(1)) props->AddCall("VtxX", this, "SetVertexXY", 1, GetActionTarget(1)->GetX(), GetActionTarget(1)->GetY());
168 if (pipe_kit) props->AddCall("PipeKit", this, "SetPipeKit", pipe_kit);
169 if (IsAirPipe()) props->AddCall("AirPipe", this, "SetAir");
170 if (this.BlockPipeCutting) props->AddSet("BlockPipeCutting", this, "BlockPipeCutting", this.BlockPipeCutting);
171 return true;
172 }
173
174 /*-- Properties --*/
175
176 local Name = "$Name$";
177 local PipeMaxLength = 1200;
178 local BlockPipeCutting = false;
179
180 local ActMap = {
181 Connect = {
182 Prototype = Action,
183 Name = "Connect",
184 Procedure = DFA_CONNECT,
185 NextAction = "Connect"
186 }
187 };
188