示例#1
0
        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;
        }
示例#2
0
 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;
 }
示例#3
0
        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;
            }
        }
示例#4
0
        // 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;
        }
示例#5
0
        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);
            }
        }
示例#6
0
        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();
        }
示例#7
0
        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;
        }
示例#8
0
        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();
        }
示例#9
0
        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);
        }
示例#10
0
        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;
        }
示例#11
0
        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);
        }
示例#12
0
        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;
            }
        }
示例#13
0
        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();
        }
示例#14
0
        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);
            }
        }
示例#15
0
        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));
        }
示例#16
0
        // 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);
        }
示例#17
0
        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);
        }
示例#18
0
        // 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;
        }
示例#19
0
        // 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));
        }
示例#20
0
        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);
        }
示例#21
0
        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;
                }
            }
        }
示例#22
0
 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;
 }
示例#23
0
        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));
                        }
                    }
                }
            }
        }