5 local Length
, CalcedLength
;
8 Unbenannte lokale Variablen
11 2 - Mittigster Vertex von ActionTarget 1
12 3 - '' '' '' ActionTarget 2
15 protected func
Initialize() {
21 public func
CalcLength(object Target1
, object Target2
) {
23 var i
=GetVertexNum() - 1;
25 // für jedes Paar berechnen
26 while (i
--) Count
+= VerticeLength (i
, Target1
, Target2
);
30 private func
VerticeLength(int i
,object Target1
,object Target2
) {
31 // erster Vertex: Geschwindigkeit von 1.Actiontarget berücksichtigen
33 return Distance(GetVertex (0) + GetXDir (Target1
) / 2,GetVertex (0, 1) + GetYDir (Target1
) / 2,GetVertex (1),GetVertex (1, 1));
34 // vorletzter Vertex: Geschwindigkeit von 2.Actiontarget berücksichtigen
35 if(i
== (GetVertexNum () - 2))
36 return Distance(GetVertex (i
),GetVertex (i
, 1),GetVertex (i
+ 1) + GetXDir (Target2
) / 2,GetVertex (i
+ 1, 1) + GetYDir (Target2
)) / 2;
37 // Ansonsten nur die Positionen
38 return Distance(GetVertex (i
),GetVertex (i
, 1),GetVertex (i
+ 1),GetVertex (i
+ 1, 1));
41 public func
MoveRope(object pObj1
,object pObj2
) {
43 // Hier, weil das Seil immer verschwinden soll, wenn ein angeknotetes Objekt verschwindet.
44 if(!pObj1
|| !pObj2
) return RemoveObject();
45 // Wir brauchen mindesten 3 Vertices, damit die Algorithmen funktionieren
46 if(GetVertexNum () < 3)
47 InsertVertex(1, (GetVertex (0) + GetVertex (1)) / 2, (GetVertex (0, 1) + GetVertex (1, 1)) / 2);
48 SetRopeEnd(pObj1
, 0, Local(2), 2);
49 SetRopeEnd(pObj2
, GetVertexNum () - 1, Local (3), -2);
50 var vertexdistance
= 7 + 3 * GetVertexNum ();
51 // für jeden Vertex ausführen
52 for(var i
= GetVertexNum () - 2; i
> 0; i
--) {
53 // Neue Position des Vertices
54 a
= (GetVertex (i
- 1) + GetVertex (i
+ 1)) / 2;
55 b
= (GetVertex (i
- 1, 1) + GetVertex (i
+ 1, 1)) / 2;
56 // Überschüssige Vertices, die nahe genug aneinander sind entfernen
57 if(GetVertexNum () > 3)
58 if(Distance(GetVertex (i
- 1, 0), GetVertex (i
- 1, 1), GetVertex (i
+ 1, 0), GetVertex (i
+ 1, 1)) < vertexdistance
)
59 if(PathFree(GetVertex (i
- 1, 0), GetVertex (i
- 1, 1), GetVertex (i
+ 1, 0), GetVertex (i
+ 1, 1))) {
63 // bei zu langem Abstand einen neuen Vertex einfügen
64 if(Distance(GetVertex(i
- 1, 0), GetVertex (i
- 1, 1), GetVertex (i
, 0), GetVertex (i
, 1)) > (5 + vertexdistance
)) {
65 InsertVertex(i
, (GetVertex (i
- 1, 0) + GetVertex (i
, 0)) / 2, (GetVertex (i
- 1, 1) + GetVertex (i
, 1)) / 2);
68 // Wenn durch verschieben des Vertex das Seil durch solides ginge, nicht verschieben, und bei genug Platz einen zusätzlichen Vertex einfügen
69 if(!PathFree (a
, b
, GetVertex (i
- 1), GetVertex (i
- 1, 1))) {
70 if(Distance (GetVertex (i
- 1, 0), GetVertex (i
- 1, 1), GetVertex (i
, 0), GetVertex (i
, 1)) > vertexdistance
)
71 InsertVertex (i
, (GetVertex (i
-1, 0)+GetVertex (i
, 0))/2, (GetVertex (i
-1, 1)+GetVertex (i
, 1))/2);
74 if(!PathFree (a
, b
, GetVertex (i
+ 1), GetVertex (i
+ 1, 1))) {
75 if(Distance (GetVertex (i
+1, 0),GetVertex (i
+1, 1),GetVertex (i
, 0),GetVertex (i
, 1)) > vertexdistance
)
76 InsertVertex (i
+1, (GetVertex (i
+1, 0) + GetVertex (i
, 0))/2, (GetVertex (i
+1, 1) + GetVertex (i
, 1))/2);
85 func
SetRopeEnd(object pObj
,int iRopeVertex
,int iObjVertex
,int iWhichEnd
) {
87 x
= GetX (pObj
) + GetVertex (iObjVertex
, 0, pObj
);
88 y
= GetY (pObj
) + GetVertex (iObjVertex
, 1, pObj
);
89 // Wenn durch die Bewegung des angebundenen Objekts das Seil durch solides ginge,
90 // einen Vertex an der letzten Position des Objekts einfügen
91 // wenn das Objekt selbst in fester Materie steckt, hülfe das auch nichts
92 if(!GBackSolid (x
- GetX (), y
- GetY ())) {
93 if(!PathFree (x
, y
, GetVertex(iRopeVertex
+ iWhichEnd
, 0), GetVertex (iRopeVertex
+ iWhichEnd
, 1))) {
94 InsertVertex (iRopeVertex
- BoundBy (iWhichEnd
, -1, 0), x
, y
);
97 SetVertex (iRopeVertex
, 0, x
);
98 SetVertex (iRopeVertex
, 1, y
);
104 private func
InsertVertex(int iIndex
,int iX
,int iY
) {
105 if (!AddVertex ()) return 0;
106 for (var i
= GetVertexNum () - 1; i
> iIndex
; i
-- ) {
107 SetVertex (i
, 0, GetVertex (i
- 1, 0));
108 SetVertex (i
, 1, GetVertex (i
- 1, 1));
110 SetVertex (iIndex
, 0, iX
);
111 SetVertex (iIndex
, 1, iY
);
115 /* ActionCall From Connect */
118 var Target1
= GetRealContainer(GetActionTarget(0));
119 var Target2
= GetRealContainer(GetActionTarget(1));
120 MoveRope(GetActionTarget(0), GetActionTarget(1));
121 if(Target1
== Target2
) return 0;
122 if(!Target1
|| !Target2
) return 0;
123 CalcedLength
= CalcLength(Target1
, Target2
);
124 var Difference
= CalcedLength
- Length
;
125 Length
= Max(Length
+ GetActionTarget(0)->~RopeAskChangeLength(Difference
, this), 3);
126 Length
= Max(Length
+ GetActionTarget(1)->~RopeAskChangeLength(Difference
, this), 3);
127 Difference
= CalcedLength
- Length
;
128 if(Difference
<= 0) return 0;
129 var iMass
= GetMass(Target1
) + GetMass (Target2
);
130 Do_Stuff(Target1
, Target2
, iMass
, Difference
, 1, Local(2));
131 Do_Stuff(Target2
, Target1
, iMass
, Difference
, GetVertexNum () - 2, Local(3));
135 func
Do_Stuff(object pPullingObject
,object Target2
,int iMass
,int iDifference
,int RopeVertex
,int ObjVertex
) {
136 var Strength
= (iDifference
* GetMass(Target2
)) / iMass
;
137 // Wenn Crewmember, dann wird Physical Fight miteingerechnet: Je größer, desto weniger wird gezogen
138 // Masse: Je schwerer das gegenüberliegende Objekt, desto mehr wird gezogen
139 if(GetProcedure(pPullingObject
) == "Walk")
140 Strength
= Max(0, Strength
- (GetPhysical ("Fight", 0, pPullingObject
) / 30000));
141 if(GetProcedure(pPullingObject
) == "Float")
142 Strength
= Max(0, Strength
- (GetPhysical ("Float", 0, pPullingObject
) / 100));
143 PullObject(GetVertex(RopeVertex
), GetVertex(RopeVertex
, 1), Strength
, pPullingObject
, ObjVertex
);
146 private func
PullObject(int toX
,int toY
,int length
,object obj
,int vtx
) {
147 var len
= Min(length
,Distance(toX
, toY
,GetX(obj
) + GetVertex(vtx
, 0, obj
), GetY (obj
)+GetVertex (vtx
, 1, obj
)));
148 var iAngle
= MakeThisAngleUseful(Angle(GetX (obj
)+GetVertex (vtx
, 0, obj
), GetY (obj
)+GetVertex (vtx
, 1, obj
), toX
, toY
), -180, +180);
149 var iAngle2
= MakeThisAngleUseful(Angle(0, 0, GetVertex (vtx
, 0, obj
), GetVertex (vtx
, 1, obj
)), -180, +180);
150 var x
= Sin(iAngle
, len
*10);
151 var y
= Cos(iAngle
, len
*10);
152 if(Stuck (obj
)) return 0;
153 SetXDir(BoundBy(GetXDir (obj
, 100) + x
, -1000, 1000), obj
, 100);
154 SetYDir(BoundBy(GetYDir (obj
, 100) - y
, -1000, 1000), obj
, 100);
155 SetRDir(GetRDir(obj
, 100) + (iAngle
- iAngle2
) / 10, obj
, 100);
157 SetPosition (GetX (obj
) + BoundBy (x
,-1,1), GetY (obj
) - BoundBy (y
,-1,1), obj
);
160 func
MakeThisAngleUseful (winkel
, m
, p
) {
162 winkel
= winkel
- 360;
164 winkel
= winkel
+ 360;
168 public func
Activate(object obj1
,object obj2
) {
169 Local(2) = GetMiddlestVertex(obj1
);
170 Local(3) = GetMiddlestVertex(obj2
);
171 // Vertices erzeugen/ändern
172 SetVertex(0, 0, GetX (obj1
) + GetVertex (Local (2), 0, obj1
));
173 SetVertex(0, 1, GetY (obj1
) + GetVertex (Local (2), 1, obj1
));
174 SetVertex(1, 0, GetX (obj2
) + GetVertex (Local (3), 0, obj2
));
175 SetVertex(1, 1, GetY (obj2
) + GetVertex (Local (3), 1, obj2
));
176 SetAction("Connect", obj1
, obj2
);
177 Length
= CalcLength();
180 public func
CheckConVertices () {
181 Local(2) = GetMiddlestVertex (GetActionTarget ());
182 Local(3) = GetMiddlestVertex (GetActionTarget (1));
185 /* Mit SetObject kann man die angeknüpften Objekte ändern. num=0 für Actiontarget0 und num=1 für Actiontarget1 */
187 public func
SetObject(object obj
,int num
) {
189 if (GetCategory(obj
) & C4D_Structure
) return 0;
192 // Action und 2.Actiontarget bleiben erhalten
193 Local(2) = GetMiddlestVertex (obj
);
194 SetAction("Connect", obj
, GetActionTarget(1));
198 Local(3) = GetMiddlestVertex(obj
);
199 SetAction("Connect", GetActionTarget(), obj
);
204 public func
LineBreak(object pBreak
) {
206 if(!pBreak
) BreakMessage();
210 func
BreakMessage() {
211 // Meldung bei Leitungsbausatz am einen oder anderen Ende ausgeben
212 var pObj
= GetActionTarget(0);
213 if(GetID(pObj
) != LNKT
)
214 pObj
= GetActionTarget(1);
215 Message("$RopeBroken$",pObj
);
219 public func
GetLength () { return (Length
); }
221 protected func
Destruction () {
222 // Benachrichtigungen
223 if(GetActionTarget(0)) GetActionTarget(0)->~RopeBreak(GetID(GetActionTarget(1)));
224 if(GetActionTarget(1)) GetActionTarget(1)->~RopeBreak(GetID(GetActionTarget(0)));