Exemple #1
0
        public override void Enter(SteeringBlender steering, Actor owner, IAgentStateManager agent)
        {
            ZombieSkillSet zss = owner.GetBehaviorThatImplementsType <ZombieSkillSet>();
            //zss.RangedSkill.CurrentOperation = WeaponFunctions.Neutral;
            BipedControllerComponent bcc = owner.GetComponent <BipedControllerComponent>(ActorComponent.ComponentType.Control);

            zss.RangedSkill.UpdateInputState(false, bcc);
            zss.MeleeSkill.UpdateInputState(false, bcc);

            int   opponentId = agent.GetProperty <int>(AgentPropertyName.ActiveOpponent);
            Actor opponent   = GameResources.ActorManager.GetActorById(opponentId);
            BipedControllerComponent opponentBcc = opponent.GetComponent <BipedControllerComponent>(ActorComponent.ComponentType.Control);

            BepuVec3 towardOpponent = opponentBcc.Controller.Body.Position - bcc.Controller.Body.Position;

            towardOpponent.Y = 0.0f;
            towardOpponent.Normalize();

            const float MOVE_SECS_MAX = 2.5f;
            const float MOVE_SECS_MIN = 0.5f;

            float moveRand = SlagMath.Get0To1UpperFloat(GameResources.ActorManager.Random);

            switch (mMovementType)
            {
            case MovementType.Lateral:
                BepuVec3 right = BepuVec3.Cross(towardOpponent, BepuVec3.Up);
                // Make the random symmetrical about 0.5f so that we can divide it into two equal segments for right and left.
                moveRand        = Math.Abs(moveRand - 0.5f);
                mDurationTicks  = (long)(TimeSpan.TicksPerSecond * (moveRand * 2.0f * (MOVE_SECS_MAX - MOVE_SECS_MIN) + MOVE_SECS_MIN));
                steering.Target = BepuConverter.Convert(bcc.Controller.Body.Position + (moveRand > 0.5f ? right : -right) * 100.0f);
                break;

            case MovementType.Close:
                steering.Target = BepuConverter.Convert(opponentBcc.Controller.Body.Position + towardOpponent * 100.0f);
                mDurationTicks  = (long)(TimeSpan.TicksPerSecond * (moveRand * (MOVE_SECS_MAX - MOVE_SECS_MIN) + MOVE_SECS_MIN));
                break;

            case MovementType.Retreat:
                steering.Target = BepuConverter.Convert(opponentBcc.Controller.Body.Position - towardOpponent * 100.0f);
                mDurationTicks  = (long)(TimeSpan.TicksPerSecond * (moveRand * (MOVE_SECS_MAX - MOVE_SECS_MIN) + MOVE_SECS_MIN));
                break;

            default:
                steering.Target = BepuConverter.Convert(towardOpponent * 100.0f);
                mDurationTicks  = 0;
                break;
            }

            steering.Weights[(int)SteeringBlender.WeightType.Arrive] = 0.0f;
            steering.Weights[(int)SteeringBlender.WeightType.Seek]   = 0.67f;
            steering.Weights[(int)SteeringBlender.WeightType.Wander] = 0.33f;
            steering.Weights[(int)SteeringBlender.WeightType.Wait]   = 0.0f;
            steering.Urgency    = 1.0f;
            steering.ForceScale = 1.0f;
        }
