public override void Execute(clsGroundAtom refGroundAtom) { // stop all activities if you're dead if (refGroundAtom.healthStatus.isDead) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new DEAD_STATE()); return; } // or incapacitated if (refGroundAtom.healthStatus.isIncapacitated) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new INCAPACITATED_STATE()); return; } // get next waypoint when the current waypoint is reached if (reachedTargetPosition(refGroundAtom)) { targetPosition = CalculateNextWaypointPosition(refGroundAtom); return; } // perform step base.Execute(refGroundAtom); }
protected void reevaluationAfterForcesHaveArrivedEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.currentSpeed = refGroundAtom.baselineSpeed; // if in social comparison state and not stuck stay in social comparison - things seems to be moving if (refGroundAtom.currentState.GetType() == typeof(SOCIAL_COMPARISON_STATE)) { SOCIAL_COMPARISON_STATE sc = (SOCIAL_COMPARISON_STATE)refGroundAtom.currentState; bool stuck = refGroundAtom.currentSpeed <= (float)sc.baselineSpeed / 10.0; if (stuck) { clsActivityMovement barrierMovement = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_TO_POLICE_BARRIER_STATE(barrierMovement)); } } if (refGroundAtom.currentState.GetType() != typeof(GO_TO_POLICE_BARRIER_STATE)) { clsActivityMovement barrierMovement = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_TO_POLICE_BARRIER_STATE(barrierMovement)); return; } }
public override void Execute(clsGroundAtom refGroundAtom) { // go to a different direction if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) { if (routeFromPoint == null) { refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } // destination waypoint is now the source waypoint refGroundAtom.currentStartWaypoint = refGroundAtom.currentEndWaypoint; int randomWaypoint = Util.random.Next(refGroundAtom.m_GameObject.travelRoutes.GetLength(1) - 1); if (randomWaypoint >= refGroundAtom.currentStartWaypoint) { randomWaypoint++; } refGroundAtom.currentEndWaypoint = randomWaypoint; refGroundAtom.currentLeg = 1; refGroundAtom.ChangeState(new REGULAR_MOVEMENT_STATE(refActivityMovement)); refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeEndedEventHandler; return; } base.Execute(refGroundAtom); }
public override void Execute(clsGroundAtom refGroundAtom) { // continue evacuating only if there are people to evacuate DPoint groundZeroLocation = refGroundAtom.m_GameObject.getExplosionLocation(); double groundZeroRadius = refGroundAtom.m_GameObject.getExplosionRadius(); if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { List <clsGroundAtom> atomsInGroundZero = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(groundZeroLocation.x, groundZeroLocation.y, groundZeroRadius, isPrecise: true); bool thereAreMoreCasualties = false; foreach (clsGroundAtom atom in atomsInGroundZero) { if (atom.healthStatus.isDead || atom.healthStatus.isIncapacitated) { thereAreMoreCasualties = true; break; } } if (!thereAreMoreCasualties) { // if there are no more casualties in ground zero no need to go there. refGroundAtom.ChangeState(new AMBULANCE_ADMINISTRATIVE_STATE()); return; } refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.knowsAboutEarthquake = true; DPoint ambulanceStartPoint = new DPoint(34.8514473088014, 32.1008536878526); refGroundAtom.curr_X = ambulanceStartPoint.x; refGroundAtom.curr_Y = ambulanceStartPoint.y; Route straightLine = RouteUtils.createRoute(new DPoint(ambulanceStartPoint.x, ambulanceStartPoint.y), refGroundAtom.m_GameObject.getExplosionLocation()); clsActivityMovement arrivalMovement = RouteUtils.createActivityAndStart(refGroundAtom, 80, straightLine); refGroundAtom.ChangeState(new AMBULANCE_ARRIVAL_MOVEMENT_STATE(arrivalMovement)); return; } base.Execute(refGroundAtom); // take the evacuee with me refCasualty.curr_X = refGroundAtom.curr_X; refCasualty.curr_Y = refGroundAtom.curr_Y; }
// default event handler for incapacitation protected void incapacitationDefaultEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.ChangeState(new INCAPACITATED_STATE()); return; }
// default event handler for death protected void deathDefaultEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.ChangeState(new DEAD_STATE()); return; }
// YD: default event handler for when an earthquake starts when not in structure protected void earthquakeStartedDefaultEventHandler(object sender, EventArgs e) { // default action is holding on to an immobile object, be it the ground, a fence, a car etc. clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; // there's an earthquake. better move fast before something falls on me double panicSpeedMultiplier = (Util.random.NextDouble() + 1.5); refGroundAtom.currentSpeed = panicSpeedMultiplier * refGroundAtom.baselineSpeed; refGroundAtom.knowsAboutEarthquake = true; // there are no proxemics in non-normative conditions refGroundAtom.collisionRadius = 2 * clsGroundAtom.RADIUS; refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeStartedEventHandler; refGroundAtom.lastRoutePoint.x = refGroundAtom.X_Route; refGroundAtom.lastRoutePoint.y = refGroundAtom.Y_Route; if (moveToSocialComparisonStateIfShould(refGroundAtom)) { return; } clsActivityMovement activity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new HOLD_ON_TO_OBJECT_STATE(activity)); return; }
public override void Execute(clsGroundAtom refGroundAtom) { if (refGroundAtom.currentRoute == null) return; if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // arrived to ground zero. Now search for casualties refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; DPoint groundZeroLocation = refGroundAtom.m_GameObject.getExplosionLocation(); double groundZeroRadius = refGroundAtom.m_GameObject.getExplosionRadius(); List<clsGroundAtom> atomsInGroundZero = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(groundZeroLocation.x, groundZeroLocation.y, groundZeroRadius, isPrecise: true); foreach (clsGroundAtom atom in atomsInGroundZero) { if (atom.healthStatus.isDead || atom.healthStatus.isIncapacitated) { refGroundAtom.resetMovementData(); Route straightLine = RouteUtils.createRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(atom.curr_X, atom.curr_Y)); clsActivityMovement extractionMovement = RouteUtils.createActivityAndStart(refGroundAtom, 5, straightLine); refGroundAtom.ChangeState(new AMBULANCE_GO_TO_CASUALTY_STATE(extractionMovement, atom)); return; } } return; } base.Execute(refGroundAtom); }
protected void actAfterEarthquakeEnded(clsGroundAtom refGroundAtom) { List <clsGroundAtom> atomsNearby = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 20, isPrecise: true); List <clsGroundAtom> casualtiesNearby = new List <clsGroundAtom>(); if (moveToSocialComparisonStateIfShould(refGroundAtom)) { return; } // should the atom be curious? foreach (clsGroundAtom atom in atomsNearby) { if (atom.healthStatus.isIncapacitated || atom.healthStatus.isDead) { casualtiesNearby.Add(atom); } } // decide whether to flock towards casualties if (casualtiesNearby.Count() > 0) { double randomAction = Util.random.NextDouble(); int randomCasualty = Util.random.Next(casualtiesNearby.Count()); clsActivityMovement curiousityActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); if (randomAction < 0.3) { refGroundAtom.ChangeState(new CURIOSITY_MOVEMENT_STATE(curiousityActivity, casualtiesNearby[randomCasualty])); } else if (randomAction >= 0.3 && randomAction < 0.8) { refGroundAtom.ChangeState(new HELP_OTHER_STATE(curiousityActivity, casualtiesNearby[randomCasualty])); } else { goToRegularMovementAfterExitingStructure(refGroundAtom); } } else { goToRegularMovementAfterExitingStructure(refGroundAtom); } }
public override void Execute(clsGroundAtom refGroundAtom) { // stop all activities if you're dead if (refGroundAtom.healthStatus.isDead) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new DEAD_STATE()); return; } // or incapacitated if (refGroundAtom.healthStatus.isIncapacitated) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new INCAPACITATED_STATE()); return; } base.Execute(refGroundAtom); }
public override void Execute(clsGroundAtom refGroundAtom) { // stop all activities if you're dead if (refGroundAtom.healthStatus.isDead) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new DEAD_STATE()); return; } // or incapacitated if (refGroundAtom.healthStatus.isIncapacitated) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new INCAPACITATED_STATE()); return; } if (refGroundAtom.currentRoute == null) { return; } // YD: go to a different direction when reached destination if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) { // destination waypoint is now the source waypoint refGroundAtom.currentStartWaypoint = refGroundAtom.currentEndWaypoint; int randomWaypoint = Util.random.Next(refGroundAtom.m_GameObject.travelRoutes.GetLength(1) - 1); if (randomWaypoint >= refGroundAtom.currentStartWaypoint) { randomWaypoint++; } refGroundAtom.currentEndWaypoint = randomWaypoint; refGroundAtom.currentLeg = 1; REGULAR_MOVEMENT_STATE regularMovement = (REGULAR_MOVEMENT_STATE)refGroundAtom.currentState; // re-enter the state regularMovement.Enter(refGroundAtom); return; } base.Execute(refGroundAtom); }
public override void Execute(clsGroundAtom refGroundAtom) { // stop all activities if you're dead if (refGroundAtom.healthStatus.isDead) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new DEAD_STATE()); return; } // or incapacitated if (refGroundAtom.healthStatus.isIncapacitated) { refGroundAtom.isCollision = false; refGroundAtom.ChangeState(new INCAPACITATED_STATE()); return; } if (refGroundAtom.currentRoute == null) { return; } // YD: go to a different direction when reached destination if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) { // destination waypoint is now the source waypoint refGroundAtom.currentStartWaypoint = refGroundAtom.currentEndWaypoint; int randomWaypoint = Util.random.Next(refGroundAtom.m_GameObject.travelRoutes.GetLength(1) - 1); if (randomWaypoint >= refGroundAtom.currentStartWaypoint) randomWaypoint++; refGroundAtom.currentEndWaypoint = randomWaypoint; refGroundAtom.currentLeg = 1; refGroundAtom.ChangeState(new REGULAR_MOVEMENT_STATE(refActivityMovement)); return; } base.Execute(refGroundAtom); }
protected void earthquakeEndedInStructureEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeEndedInStructureEventHandler; if (moveToSocialComparisonStateInStructureIfShould(refGroundAtom)) { return; } // exit the structure refGroundAtom.ChangeState(new EXIT_STRUCTURE_STATE(Structure)); }
public override void Execute(clsGroundAtom refGroundAtom) { if (!refGroundAtom.knowsAboutEarthquake && refGroundAtom.m_GameObject.earthquakeStarted()) { refGroundAtom.knowsAboutEarthquake = true; refGroundAtom.resetMovementData(); Route straightLine = RouteUtils.createRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), refGroundAtom.m_GameObject.getExplosionLocation()); clsActivityMovement arrivalMovement = RouteUtils.createActivityAndStart(refGroundAtom, 80, straightLine); refGroundAtom.ChangeState(new AMBULANCE_ARRIVAL_MOVEMENT_STATE(arrivalMovement)); return; } }
public override void Execute(clsGroundAtom refGroundAtom) { targetPosition.x = mostSimilar.curr_X; targetPosition.y = mostSimilar.curr_Y; // minimize differences SocialComparison.correctBehaviorToMostSimilar(refGroundAtom, mostSimilar, m_baselineSpeed); TerrainService.shPoint[] pnts = Structure.Points.ToArray(); // if most similar leads to outside of structure do social comparison outside of structure bool mostSimilarExitedStructure = !TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(mostSimilar.curr_X, mostSimilar.curr_Y, ref pnts); if (mostSimilarExitedStructure) { refGroundAtom.clearStageTransitionEventSubscriptions(); refGroundAtom.earthquakeStartedEventHandler += earthquakeStartedDefaultEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; clsActivityMovement moveToMostSimilar = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new SOCIAL_COMPARISON_STATE(moveToMostSimilar, mostSimilar)); // re-assign reevaluation handler. It should not be the same outside of a structure. switch (refGroundAtom.m_GameObject.simulationStage) { case GameObject.SimulationStage.STAGE_2: refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeStartedEventHandler; break; case GameObject.SimulationStage.STAGE_3: refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeEndedEventHandler; break; case GameObject.SimulationStage.STAGE_4: refGroundAtom.reEvaluationEventHandler += reevaluationAfterForcesHaveArrivedEventHandler; break; default: refGroundAtom.reEvaluationEventHandler += null; break; } return; } base.Execute(refGroundAtom); }
protected void forcesHaveArrivedInStructureEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.currentSpeed = refGroundAtom.baselineSpeed; refGroundAtom.reEvaluationEventHandler += reevaluationAfterForcesHaveArrivedInStructureEventHandler; if (moveToSocialComparisonStateInStructureIfShould(refGroundAtom)) { return; } // exit the structure refGroundAtom.ChangeState(new EXIT_STRUCTURE_STATE(Structure)); }
protected void reevaluationAfterEarthquakeEndedInStructureEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; // check if stuck in mutual social comparison if (refGroundAtom.currentState.GetType() == typeof(SOCIAL_COMPARISON_IN_STRUCTURE_STATE)) { SOCIAL_COMPARISON_IN_STRUCTURE_STATE sc = (SOCIAL_COMPARISON_IN_STRUCTURE_STATE)refGroundAtom.currentState; bool stuck = refGroundAtom.currentSpeed <= (float)sc.baselineSpeed / 5.0; if (stuck) { // don't stay in social comparison if stuck. The building is going to fall apart! refGroundAtom.ChangeState(new EXIT_STRUCTURE_STATE(Structure)); } } }
public override void Execute(clsGroundAtom refGroundAtom) { //VH if (!refGroundAtom.knowsAboutEarthquake && refGroundAtom.m_GameObject.earthquakeStarted()) { refGroundAtom.knowsAboutEarthquake = true; clsActivityMovement movement = new clsActivityMovement(); refGroundAtom.reRouteToEscape(movement); refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } // -------------------------------------------------------------------------------------- clsGroundAtom.CheckNextMission(refGroundAtom); }
private void goToRegularMovementAfterExitingStructure(clsGroundAtom refGroundAtom) { clsActivityMovement backToNormal = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); clsPolygonOpeningEscapePoint escapePoint = Structure.EscapePoints[exitEdgeNumber]; PointData closestPoint = refGroundAtom.m_GameObject.lookForClosestRegularRoute(refGroundAtom); Route route = RouteUtils.typRouteToRoute(closestPoint.route); List <DPoint> trimmedRoutePoints = new List <DPoint>(); for (int i = closestPoint.legNum; i < route.Points.Count(); i++) { trimmedRoutePoints.Add(route.Points.ElementAt(i)); } route.Points = trimmedRoutePoints; refGroundAtom.currentStartWaypoint = closestPoint.routeIndex1; refGroundAtom.currentEndWaypoint = closestPoint.routeIndex2; refGroundAtom.resetMovementData(); refGroundAtom.currentSpeed = refGroundAtom.baselineSpeed; refGroundAtom.ChangeState(new GET_ON_SIDEWALK(backToNormal, new DPoint(escapePoint.x, escapePoint.y), route)); }
public override void Execute(clsGroundAtom refGroundAtom) { // once reached casualty start evacuating if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { refGroundAtom.resetMovementData(); List <DPoint> points = new List <DPoint>(); // go from casualty location to route and then to extraction location points.Add(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y)); points.Add(new DPoint(refGroundAtom.m_GameObject.getExplosionLocation().x, refGroundAtom.m_GameObject.getExplosionLocation().y)); points.Add(new DPoint(34.8514473088014, 32.1008536878526)); Route route = RouteUtils.createRoute(points); clsActivityMovement evacuationMovement = RouteUtils.createActivityAndStart(refGroundAtom, 80, route); refGroundAtom.ChangeState(new AMBULANCE_EVACUATION_MOVEMENT_STATE(evacuationMovement, refCasualty)); return; } base.Execute(refGroundAtom); }
// move to social comparison state if can. public bool moveToSocialComparisonStateIfCan(clsGroundAtom refGroundAtom) { double socialComparisonProbability = Util.random.NextDouble(); // draw probabilistically whether to compare or not // do social comparison clsGroundAtom mostSimilar = SocialComparison.findMostSimilarByDistanceAndAzimuth(refGroundAtom); // check if there is someone similar to me if (mostSimilar != null) { clsActivityMovement moveToMostSimilar = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new SOCIAL_COMPARISON_STATE(moveToMostSimilar, mostSimilar)); return(true); } // if couldn't find someone similar in vicinity do not compare return(false); }
// YD: default event handler for when forces arrive protected void forcesHaveArrivedDefaultEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; refGroundAtom.reEvaluationEventHandler += reevaluationAfterForcesHaveArrivedEventHandler; // no need to hurry, everything is under control by the police, military, etc. refGroundAtom.currentSpeed = refGroundAtom.baselineSpeed; refGroundAtom.resetMovementData(); if (moveToSocialComparisonStateIfShould(refGroundAtom)) { return; } // default action is simply going to the nearest police barrier clsActivityMovement barrierMovement = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_TO_POLICE_BARRIER_STATE(barrierMovement)); return; }
// move to social comparison state if can and should. Return true if can and should and move, else return false public bool moveToSocialComparisonStateInStructureIfShould(clsGroundAtom refGroundAtom) { double socialComparisonProbability = Util.random.NextDouble(); // draw probabilistically whether to compare or not if (socialComparisonProbability <= refGroundAtom.getSocialComparisonProbability()) { // do social comparison clsGroundAtom mostSimilar = SocialComparison.findMostSimilarInStructure(refGroundAtom, Structure); // check if there is someone similar to me if (mostSimilar != null) { refGroundAtom.ChangeState(new SOCIAL_COMPARISON_IN_STRUCTURE_STATE(Structure, mostSimilar)); return(true); } // if couldn't find someone similar in vicinity do not compare } return(false); }
// YD: event handler for when earthquake started and in structure protected void earthquakeStartedInStructureEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; // there are no proxemics in non-normative conditions refGroundAtom.collisionRadius = 2 * clsGroundAtom.RADIUS; // better hurry up, the building might collapse double panicSpeedMultiplier = (Util.random.NextDouble() + 1.5); refGroundAtom.currentSpeed = panicSpeedMultiplier * refGroundAtom.baselineSpeed; refGroundAtom.reEvaluationEventHandler += reevaluationAfterEarthquakeStartedInStructureEventHandler; if (moveToSocialComparisonStateInStructureIfShould(refGroundAtom)) { return; } // exit the structure refGroundAtom.ChangeState(new EXIT_STRUCTURE_STATE(Structure)); }
// get back to regular activity private void getBackToRegularMovement(clsGroundAtom refGroundAtom) { clsActivityMovement backToNormal = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); PointData closestPoint = refGroundAtom.m_GameObject.lookForClosestRegularRoute(refGroundAtom); Route route = RouteUtils.typRouteToRoute(closestPoint.route); List <DPoint> trimmedRoute = new List <DPoint>(); for (int i = closestPoint.legNum; i < route.Points.Count(); i++) { trimmedRoute.Add(route.Points.ElementAt(i)); } route.Points = trimmedRoute; refGroundAtom.currentLeg = 1; refGroundAtom.currentStartWaypoint = closestPoint.routeIndex1; refGroundAtom.currentEndWaypoint = closestPoint.routeIndex2; refGroundAtom.resetMovementData(); double distanceFromLastRoutePoint = TerrainService.MathEngine.CalcDistance(refGroundAtom.lastRoutePoint.x, refGroundAtom.lastRoutePoint.y, refGroundAtom.curr_X, refGroundAtom.curr_Y); DPoint pointOnSidewalk; if ((refGroundAtom.lastRoutePoint.x == 0 && refGroundAtom.lastRoutePoint.y == 0) || (distanceFromLastRoutePoint > 5)) { // go to the closest sidewalk pointOnSidewalk = new DPoint(route.Points.ElementAt(0).x, route.Points.ElementAt(0).y); refGroundAtom.lastRoutePoint.x = pointOnSidewalk.x; refGroundAtom.lastRoutePoint.y = pointOnSidewalk.y; } else { // continue from where you were before the earthquake started pointOnSidewalk = refGroundAtom.lastRoutePoint; } refGroundAtom.ChangeState(new GET_ON_SIDEWALK(backToNormal, pointOnSidewalk, route)); }
public override void Execute(clsGroundAtom refGroundAtom) { if (refGroundAtom.currentRoute == null) { return; } if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // arrived to ground zero. Now search for casualties refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; DPoint groundZeroLocation = refGroundAtom.m_GameObject.getExplosionLocation(); double groundZeroRadius = refGroundAtom.m_GameObject.getExplosionRadius(); List <clsGroundAtom> atomsInGroundZero = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(groundZeroLocation.x, groundZeroLocation.y, groundZeroRadius, isPrecise: true); foreach (clsGroundAtom atom in atomsInGroundZero) { if (atom.healthStatus.isDead || atom.healthStatus.isIncapacitated) { refGroundAtom.resetMovementData(); Route straightLine = RouteUtils.createRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(atom.curr_X, atom.curr_Y)); clsActivityMovement extractionMovement = RouteUtils.createActivityAndStart(refGroundAtom, 5, straightLine); refGroundAtom.ChangeState(new AMBULANCE_GO_TO_CASUALTY_STATE(extractionMovement, atom)); return; } } return; } base.Execute(refGroundAtom); }
// get back to regular activity private void getBackToRegularMovement(clsGroundAtom refGroundAtom) { clsActivityMovement backToNormal = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); PointData closestPoint = refGroundAtom.m_GameObject.lookForClosestRegularRoute(refGroundAtom); Route route = RouteUtils.typRouteToRoute(closestPoint.route); List<DPoint> trimmedRoute = new List<DPoint>(); for (int i = closestPoint.legNum; i < route.Points.Count(); i++) trimmedRoute.Add(route.Points.ElementAt(i)); route.Points = trimmedRoute; refGroundAtom.currentLeg = 1; refGroundAtom.currentStartWaypoint = closestPoint.routeIndex1; refGroundAtom.currentEndWaypoint = closestPoint.routeIndex2; refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new GET_ON_SIDEWALK(backToNormal, refGroundAtom.lastRoutePoint, route)); }
public override void Execute(clsGroundAtom refGroundAtom) { List<CollisionTime> CollisionsToDelete=new List<CollisionTime>(); foreach(var v in refGroundAtom.Collisions) { if((refGroundAtom.m_GameObject.Ex_clockDate-v.time).TotalSeconds>2) { CollisionsToDelete.Add(v); } } foreach (var v in CollisionsToDelete) { refGroundAtom.Collisions.Remove(v); } // refGroundAtom.Collisions.ForEach(t=>(refGroundAtom.m_GameObject.Ex_clockDate-t.time).TotalSeconds>2) if(refActivityMovement.TimeTo<refGroundAtom.m_GameObject.Ex_clockDate) { refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } if (refGroundAtom.currentRoute == null) return; if ( refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // Fix 01 Start int nl = refGroundAtom.currentRoute.arr_legs.Count; double xEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLongn; double yEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLatn; refGroundAtom.curr_X = xEnd; refGroundAtom.curr_Y = yEnd; // Fix 01 End refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } double nextRoute_X = 0; double nextRoute_Y = 0; int nextLeg = 0; double X_Distination = 0; double Y_Distination = 0; double AzimDepl; refGroundAtom.VirtualMoveOnRoute(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution, refGroundAtom.X_Route, refGroundAtom.Y_Route, out nextRoute_X, out nextRoute_Y,out nextLeg); double currentAzimuth = Util.Azimuth2Points(refGroundAtom.X_Route, refGroundAtom.Y_Route, nextRoute_X, nextRoute_Y); bool isRight = true; // Yinon Douchan: Collision management bool isLeft = true; refGroundAtom.currentAzimuth = currentAzimuth; // ----------------------------------- // refGroundAtom.Collisions.Clear(); Lab1: ; refGroundAtom.isCollision = false; // Fix 02 if (refGroundAtom.Offset_Azimuth != 0.0 || refGroundAtom.Offset_Distance!=0.0) if (refGroundAtom.Offset_Distance != 0.0) { AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; TerrainService.MathEngine.CalcProjectedLocationNew(nextRoute_X, nextRoute_Y, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); } else { X_Distination = nextRoute_X; Y_Distination = nextRoute_Y; } List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, Y_Distination, 2 * clsGroundAtom.RADIUS, isPrecise: true); // List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, refGroundAtom.curr_Y, clsGroundAtom.OFFSET_IN_COLLISION, isPrecise: true); foreach (clsGroundAtom atom in colAtoms) { if (atom != refGroundAtom) { TerrainService.Vector vDest= new TerrainService.Vector(X_Distination, Y_Distination, 0); TerrainService.Vector vMe = new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); TerrainService.Vector vCollision = new TerrainService.Vector(atom.curr_X, atom.curr_Y, 0); TerrainService.Vector MyDirection = vDest - vMe; MyDirection.normalize(); TerrainService.Vector CollisionDirection = vCollision - vMe; CollisionDirection.normalize(); double dot = MyDirection * CollisionDirection; if (dot >=0.8)// 0.6) //Against Main Direction { // if (atom.Collisions.Contains(refGroundAtom.MyName)) continue; // Fix 03 if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; //Fix 04 - New If double d = TerrainService.MathEngine.CalcDistance(X_Distination, Y_Distination, atom.curr_X, atom.curr_Y); refGroundAtom.isCollision = true; CollisionTime cTime = new CollisionTime(); cTime.name = atom.MyName; cTime.time = refGroundAtom.m_GameObject.Ex_clockDate; refGroundAtom.Collisions.Add(cTime); break; } } } if(refGroundAtom.isCollision) { refGroundAtom.Offset_Azimuth = 90; // Yinon Douchan: Modified collision handling // check if I cannot go right or cannot go left if ((refGroundAtom.Offset_Distance + clsGroundAtom.OFFSET_IN_COLLISION) > clsGroundAtom.MAX_OFFSET) isRight = false; if ((refGroundAtom.Offset_Distance - clsGroundAtom.OFFSET_IN_COLLISION) < -clsGroundAtom.MAX_OFFSET) isLeft = false; if (isRight && !isLeft) { // can only evade right refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && !isRight) { // can only evade left refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && isRight) { // decide whether to turn right or left based on social comparison to most similar clsGroundAtom mostSimilar = SocialComparison.findMostSimilar(refGroundAtom); if (mostSimilar != null) { SocialComparison.setOffsetTowardsMostSimilar(refGroundAtom, mostSimilar); } else { // no similar agent - pick a side randomly if (Util.random.NextDouble() > 0.5) { refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else { refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } } } if (refGroundAtom.Offset_Distance < -clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = -clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } else if (refGroundAtom.Offset_Distance > clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } // refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION;// 2*clsGroundAtom.RADIUS; if (refGroundAtom.Offset_Distance < 0) { refGroundAtom.Offset_Azimuth = 180 - refGroundAtom.Offset_Azimuth; } // -------------------------------------------------------------------------- // Yinon Douchan: Commented out - Why are you assigning offsetted position to route position? This caused bugs in movement //nextRoute_X = X_Distination; //nextRoute_Y = Y_Distination; // ------------------------------------------------------------------------------------ // AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; // if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; // TerrainService.MathEngine.CalcProjectedLocationNew(X_Distination, Y_Distination, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); // Yinon Douchan: Commented out - This caused the simulator to enter an endless loop //goto Lab1; // --------------------------------------------------------------------------------- //AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; //if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; } else { refGroundAtom.X_Route = nextRoute_X; refGroundAtom.Y_Route = nextRoute_Y; refGroundAtom.currentLeg = nextLeg; refGroundAtom.X_Distination = X_Distination; refGroundAtom.Y_Distination = Y_Distination; refGroundAtom.MoveToDestination(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); } //List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 10, isPrecise: true); //foreach (clsGroundAtom atom in colAtoms) //{ // if(atom!=refGroundAtom) // { // refGroundAtom.isCollision = true; // break; // } //} //if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) // { // refActivityMovement.isEnded = true; // refActivityMovement.isActive = false; // refGroundAtom.currentRoute = null; // refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); // return; // } //else //{ // refGroundAtom.Move(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); //} }
public override void Execute(clsGroundAtom refGroundAtom) { // continue evacuating only if there are people to evacuate DPoint groundZeroLocation = refGroundAtom.m_GameObject.getExplosionLocation(); double groundZeroRadius = refGroundAtom.m_GameObject.getExplosionRadius(); if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { List<clsGroundAtom> atomsInGroundZero = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(groundZeroLocation.x, groundZeroLocation.y, groundZeroRadius, isPrecise: true); bool thereAreMoreCasualties = false; foreach (clsGroundAtom atom in atomsInGroundZero) { if (atom.healthStatus.isDead || atom.healthStatus.isIncapacitated) { thereAreMoreCasualties = true; break; } } if (!thereAreMoreCasualties) { // if there are no more casualties in ground zero no need to go there. refGroundAtom.ChangeState(new AMBULANCE_ADMINISTRATIVE_STATE()); return; } refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.knowsAboutEarthquake = true; DPoint ambulanceStartPoint = new DPoint(34.8514473088014, 32.1008536878526); refGroundAtom.curr_X = ambulanceStartPoint.x; refGroundAtom.curr_Y = ambulanceStartPoint.y; Route straightLine = RouteUtils.createRoute(new DPoint(ambulanceStartPoint.x, ambulanceStartPoint.y), refGroundAtom.m_GameObject.getExplosionLocation()); clsActivityMovement arrivalMovement = RouteUtils.createActivityAndStart(refGroundAtom, 80, straightLine); refGroundAtom.ChangeState(new AMBULANCE_ARRIVAL_MOVEMENT_STATE(arrivalMovement)); return; } base.Execute(refGroundAtom); // take the evacuee with me refCasualty.curr_X = refGroundAtom.curr_X; refCasualty.curr_Y = refGroundAtom.curr_Y; }
public override void Execute(clsGroundAtom refGroundAtom) { if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) { refActivityMovement.isEnded = true; refActivityMovement.isActive = false; if (refGroundAtom.m_GameObject.earthquakeEnded()) { List<clsGroundAtom> atomsNearby = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 50, isPrecise: true); List<clsGroundAtom> casualtiesNearby = new List<clsGroundAtom>(); // should the atom be curious? foreach (clsGroundAtom atom in atomsNearby) { if (atom.healthStatus.isIncapacitated || atom.healthStatus.isDead) { casualtiesNearby.Add(atom); } } // decide whether to flock towards casualties if (casualtiesNearby.Count() > 0) { double randomAction = Util.random.NextDouble(); int randomCasualty = Util.random.Next(casualtiesNearby.Count()); clsActivityMovement curiousityActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); if (randomAction < 0.3) { refGroundAtom.ChangeState(new CURIOSITY_MOVEMENT_STATE(curiousityActivity, casualtiesNearby[randomCasualty])); } else if (randomAction >= 0.3 && randomAction < 0.8) { refGroundAtom.ChangeState(new HELP_OTHER_STATE(curiousityActivity, casualtiesNearby[randomCasualty])); } else { goToRegularMovement(refGroundAtom); } } else { goToRegularMovement(refGroundAtom); } } return; } base.Execute(refGroundAtom); }
public override void Execute(clsGroundAtom refGroundAtom) { // go to a different direction if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) { if (routeFromPoint == null) { refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } // destination waypoint is now the source waypoint refGroundAtom.currentStartWaypoint = refGroundAtom.currentEndWaypoint; int randomWaypoint = Util.random.Next(refGroundAtom.m_GameObject.travelRoutes.GetLength(1) - 1); if (randomWaypoint >= refGroundAtom.currentStartWaypoint) randomWaypoint++; refGroundAtom.currentEndWaypoint = randomWaypoint; refGroundAtom.currentLeg = 1; refGroundAtom.ChangeState(new REGULAR_MOVEMENT_STATE(refActivityMovement)); return; } base.Execute(refGroundAtom); }
private void exitBuilding(clsGroundAtom refGroundAtom) { double distanceToExit = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, targetPosition.x, targetPosition.y); double DeltaTimeSec = refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution * 0.001; double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double stepDistanceInMeters = 1000 * (refGroundAtom.currentSpeed * DeltaTimeSec / 3600); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, stepDistanceInMeters, out NewPosition.x, out NewPosition.y); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); // reached exit - go away from building, you don't want it to fall on you if (isCross) { // calculate displacement vector TerrainService.Vector currentDirection = NewPosition - new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); // calculate edge vector TerrainService.Vector edgePointVector0 = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0); TerrainService.Vector edgePointVector1 = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector edgeVector = edgePointVector1 - edgePointVector0; // now calculate the perpendicular to the edge TerrainService.Vector projectionOnEdge = edgeVector * (currentDirection * edgeVector) / (edgeVector * edgeVector); TerrainService.Vector perpendicular = currentDirection - projectionOnEdge; // and normalize it perpendicular.normalize(); // get the azimuth perpendicular to the edge double perpendicularAzimuth = Util.Azimuth2Points(0, 0, perpendicular.x, perpendicular.y) + Util.random.NextDouble() * 120 - 30; // distance to go away from building double distanceMeters = 15 * Util.random.NextDouble() + 10; TerrainService.Vector targetLocation = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.curr_X, refGroundAtom.curr_Y, perpendicularAzimuth, distanceMeters, out targetLocation.x, out targetLocation.y); clsActivityMovement goAwayActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_AWAY_FROM_BUILDING_STATE(goAwayActivity, targetLocation, Structure, exitEdgeNumber)); return; } }
protected void reevaluationAfterEarthquakeEndedEventHandler(object sender, EventArgs e) { clsGroundAtom refGroundAtom = ((clsGroundAtomEventArgs)e).groundAtom; List <clsGroundAtom> atomsNearby = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 20, isPrecise: true); // if in social comparison state and not stuck stay in social comparison - things seem to be moving if (refGroundAtom.currentState.GetType() == typeof(SOCIAL_COMPARISON_STATE)) { SOCIAL_COMPARISON_STATE sc = (SOCIAL_COMPARISON_STATE)refGroundAtom.currentState; bool stuck = refGroundAtom.currentSpeed <= (float)sc.baselineSpeed / 10.0; if (!stuck) { return; } else { // stuck in social comparison - first return to baseline speed refGroundAtom.currentSpeed = sc.baselineSpeed; getBackToRegularMovement(refGroundAtom); } } else { refGroundAtom.currentSpeed = refGroundAtom.baselineSpeed; // check for casualties nearby List <clsGroundAtom> casualtiesNearby = new List <clsGroundAtom>(); foreach (clsGroundAtom atom in atomsNearby) { if (atom.healthStatus.isIncapacitated || atom.healthStatus.isDead) { casualtiesNearby.Add(atom); } } // check if already handled the specific trigger foreach (clsGroundAtom casualty in casualtiesNearby) { bool casualtyHandled = false; foreach (Trigger trigger in refGroundAtom.triggers) { if (trigger.type != Trigger.Type.DEAD_OR_INCAPACITATED) { continue; } DeadOrIncapacitatedTrigger doiTrigger = (DeadOrIncapacitatedTrigger)trigger; if (doiTrigger.atomName == casualty.MyName) { casualtyHandled = true; break; } } if (!casualtyHandled) { // decide whether to help casualty or not double helpOrNot = Util.random.NextDouble(); if (helpOrNot < 0.2) { // decide individually to help clsActivityMovement helpActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new HELP_OTHER_STATE(helpActivity, casualty)); refGroundAtom.triggers.Add(new DeadOrIncapacitatedTrigger(casualty.MyName)); return; } else if (helpOrNot >= 0.2 && helpOrNot < 0.3) { // decide individually just to look clsActivityMovement curiosityActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new CURIOSITY_MOVEMENT_STATE(curiosityActivity, casualty)); refGroundAtom.triggers.Add(new DeadOrIncapacitatedTrigger(casualty.MyName)); return; } else if (helpOrNot >= 0.3 && helpOrNot < 0.5) { // decide by socially comparing behavior if (moveToSocialComparisonStateIfCan(refGroundAtom)) { refGroundAtom.triggers.Add(new DeadOrIncapacitatedTrigger(casualty.MyName)); return; } } else { refGroundAtom.triggers.Add(new DeadOrIncapacitatedTrigger(casualty.MyName)); } } } } }
private void exitBuilding(clsGroundAtom refGroundAtom) { double distanceToExit = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, targetPosition.x, targetPosition.y); double DeltaTimeSec = refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution * 0.001; double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double stepDistanceInMeters = 1000 * (refGroundAtom.currentSpeed * DeltaTimeSec / 3600); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, stepDistanceInMeters, out NewPosition.x, out NewPosition.y); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); // reached exit - go away from building, you don't want it to fall on you if (isCross) { // calculate displacement vector TerrainService.Vector currentDirection = NewPosition - new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); // calculate edge vector TerrainService.Vector edgePointVector0 = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0); TerrainService.Vector edgePointVector1 = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector edgeVector = edgePointVector1 - edgePointVector0; // now calculate the perpendicular to the edge TerrainService.Vector projectionOnEdge = edgeVector * (currentDirection * edgeVector) / (edgeVector * edgeVector); TerrainService.Vector perpendicular = currentDirection - projectionOnEdge; // and normalize it perpendicular.normalize(); // get the azimuth perpendicular to the edge double perpendicularAzimuth = Util.Azimuth2Points(0, 0, perpendicular.x, perpendicular.y) + Util.random.NextDouble() * 120 - 30; // distance to go away from building double distanceMeters = 15 * Util.random.NextDouble() + 10; TerrainService.Vector targetLocation = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.curr_X, refGroundAtom.curr_Y, perpendicularAzimuth, distanceMeters, out targetLocation.x, out targetLocation.y); // decide according to earthquake status if (!refGroundAtom.m_GameObject.forcesHaveArrived()) { // refGroundAtom.clearStageTransitionEventSubscriptions(); refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; clsActivityMovement goAwayActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_AWAY_FROM_BUILDING_STATE(goAwayActivity, targetLocation, Structure, exitEdgeNumber)); return; } else { refGroundAtom.clearStageTransitionEventSubscriptions(); refGroundAtom.clearReevaluationEventSubscription(); refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; refGroundAtom.reEvaluationEventHandler += reevaluationAfterForcesHaveArrivedEventHandler; clsActivityMovement barrierMovement = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new GO_TO_POLICE_BARRIER_STATE(barrierMovement)); return; } } }
private void goToRegularMovement(clsGroundAtom refGroundAtom) { clsActivityMovement backToNormal = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); clsPolygonOpeningEscapePoint escapePoint = Structure.EscapePoints[exitEdgeNumber]; PointData closestPoint = refGroundAtom.m_GameObject.lookForClosestRegularRoute(refGroundAtom); Route route = RouteUtils.typRouteToRoute(closestPoint.route); List<DPoint> trimmedRoutePoints = new List<DPoint>(); for (int i = closestPoint.legNum; i < route.Points.Count(); i++) trimmedRoutePoints.Add(route.Points.ElementAt(i)); route.Points = trimmedRoutePoints; refGroundAtom.currentStartWaypoint = closestPoint.routeIndex1; refGroundAtom.currentEndWaypoint = closestPoint.routeIndex2; refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new GET_ON_SIDEWALK(backToNormal, new DPoint(escapePoint.x, escapePoint.y), route)); }
public override void Execute(clsGroundAtom refGroundAtom) { // once reached casualty start evacuating if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { refGroundAtom.resetMovementData(); List<DPoint> points = new List<DPoint>(); // go from casualty location to route and then to extraction location points.Add(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y)); points.Add(new DPoint(refGroundAtom.m_GameObject.getExplosionLocation().x, refGroundAtom.m_GameObject.getExplosionLocation().y)); points.Add(new DPoint(34.8514473088014, 32.1008536878526)); Route route = RouteUtils.createRoute(points); clsActivityMovement evacuationMovement = RouteUtils.createActivityAndStart(refGroundAtom, 80, route); refGroundAtom.ChangeState(new AMBULANCE_EVACUATION_MOVEMENT_STATE(evacuationMovement, refCasualty)); return; } base.Execute(refGroundAtom); }
public override void Execute(clsGroundAtom refGroundAtom) { List <CollisionTime> CollisionsToDelete = new List <CollisionTime>(); foreach (var v in refGroundAtom.Collisions) { if ((refGroundAtom.m_GameObject.Ex_clockDate - v.time).TotalSeconds > 2) { CollisionsToDelete.Add(v); } } foreach (var v in CollisionsToDelete) { refGroundAtom.Collisions.Remove(v); } // refGroundAtom.Collisions.ForEach(t=>(refGroundAtom.m_GameObject.Ex_clockDate-t.time).TotalSeconds>2) if (refActivityMovement.TimeTo < refGroundAtom.m_GameObject.Ex_clockDate) { refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } if (refGroundAtom.currentRoute == null) { return; } if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // Fix 01 Start int nl = refGroundAtom.currentRoute.arr_legs.Count; double xEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLongn; double yEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLatn; refGroundAtom.curr_X = xEnd; refGroundAtom.curr_Y = yEnd; // Fix 01 End refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } double nextRoute_X = 0; double nextRoute_Y = 0; int nextLeg = 0; double X_Distination = 0; double Y_Distination = 0; double AzimDepl; refGroundAtom.VirtualMoveOnRoute(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution, refGroundAtom.X_Route, refGroundAtom.Y_Route, out nextRoute_X, out nextRoute_Y, out nextLeg); double currentAzimuth = Util.Azimuth2Points(refGroundAtom.X_Route, refGroundAtom.Y_Route, nextRoute_X, nextRoute_Y); bool isRight = true; // Yinon Douchan: Collision management bool isLeft = true; refGroundAtom.currentAzimuth = currentAzimuth; // ----------------------------------- // refGroundAtom.Collisions.Clear(); Lab1 :; refGroundAtom.isCollision = false; // Fix 02 if (refGroundAtom.Offset_Azimuth != 0.0 || refGroundAtom.Offset_Distance!=0.0) if (refGroundAtom.Offset_Distance != 0.0) { AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; if (AzimDepl >= 360) { AzimDepl = AzimDepl - 360; } TerrainService.MathEngine.CalcProjectedLocationNew(nextRoute_X, nextRoute_Y, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); } else { X_Distination = nextRoute_X; Y_Distination = nextRoute_Y; } List <clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, Y_Distination, refGroundAtom.collisionRadius, isPrecise: true); // List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, refGroundAtom.curr_Y, clsGroundAtom.OFFSET_IN_COLLISION, isPrecise: true); foreach (clsGroundAtom atom in colAtoms) { if (atom != refGroundAtom) { TerrainService.Vector vDest = new TerrainService.Vector(X_Distination, Y_Distination, 0); TerrainService.Vector vMe = new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); TerrainService.Vector vCollision = new TerrainService.Vector(atom.curr_X, atom.curr_Y, 0); TerrainService.Vector MyDirection = vDest - vMe; MyDirection.normalize(); TerrainService.Vector CollisionDirection = vCollision - vMe; CollisionDirection.normalize(); double dot = MyDirection * CollisionDirection; if (dot >= 0.8)// 0.6) //Against Main Direction { // if (atom.Collisions.Contains(refGroundAtom.MyName)) continue; // Fix 03 if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) { continue; } //Fix 04 - New If double d = TerrainService.MathEngine.CalcDistance(X_Distination, Y_Distination, atom.curr_X, atom.curr_Y); refGroundAtom.isCollision = true; CollisionTime cTime = new CollisionTime(); cTime.name = atom.MyName; cTime.time = refGroundAtom.m_GameObject.Ex_clockDate; refGroundAtom.Collisions.Add(cTime); break; } } } if (refGroundAtom.isCollision) { refGroundAtom.Offset_Azimuth = 90; // Yinon Douchan: Modified collision handling // check if I cannot go right or cannot go left if ((refGroundAtom.Offset_Distance + clsGroundAtom.OFFSET_IN_COLLISION) > clsGroundAtom.MAX_OFFSET) { isRight = false; } if ((refGroundAtom.Offset_Distance - clsGroundAtom.OFFSET_IN_COLLISION) < -clsGroundAtom.MAX_OFFSET) { isLeft = false; } if (isRight && !isLeft) { // can only evade right refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && !isRight) { // can only evade left refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && isRight) { // decide whether to turn right or left based on social comparison to most similar clsGroundAtom mostSimilar = SocialComparison.findMostSimilarByDistanceAndAzimuth(refGroundAtom); if (mostSimilar != null) { SocialComparison.setOffsetTowardsMostSimilar(refGroundAtom, mostSimilar); } else { // no similar agent - pick a side randomly if (Util.random.NextDouble() > 0.5) { refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else { refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } } } if (refGroundAtom.Offset_Distance < -clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = -clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } else if (refGroundAtom.Offset_Distance > clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } // refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION;// 2*clsGroundAtom.RADIUS; if (refGroundAtom.Offset_Distance < 0) { refGroundAtom.Offset_Azimuth = 180 - refGroundAtom.Offset_Azimuth; } // -------------------------------------------------------------------------- // Yinon Douchan: Commented out - Why are you assigning offsetted position to route position? This caused bugs in movement //nextRoute_X = X_Distination; //nextRoute_Y = Y_Distination; // ------------------------------------------------------------------------------------ // AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; // if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; // TerrainService.MathEngine.CalcProjectedLocationNew(X_Distination, Y_Distination, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); // Yinon Douchan: Commented out - This caused the simulator to enter an endless loop //goto Lab1; // --------------------------------------------------------------------------------- //AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; //if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; } else { refGroundAtom.X_Route = nextRoute_X; refGroundAtom.Y_Route = nextRoute_Y; refGroundAtom.currentLeg = nextLeg; refGroundAtom.X_Distination = X_Distination; refGroundAtom.Y_Distination = Y_Distination; refGroundAtom.MoveToDestination(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); } //List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 10, isPrecise: true); //foreach (clsGroundAtom atom in colAtoms) //{ // if(atom!=refGroundAtom) // { // refGroundAtom.isCollision = true; // break; // } //} //if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) // { // refActivityMovement.isEnded = true; // refActivityMovement.isActive = false; // refGroundAtom.currentRoute = null; // refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); // return; // } //else //{ // refGroundAtom.Move(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); //} }