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