Exemple #2
0
        public override void Update(/* inout */ SteeringBlender steering, Actor owner, IAgentStateManager agent)
        {
            if (!agent.HasProperty(AgentPropertyName.ActiveOpponent))
            {
                ZombieWaitState zws = new ZombieWaitState(6.0f);
                agent.CurrentState = zws;
                return;
            }

            Actor opponent = GameResources.ActorManager.GetActorById(agent.GetProperty <int>(AgentPropertyName.ActiveOpponent));
            BipedControllerComponent opponentBcc = opponent.GetComponent <BipedControllerComponent>(ActorComponent.ComponentType.Control);

            steering.Target = BepuConverter.Convert(opponentBcc.Controller.Body.Position);

            BipedControllerComponent bcc = owner.GetComponent <BipedControllerComponent>(ActorComponent.ComponentType.Control);

            BepuVec3       toOpponent   = opponentBcc.Controller.Body.Position - bcc.Controller.Body.Position;
            float          distance     = toOpponent.Length();
            ZombieSkillSet zss          = owner.GetBehaviorThatImplementsType <ZombieSkillSet>();
            BipedWeapon    chosenAttack = distance <= zss.MeleeSkill.EffectiveRangeMax ? zss.MeleeSkill : zss.RangedSkill;

            Matrix attackTransform = Matrix.CreateTranslation(chosenAttack.MuzzleOffset) * Matrix.CreateWorld(
                BepuConverter.Convert(bcc.Controller.Body.Position), BepuConverter.Convert(bcc.Controller.ViewDirection), Vector3.Up);

            BepuVec3 bulletPath = opponentBcc.Controller.Body.Position - BepuConverter.Convert(attackTransform.Translation);

            // If we don't have a shot, we need to specify what kind of movement we need to remedy that.
            ZombieTacticalMovementState.MovementType movement = ZombieTacticalMovementState.MovementType.None;

            if (distance < chosenAttack.EffectiveRangeMin)
            {
                movement = ZombieTacticalMovementState.MovementType.Retreat;
            }
            else if (distance > chosenAttack.EffectiveRangeMax)
            {
                movement = ZombieTacticalMovementState.MovementType.Close;
            }
            else
            {
                BepuRay       loeRay = new BepuRay(BepuConverter.Convert(attackTransform.Translation), bulletPath);
                LOSFilter     filter = new LOSFilter(bcc.Controller.Body.CollisionInformation, opponentBcc.Controller.Body.CollisionInformation);
                RayCastResult loeResult;
                GameResources.ActorManager.SimSpace.RayCast(loeRay, chosenAttack.EffectiveRangeMax * 1.5f, filter.Test, out loeResult);

                EntityCollidable otherEntityCollidable = loeResult.HitObject as EntityCollidable;
                if (otherEntityCollidable != null &&
                    otherEntityCollidable.Entity != null &&
                    otherEntityCollidable.Entity.Tag != null &&
                    (int)(otherEntityCollidable.Entity.Tag) == opponent.Id)
                {
                    toOpponent.Y = 0.0f;
                    toOpponent.Normalize();
                    float       aimTheta         = (float)(Math.Acos(MathHelper.Clamp(BepuVec3.Dot(toOpponent, bcc.Controller.ViewDirection), 0.0f, 1.0f)));
                    const float AIM_CONE_RADIANS = MathHelper.Pi / 12.0f;
                    if (aimTheta <= AIM_CONE_RADIANS)
                    {
                        // TODO: P2: Add some wander to this value:
                        bcc.WorldAim = BepuConverter.Convert(bulletPath);
                        //chosenAttack.CurrentOperation = WeaponFunctions.TriggerPulled;
                        BipedWeapon otherAttack = chosenAttack == zss.MeleeSkill ? zss.RangedSkill : zss.MeleeSkill;
                        otherAttack.UpdateInputState(false, bcc);
                        chosenAttack.UpdateInputState(true, bcc);
                        return;
                    }
                }
                else
                {
                    movement = ZombieTacticalMovementState.MovementType.Lateral;
                }
            }

            if (movement != ZombieTacticalMovementState.MovementType.None)
            {
                ZombieTacticalMovementState ztms = new ZombieTacticalMovementState(movement);
                agent.CurrentState = ztms;
            }
        }
