From 8ae824ff095605c5889828503cec09006ac07cc0 Mon Sep 17 00:00:00 2001 From: nebadon Date: Sun, 11 Dec 2011 23:25:12 -0700 Subject: Mantis 5816: osParseJSON Decoding Problems osParseJSON uses hand-crafted decoding that has two issues * does not seem to handle top-level JSON lists * does not seem to handle unicode text thanks otakup0pe! --- .../Shared/Api/Implementation/OSSL_Api.cs | 256 ++++++--------------- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 + 3 files changed, 72 insertions(+), 191 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index f3206ac..503b5d0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1552,209 +1552,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_ScriptEngine.World.GetSimulatorVersion(); } - public Hashtable osParseJSON(string JSON) + private Hashtable osdToHashtable(OSDMap map) + { + Hashtable result = new Hashtable(); + foreach (KeyValuePair item in map) { + result.Add(item.Key, osdToObject(item.Value)); + } + return result; + } + + private ArrayList osdToArray(OSDArray list) + { + ArrayList result = new ArrayList(); + foreach ( OSD item in list ) { + result.Add(osdToObject(item)); + } + return result; + } + + private Object osdToObject(OSD decoded) + { + if ( decoded is OSDString ) { + return (string) decoded.AsString(); + } else if ( decoded is OSDInteger ) { + return (int) decoded.AsInteger(); + } else if ( decoded is OSDReal ) { + return (float) decoded.AsReal(); + } else if ( decoded is OSDBoolean ) { + return (bool) decoded.AsBoolean(); + } else if ( decoded is OSDMap ) { + return osdToHashtable((OSDMap) decoded); + } else if ( decoded is OSDArray ) { + return osdToArray((OSDArray) decoded); + } else { + return null; + } + } + + public Object osParseJSONNew(string JSON) { CheckThreatLevel(ThreatLevel.None, "osParseJSON"); m_host.AddScriptLPS(1); - // see http://www.json.org/ for more details on JSON - - string currentKey = null; - Stack objectStack = new Stack(); // objects in JSON can be nested so we need to keep a track of this - Hashtable jsondata = new Hashtable(); // the hashtable to be returned - int i = 0; try { + OSD decoded = OSDParser.DeserializeJson(JSON); + return osdToObject(decoded); + } + catch(Exception e) + { + OSSLError("osParseJSONNew: Problems decoding JSON string " + JSON + " : " + e.Message) ; + return null; + } + } - // iterate through the serialised stream of tokens and store at the right depth in the hashtable - // the top level hashtable may contain more nested hashtables within it each containing an objects representation - for (i = 0; i < JSON.Length; i++) - { - - // m_log.Debug(""+JSON[i]); - switch (JSON[i]) - { - case '{': - // create hashtable and add it to the stack or array if we are populating one, we can have a lot of nested objects in JSON - - Hashtable currentObject = new Hashtable(); - if (objectStack.Count == 0) // the stack should only be empty for the first outer object - { - - objectStack.Push(jsondata); - } - else if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - // add it to the parent array - ((ArrayList)objectStack.Peek()).Add(currentObject); - objectStack.Push(currentObject); - } - else - { - // add it to the parent hashtable - ((Hashtable)objectStack.Peek()).Add(currentKey,currentObject); - objectStack.Push(currentObject); - } - - // clear the key - currentKey = null; - break; - - case '}': - // pop the hashtable off the stack - objectStack.Pop(); - break; - - case '"':// string boundary - - string tokenValue = ""; - i++; // move to next char - - // just loop through until the next quote mark storing the string, ignore quotes with pre-ceding \ - while (JSON[i] != '"') - { - tokenValue += JSON[i]; - - // handle escaped double quotes \" - if (JSON[i] == '\\' && JSON[i+1] == '"') - { - tokenValue += JSON[i+1]; - i++; - } - i++; - - } - - // ok we've got a string, if we've got an array on the top of the stack then we store it - if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - ((ArrayList)objectStack.Peek()).Add(tokenValue); - } - else if (currentKey == null) // no key stored and its not an array this must be a key so store it - { - currentKey = tokenValue; - } - else - { - // we have a key so lets store this value - ((Hashtable)objectStack.Peek()).Add(currentKey,tokenValue); - // now lets clear the key, we're done with it and moving on - currentKey = null; - } - - break; - - case ':':// key : value separator - // just ignore - break; - - case ' ':// spaces - // just ignore - break; - - case '[': // array start - ArrayList currentArray = new ArrayList(); - - if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - ((ArrayList)objectStack.Peek()).Add(currentArray); - } - else - { - ((Hashtable)objectStack.Peek()).Add(currentKey,currentArray); - // clear the key - currentKey = null; - } - objectStack.Push(currentArray); - - break; - - case ',':// seperator - // just ignore - break; - - case ']'://Array end - // pop the array off the stack - objectStack.Pop(); - break; - - case 't': // we've found a character start not in quotes, it must be a boolean true - - if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - ((ArrayList)objectStack.Peek()).Add(true); - } - else - { - ((Hashtable)objectStack.Peek()).Add(currentKey,true); - currentKey = null; - } - - //advance the counter to the letter 'e' - i = i + 3; - break; - - case 'f': // we've found a character start not in quotes, it must be a boolean false - - if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - ((ArrayList)objectStack.Peek()).Add(false); - } - else - { - ((Hashtable)objectStack.Peek()).Add(currentKey,false); - currentKey = null; - } - //advance the counter to the letter 'e' - i = i + 4; - break; - - case '\n':// carriage return - // just ignore - break; - - case '\r':// carriage return - // just ignore - break; - - default: - // ok here we're catching all numeric types int,double,long we might want to spit these up mr accurately - // but for now we'll just do them as strings - - string numberValue = ""; - - // just loop through until the next known marker quote mark storing the string - while (JSON[i] != '"' && JSON[i] != ',' && JSON[i] != ']' && JSON[i] != '}' && JSON[i] != ' ') - { - numberValue += "" + JSON[i++]; - } - - i--; // we want to process this caracter that marked the end of this string in the main loop + public Hashtable osParseJSON(string JSON) + { + CheckThreatLevel(ThreatLevel.None, "osParseJSON"); - // ok we've got a string, if we've got an array on the top of the stack then we store it - if (objectStack.Peek().ToString() == "System.Collections.ArrayList") - { - ((ArrayList)objectStack.Peek()).Add(numberValue); - } - else - { - // we have a key so lets store this value - ((Hashtable)objectStack.Peek()).Add(currentKey,numberValue); - // now lets clear the key, we're done with it and moving on - currentKey = null; - } + m_host.AddScriptLPS(1); - break; - } + Object decoded = osParseJSONNew(JSON); + + if ( decoded is Hashtable ) { + return (Hashtable) decoded; + } else if ( decoded is ArrayList ) { + ArrayList decoded_list = (ArrayList) decoded; + Hashtable fakearray = new Hashtable(); + int i = 0; + for ( i = 0; i < decoded_list.Count ; i++ ) { + fakearray.Add(i, decoded_list[i]); } + return fakearray; + } else { + OSSLError("osParseJSON: unable to parse JSON string " + JSON); + return null; } - catch(Exception) - { - OSSLError("osParseJSON: The JSON string is not valid " + JSON) ; - } - - return jsondata; } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 3221833..00ca070 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections; using OpenSim.Region.ScriptEngine.Interfaces; @@ -140,6 +141,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osGetScriptEngineName(); string osGetSimulatorVersion(); + Object osParseJSONNew(string JSON); Hashtable osParseJSON(string JSON); void osMessageObject(key objectUUID,string message); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 9e7c8da..0d7d5ea 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -396,6 +396,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osParseJSON(JSON); } + + public Object osParseJSONNew(string JSON) + { + return m_OSSL_Functions.osParseJSONNew(JSON); + } public void osMessageObject(key objectUUID,string message) { -- cgit v1.1 From c34ab0ee669f674b29d863267e64104b1a3437ef Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 12 Dec 2011 02:43:38 -0800 Subject: Cleaned up ScenePresence parameters for Flying, WasFlying, FlyingOld and IsColliding --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 89 ++++++++++++---------- .../Scenes/Tests/ScenePresenceAnimationTests.cs | 2 +- .../Scenes/Tests/ScenePresenceAutopilotTests.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 4 +- 6 files changed, 57 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 85debc4..4ab6fe4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5083,7 +5083,7 @@ namespace OpenSim.Region.Framework.Scenes presence.AbsolutePosition = presence.MoveToPositionTarget; presence.ResetMoveToTarget(); - if (presence.PhysicsActor.Flying) + if (presence.Flying) { // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot // the target if flying. @@ -5091,16 +5091,16 @@ namespace OpenSim.Region.Framework.Scenes // least be able to set collision status once, rather than 5 times to give it enough // weighting so that that PhysicsActor thinks it really is colliding. for (int i = 0; i < 5; i++) - presence.PhysicsActor.IsColliding = true; + presence.IsColliding = true; if (presence.LandAtTarget) - presence.PhysicsActor.Flying = false; + presence.Flying = false; // Vector3 targetPos = presence.MoveToPositionTarget; // float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; // if (targetPos.Z - terrainHeight < 0.2) // { -// presence.PhysicsActor.Flying = false; +// presence.Flying = false; // } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fa731a7..beff239 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -142,12 +142,27 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_userFlags; } } - private bool m_flyingOld; // add for fly velocity control + + // Flying + public bool Flying + { + get { return PhysicsActor != null && PhysicsActor.Flying; } + set { PhysicsActor.Flying = value; } + } + + // add for fly velocity control + private bool FlyingOld {get; set;} public bool WasFlying { - get { return m_wasFlying; } + get; private set; + } + + public bool IsColliding + { + get { return PhysicsActor != null && PhysicsActor.IsColliding; } + // We would expect setting IsColliding to be private but it's used by a hack in Scene + set { PhysicsActor.IsColliding = value; } } - private bool m_wasFlying; // add for fly velocity control // private int m_lastColCount = -1; //KF: Look for Collision chnages // private int m_updateCount = 0; //KF: Update Anims for a while @@ -682,9 +697,9 @@ namespace OpenSim.Region.Framework.Scenes set { if(value) { - if ((PhysicsActor != null) && PhysicsActor.Flying) + if (Flying) m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; - else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) + else m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; } m_inTransit = value; @@ -908,11 +923,11 @@ namespace OpenSim.Region.Framework.Scenes if (ForceFly) { - PhysicsActor.Flying = true; + Flying = true; } else if (FlyDisabled) { - PhysicsActor.Flying = false; + Flying = false; } // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying @@ -1037,10 +1052,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void Teleport(Vector3 pos) { - bool isFlying = false; - if (PhysicsActor != null) - isFlying = PhysicsActor.Flying; - + bool isFlying = Flying; RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -1051,10 +1063,7 @@ namespace OpenSim.Region.Framework.Scenes public void TeleportWithMomentum(Vector3 pos) { - bool isFlying = false; - if (PhysicsActor != null) - isFlying = PhysicsActor.Flying; - + bool isFlying = Flying; RemoveFromPhysicalScene(); AbsolutePosition = pos; AddToPhysicalScene(isFlying); @@ -1188,8 +1197,8 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; } - bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - MakeRootAgent(AbsolutePosition, m_flying); + bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + MakeRootAgent(AbsolutePosition, flying); if ((m_callbackURI != null) && !m_callbackURI.Equals("")) { @@ -1414,7 +1423,7 @@ namespace OpenSim.Region.Framework.Scenes bool DCFlagKeyPressed = false; Vector3 agent_control_v3 = Vector3.Zero; - bool oldflying = PhysicsActor.Flying; + bool oldflying = Flying; if (ForceFly) actor.Flying = true; @@ -1434,7 +1443,7 @@ namespace OpenSim.Region.Framework.Scenes // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying // this prevents 'jumping' in inappropriate situations. - if ((m_mouseLook && !PhysicsActor.Flying) || (m_leftButtonDown && !PhysicsActor.Flying)) + if (!Flying && (m_mouseLook || m_leftButtonDown)) dirVectors = GetWalkDirectionVectors(); else dirVectors = Dir_Vectors; @@ -1521,7 +1530,7 @@ namespace OpenSim.Region.Framework.Scenes // with something with the down arrow pressed. // Only do this if we're flying - if (PhysicsActor != null && PhysicsActor.Flying && !ForceFly) + if (Flying && !ForceFly) { // Landing detection code @@ -1529,7 +1538,7 @@ namespace OpenSim.Region.Framework.Scenes bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - if (PhysicsActor.Flying && PhysicsActor.IsColliding && controlland) + if (Flying && IsColliding && controlland) { // nesting this check because LengthSquared() is expensive and we don't // want to do it every step when flying. @@ -1742,9 +1751,9 @@ namespace OpenSim.Region.Framework.Scenes Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); if (noFly) - PhysicsActor.Flying = false; + Flying = false; else if (pos.Z > terrainHeight) - PhysicsActor.Flying = true; + Flying = true; LandAtTarget = landAtTarget; MovingToTarget = true; @@ -2307,42 +2316,42 @@ namespace OpenSim.Region.Framework.Scenes Vector3 direc = vec * Rotation; direc.Normalize(); - if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control + if (Flying != FlyingOld) // add for fly velocity control { - m_flyingOld = PhysicsActor.Flying; // add for fly velocity control - if (!PhysicsActor.Flying) - m_wasFlying = true; // add for fly velocity control + FlyingOld = Flying; // add for fly velocity control + if (!Flying) + WasFlying = true; // add for fly velocity control } - if (PhysicsActor.IsColliding == true) - m_wasFlying = false; // add for fly velocity control + if (IsColliding) + WasFlying = false; // add for fly velocity control - if ((vec.Z == 0f) && !PhysicsActor.Flying) + if ((vec.Z == 0f) && !Flying) direc.Z = 0f; // Prevent camera WASD up. direc *= 0.03f * 128f * SpeedModifier; if (PhysicsActor != null) { - if (PhysicsActor.Flying) + if (Flying) { direc *= 4.0f; //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); //if (controlland) // m_log.Info("[AGENT]: landCommand"); - //if (PhysicsActor.IsColliding) + //if (IsColliding) // m_log.Info("[AGENT]: colliding"); - //if (PhysicsActor.Flying && PhysicsActor.IsColliding && controlland) + //if (Flying && IsColliding && controlland) //{ // StopFlying(); // m_log.Info("[AGENT]: Stop Flying"); //} } - if (Animator.Falling && m_wasFlying) // if falling from flying, disable motion add + if (Animator.Falling && WasFlying) // if falling from flying, disable motion add { direc *= 0.0f; } - else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) + else if (!Flying && IsColliding) { if (direc.Z > 2.0f) { @@ -2809,7 +2818,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_requestedSitTargetUUID == UUID.Zero) { - bool isFlying = PhysicsActor.Flying; + bool isFlying = Flying; RemoveFromPhysicalScene(); Vector3 pos = AbsolutePosition; @@ -2836,7 +2845,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_requestedSitTargetUUID == UUID.Zero) { - bool isFlying = PhysicsActor.Flying; + bool isFlying = Flying; RemoveFromPhysicalScene(); Vector3 pos = AbsolutePosition; @@ -2886,7 +2895,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - return m_scene.CrossAgentToNewRegion(this, PhysicsActor.Flying); + return m_scene.CrossAgentToNewRegion(this, Flying); } catch { @@ -3162,7 +3171,7 @@ namespace OpenSim.Region.Framework.Scenes Appearance = new AvatarAppearance(cAgent.Appearance); if (PhysicsActor != null) { - bool isFlying = PhysicsActor.Flying; + bool isFlying = Flying; RemoveFromPhysicalScene(); AddToPhysicalScene(isFlying); } @@ -3265,7 +3274,7 @@ namespace OpenSim.Region.Framework.Scenes private void OutOfBoundsCall(Vector3 pos) { - //bool flying = PhysicsActor.Flying; + //bool flying = Flying; //RemoveFromPhysicalScene(); //AddToPhysicalScene(flying); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs index 4a0533c..89f8007 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene scene = SceneHelpers.SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); - sp.PhysicsActor.Flying = true; + sp.Flying = true; sp.PhysicsCollisionUpdate(new CollisionEventUpdate()); Assert.That(sp.Animator.CurrentMovementAnimation, Is.EqualTo("HOVER")); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index 64c36ff..442cb8b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Vector3 startPos = new Vector3(128, 128, 30); // For now, we'll make the scene presence fly to simplify this test, but this needs to change. - sp.PhysicsActor.Flying = true; + sp.Flying = true; m_scene.Update(); Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index dce0ec8..9c66b25 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); // For now, we'll make the scene presence fly to simplify this test, but this needs to change. - npc.PhysicsActor.Flying = true; + npc.Flying = true; scene.Update(); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6d067b0..443e7a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5573,9 +5573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // note: this may need some tweaking when walking downhill. you "fall down" for a brief instant // and don't collide when walking downhill, which instantly registers as in-air, briefly. should // there be some minimum non-collision threshold time before claiming the avatar is in-air? - if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && - agent.PhysicsActor != null && - !agent.PhysicsActor.IsColliding) + if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && !agent.IsColliding ) { flags |= ScriptBaseClass.AGENT_IN_AIR; } -- cgit v1.1