// CHECKME: check if this method allows to make people get away from traffic private static ushort CheckCitizen(Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max) { CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData(); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3(position, b); Vector3 vector = segment2.Min(); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max(); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; float num; float num2; if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius)) { float num3 = lastLen + nextLen * num; if (num3 >= 0.01f) { num3 -= 2f; float b2 = Mathf.Max(1f, CalculateMaxSpeed(num3, 0f, maxBraking)); maxSpeed = Mathf.Min(maxSpeed, b2); } } return(otherData.m_nextGridInstance); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider) { if (otherID == instanceID) { return(otherData.m_nextGridInstance); } if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground)) { return(otherData.m_nextGridInstance); } CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData(); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3(position, b); Vector3 vector = segment2.Min(); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max(); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + info.m_radius; float num3; float t; float num2 = segment.DistanceSqr(segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt(num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position(num3 * 0.9f); Vector3 b2 = segment2.Position(t); a.y = 0f; b2.y = 0f; Vector3 vector3 = a - b2; Vector3 vector4 = new Vector3(segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x); if (Vector3.Dot(vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3.normalized * (num4 * num5); pushDivider += num5; } } return(otherData.m_nextGridInstance); }
public override void SetSource(ushort instanceID, ref CitizenInstance data, ushort sourceBuilding) { //begin mod if (IsCagedAnimal(data) || LivestockAIDetour.isFreeAnimal(data)) { SetSourceCaged(instanceID, ref data, sourceBuilding); return; } //end mod if ((int)sourceBuilding == 0) { return; } CitizenManager instance = Singleton <CitizenManager> .instance; data.Unspawn(instanceID); Randomizer randomizer = new Randomizer((int)instanceID); CitizenInstance.Frame lastFrameData = instance.m_instances.m_buffer[(int)sourceBuilding].GetLastFrameData(); Quaternion quaternion = lastFrameData.m_rotation; Vector3 vector3_1 = quaternion * new Vector3(0.5f, 0.0f, 0.0f); if (randomizer.Int32(2U) == 0) { vector3_1 = -vector3_1; } Vector3 vector3_2 = lastFrameData.m_position + vector3_1; Vector4 vector4 = instance.m_instances.m_buffer[(int)sourceBuilding].m_targetPos + (Vector4)vector3_1; data.m_frame0.m_velocity = Vector3.zero; data.m_frame0.m_position = vector3_2; data.m_frame0.m_rotation = quaternion; data.m_frame1 = data.m_frame0; data.m_frame2 = data.m_frame0; data.m_frame3 = data.m_frame0; data.m_targetPos = vector4; data.Spawn(instanceID); }
public override void SimulationStep(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, bool lodPhysics) { float sqrMagnitude1 = frameData.m_velocity.sqrMagnitude; if ((double)sqrMagnitude1 > 0.00999999977648258) { frameData.m_position += frameData.m_velocity * 0.5f; } Vector3 vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; float sqrMagnitude2 = vector3_1.sqrMagnitude; float num1 = Mathf.Max(sqrMagnitude1 * 3f, 6f); if ((double)sqrMagnitude2 < (double)num1 && Singleton <SimulationManager> .instance.m_randomizer.Int32(20U) == 0 && (int)citizenData.m_targetBuilding != 0) { BuildingManager instance = Singleton <BuildingManager> .instance; Vector3 position; Vector3 target; Vector2 direction; CitizenInstance.Flags specialFlags; instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info.m_buildingAI.CalculateUnspawnPosition(citizenData.m_targetBuilding, ref instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding], ref Singleton <SimulationManager> .instance.m_randomizer, this.m_info, instanceID, out position, out target, out direction, out specialFlags); position.y = Singleton <TerrainManager> .instance.SampleDetailHeight(position); citizenData.m_targetPos = (Vector4)position; vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; sqrMagnitude2 = vector3_1.sqrMagnitude; } float a = this.m_info.m_walkSpeed; float b = 2f; if ((double)sqrMagnitude2 < 4.0) { vector3_1 = Vector3.zero; } else { float num2 = Mathf.Sqrt(sqrMagnitude2); //begin mod if (isFreeAnimal(citizenData)) { float maxLength = Mathf.Min(a, Mathf.Sqrt(num2 * b)); float num3_ = Mathf.Max(1f, 0.5f * sqrMagnitude1 / b); float num4 = Mathf.Max(8f, 0.5f * sqrMagnitude1 / b + maxLength); Vector3 position = frameData.m_position + vector3_1 * (num3_ / num2); var stubAi = new WildlifeAI { m_info = this.m_info }; if (WildlifeAIDetour.IsFreePosition(stubAi, frameData.m_position + vector3_1 * (num4 / num2))) { vector3_1 = Quaternion.Inverse(frameData.m_rotation) * vector3_1; if ((double)vector3_1.z < (double)Mathf.Abs(vector3_1.x) * 1.70000004768372) { vector3_1.x = (double)vector3_1.x < 0.0 ? Mathf.Min(-1f, vector3_1.x) : Mathf.Max(1f, vector3_1.x); vector3_1.z = Mathf.Abs(vector3_1.x) * 1.7f; maxLength = Mathf.Min(1.5f, num2 * 0.1f); } vector3_1 = Vector3.ClampMagnitude(frameData.m_rotation * vector3_1, maxLength); } else if (WildlifeAIDetour.IsFreePosition(stubAi, position)) { citizenData.m_targetPos = (Vector4)position; vector3_1 = Vector3.zero; } else if (WildlifeAIDetour.IsFreePosition(stubAi, frameData.m_position)) { citizenData.m_targetPos = (Vector4)frameData.m_position; vector3_1 = Vector3.zero; } else { citizenData.Unspawn(instanceID); return; } } else { //end mod float maxLength = Mathf.Min(a, num2 * 0.5f); vector3_1 = Quaternion.Inverse(frameData.m_rotation) * vector3_1; if ((double)vector3_1.z < (double)Mathf.Abs(vector3_1.x) * 5.0) { vector3_1.x = (double)vector3_1.x < 0.0 ? Mathf.Min(-1f, vector3_1.x) : Mathf.Max(1f, vector3_1.x); vector3_1.z = Mathf.Abs(vector3_1.x) * 5f; maxLength = Mathf.Min(0.5f, num2 * 0.1f); } vector3_1 = Vector3.ClampMagnitude(frameData.m_rotation * vector3_1, maxLength); //begin mod } //end mod } Vector3 vector3_2 = vector3_1 - frameData.m_velocity; float magnitude = vector3_2.magnitude; Vector3 vector3_3 = vector3_2 * (b / Mathf.Max(magnitude, b)); frameData.m_velocity += vector3_3; citizenData.m_targetPos.y = Singleton <TerrainManager> .instance.SampleDetailHeight(frameData.m_position + frameData.m_velocity); frameData.m_velocity.y = citizenData.m_targetPos.y - frameData.m_position.y; float sqrMagnitude3 = frameData.m_velocity.sqrMagnitude; if ((double)sqrMagnitude3 > 0.00999999977648258) { Vector3 forward = frameData.m_velocity; if (!lodPhysics) { Vector3 pushAmount = Vector3.zero; float pushDivider = 0.0f; //begin mod this.CheckCollisions(instanceID, ref citizenData, frameData.m_position, frameData.m_position + frameData.m_velocity, isFreeAnimal(citizenData) ? (ushort)0 : citizenData.m_targetBuilding, ref pushAmount, ref pushDivider); //end mod if ((double)pushDivider > 0.00999999977648258) { pushAmount *= 1f / pushDivider; pushAmount = Vector3.ClampMagnitude(pushAmount, Mathf.Sqrt(sqrMagnitude3) * 0.5f); frameData.m_velocity += pushAmount; forward += pushAmount * 0.25f; } } frameData.m_position += frameData.m_velocity * 0.5f; if ((double)forward.sqrMagnitude > 0.00999999977648258) { frameData.m_rotation = Quaternion.LookRotation(forward); } } if (this.m_randomEffect == null || Singleton <SimulationManager> .instance.m_randomizer.Int32(40U) != 0) { return; } InstanceID instance1 = new InstanceID(); instance1.CitizenInstance = instanceID; EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(frameData.m_position, Vector3.up, 0.0f); float num3 = 3.75f; Singleton <EffectManager> .instance.DispatchEffect(this.m_randomEffect, instance1, spawnArea, frameData.m_velocity *num3, 0.0f, 1f, Singleton <CitizenManager> .instance.m_audioGroup); }
public void SimulationStepCaged(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, bool lodPhysics) { float sqrMagnitude1 = frameData.m_velocity.sqrMagnitude; if ((double)sqrMagnitude1 > 0.00999999977648258) { frameData.m_position += frameData.m_velocity * 0.5f; } Vector3 vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; float sqrMagnitude2 = vector3_1.sqrMagnitude; float num1 = Mathf.Max(sqrMagnitude1 * 3f, 6f); if ((double)sqrMagnitude2 < (double)num1 && Singleton <SimulationManager> .instance.m_randomizer.Int32(20U) == 0 && (int)citizenData.m_targetBuilding != 0) { BuildingManager instance = Singleton <BuildingManager> .instance; Vector3 position; Vector3 target; Vector2 direction; CitizenInstance.Flags specialFlags; instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info.m_buildingAI.CalculateUnspawnPosition(citizenData.m_targetBuilding, ref instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding], ref Singleton <SimulationManager> .instance.m_randomizer, this.m_info, instanceID, out position, out target, out direction, out specialFlags); position.y = Singleton <TerrainManager> .instance.SampleDetailHeight(position); citizenData.m_targetPos = (Vector4)position; vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; sqrMagnitude2 = vector3_1.sqrMagnitude; } float a = this.m_info.m_walkSpeed; float b = 2f; if ((double)sqrMagnitude2 < 4.0) { vector3_1 = Vector3.zero; } else { float num2 = Mathf.Sqrt(sqrMagnitude2); float maxLength = Mathf.Min(a, num2 * 0.5f); vector3_1 = Quaternion.Inverse(frameData.m_rotation) * vector3_1; if ((double)vector3_1.z < (double)Mathf.Abs(vector3_1.x) * 5.0) { vector3_1.x = (double)vector3_1.x < 0.0 ? Mathf.Min(-1f, vector3_1.x) : Mathf.Max(1f, vector3_1.x); vector3_1.z = Mathf.Abs(vector3_1.x) * 5f; maxLength = Mathf.Min(0.5f, num2 * 0.1f); } vector3_1 = Vector3.ClampMagnitude(frameData.m_rotation * vector3_1, maxLength); } Vector3 vector3_2 = vector3_1 - frameData.m_velocity; float magnitude = vector3_2.magnitude; Vector3 vector3_3 = vector3_2 * (b / Mathf.Max(magnitude, b)); frameData.m_velocity += vector3_3; citizenData.m_targetPos.y = Singleton <TerrainManager> .instance.SampleDetailHeight(frameData.m_position + frameData.m_velocity); frameData.m_velocity.y = citizenData.m_targetPos.y - frameData.m_position.y; float sqrMagnitude3 = frameData.m_velocity.sqrMagnitude; if ((double)sqrMagnitude3 > 0.00999999977648258) { Vector3 forward = frameData.m_velocity; if (!lodPhysics) { Vector3 pushAmount = Vector3.zero; float pushDivider = 0.0f; this.CheckCollisions(instanceID, ref citizenData, frameData.m_position, frameData.m_position + frameData.m_velocity, citizenData.m_targetBuilding, ref pushAmount, ref pushDivider); if ((double)pushDivider > 0.00999999977648258) { pushAmount *= 1f / pushDivider; pushAmount = Vector3.ClampMagnitude(pushAmount, Mathf.Sqrt(sqrMagnitude3) * 0.5f); frameData.m_velocity += pushAmount; forward += pushAmount * 0.25f; } } frameData.m_position += frameData.m_velocity * 0.5f; if ((double)forward.sqrMagnitude > 0.00999999977648258) { frameData.m_rotation = Quaternion.LookRotation(forward); } } var m_randomEffect = ((PetAI)Convert.ChangeType(this, typeof(PetAI))).m_randomEffect; if (m_randomEffect == null || Singleton <SimulationManager> .instance.m_randomizer.Int32(40U) != 0) { return; } InstanceID instance1 = new InstanceID(); instance1.CitizenInstance = instanceID; EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(frameData.m_position, Vector3.up, 0.0f); float num3 = 3.75f; Singleton <EffectManager> .instance.DispatchEffect(m_randomEffect, instance1, spawnArea, frameData.m_velocity *num3, 0.0f, 1f, Singleton <CitizenManager> .instance.m_audioGroup); }
public override void SimulationStep(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, bool lodPhysics) { if (IsCagedAnimal(citizenData)) { SimulationStepCaged(instanceID, ref citizenData, ref frameData, lodPhysics); return; } else if (LivestockAIDetour.isFreeAnimal(citizenData)) { SimulationStepWild(instanceID, ref citizenData, ref frameData, lodPhysics); return; } float sqrMagnitude1 = frameData.m_velocity.sqrMagnitude; if ((double)sqrMagnitude1 > 0.00999999977648258) { frameData.m_position += frameData.m_velocity * 0.5f; } CitizenInstance.Flags flags1 = CitizenInstance.Flags.None; if ((int)citizenData.m_targetBuilding != 0) { CitizenManager instance = Singleton <CitizenManager> .instance; CitizenInstance.Flags flags2 = instance.m_instances.m_buffer[(int)citizenData.m_targetBuilding].m_flags; if ((flags2 & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None) { Randomizer randomizer = new Randomizer((int)instanceID); CitizenInstance.Frame lastFrameData = instance.m_instances.m_buffer[(int)citizenData.m_targetBuilding].GetLastFrameData(); Vector3 vector3 = lastFrameData.m_rotation * new Vector3(0.5f, 0.0f, 0.0f); if (randomizer.Int32(2U) == 0) { vector3 = -vector3; } Vector4 vector4 = instance.m_instances.m_buffer[(int)citizenData.m_targetBuilding].m_targetPos + (Vector4)vector3; if ((double)Vector3.SqrMagnitude(lastFrameData.m_position - frameData.m_position) > 10000.0) { citizenData.m_targetBuilding = (ushort)0; } else { flags1 = flags2 & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.InsideBuilding | CitizenInstance.Flags.Transition); citizenData.m_targetPos = vector4; } } else { citizenData.m_targetBuilding = (ushort)0; } } citizenData.m_flags = citizenData.m_flags & ~(CitizenInstance.Flags.Underground | CitizenInstance.Flags.InsideBuilding | CitizenInstance.Flags.Transition) | flags1; Vector3 v = (Vector3)citizenData.m_targetPos - frameData.m_position; float f = lodPhysics || (double)citizenData.m_targetPos.w <= 1.0 / 1000.0 ? v.sqrMagnitude : VectorUtils.LengthSqrXZ(v); float a = this.m_info.m_walkSpeed; float b = 2f; if ((double)f < 1.0) { v = Vector3.zero; } else { float num = Mathf.Sqrt(f); float maxLength = Mathf.Min(a, num * 0.75f); v = Quaternion.Inverse(frameData.m_rotation) * v; if ((double)v.z < (double)Mathf.Abs(v.x)) { v.x = (double)v.x < 0.0 ? Mathf.Min(-1f, v.x) : Mathf.Max(1f, v.x); v.z = Mathf.Abs(v.x); maxLength = Mathf.Min(0.5f, num * 0.1f); } v = Vector3.ClampMagnitude(frameData.m_rotation * v, maxLength); } Vector3 vector3_1 = v - frameData.m_velocity; float magnitude = vector3_1.magnitude; Vector3 vector3_2 = vector3_1 * (b / Mathf.Max(magnitude, b)); frameData.m_velocity += vector3_2; float sqrMagnitude2 = frameData.m_velocity.sqrMagnitude; bool flag = !lodPhysics && (double)citizenData.m_targetPos.w > 1.0 / 1000.0 && ((double)sqrMagnitude2 > 0.00999999977648258 || (double)sqrMagnitude1 > 0.00999999977648258); ushort buildingID = !flag ? (ushort)0 : Singleton <BuildingManager> .instance.GetWalkingBuilding(frameData.m_position + frameData.m_velocity * 0.5f); if ((double)sqrMagnitude2 > 0.00999999977648258) { Vector3 forward = frameData.m_velocity; if (!lodPhysics) { Vector3 pushAmount = Vector3.zero; float pushDivider = 0.0f; this.CheckCollisions(instanceID, ref citizenData, frameData.m_position, frameData.m_position + frameData.m_velocity, buildingID, ref pushAmount, ref pushDivider); if ((double)pushDivider > 0.00999999977648258) { pushAmount *= 1f / pushDivider; pushAmount = Vector3.ClampMagnitude(pushAmount, Mathf.Sqrt(sqrMagnitude2) * 0.5f); frameData.m_velocity += pushAmount; forward += pushAmount * 0.25f; } } frameData.m_position += frameData.m_velocity * 0.5f; if ((double)forward.sqrMagnitude > 0.00999999977648258) { frameData.m_rotation = Quaternion.LookRotation(forward); } } if (flag) { Vector3 worldPos = frameData.m_position; float terrainHeight = Singleton <TerrainManager> .instance.SampleDetailHeight(worldPos); if ((int)buildingID != 0) { float num = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)buildingID].SampleWalkingHeight(worldPos, terrainHeight); worldPos.y = worldPos.y + (num - worldPos.y) * Mathf.Min(1f, citizenData.m_targetPos.w * 4f); frameData.m_position.y = worldPos.y; } else if ((double)Mathf.Abs(terrainHeight - worldPos.y) < 2.0) { worldPos.y = worldPos.y + (terrainHeight - worldPos.y) * Mathf.Min(1f, citizenData.m_targetPos.w * 4f); frameData.m_position.y = worldPos.y; } } frameData.m_underground = (citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None; frameData.m_insideBuilding = (citizenData.m_flags & CitizenInstance.Flags.InsideBuilding) != CitizenInstance.Flags.None; frameData.m_transition = (citizenData.m_flags & CitizenInstance.Flags.Transition) != CitizenInstance.Flags.None; var mRandomEffect = ((PetAI)Convert.ChangeType(this, typeof(PetAI))).m_randomEffect; if (mRandomEffect == null || Singleton <SimulationManager> .instance.m_randomizer.Int32(40U) != 0) { return; } InstanceID instance1 = new InstanceID(); instance1.CitizenInstance = instanceID; EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(frameData.m_position, Vector3.up, 0.0f); float num1 = 3.75f; Singleton <EffectManager> .instance.DispatchEffect(mRandomEffect, instance1, spawnArea, frameData.m_velocity *num1, 0.0f, 1f, Singleton <CitizenManager> .instance.m_audioGroup); }
public override void SimulationStep(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, bool lodPhysics) { //Debug.Log(CitizenManager.instance.GetDefaultCitizenName(citizenData.m_citizen) + ", leaving from " + BuildingManager.instance.GetBuildingName(citizenData.m_sourceBuilding, new InstanceID { Building = citizenData.m_sourceBuilding }) + ", is headed to target " + BuildingManager.instance.GetBuildingName(citizenData.m_targetBuilding, new InstanceID { Building = citizenData.m_targetBuilding }) + "."); //Debug.Log(CitizenManager.instance.GetDefaultCitizenName(citizenData.m_citizen) + ", leaving from " + BuildingManager.instance.m_buildings.m_buffer[(int)citizenData.m_sourceBuilding].m_position.x + "/" + BuildingManager.instance.m_buildings.m_buffer[(int)citizenData.m_sourceBuilding].m_position.z + " is traveling to " + BuildingManager.instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].m_position.x + "/" + BuildingManager.instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].m_position.z + "."); //Debug.Log(CitizenManager.instance.GetDefaultCitizenName(citizenData.m_citizen) + ", is traveling to " + citizenData.m_targetPos.x + "/" + citizenData.m_targetPos.z + ". and is at " + frameData.m_position.x + "/" + frameData.m_position.z + "."); /* * citizenData.m_path * citizenData.m_targetDir * citizenData.m_targetPos * PathManager.instance.m_properties * frameData.m_insideBuilding * frameData.m_position * frameData.m_velocity */ uint num1 = Singleton <SimulationManager> .instance.m_currentFrameIndex; //num1 = current frame Vector3 vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; //vector3_1 = targetpos - citizen's frame location float f = lodPhysics || (double)citizenData.m_targetPos.w <= 1.0 / 1000.0 ? vector3_1.sqrMagnitude : VectorUtils.LengthSqrXZ(vector3_1); //set physics float sqrMagnitude1 = frameData.m_velocity.sqrMagnitude; //sqrMagnitude1 = square lendth of the frame vector float minSqrDistance = Mathf.Max(sqrMagnitude1 * 3f, 3f); //minSqrDistance = max (sqrMagnitude1 * 3 , 3) if (lodPhysics && (long)(num1 >> 4 & 3U) == (long)((int)instanceID & 3)) //if physics and if ??? { minSqrDistance *= 4f; //multiply minSqrDistance by 4 } bool flag1 = false; //flag1 = false if ((citizenData.m_flags & CitizenInstance.Flags.TryingSpawnVehicle) != CitizenInstance.Flags.None) //if the citizen is trying to spawn a vehicle { bool flag2 = true; //flag2 is true if ((int)++citizenData.m_waitCounter == (int)byte.MaxValue || (int)citizenData.m_path == 0) //if the citizen has no path or if their wait counter is approaching max { flag2 = false; //flag2 is false } if (flag2) //if flag is true { PathUnit.Position position; flag2 = Singleton <PathManager> .instance.m_pathUnits.m_buffer[(long)citizenData.m_path].GetPosition((int)citizenData.m_pathPositionIndex >> 1, out position); //flag2 (bool) set to validity of citizen's location if (flag2) //if flag2 is still true { flag2 = this.SpawnVehicle(instanceID, ref citizenData, position); //flag2 is set to the success of spawning a vehicle } } if (!flag2) //if flag2 is false { citizenData.m_flags &= ~CitizenInstance.Flags.TryingSpawnVehicle; //set flag TryingSpawnVehicle is false citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; //set flag Bored of Waiting to false citizenData.m_waitCounter = (byte)0; //reset Wait counter this.InvalidPath(instanceID, ref citizenData); //report an invalid path } } else if ((citizenData.m_flags & CitizenInstance.Flags.WaitingTransport) != CitizenInstance.Flags.None) //else if flag WaitingTransport is true { bool flag2 = true; //flag2 is true if ((int)citizenData.m_waitCounter < (int)byte.MaxValue) //if wait counter is less than 255 { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) //have a 33%-50% chance of in { ++citizenData.m_waitCounter; } } else if ((citizenData.m_flags & CitizenInstance.Flags.BoredOfWaiting) == CitizenInstance.Flags.None) //else if flag BoredofWaiting is false { citizenData.m_flags |= CitizenInstance.Flags.BoredOfWaiting; //set flag BoredOfWaiting to true citizenData.m_waitCounter = (byte)0; //reset wait counter } //else (wait counter exceeded AND bored of waiting is true) else { citizenData.m_flags &= ~CitizenInstance.Flags.WaitingTransport; //flag WaitingTransport is false citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; //flag BoredOfWaiting is false citizenData.m_flags |= CitizenInstance.Flags.CannotUseTransport; //flag CannotUseTransport is true citizenData.m_waitCounter = (byte)0; //reset wait counter flag2 = false; //flag2 is false this.InvalidPath(instanceID, ref citizenData); //report invalid path } if (flag2 && (double)f < (double)minSqrDistance) //if flag2 is true and f (physics) < minSqrDistance { if ((long)(num1 >> 4 & 7U) == (long)((int)instanceID & 7)) //if num1 (currentframeindex) is equal to the instanceID ??? { citizenData.m_targetPos = this.GetTransportWaitPosition(instanceID, ref citizenData, ref frameData, minSqrDistance); //set the target position to GetTransportWaitPosition ** } vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; //vector3_1 = target position - frame position (current position?) f = lodPhysics || (double)citizenData.m_targetPos.w <= 1.0 / 1000.0 ? vector3_1.sqrMagnitude : VectorUtils.LengthSqrXZ(vector3_1); //something with physics } } else if ((citizenData.m_flags & CitizenInstance.Flags.WaitingTaxi) != CitizenInstance.Flags.None) //else if flag WaitingTaxi is true { bool flag2 = false; //flag2 is false if ((int)citizenData.m_citizen != 0) //if citizen is valid { flag2 = (int)Singleton <CitizenManager> .instance.m_citizens.m_buffer[(long)citizenData.m_citizen].m_vehicle != 0; //flag2 is the validity of the citizen's vehicle if (!flag2 && (long)(num1 >> 4 & 15U) == (long)((int)instanceID & 15)) //if vehicle is valid and if frame instance is equal to the citizen instance { Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.Taxi, new TransferManager.TransferOffer() //AddIncomingOFfer(reason: taxi) { Priority = 7, //Sets attributes of transfer offer Citizen = citizenData.m_citizen, Position = frameData.m_position, Amount = 1, Active = false }); } } if ((int)citizenData.m_waitCounter < (int)byte.MaxValue) //if wait counter isn't exceeded { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0) //33%-50% chance of incrementing counter { ++citizenData.m_waitCounter; } } else if ((citizenData.m_flags & CitizenInstance.Flags.BoredOfWaiting) == CitizenInstance.Flags.None) //else if flag BoredOfWaiting is false { citizenData.m_flags |= CitizenInstance.Flags.BoredOfWaiting; //flag BoredOfWaiting is true citizenData.m_waitCounter = (byte)0; //reset wait counter } else if (!flag2) //else if flag2 is false { citizenData.m_flags &= ~CitizenInstance.Flags.WaitingTaxi; //flag WaitingTaxi is false citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; //flag BoredOfWaiting is false citizenData.m_flags |= CitizenInstance.Flags.CannotUseTaxi; //flag CannotUseTaxi is true citizenData.m_waitCounter = (byte)0; //reset wait counter this.InvalidPath(instanceID, ref citizenData); //report invalid path } } else if ((citizenData.m_flags & CitizenInstance.Flags.EnteringVehicle) != CitizenInstance.Flags.None) //else if flag EnteringVehicle is true { if ((double)f < (double)minSqrDistance) //if f (physics) is less than minSqrDistance { citizenData.m_targetPos = this.GetVehicleEnterPosition(instanceID, ref citizenData, minSqrDistance); //set target position to GetVechileEnterPosition (citizen instance, minSqrDistance vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; //vector3_1 is target position - frame (instance?) position f = lodPhysics || (double)citizenData.m_targetPos.w <= 1.0 / 1000.0 ? vector3_1.sqrMagnitude : VectorUtils.LengthSqrXZ(vector3_1); //something with physics } } else if ((double)f < (double)minSqrDistance) //else if f (physics) is less than minSqrDistance { if ((int)citizenData.m_path != 0) //if citizen has a path { if ((citizenData.m_flags & CitizenInstance.Flags.WaitingPath) == CitizenInstance.Flags.None) //if flag WaitingPathis false { citizenData.m_targetPos = this.GetPathTargetPosition(instanceID, ref citizenData, ref frameData, minSqrDistance); //target position = GetPathTargetPosition (ID, citizen instance, minSqrDistance if ((citizenData.m_flags & CitizenInstance.Flags.OnPath) == CitizenInstance.Flags.None) //if flag OnPath is false { citizenData.m_targetPos.w = 1f; //target position's w = 1 } } } else { //else (if citizen lacks a path) if ((citizenData.m_flags & CitizenInstance.Flags.RidingBicycle) != CitizenInstance.Flags.None) //if flag RidingBicycle is true { if ((int)citizenData.m_citizen != 0) //if citizen is valid { Singleton <CitizenManager> .instance.m_citizens.m_buffer[(long)citizenData.m_citizen].SetVehicle(citizenData.m_citizen, (ushort)0, 0U); //set this citizen's vehicle to 0 } citizenData.m_flags &= ~CitizenInstance.Flags.RidingBicycle; //flag RidingBicycle is false } citizenData.m_flags &= ~(CitizenInstance.Flags.OnPath | CitizenInstance.Flags.OnBikeLane); //??? probably means that both flags OnPath and OnBikeLane are set to false? if ((int)citizenData.m_targetBuilding != 0 && ((citizenData.m_flags & CitizenInstance.Flags.AtTarget) == CitizenInstance.Flags.None || (long)(num1 >> 4 & 15U) == (long)((int)instanceID & 15))) { //if target building is valid and if (flag AtTarget is false or if some condition comparing frame instance and citizen ID is met) this.GetBuildingTargetPosition(instanceID, ref citizenData, minSqrDistance); //GetBuildingTargetPosition (iD, citizen instanec and minSqrDistance) } if ((citizenData.m_flags & CitizenInstance.Flags.Panicking) == CitizenInstance.Flags.None) //if flag Panicking is false { flag1 = true; //flag1 is true } } vector3_1 = (Vector3)citizenData.m_targetPos - frameData.m_position; //Vector3_1 = tgarget position - frame (instance?) position f = lodPhysics || (double)citizenData.m_targetPos.w <= 1.0 / 1000.0 ? vector3_1.sqrMagnitude : VectorUtils.LengthSqrXZ(vector3_1); //physics command } float num2 = this.m_info.m_walkSpeed; //num2 = walk speed float b = 2f; //b = 2 if ((citizenData.m_flags & CitizenInstance.Flags.HangAround) != CitizenInstance.Flags.None) //if flag HangAround is true { num2 = Mathf.Max(num2 * 0.5f, 1f); //num2 = max(num2 / 2 , 1) } else if ((citizenData.m_flags & CitizenInstance.Flags.RidingBicycle) != CitizenInstance.Flags.None) //else if flag RidingBicycle is true (meaning that flag HangAround is false) { if ((citizenData.m_flags & CitizenInstance.Flags.OnBikeLane) != CitizenInstance.Flags.None) //if flag OnBikeLane is true { num2 *= 2f; //num2 *= } else { num2 *= 1.5f; } //else //num2 *= 1.5 } if ((double)sqrMagnitude1 > 0.00999999977648258) //if sqrMagnitude1 > 0.999999 (could mean >= 1 or a loss of precision (>1) { frameData.m_position += frameData.m_velocity * 0.5f; //position += velocity / 2 } Vector3 vector3_2; if ((double)f < 1.0) // { vector3_2 = Vector3.zero; if ((citizenData.m_flags & CitizenInstance.Flags.EnteringVehicle) != CitizenInstance.Flags.None) { if (this.EnterVehicle(instanceID, ref citizenData)) { return; } } else if (flag1) { if (this.ArriveAtTarget(instanceID, ref citizenData)) { return; } citizenData.m_flags |= CitizenInstance.Flags.AtTarget; if (Singleton <SimulationManager> .instance.m_randomizer.Int32(256U) == 0) { citizenData.m_targetSeed = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(256U); } } else { citizenData.m_flags &= ~CitizenInstance.Flags.AtTarget; } } else { float num3 = Mathf.Sqrt(f); float num4 = Mathf.Sqrt(sqrMagnitude1); float num5 = Mathf.Max(0.0f, Vector3.Dot(vector3_1, frameData.m_velocity) / Mathf.Max(1f, num4 * num3)); float num6 = Mathf.Max(0.5f, num2 * num5 * num5 * num5); vector3_2 = vector3_1 * Mathf.Min(0.577f, num6 / num3); citizenData.m_flags &= ~CitizenInstance.Flags.AtTarget; if ((citizenData.m_flags & CitizenInstance.Flags.RequireSlowStart) != CitizenInstance.Flags.None && (int)citizenData.m_waitCounter < 8) { ++citizenData.m_waitCounter; frameData.m_velocity = Vector3.zero; return; } } frameData.m_underground = (citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None; frameData.m_insideBuilding = (citizenData.m_flags & CitizenInstance.Flags.InsideBuilding) != CitizenInstance.Flags.None; frameData.m_transition = (citizenData.m_flags & CitizenInstance.Flags.Transition) != CitizenInstance.Flags.None; if ((double)f < 1.0 && flag1 && (citizenData.m_flags & CitizenInstance.Flags.SittingDown) != CitizenInstance.Flags.None) { citizenData.m_flags |= CitizenInstance.Flags.RequireSlowStart; citizenData.m_waitCounter = (byte)0; frameData.m_velocity = ((Vector3)citizenData.m_targetPos - frameData.m_position) * 0.5f; frameData.m_position += frameData.m_velocity * 0.5f; if ((double)citizenData.m_targetDir.sqrMagnitude <= 0.00999999977648258) { return; } frameData.m_rotation = Quaternion.LookRotation(VectorUtils.X_Y(citizenData.m_targetDir)); } else { citizenData.m_flags &= ~CitizenInstance.Flags.RequireSlowStart; Vector3 vector3_3 = vector3_2 - frameData.m_velocity; float magnitude = vector3_3.magnitude; vector3_3 *= b / Mathf.Max(magnitude, b); frameData.m_velocity += vector3_3; frameData.m_velocity -= Mathf.Max(0.0f, Vector3.Dot(frameData.m_position + frameData.m_velocity - (Vector3)citizenData.m_targetPos, frameData.m_velocity)) / Mathf.Max(0.01f, frameData.m_velocity.sqrMagnitude) * frameData.m_velocity; float sqrMagnitude2 = frameData.m_velocity.sqrMagnitude; bool flag2 = !lodPhysics && (double)citizenData.m_targetPos.w > 1.0 / 1000.0 && ((double)sqrMagnitude2 > 0.00999999977648258 || (double)sqrMagnitude1 > 0.00999999977648258); ushort buildingID = !flag2 ? (ushort)0 : Singleton <BuildingManager> .instance.GetWalkingBuilding(frameData.m_position + frameData.m_velocity * 0.5f); if ((double)sqrMagnitude2 > 0.00999999977648258) { if (!lodPhysics) { Vector3 zero = Vector3.zero; float pushDivider = 0.0f; this.CheckCollisions(instanceID, ref citizenData, frameData.m_position, frameData.m_position + frameData.m_velocity, buildingID, ref zero, ref pushDivider); if ((double)pushDivider > 0.00999999977648258) { Vector3 vector3_4 = Vector3.ClampMagnitude(zero * (1f / pushDivider), Mathf.Sqrt(sqrMagnitude2) * 0.9f); frameData.m_velocity += vector3_4; } } frameData.m_position += frameData.m_velocity * 0.5f; Vector3 forward = frameData.m_velocity; if ((citizenData.m_flags & CitizenInstance.Flags.RidingBicycle) == CitizenInstance.Flags.None) { forward.y = 0.0f; } if ((double)forward.sqrMagnitude > 0.00999999977648258) { frameData.m_rotation = Quaternion.LookRotation(forward); } } if (!flag2) { return; } Vector3 worldPos = frameData.m_position; float terrainHeight = Singleton <TerrainManager> .instance.SampleDetailHeight(worldPos); if ((int)buildingID != 0) { float num3 = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)buildingID].SampleWalkingHeight(worldPos, terrainHeight); worldPos.y = worldPos.y + (num3 - worldPos.y) * Mathf.Min(1f, citizenData.m_targetPos.w * 4f); frameData.m_position.y = worldPos.y; } else { if ((double)Mathf.Abs(terrainHeight - worldPos.y) >= 2.0) { return; } worldPos.y = worldPos.y + (terrainHeight - worldPos.y) * Mathf.Min(1f, citizenData.m_targetPos.w * 4f); frameData.m_position.y = worldPos.y; } } if ((int)citizenData.m_citizen != 0) { if (Tracker.AccessibilitySourceActive()) { TrafficLog.CitizenStepBroadcastedSource(citizenData.m_citizen); } if (Tracker.AccessibilityTargetActive()) { TrafficLog.CitizenStepBroadcastedTarget(citizenData.m_citizen); } } }
private Vector4 GetTransportWaitPosition(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, float minSqrDistance) { PathManager instance1 = Singleton <PathManager> .instance; NetManager instance2 = Singleton <NetManager> .instance; PathUnit.Position position1; if (!instance1.m_pathUnits.m_buffer[citizenData.m_path].GetPosition((int)citizenData.m_pathPositionIndex >> 1, out position1)) { this.InvalidPath(instanceID, ref citizenData); return(citizenData.m_targetPos); } ushort num1 = instance2.m_segments.m_buffer[(int)position1.m_segment].m_startNode; if ((citizenData.m_flags & CitizenInstance.Flags.BoredOfWaiting) != CitizenInstance.Flags.None) { instance2.m_nodes.m_buffer[(int)num1].m_maxWaitTime = byte.MaxValue; } else if ((int)citizenData.m_waitCounter > (int)instance2.m_nodes.m_buffer[(int)num1].m_maxWaitTime) { instance2.m_nodes.m_buffer[(int)num1].m_maxWaitTime = citizenData.m_waitCounter; } uint laneID = instance2.m_nodes.m_buffer[(int)num1].m_lane; if ((int)laneID == 0) { return(citizenData.m_targetPos); } uint num2 = (uint)instance2.m_lanes.m_buffer[laneID].m_segment; NetInfo.Lane laneInfo; if (!instance2.m_segments.m_buffer[num2].GetClosestLane(laneID, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, out laneID, out laneInfo)) { return(citizenData.m_targetPos); } ushort num3 = instance2.m_segments.m_buffer[num2].m_startNode; ushort num4 = instance2.m_segments.m_buffer[num2].m_endNode; if (((instance2.m_nodes.m_buffer[(int)num3].m_flags | instance2.m_nodes.m_buffer[(int)num4].m_flags) & NetNode.Flags.Disabled) != NetNode.Flags.None) { citizenData.m_waitCounter = byte.MaxValue; } Randomizer randomizer = new Randomizer((uint)instanceID | laneID << 16); float num5 = instance2.m_nodes.m_buffer[(int)num1].Info.m_netAI.MaxTransportWaitDistance(); int num6 = (int)instance2.m_nodes.m_buffer[(int)num1].m_laneOffset << 8; int @int = Mathf.RoundToInt(num5 * 65280f / Mathf.Max(1f, instance2.m_lanes.m_buffer[laneID].m_length)); int min = Mathf.Clamp(num6 - @int, 0, 65280); int max = Mathf.Clamp(num6 + @int, 0, 65280); int num7 = randomizer.Int32(min, max); Vector3 position2; Vector3 direction; instance2.m_lanes.m_buffer[laneID].CalculatePositionAndDirection((float)num7 * 1.531863E-05f, out position2, out direction); float num8 = (float)((double)Mathf.Max(0.0f, laneInfo.m_width - 1f) * (double)randomizer.Int32(-500, 500) * (1.0 / 1000.0)); position2 += Vector3.Cross(Vector3.up, direction).normalized *num8; return(new Vector4(position2.x, position2.y, position2.z, 0.0f)); }