Exemple #3
0
        public void ImpactHandler(object sender, UpdateStepEventArgs e)
        {
            GameResources.ActorManager.PostPhysicsUpdateStep -= ImpactHandler;
            // TODO: P2: Some boooom sound effects...

            TransformComponent myXForm = Owner.GetComponent <TransformComponent>(ActorComponent.ComponentType.Transform);
            // Do a sphere cast to get actors in the blast radius
            List <RayCastResult> inRangeActors = new List <RayCastResult>();
            SphereShape          blastZone     = new SphereShape(mBlastRadius);
            RigidTransform       blastPosition = new RigidTransform(BepuConverter.Convert(myXForm.Translation));

            BEPUutilities.Vector3 bepuZero = BEPUutilities.Vector3.Zero;
            GameResources.ActorManager.SimSpace.ConvexCast(blastZone, ref blastPosition, ref bepuZero, inRangeActors);

            RayCastDistanceComparer rcdc = new RayCastDistanceComparer();

            for (int a = 0; a < inRangeActors.Count; ++a)
            {
                EntityCollidable inRangeEntityCollidable = inRangeActors[a].HitObject as EntityCollidable;
                if (inRangeEntityCollidable != null &&
                    inRangeEntityCollidable.Entity != null &&
                    inRangeEntityCollidable.Entity.Tag != null)
                {
                    Actor      blastedActor = GameResources.ActorManager.GetActorById((int)(inRangeEntityCollidable.Entity.Tag));
                    IDamagable actorDamage  = blastedActor.GetBehaviorThatImplementsType <IDamagable>();
                    DynamicCollisionComponent actorCollidable = blastedActor.GetComponent <DynamicCollisionComponent>(ActorComponent.ComponentType.Physics);
                    BepuVec3 blastToActorCenter = actorCollidable.Entity.Position - blastPosition.Position;
                    BepuRay  loeRay             = new BepuRay(blastPosition.Position, blastToActorCenter);
                    bool     hasCover           = false;
                    float    distance           = mBlastRadius;
                    if (actorDamage != null || (actorCollidable != null && actorCollidable.IsDynamic && !(actorCollidable.Entity.CollisionInformation.CollisionRules.Personal.HasFlag(BEPUphysics.CollisionRuleManagement.CollisionRule.NoSolver))))
                    {
                        List <RayCastResult> loeResults = new List <RayCastResult>();
                        GameResources.ActorManager.SimSpace.RayCast(loeRay, mBlastRadius, loeResults);
                        loeResults.Sort(rcdc);

                        for (int c = 0; c < loeResults.Count; ++c)
                        {
                            EntityCollidable possibleCover = loeResults[c].HitObject as EntityCollidable;
                            if (possibleCover != null &&
                                possibleCover.Entity == inRangeEntityCollidable.Entity)
                            {
                                // Hit
                                distance = loeResults[c].HitData.T;
                                break;
                            }
                            Terrain possibleCoverTerrain = loeResults[c].HitObject as Terrain;
                            if (possibleCoverTerrain != null)
                            {
                                hasCover = true;
                                break;
                            }
                            if (possibleCover != null &&
                                possibleCover.Entity != null &&
                                !possibleCover.Entity.IsDynamic)
                            {
                                hasCover = true;
                                break;
                            }
                        }
                    }

                    if (!hasCover && actorDamage != null)
                    {
                        actorDamage.TakeDamage((int)(MathHelper.Lerp(1.0f, 0.25f, distance / mBlastRadius) * mDamage));
                    }

                    if (!hasCover && actorCollidable != null && actorCollidable.IsDynamic && !(actorCollidable.Entity.CollisionInformation.CollisionRules.Personal.HasFlag(BEPUphysics.CollisionRuleManagement.CollisionRule.NoSolver)))
                    {
                        blastToActorCenter.Normalize();
                        blastToActorCenter = blastToActorCenter * 1200; // Math.Min(5000.0f / (distance + 1.0f));
                        actorCollidable.Entity.ApplyLinearImpulse(ref blastToActorCenter);
                        if (!actorCollidable.Entity.ActivityInformation.IsActive)
                        {
                            actorCollidable.Entity.ActivityInformation.Activate();
                        }
                    }
                }
            }

            DynamicCollisionComponent dcc = Owner.GetComponent <DynamicCollisionComponent>(ActorComponent.ComponentType.Physics);
            Vector3            myVelocity = BepuConverter.Convert(dcc.Entity.LinearVelocity);
            Actor              fireball   = GameResources.ActorManager.SpawnTemplate("ExplosionFire");
            TransformComponent fireXForm  = fireball.GetComponent <TransformComponent>(ActorComponent.ComponentType.Transform);

            fireXForm.Translation = myXForm.Translation;
            ExplosionFire fireBehavior = fireball.GetBehavior <ExplosionFire>();

            fireBehavior.Emit(myVelocity);
            Actor smoke = GameResources.ActorManager.SpawnTemplate("ExplosionSmoke");
            TransformComponent smokeXForm = smoke.GetComponent <TransformComponent>(ActorComponent.ComponentType.Transform);

            smokeXForm.Translation = myXForm.Translation;
            ExplosionSmoke smokeBehavior = smoke.GetBehavior <ExplosionSmoke>();

            smokeBehavior.Emit(myVelocity);

            Owner.Despawn();
        }