// September 2015 // Levee Patroller / Dijk Patrouille // This source file is (c) by Deltares. This source file is open source but only available to select users. Do not redistribute without written permission of Stichting Deltares, Delft, The Netherlands. // This header has been automatically generated. class FailureExporter extends Actor; var name failurename; var FileLog file; /// Used for a hack: var name nTempName; //// List of triggered objects found in the script var array triggers; /// Names which have been processed already. var array processednames; /// Likely pivot / center point. var vector LikelyCenter; struct centercalc { var vector pos; var int count; }; var rotator LikelyRotation; struct rotationcalc { var rotator rot; var int count; }; /// Array containing names of the measure events. var array MeasureEvents; function ExportFailure(name sname) { failurename = sname; Log("Exporter created " @ sname); file = Spawn( class'FileLog' ); file.OpenLog("FailureExport_" @ sname); WriteScript(); CreateObjects(false); CreateMeasureInfo(); FindExtraMeasureScripts(); CreateFailureInfo(); CreateSignalInfo(); LoopTroughFoundObjects(); FindRedMarkerActions(); /// 2nd time for attachtags: LoopTroughFoundObjects(); // FindAttachedObjects(); CreateObjects(true); file.CloseLog(); file.Destroy(); } function WriteScript(optional ScriptedTrigger otherobject) { local ScriptedTrigger Ct, O; local int i; local string t; local string c; /// Find script with given failurename if (otherobject == None) { /// Without an othername, use the failure trigger foreach AllActors(class'ScriptedTrigger', Ct) { if (Ct.Tag == self.failurename) { O = Ct; break; } } } else { O = otherobject; } /// Otherwise use the given object /// If we didn't find anything, exit: if (O == None) return; Write("sT.Actions.insert(0, " $ O.Actions.length $ ");"); Write(" "); for(i = 0; i < O.Actions.Length; i++) { t = StripClass(O.Actions[i].class); Write("sT.Actions["$ i $"] = new class'"$ t $"';"); /// Clear: c = ""; Log(i @ " - " @ O.Actions[i].class @ " - " @ O.Actions[i].name); if (t == "ACTION_WaitForTimer") { c = t $ "(sT.Actions[" $ i $ "]).PauseTime = " $ ACTION_WaitForTimer(O.Actions[i]).PauseTime $ " * speedfactor;"; } if (t == "ACTION_IfActive") { c = t $ "(sT.Actions[" $ i $ "]).FailureTag = GetName(id$\"\");"; } if (t == "ACTION_TriggerEvent") { c = t $ "(sT.Actions[" $ i $ "]).Event = GetName(id$\"" $ ACTION_TriggerEvent(O.Actions[i]).Event $ "\");"; ///Insert trigger in list: triggers.insert(0,1); triggers[0] = ACTION_TriggerEvent(O.Actions[i]).Event; } if (t == "ACTION_TriggerEventOnce") { if (IsWaterMover(ACTION_TriggerEventOnce(O.Actions[i]).Eventn) == true) { /// This is a water polder mover: c = t $ "(sT.Actions[" $ i $ "]).Eventn = LinkedTile.WaterMover.Tag;"; } else { Write("/*"); Write("Notice: TriggerEventOnce is often used for the water mover. Please check if the water mover needs to be used here:"); Write("///" $ t $ "(sT.Actions[" $ i $ "]).Eventn = LinkedTile.WaterMover.Tag );"); Write("*/"); c = t $ "(sT.Actions[" $ i $ "]).Eventn = GetName(id$\"" $ ACTION_TriggerEventOnce(O.Actions[i]).Eventn $ "\");"; } ///Insert trigger in list: triggers.insert(0,1); triggers[0] = ACTION_TriggerEventOnce(O.Actions[i]).Eventn; } if (t == "ACTION_WaitForEvent") { c = t $ "(sT.Actions[" $ i $ "]).ExternalEvent = GetName(id$\"" $ ACTION_WaitForEvent(O.Actions[i]).ExternalEvent $ "\");"; } if (t == "ACTION_IfRelevant") { c = t $ "(sT.Actions[" $ i $ "]).FailureTag = GetName(id$\"\");"; } if (t == "ACTION_IfCritical") { c = t $ "(sT.Actions[" $ i $ "]).FailureTag = GetName(id$\"\");"; } if (t == "ACTION_IfNoRightMeasuresTaken") { c = t $ "(sT.Actions[" $ i $ "]).FailureTag = GetName(id$\"\");"; } if (t == "ACTION_Failed") { c = t $ "(sT.Actions[" $ i $ "]).FailureTag = GetName(id$\"\");"; } if (t == "ACTION_DestroyActor") { c = t $ "(sT.Actions[" $ i $ "]).DestroyTag = GetName(id$\"" $ ACTION_DestroyActor(O.Actions[i]).DestroyTag $ "\");"; } if (t == "ACTION_SetHidden") { c = t $ "(sT.Actions["$ i $"]).HideActorTag = GetName(id$\"" $ ACTION_SetHidden(O.Actions[i]).HideActorTag $ "\");"; /// Write immediatly: Write(c); c = t $ "(sT.Actions["$ i $"]).bHidden = " $ ACTION_SetHidden(O.Actions[i]).bHidden $ ";"; } if (t == "ACTION_EndGame") { c = " "; } if (Len(c) == 0) { c = "//DID NOT RECOGNIZE: " $ t; } /// Write to file: Write(c); Write(""); } } /// Check if the referenced object is a water mover (true) or not (False) function bool IsWaterMover(name NameString) { local String s; s = Caps(NameString); /// Known names: if (s == "TOPPOLDERWATERMOVER") return true; if (s == "POLDERWATEROOSTMOVER") return true; if (s == "POLDERWATERNOORDMOVER") return true; return false; } /// Kind of a hack to be able to create dynamic names for the various triggers. function name GetName(string NameString) { SetPropertyText("nTempName", NameString); return nTempName; } /// Strip classname so we only get the actual name, minus the package. function string StripClass(class str) { local int p; local string s; p = InStr(str, ".") + 1; s = Mid(str, p); return s; } function Write(string str) { file.logf(str); } function array GetActors(array names) { local array ret; local int i; local actor A; Log("GetActors"); for(i = 0; i < names.Length; i++) { A = GetActor(names[i]); if (A != None) { /// Store: ret.insert(0,1); ret[0] = A; } } return ret; } function CreateObjects(bool secondloop) { local Failure O; local GraphicalActors G; // local FluidSurfaceInfo fluid; local int i,j, numkeys; local Actor A; local string classname; local Mover M; local Vector v; local Rotator r; local bool found; local array Actors; local rotator RotTemp; local array calc; local array rotcalc; local int maxcount; local string loc; /// Emitters: // local float angle_degrees; // local vector v1,v2; // local float distance; local string strarray; local array strvalues; local string movertype; //either 'M' or 'Mv'; /// Find script with given failurename O = GetFailure(); /// If we didn't find anything, exit: if (O == None) return; /// Loop through graphical actors: G = O.OnlyVisibleIfActive; Write(" "); Write(" "); Write("/// Creating World Objects:"); if (secondloop == false) { Actors = G.GraphActor; } else { Log("SecondLoop"); Actors = GetActors(triggers); } /// Calculate the likely center (based on the movers): - Loop 1 only!!!!!!!!!!!! if (secondloop == false) { for(i = 0; i < Actors.Length; i++) { A = GetActor(Actors[i].Name); /// Strip classname: classname = StripClass(A.Class); if (classname == "Mover" || classname == "VariableTimedMover" && A.StaticMesh != StaticMesh'SecDikeSM.Measures.sandbag') { v = A.Location; r = A.Rotation; found = false; for(j = 0; j < calc.Length; j++) { /// Same location? if (calc[j].pos.x ~= v.x && calc[j].pos.y ~= v.y && calc[j].pos.z ~= v.z) { calc[j].count++; found = true; break; } } if (found == false) { /// Add to list: calc.insert(0,1); calc[0].pos = v; calc[0].count = 1; } /// Rotation as well: found = false; for(j = 0; j < rotcalc.Length; j++) { /// Same location? if (rotcalc[j].rot.pitch ~= r.pitch && rotcalc[j].rot.yaw ~= r.yaw && rotcalc[j].rot.roll ~= r.roll) { rotcalc[j].count++; found = true; break; } } if (found == false) { /// Add to list: rotcalc.insert(0,1); rotcalc[0].rot = r; rotcalc[0].count = 1; } } } /// Test result: maxcount = 0; for(j = 0; j < calc.Length; j++) { // Log ("Center calc: " @ calc[j].pos @ " - " @ calc[j].count); if (calc[j].count > maxcount) { maxcount = calc[j].count; LikelyCenter = calc[j].pos; } } maxcount = 0; for(j = 0; j < rotcalc.Length; j++) { // Log ("Rotation calc: " @ rotcalc[j].rot @ " - " @ rotcalc[j].count); if (rotcalc[j].count > maxcount) { maxcount = rotcalc[j].count; LikelyRotation = rotcalc[j].rot; } } Log("Likely center:" @ LikelyCenter); Write("/// For the record: The likely center is:" @ LikelyCenter); Write("/// For the record: The likely center rotation:" @ LikelyRotation); ///Invert: LikelyRotation.Yaw = -LikelyRotation.Yaw; /// Write this value as a function so that the failure is configured for this automatically. //if (LikelyRotation.Yaw != 16384) //{ Write("/// Set relative rotation, the original failure was based on a rotation of " $ LikelyRotation.Yaw $ ". So now we need to turn it back."); Write("SetFailureRelativeRotation(" $ -LikelyRotation.Yaw $ ");"); Write(""); Write(""); //} } Log("Object creation loop. Actor length:" @ Actors.Length); //for(i = 0; i < Actors.Length; i++) i = 0; while (i < Actors.Length) { Log(Actors[i].Name); /// Not processed before? if (!in_array(Actors[i].Name)) { processednames.Insert(0,1); processednames[0] = Actors[i].Name; A = GetActor(Actors[i].Name); if (A.bHiddenEd == true) { Write("//// NOTICE: " @ A @ " is HIDDEN in the editor!!!"); } /// Determine wether it's the default location or an offset. loc = "Location"; v = A.Location; if (!(v.x ~= LikelyCenter.x) || !(v.y ~= LikelyCenter.y) || !(v.z ~= LikelyCenter.z)) { /// Offset. loc = "RotateVector("$ v.x - LikelyCenter.x $ "," $ v.y - LikelyCenter.y $ "," $ v.z - LikelyCenter.z $ ")"; } if (A == None) Write ("/// " $ Actors[i] $ " - NOT FOUND"); /// Strip classname: classname = StripClass(A.Class); /// Cannot be used. /* if (classname == "FluidSurfaceInfo") { fluid = FluidSurfaceInfo(A); Write("local FluidSurfaceInfo fluid;"); Write("fluid.SetLocation(" $ loc $ ");"); Write("fluid.SetPropertyText(\"Tag\", id$\"" $ A.Tag $ "\");"); // Workaround, see below RotTemp = A.Rotation; RotTemp.Yaw += LikelyRotation.Yaw; Write("RotationOffset(fluid" $ ", LinkedTile.Rotation, " $ RotTemp.Pitch $ "," $ RotTemp.Yaw $ "," $ RotTemp.Roll $ ");"); Write("fluid.FluidGridSpacing= " $ fluid.FluidGridSpacing $ ";"); Write("fluid.FluidXSize = " $ fluid.FluidXSize $ ";"); Write("fluid.FluidYSize = " $ fluid.FluidYSize $ ";"); Write("fluid.FluidSpeed = " $ fluid.FluidSpeed $ ";"); Write("fluid.FluidNoiseStrength.Min = " $ fluid.FluidNoiseStrength.Min $ ";"); Write("fluid.FluidNoiseStrength.Max = " $ fluid.FluidNoiseStrength.Max $ ";"); Write("fluid.Tag = GetName(id$\"" $ fluid.AttachTag $ "\");"); if (Len(A.AttachTag) > 0 && A.AttachTag != 'None') { Write("fluid.AttachTag = GetName(id$\"" $ A.AttachTag $ "\");"); Write("fluid.SetBase(GetActor(fluid.AttachTag), vect(0,0,1));"); } If (A.Skins.Length != 0) { /// Write skins: Write("fluid.Skins.Insert(0," $ A.Skins.Length $ ");"); for(j = 0; j < A.Skins.Length; j++) { Write("fluid.Skins[" $ j $ "] = Texture(DynamicLoadObject(\"" $ A.Skins[j] $ "\", class'Texture'));"); } } Write("AddToVIAList(fluid);"); } */ if (classname == "StaticMeshActor") { Write("sMA = CreateMesh("$ loc $", id$\"" $ A.Tag $ "\", StaticMesh'" $ A.StaticMesh $ "');"); if (Len(A.AttachTag) > 0 && A.AttachTag != 'None' ) Write("sMA.AttachTag = GetName(id$\"" $ A.AttachTag $ "\");"); If (A.DrawScale != 1.0) { Write("sMA.SetDrawScale(" $ A.DrawScale $ ");"); } If (A.Skins.Length != 0) { /// Write skins: Write("sMA.Skins.Insert(0," $ A.Skins.Length $ ");"); for(j = 0; j < A.Skins.Length; j++) { Write("sMA.Skins[" $ j $ "] = Texture(DynamicLoadObject(\"" $ A.Skins[j] $ "\", class'Texture'));"); } } RotTemp = A.Rotation; RotTemp.Yaw += LikelyRotation.Yaw; Write("RotationOffset(sMA" $ ", LinkedTile.Rotation, " $ RotTemp.Pitch $ "," $ RotTemp.Yaw $ "," $ RotTemp.Roll $ ");"); } if (classname == "Mover" || A.IsA('VariableTimedMover') ) { movertype = "M"; if (A.IsA('VariableTimedMover') ) { movertype = "Mv"; strarray = (A).GetPropertyText("KeyMoveTime"); Split2(strarray, ",", strvalues); } M = Mover(A); numkeys = M.NumKeys; /* /// Find first 0,0,0 ,0,0,0 combi. for(j = 1; j <= 10; j++) { v = M.GetKeyPos(j); r = M.GetKeyRot(j); /// Exit if needed. if ( (v.x ~= 0 && v.y ~= 0 && v.z ~= 0) && (r.pitch ~= 0 && r.yaw ~= 0 && r.roll ~= 0) ) { break; } numkeys++; } */ if (A.IsA('VariableTimedMover') ) { Write("Mv = CreateVariableMover("$ loc $ ", id$\"" $ A.Tag $ "\", StaticMesh'" $ A.StaticMesh $ "' , " $ M.MoveTime $ ", " $ numkeys $ ");"); } else { Write("M = CreateMover("$ loc $ ", id$\"" $ A.Tag $ "\", StaticMesh'" $ A.StaticMesh $ "' , " $ M.MoveTime $ ", " $ numkeys $ ");"); } If (A.DrawScale != 1.0) { Write(movertype $ ".SetDrawScale(" $ A.DrawScale $ ");"); } for(j = 1; j < numkeys; j++) { v = M.GetKeyPos(j); r = M.GetKeyRot(j); Write(movertype $ ".SetKeyPos( RotateVectorNoLocation(" $ v.x $ "," $ v.y $ "," $ v.z $ "), " $ j $ ");" ); Write(movertype $ ".SetKeyRot( rot(" $ r.pitch $ "," $ r.yaw $ "," $ r.roll $ "), " $ j $ ");" ); if (A.IsA('VariableTimedMover') ) { if (Len(strvalues[j]) > 0) { // bug fix: if (Right(strvalues[j],1) == ")") { strvalues[j] = Mid(strvalues[j],0, Len(strvalues[j]) -1); } Write( movertype $ ".SetMovetime(" $ strvalues[j] $ "," $ j $");" ); } } } if (Len(A.AttachTag) > 0 && A.AttachTag != 'None') { Write(movertype $ ".AttachTag = GetName(id$\"" $ A.AttachTag $ "\");"); Write(movertype $ ".SetBase(GetActor(M.AttachTag), vect(0,0,1));"); } if (M.OtherTime > 0 ) Write(movertype $ ".OtherTime = " $ M.OtherTime $ " * speedfactor;"); RotTemp = M.BaseRot; RotTemp.Yaw += LikelyRotation.Yaw; Write("RotationOffset(" $ movertype $ ", LinkedTile.Rotation, " $ RotTemp.Pitch $ "," $ RotTemp.Yaw $ "," $ RotTemp.Roll $ ");"); } if (classname == "Emitter") { /// Calculate angle: //v1 = Normal (A.Location); //v2 = Normal (LikelyCenter); //angle_degrees = ATan2( (v2.x-v1.x) , (v2.y-v1.y) ) * 57.2957795131 ; //Acos(v1 dot v2) * 180/3.141592; //Log ("Angle of " @ A.Tag @ " = " @ angle_degrees); //distance = sqrt((A.Location.x-LikelyCenter.x)*(A.Location.x-LikelyCenter.x) + (A.Location.y-LikelyCenter.y)*(A.Location.y-LikelyCenter.y)); //Log ("Distance of " @ A.Tag @ " = " @ distance @ " - " @ A.Location @ " - " @ LikelyCenter); /// Emitters aren't based on objects, so we will just write some info down, we cannot write down complete emitters: found = false; if (Instr(A.Tag, "LotsOfWaterEmitter") > -1) { Write("E = Spawn(class'LotsOfWaterEmitter');"); found = true; } if (Instr(A.Tag, "CrashSplash") > -1) { Write("E = Spawn(class'SplashCrashEmitter');"); found = true; } if (Instr(A.Tag, "BigMud") > -1) { Write("E = Spawn(class'BigMudEmitter');"); found = true; } if (Instr(A.Tag, "Bubbles") > -1) { Write("E = Spawn(class'MudBubbles');"); found = true; } if (found == false) { /// We do not recognize it as common emitter, write it down: Write("E = Spawn(class'');"); } /// default stuff: //Write("t = CalculateRotation(E, " $ distance $", " $ angle_degrees $ ");"); //Write("E.SetLocation(t);"); /// E.SetLocation(VectorOffset(vect(992.00,-3104.00,576.00)) ); RotTemp = A.Rotation; RotTemp.Yaw += LikelyRotation.Yaw; Write("E.SetLocation(" $ loc $ ");"); Write("E.SetPropertyText(\"Tag\", id$\"" $ A.Tag $ "\");"); // Workaround, see below Write("RotationOffset(E" $ ", LinkedTile.Rotation, " $ RotTemp.Pitch $ "," $ RotTemp.Yaw $ "," $ RotTemp.Roll $ ");"); /// Write Location as comment, might be useful: //Write("/// E.SetLocation(" $ loc $ " );"); Write("AddToVIAList(E);"); if (Len(A.AttachTag) > 0 && A.AttachTag != 'None') { Write("E.AttachTag = GetName(id$\"" $ A.AttachTag $ "\");"); Write("E.SetBase(GetActor(E.AttachTag), vect(0,0,1));"); } } /// Does it have an attachtag? if (Len(O.AttachTag) > 0 && O.AttachTag != 'None' ) { if (!in_triggerarray(O.AttachTag)) { ///Insert in list: triggers.insert(0,1); triggers[0] = O.AttachTag; } } Write(" "); } i++; } if (secondloop == false) { Write("/// CHECK AT THE BOTTOM OF THIS FILE FOR ADDITIONAL OBJECTS CREATED IN THE 2ND PASS!!!"); } ///exit. //Consolecommand("quit"); } function float ATan2(float Y,float X) { local float tempang; if(X==0) { //div by 0 checks. if(Y<0) return -pi/2.0; else if(Y>0) return pi/2.0; else return 0; //technically impossible (nothing exists) } tempang=ATan(Y/X,1); if (X<0) tempang+=pi; //1st/3rd quad //normalize (from -pi to pi) if(tempang>pi) tempang-=pi*2.0; if(tempang<-pi) tempang+=pi*2.0; return tempang; } /// Loop through all actors which have been referenced by TriggerEvent actions in the script, and see if we need to add them. function LoopTroughFoundObjects() { local int i; local Actor O; Write(" "); Write(" "); Write("/// Creating Linked Objects:"); for(i = 0; i < triggers.Length; i++) { Log(triggers[i]); } for(i = 0; i < triggers.Length; i++) { /// Find script with given failurename if (triggers[i] != 'None') { foreach AllActors(class'Actor', O, triggers[i]) { if (!in_array(O.Name) && !in_triggerarray(O.name)) { Write("/// Found additional NAME (by loop): " $ O.Tag $ " " $ O.Name $ " trigger: " $ triggers[i]); triggers.insert(0,1); triggers[0] = O.Name; } /// Does it have an attachtag? if (Len(O.AttachTag) > 0 && O.AttachTag != 'None') { if (!in_triggerarray(O.AttachTag)) { Write("/// Found additional AttachTag (by loop): " $ O.Tag $ " " $ O.Name $ " trigger: " $ triggers[i]); ///Insert in list: triggers.insert(0,1); triggers[0] = O.AttachTag; } } //} //} } } } } function bool in_array(name nm) { local int i; for(i = 0; i < processednames.Length; i++) { if (processednames[i] == nm) { return true; /// Found. } } /// Not found: return false; } function bool in_triggerarray(name nm) { local int i; Log("Trigger array length: " @ triggers.Length); if (nm == 'None') return true; for(i = 0; i < triggers.Length; i++) { if (triggers[i] == nm) { return true; /// Found. } } /// Not found: return false; } function CreateFailureInfo() { local Failure F; /// Find script with given failurename F = GetFailure(); /// If we didn't find anything, exit: if (F == None) return; Write(" "); Write(" "); Write("/// Failure information:"); Write("Mechanism = " $ GetEnum( enum'FailingMechanisms',F.Mechanism) $ ";"); Write("LinkedTile.Mechanism = Mechanism;"); Write("NL_FailureName = \"" $ F.NL_FailureName $ "\";"); Write("EN_FailureName = \"" $ F.EN_FailureName $ "\";"); // Write("LeveeType = " $ GetEnum( enum'TypeOfLevee',F.LeveeType) $ ";"); } function Failure GetFailure() { local Failure F, O; /// Find script with given failurename foreach AllActors(class'Failure', F) { if (F.Tag == self.failurename) { O = F; break; } } return O; } function Actor GetActor(name sname) { local Actor P; local int i; foreach AllActors(class'Actor', P) { i++; /// ridiculous fix, really. if (i > 99998) { return None; } if (P.Name == sname) { return P; } } return None; } function CreateSignalInfo() { local Failure O; local int i,j; local string t, t2; local string sclass, sclass2; /// If we didn't find anything, exit: O = GetFailure(); if (O == None) return; Write(" "); Write(" "); Write("/// Signals information:"); Write("Signals.Insert(0," $ O.Signals.Length $ ");"); for(i = 0; i < O.Signals.Length; i++) { Write(" "); t = "signal" $ i; sclass = StripClass(O.Signals[i].class); /// Write variable declaration, these will have to be pasted manually. Write("/// local " $ sclass $ " " $ t $ ";"); if (sclass == "SignalSettlement") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".RevetmentType=" $ GetEnum( enum'GeoRevetments', SignalSettlement( O.Signals[i]).RevetmentType) $ ";"); Write(t $ ".SettlementPosition=" $ GetEnum( enum'SettlementPositions', SignalSettlement(O.Signals[i]).SettlementPosition) $ ";"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalSettlement(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalSettlement(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalHorizontalMovement") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".RevetmentType=" $ GetEnum( enum'GeoRevetments', SignalHorizontalMovement(O.Signals[i]).RevetmentType) $ ";"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalHorizontalMovement(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalHorizontalMovement(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalWaterOutflow") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalWaterOutflow(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalCrack") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".RevetmentType=" $ GetEnum( enum'GeoRevetments', SignalCrack(O.Signals[i]).RevetmentType) $ ";"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalCrack(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalCrack(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalHumanActivity") { Write(t $ " = New class'" $ sclass $ "';"); //Write(t $ ".RevetmentType=" $ GetEnum( enum'GeoRevetments', SignalCrack(O.Signals[i]).RevetmentType) $ ";"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalHumanActivity(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalHumanActivity(O.Signals[i]).CrossCutLocation) $ ";"); Write(t $ ".RiskCause=" $ GetEnum( enum'RiskFactor', SignalHumanActivity(O.Signals[i]).RiskCause) $ ";"); } if (sclass == "SignalOverToppingWash") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalOverToppingWash(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalOverToppingWash(O.Signals[i]).CrossCutLocation) $ ";"); Write(t $ ".TypeOcurring=" $ GetEnum( enum'OverType', SignalOverToppingWash(O.Signals[i]).TypeOcurring) $ ";"); } if (sclass == "SignalLiquefaction") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalLiquefaction(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalLiquefaction(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalGrass") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalGrass(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalGrass(O.Signals[i]).CrossCutLocation) $ ";"); } if (sclass == "SignalFloatingWaste") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalFloatingWaste(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalFloatingWaste(O.Signals[i]).CrossCutLocation) $ ";"); Write(t $ ".RiskCause=" $ GetEnum( enum'RiskFactor', SignalFloatingWaste(O.Signals[i]).RiskCause) $ ";"); } if (sclass == "SignalRipPitching") { Write(t $ " = New class'" $ sclass $ "';"); Write(t $ ".FirstState=" $ GetEnum( enum'GeoStates', SignalRipPitching(O.Signals[i]).FirstState) $ ";"); Write(t $ ".CrossCutLocation=" $ GetEnum( enum'GeoCutLocation', SignalRipPitching(O.Signals[i]).CrossCutLocation) $ ";"); Write(t $ ".RevetmentType=" $ GetEnum( enum'GeoRevetments', SignalRipPitching(O.Signals[i]).RevetmentType) $ ";"); } Write(t $ ".SignalType=" $ GetEnum( enum'GeoSignalTypes', (O.Signals[i]).SignalType) $ ";"); Write(" "); Write(t $ ".SignalReports.insert(0," $ O.Signals[i].SignalReports.Length $ ");"); for(j = 0; j < O.Signals[i].SignalReports.Length; j++) { t2 = t $ "report" $ j; sclass2 = StripClass(O.Signals[i].SignalReports[j].class); Write("/// local " $ sclass2 $ " " $ t2 $ ";"); Write(t2 $ " = New class'" $ sclass2 $ "';"); Write(t2 $ ".GeoState = " $ GetEnum( enum'GeoStates', (O.Signals[i].SignalReports[j]).GeoState)$ ";"); if (sclass2 == "SignalReportSettlement") { /// Report: Write(t2 $ ".HeightDifference = " $ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).HeightDifference)$ ";"); Write(t2 $ ".HeightDifferenceMax = "$ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).HeightDifferenceMax)$ ";"); Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportSettlement(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); } if (sclass2 == "SignalReportHorizontalMovement") { /// Report: Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportHorizontalMovement(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportHorizontalMovement(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportHorizontalMovement(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportHorizontalMovement(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); } if (sclass2 == "SignalReportWaterOutflow") { /// Report: Write(t2 $ ".CurrentSpeed = " $ GetEnum( enum'Speed', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).CurrentSpeed) $ ";"); Write(t2 $ ".WaterFlowOut = " $ GetEnum( enum'Quantity', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).WaterFlowOut)$ ";"); Write(t2 $ ".MultipleLocations = " $ GetEnum( enum'GeoYesNo', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).MultipleLocations) $";"); Write(t2 $ ".FlushingSoil = " $ GetEnum( enum'GeoYesNo', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).FlushingSoil)$ ";"); Write(t2 $ ".FlushingSoilQuantity = " $ GetEnum( enum'Quantity', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).FlushingSoilQuantity)$ ";"); Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportWaterOutflow(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); } if (sclass2 == "SignalReportCrack") { /// Report: Write(t2 $ ".MultipleCracks = "$ GetEnum( enum'GeoYesNo', SignalReportCrack(O.Signals[i].SignalReports[j]).MultipleCracks) $";"); Write(t2 $ ".FlushingSoil = "$ GetEnum( enum'GeoYesNo', SignalReportCrack(O.Signals[i].SignalReports[j]).FlushingSoil) $";"); Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportCrack(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportCrack(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportCrack(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportCrack(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); } if (sclass2 == "SignalReportFloatingWaste") { /// Report: /// Nothing? } if (sclass2 == "SignalReportHumanActivity") { /// Report: } if (sclass2 == "SignalReportGrass") { /// Report: Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportGrass(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportGrass(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportGrass(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportGrass(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); } if (sclass2 == "SignalReportOverToppingWash") { /// Report: Write(t2 $ ".IsAccessible = "$ GetEnum( enum'GeoYesNo', SignalReportOverToppingWash(O.Signals[i].SignalReports[j]).IsAccessible) $";"); Write(t2 $ ".InfiltrateTopInner = "$ GetEnum( enum'GeoYesNo', SignalReportOverToppingWash(O.Signals[i].SignalReports[j]).InfiltrateTopInner) $";"); Write(t2 $ ".WaterFlowQuantity = "$ GetEnum( enum'Quantity', SignalReportOverToppingWash(O.Signals[i].SignalReports[j]).WaterFlowQuantity) $";"); Write(t2 $ ".FlushingSoil = "$ GetEnum( enum'GeoYesNo', SignalReportOverToppingWash(O.Signals[i].SignalReports[j]).FlushingSoil) $";"); Write(t2 $ ".FlushingSoilQuantity = "$ GetEnum( enum'Quantity', SignalReportOverToppingWash(O.Signals[i].SignalReports[j]).FlushingSoilQuantity) $";"); } if (sclass2 == "SignalReportRipPitching") { Write(t2 $ ".LengthOfDamage = " $ GetEnum( enum'GeoSizes', SignalReportRipPitching(O.Signals[i].SignalReports[j]).LengthOfDamage) $ ";"); Write(t2 $ ".LengthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportRipPitching(O.Signals[i].SignalReports[j]).LengthOfDamageMax)$ ";"); Write(t2 $ ".WidthOfDamage = "$ GetEnum( enum'GeoSizes', SignalReportRipPitching(O.Signals[i].SignalReports[j]).WidthOfDamage)$ ";"); Write(t2 $ ".WidthOfDamageMax = "$ GetEnum( enum'GeoSizes', SignalReportRipPitching(O.Signals[i].SignalReports[j]).WidthOfDamageMax)$ ";"); Write(t2 $ ".ElementsMissingOrMoved = "$ GetEnum( enum'GeoYesNo', SignalReportRipPitching(O.Signals[i].SignalReports[j]).ElementsMissingOrMoved)$ ";"); Write(t2 $ ".FlushingSoil = "$ GetEnum( enum'GeoYesNo', SignalReportRipPitching(O.Signals[i].SignalReports[j]).FlushingSoil)$ ";"); Write(t2 $ ".FlushingSoilQuantity = "$ GetEnum( enum'Quantity', SignalReportRipPitching(O.Signals[i].SignalReports[j]).FlushingSoilQuantity)$ ";"); Write(t2 $ ".ElementsLoose = "$ GetEnum( enum'GeoYesNo', SignalReportRipPitching(O.Signals[i].SignalReports[j]).ElementsLoose)$ ";"); } /// Store: Write(t $ ".SignalReports[" $ j $ "] = " $ t2 $ ";"); Write("Signals[" $ i $ "] = " $ t $ ";"); } } } function CreateMeasureInfo() { local Failure O; local int i,j; local bool found; /// If we didn't find anything, exit: O = GetFailure(); if (O == None) return; Write(" "); Write(" "); Write("/// Creating measures:"); Write("Measures.Insert(0," $ O.Measures.Length $ ");"); for(i = 0; i < O.Measures.Length; i++) { Write("Msr = New class'Measure';"); Write("Msr.SetPropertyText(\"EventMeasureTaken\", id$\"" $ O.Measures[i].EventMeasureTaken $ "\");"); // Workaround, see below Write("Msr.bMeasureEffective = " $ O.Measures[i].bMeasureEffective $ ";"); Write("Msr.MeasureType = " $ GetEnum( enum'EMeasures',O.Measures[i].MeasureType) $ ";"); Write("Measures[" $ i $ "] = Msr;"); /// Insert into measurement array. - If it does not exist yet found = false; for (j = 0; j < MeasureEvents.Length ; j++ ) { if (MeasureEvents[i] == O.Measures[i].EventMeasureTaken) { found = true; } } /// Not found? add: if (found == false) { MeasureEvents.Insert(0,1); MeasureEvents[i] = O.Measures[i].EventMeasureTaken; } } } function FindExtraMeasureScripts() { local ScriptedTrigger Ct; local int i; local string t; local Actor O; Write(" "); Write(" "); Write("/// Trying to write down extra measure scriptedtriggers"); /// Loop through all events: for (i = 0; i < MeasureEvents.Length ; i++ ) { if (MeasureEvents[i] != 'None') { Write("/// Trying to find: " @ MeasureEvents[i]); /// Without an othername, use the failure trigger foreach AllActors(class'ScriptedTrigger', Ct) { /// Classname: /// Check if first action is a wait for event: t = StripClass(Ct.Actions[0].class); if (t == "ACTION_WaitForEvent") { //Write("/// Event: " @ ACTION_WaitForEvent(Ct.Actions[0]).ExternalEvent); if (ACTION_WaitForEvent(Ct.Actions[0]).ExternalEvent == MeasureEvents[i]) { /// Write script: WriteScript(Ct); Write(" "); } } /// 2007-11-13 Jln /// Sometimes the first one is pauze, so we need to check the second as well: /// Check if first action is a wait for event: t = StripClass(Ct.Actions[1].class); if (t == "ACTION_WaitForEvent") { if (ACTION_WaitForEvent(Ct.Actions[1]).ExternalEvent == MeasureEvents[i]) { /// Write script: WriteScript(Ct); Write(" "); } } } /// Find additional objects with this trigger: foreach AllActors(class'Actor', O, MeasureEvents[i]) { if (!in_array(O.Name) && !in_triggerarray(O.name)) { Write("/// Found additional (by measure): " $ O.Tag $ " " $ O.Name); triggers.insert(0,1); triggers[0] = O.Name; /// Does it have an attachtag? if (Len(O.AttachTag) > 0 && O.AttachTag != 'None') { ///Insert in list: if (!in_array(O.Name) && !in_triggerarray(O.AttachTag)) { triggers.insert(0,1); triggers[0] = O.AttachTag; } } } } } } } function FindRedMarkerActions() { /// Levels seem to have one central script that makes some events happen /// This also includes the relocation of RedMarkers when the waterlevel is rising /// we need to take these actions in to account as well. These happen in a different script which is not attached to anything though /// therefore we have to search for the object first. /// We only use the redmarker move event which belongs to this failure. local ScriptedTrigger Ct; local int i; local string t,loc; local vector vecredmarker, v; Write(" "); Write(" "); Write("/// Searching RedMarker events "); /// Without an othername, use the failure trigger foreach AllActors(class'ScriptedTrigger', Ct) { /// Loop through al lactions: for (i = 0; i < Ct.Actions.Length ; i++ ) { t = StripClass(Ct.Actions[i].class); if (t == "ACTION_MoveRedMarker") { Log("found redmarker, exporting"); if (ACTION_MoveRedMarker(Ct.Actions[i]).FailureTag == failurename) { /// Calculate offset: vecredmarker = ACTION_MoveRedMarker(Ct.Actions[i]).Location; loc = "RedMarkerLocation = RotateVectorInvertRelative(" $ vecredmarker.x $ "," $ vecredmarker.y $ "," $ vecredmarker.z $ ");"; v = vecredmarker; if (!(v.x ~= LikelyCenter.x) || !(v.y ~= LikelyCenter.y) || !(v.z ~= LikelyCenter.z)) { /// Offset. loc = "RedMarkerLocation = RotateVectorInvertRelative("$ v.x - LikelyCenter.x $ "," $ v.y - LikelyCenter.y $ "," $ v.z - LikelyCenter.z $ ");"; } Write(loc); Write(" "); } } } } } function FindAttachedObjects() { local Actor O, K; foreach AllActors(class'Actor', O) { /// Does it have an AttachTag? if (Len(O.AttachTag) > 0 && O.AttachTag != 'None') { /// Check if the attachtag refers to one our already known objects? foreach AllActors(class'Actor',K, O.AttachTag) { /// Match, add it to the trigger list: if (!in_triggerarray(O.name)) { triggers.insert(0,1); triggers[0] = O.Name; } break; } } } } static final function int Split2(coerce string src, string delim, out array parts, optional bool ignoreEmpty, optional string quotechar) { local string temp; Parts.Remove(0, Parts.Length); if (delim == "" || Src == "" ) return 0; while (src != "") { temp = StrShift(src, delim, quotechar); if (temp == "") { if (!ignoreEmpty) { parts.length = parts.length+1; parts[parts.length-1] = temp; } } else { parts.length = parts.length+1; parts[parts.length-1] = temp; } } return parts.length; } static final function string StrShift(out string line, string delim, optional string quotechar) { local int delimpos, quotepos; local string result; if ( quotechar != "" && Left(line, Len(quotechar)) == quotechar ) { do { quotepos = InstrFrom(line, quotechar, quotepos + 1); } until (quotepos == -1 || quotepos + Len(quotechar) == Len(line) || Mid(line, quotepos + len(quotechar), len(delim)) == delim); } if ( quotepos != -1 ) { delimpos = InstrFrom(line, delim, quotepos); } else { delimpos = Instr(line, delim); } if (delimpos == -1) { result = line; line = ""; } else { result = Left(line,delimpos); line = Mid(line,delimpos+len(delim)); } if ( quotechar != "" && Left(result, Len(quotechar)) == quotechar ) { result = Mid(result, Len(quotechar), Len(result)-(Len(quotechar)*2)); } return result; } // InStr starting from an offset static final function int InStrFrom(coerce string StrText, coerce string StrPart, optional int OffsetStart) { local int OffsetPart; OffsetPart = InStr(Mid(StrText, OffsetStart), StrPart); if (OffsetPart >= 0) OffsetPart += OffsetStart; return OffsetPart; }