public override void Enter(clsGroundAtom refGroundAtom) { // plan route to closest barrier Barrier closestBarrier = getClosestBarrier(refGroundAtom); //refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), // new DPoint(closestBarrier.x, closestBarrier.y), "GoToBarrier"); //refGroundAtom.currentRoute = await refGroundAtom.m_GameObject.m_GameManager.refTerrain.createRouteByShortestPathOnly(refGroundAtom.curr_X, refGroundAtom.curr_Y, // closestBarrier.x, closestBarrier.y); PointData closestRouteToBarrier = refGroundAtom.m_GameObject.lookForClosestRouteToBarrier(refGroundAtom, closestBarrier); typRoute closestRoute = closestRouteToBarrier.route; int routeLength = closestRoute.arr_legs.Count(); refGroundAtom.resetMovementData(); List <DPoint> routePoints = new List <DPoint>(); routePoints.Add(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y)); for (int i = closestRouteToBarrier.legNum; i < closestRoute.arr_legs.Count(); i++) { routePoints.Add(new DPoint(closestRoute.arr_legs[i].FromLongn, closestRoute.arr_legs[i].FromLatn)); } // add last point routePoints.Add(new DPoint(closestRoute.arr_legs[routeLength - 1].ToLongn, closestRoute.arr_legs[routeLength - 1].ToLatn)); typRoute routeFromAtom = RouteUtils.createTypRoute(routePoints, "GoToBarrier"); refGroundAtom.currentRoute = routeFromAtom; }
public override void Enter(clsGroundAtom refGroundAtom) { refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(refActivityMovement.RouteActivity.Points.ElementAt(0), refActivityMovement.RouteActivity.Points.ElementAt(1), refActivityMovement.RouteActivity.RouteName); refGroundAtom.currentSpeed = refActivityMovement.Speed; }
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; } }
// 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 Enter(clsGroundAtom refGroundAtom) { if (routeFromPoint == null) { // only go to sidewalk DPoint source = new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y); DPoint dest = new DPoint(pointOnSidewalk.x, pointOnSidewalk.y); refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(source, dest, "GetOnSidewalk_" + refGroundAtom.MyName); } else { // go to sidewalk and then to a route from that sidewalk given at routeFromPoint List <DPoint> points = new List <DPoint>(); points.Add(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y)); points.Add(new DPoint(pointOnSidewalk.x, pointOnSidewalk.y)); // add all points except first which is the point on the sidewalk for (int i = 0; i < routeFromPoint.Points.Count(); i++) { points.Add(routeFromPoint.Points.ElementAt(i));; } refGroundAtom.currentRoute = RouteUtils.createTypRoute(points, "GetOnSidewalk_" + refGroundAtom.MyName); } }
public override void Enter(clsGroundAtom refGroundAtom) { typRoute route = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(triggerAtom.curr_X, triggerAtom.curr_Y), "help_other"); refGroundAtom.currentRoute = route; refGroundAtom.resetMovementData(); }
public override void Enter(clsGroundAtom refGroundAtom) { typRoute route = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(targetPosition.x, targetPosition.y), "go_away_from_building"); refGroundAtom.currentRoute = route; refGroundAtom.resetMovementData(); refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedExitingEventHandler; }
public override void Enter(clsGroundAtom refGroundAtom) { // go towards trigger in a straight line typRoute route = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(triggerAtom.curr_X, triggerAtom.curr_Y), "curiosity"); refGroundAtom.currentRoute = route; refGroundAtom.resetMovementData(); }
public override void Execute(clsGroundAtom refGroundAtom) { // update route so that the destination will be the most similar atom refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(mostSimilarAtom.curr_X, mostSimilarAtom.curr_Y), "RouteToMostSimilar"); // minimize differences SocialComparison.correctBehaviorToMostSimilar(refGroundAtom, mostSimilarAtom, m_baselineSpeed); // move 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; }
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); }
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 Enter(clsGroundAtom refGroundAtom) { // move towards a grabable object and a safer place double randomDistance = Util.random.NextDouble() * 5; double randomAzimuth = Util.random.NextDouble() * 360; double newX, newY; // calculate new point TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.curr_X, refGroundAtom.curr_Y, randomAzimuth, randomDistance, out newX, out newY); // make it the new route refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(newX, newY), "HoldOnToObject"); refGroundAtom.resetMovementData(); }
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); } }
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)); }
// 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); }
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); }
// 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; }
// 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); }
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; } } }
public override void Enter(clsGroundAtom refGroundAtom) { refGroundAtom.currentRoute = RouteUtils.planStraightLineRoute(new DPoint(refGroundAtom.curr_X, refGroundAtom.curr_Y), new DPoint(mostSimilarAtom.curr_X, mostSimilarAtom.curr_Y), "RouteToMostSimilar"); m_baselineSpeed = refGroundAtom.currentSpeed; }
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)); } } } } }