private void PropsUpdateVisibility(
     MobUpdateContext context)
 {
     UpdatePlayerPropVisibility(context);
     UpdateAIPropVisibility(context);
     UpdateEnergyTankPropVisibility(context);
 }
        private void PropsUpdateStatus(
            MobUpdateContext context)
        {
            Mob ownerMob = context.mob;

            player_props.ForEach(prop => MobAIPerceptionState.UpdatePropStatus(ownerMob, prop));
            ai_props.ForEach(prop => MobAIPerceptionState.UpdatePropStatus(ownerMob, prop));
            energy_tank_props.ForEach(prop => MobAIPerceptionState.UpdatePropStatus(ownerMob, prop));
        }
 // -- Top Level Update Functions --
 private void PropListsRefresh(
     MobUpdateContext context)
 {
     // Create props for any Entity that we don't already have a prop for.
     // Remove props for any Entity that no longer exists.
     player_props      = MobAIPerceptionState.PropListsRefresh(context.mob, context.moveRequest.Players, player_props);
     ai_props          = MobAIPerceptionState.PropListsRefresh(context.mob, context.otherMobs, ai_props);
     energy_tank_props = MobAIPerceptionState.PropListsRefresh(context.mob, context.moveRequest.EnergyTanks, energy_tank_props);
 }
        private void PropsUpdateSalience(
            MobUpdateContext context)
        {
            Mob ownerMob = context.mob;

            // Compute a salience score for all props
            player_props.ForEach(prop => prop.salience      = MobAIPerceptionState.ComputePropSalience(PlayerPropEvaluators, ownerMob, prop));
            ai_props.ForEach(prop => prop.salience          = MobAIPerceptionState.ComputePropSalience(AIPropEvaluators, ownerMob, prop));
            energy_tank_props.ForEach(prop => prop.salience = MobAIPerceptionState.ComputePropSalience(EnergyTankPropEvaluators, ownerMob, prop));
        }
        private void UpdateEnergyTankPropVisibility(
            MobUpdateContext context)
        {
            Mob     ownerMob = context.mob;
            NavMesh navMesh  = context.moveRequest.Room.runtime_nav_mesh;

            foreach (EntityProp prop in energy_tank_props)
            {
                Point3d oldPropPosition = prop.GetPosition();

                // Find the energy tank associated with the player id
                EnergyTank energyTank = context.moveRequest.EnergyTanks.Find(e => e.ID == prop.target_object_id);

                // Can the mob see the player at their current location
                bool canSee = CanMobSeePoint(navMesh, ownerMob, energyTank.Position);

                TypedFlags <EntityProp.ePropVisibilityFlags> oldVisibilityFlags =
                    new TypedFlags <EntityProp.ePropVisibilityFlags>(prop.visibilityFlags);

                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.canSee, canSee);
                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.caughtGlimpse, canSee);
                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.stationary, true);

                if (canSee)
                {
                    // If so, we get to pull the entity properties
                    prop.RefeshEntityProperties(ownerMob, energyTank);
                    prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.seenAtLeastOnce, true);
                }

                // Update the status of the prop based on the current visibility
                UpdatePropStatus(ownerMob, prop);

                // Post an event if we just spotted an energy that we've never seen before
                if (!oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) &&
                    !oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.seenAtLeastOnce) &&
                    (prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) ||
                     prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.caughtGlimpse)))
                {
                    context.output_game_events.Add(
                        new GameEvent_MobEnergyTankPropSpotted()
                    {
                        mob_id         = ownerMob.ID,
                        energy_tank_id = prop.target_object_id
                    });
                }
            }
        }
        public void Update(
            MobUpdateContext context)
        {
            // See if there are any new props we should be paying attention to
            PropListsRefresh(context);

            // Update the prop status for each prop based on visibility
            PropsUpdateVisibility(context);

            //TODO: Update the prop status for each prop based on audibility events

            // Compute the new status based on the new visibility / audibility of each props
            PropsUpdateStatus(context);

            // Update salience scores of our targets
            PropsUpdateSalience(context);

            // Pick friendly, enemy, and neutral targets based on salience
            UpdateTargets();
        }
        private void UpdateAIPropVisibility(
            MobUpdateContext context)
        {
            Mob     ownerMob = context.mob;
            NavMesh navMesh  = context.moveRequest.Room.runtime_nav_mesh;

            foreach (EntityProp prop in ai_props)
            {
                Point3d oldPropPosition = prop.GetPosition();

                // Find the player associated with the player id
                MobUpdateContext otherMobContext = context.moveRequest.MobContexts.Find(m => m.mob.ID == prop.target_object_id);
                Mob otherMob = otherMobContext.mob;

                // Can the mob see the other mob at their current location
                bool canSee = CanMobSeePoint(navMesh, ownerMob, otherMob.Position);

                TypedFlags <EntityProp.ePropVisibilityFlags> oldVisibilityFlags =
                    new TypedFlags <EntityProp.ePropVisibilityFlags>(prop.visibilityFlags);

                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.canSee, canSee);
                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.caughtGlimpse, canSee);

                if (canSee)
                {
                    // If so, we get to pull the entity properties
                    prop.RefeshEntityProperties(ownerMob, otherMob);
                    prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.seenAtLeastOnce, true);
                }
                else
                {
                    EntityPath entityPath = otherMobContext.path;

                    if (entityPath != null)
                    {
                        // Find the last place we saw the player along their path, if at all
                        for (int pathStepIndex = entityPath.path.Count - 1; pathStepIndex >= 0; pathStepIndex--)
                        {
                            PathStep pathStep = entityPath.path[pathStepIndex];

                            if (CanMobSeePoint(navMesh, ownerMob, pathStep.StepPoint))
                            {
                                prop.position_x = pathStep.StepPoint.x;
                                prop.position_y = pathStep.StepPoint.y;
                                prop.position_z = pathStep.StepPoint.z;
                                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.caughtGlimpse, true);
                                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.seenAtLeastOnce, true);
                                break;
                            }
                        }
                    }
                }

                // Post an event if we just spotted another mob that we've never seen before
                if (!oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) &&
                    !oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.seenAtLeastOnce) &&
                    (prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) ||
                     prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.caughtGlimpse)))
                {
                    context.output_game_events.Add(
                        new GameEvent_MobAIPropSpotted()
                    {
                        mob_id         = ownerMob.ID,
                        spotted_mob_id = prop.target_object_id,
                        x = prop.position_x,
                        y = prop.position_y,
                        z = prop.position_z
                    });
                }
            }
        }