Exemple #1
0
        /// <summary>
        /// Creates a projectile starting at the given location with the given rotation in radians
        /// </summary>
        /// <param name="name"></param>
        /// <param name="origin"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public Projectile CreateProjectile(string name, Vec2 origin, float rotation, ProjectileSource source)
        {
            var definition = _weaponDefinitions.FirstOrDefault(x => x.Name.ToLower().Equals(name.ToLower()));

            if (definition == null)
            {
                throw new Exception($"No WeaponDefinition found for {name}");
            }

            var texture     = _contentManager.Load <Texture2D>(definition.SpriteSheet);
            var shapeDef    = new PolygonDef();
            var physicsSize = GameUtils.PhysicsVec(new Vector2(definition.Width, definition.Height));

            shapeDef.Vertices    = new Vec2[4];
            shapeDef.Vertices[0] = new Vec2(-(physicsSize.X / 2), -(physicsSize.Y / 2));
            shapeDef.Vertices[1] = new Vec2((physicsSize.X / 2), -(physicsSize.Y / 2));
            shapeDef.Vertices[2] = new Vec2((physicsSize.X / 2), (physicsSize.Y / 2));
            shapeDef.Vertices[3] = new Vec2(-(physicsSize.X / 2), (physicsSize.Y / 2));
            shapeDef.VertexCount = 4;

            shapeDef.Density  = definition.Density;
            shapeDef.Friction = definition.Friction;
            //projectiles cannot collide with eachother
            if (source == ProjectileSource.Player)
            {
                shapeDef.Filter.CategoryBits = CollisionCategory.PlayerProjectile;
                shapeDef.Filter.MaskBits     = (ushort)(CollisionCategory.Alien | CollisionCategory.AlienProjectile | CollisionCategory.Wall);
            }
            else
            {
                shapeDef.Filter.CategoryBits = CollisionCategory.AlienProjectile;
                shapeDef.Filter.MaskBits     = (ushort)(CollisionCategory.Player | CollisionCategory.PlayerProjectile | CollisionCategory.Wall);
            }

            var bodyDef = new BodyDef();

            bodyDef.IsBullet = true; bodyDef.Position.Set(origin.X, origin.Y);
            var body  = _physicsWorld.CreateBody(bodyDef);
            var shape = body.CreateShape(shapeDef);

            body.SetMassFromShapes();

            var velocityVector = GameUtils.RotationToVec2((float)(rotation * 180.0f / System.Math.PI));

            body.SetLinearVelocity(velocityVector * definition.Velocity);

            var gameObject = new Projectile(_physicsWorld
                                            , definition
                                            , texture
                                            , shape
                                            , body
                                            , origin
                                            , rotation
                                            , GameData
                                            , GameUtils);

            GameWorld.AddGameObject(gameObject);
            return(gameObject);
        }
Exemple #2
0
        protected void SpawnProjectile(string projectileName, ProjectileSource source)
        {
            var slop = 20;
            //spawn the projectile just outside the players bounding box in the direction the player is facing.
            var offset       = GameUtils.RotationToVec2((float)(RigidBody.GetAngle() * 180 / System.Math.PI));
            var offsetLength = GameUtils.PhysicsVec(new Vector2(0, (Texture.Height + slop) / 2));

            offset = offset * offsetLength.Length();

            WeaponFactory.Instance.CreateProjectile(projectileName, RigidBody.GetPosition() + offset, RigidBody.GetAngle(), source);
        }
Exemple #3
0
        public override void OnCollideObject(WorldObject _target)
        {
            //Console.WriteLine($"{Name}.OnCollideObject({_target.Name})");

            var player = ProjectileSource as Player;

            if (player != null)
            {
                player.LastHitSpellProjectile = Spell;
            }

            // ensure valid creature target
            // non-target objects will be excluded beforehand from collision detection
            var target = _target as Creature;

            if (target == null)
            {
                OnCollideEnvironment();
                return;
            }

            ProjectileImpact();

            // if player target, ensure matching PK status
            var targetPlayer = target as Player;

            var checkPKStatusVsTarget = CheckPKStatusVsTarget(player, targetPlayer, Spell);

            if (checkPKStatusVsTarget != null && checkPKStatusVsTarget == false)
            {
                player.Session.Network.EnqueueSend(new GameEventWeenieError(player.Session, WeenieError.InvalidPkStatus));
                return;
            }

            var critical = false;
            var damage   = CalculateDamage(ProjectileSource, target, ref critical);

            // null damage -> target resisted; damage of -1 -> target already dead
            if (damage != null && damage != -1)
            {
                // handle void magic DoTs:
                // instead of instant damage, add DoT to target's enchantment registry
                if (Spell.School == MagicSchool.VoidMagic && Spell.Duration > 0)
                {
                    var dot = ProjectileSource.CreateEnchantment(target, ProjectileSource, Spell);
                    if (dot.message != null && player != null)
                    {
                        player.Session.Network.EnqueueSend(dot.message);
                    }

                    // corruption / corrosion playscript?
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, ACE.Entity.Enum.PlayScript.HealthDownVoid));
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, ACE.Entity.Enum.PlayScript.DirtyFightingDefenseDebuff));
                }
                else
                {
                    DamageTarget(target, damage, critical);
                }

                if (player != null)
                {
                    Proficiency.OnSuccessUse(player, player.GetCreatureSkill(Spell.School), Spell.PowerMod);
                }
            }

            // also called on resist
            if (player != null && targetPlayer == null)
            {
                player.OnAttackMonster(target);
            }
        }
Exemple #4
0
        public override void OnCollideObject(WorldObject target)
        {
            //Console.WriteLine($"{Name}.OnCollideObject({target.Name})");

            var player = ProjectileSource as Player;

            if (Info != null && player != null && player.DebugSpell)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name}.OnCollideObject({target?.Name} ({target?.Guid}))", ChatMessageType.Broadcast));
                player.Session.Network.EnqueueSend(new GameMessageSystemChat(Info.ToString(), ChatMessageType.Broadcast));
            }

            ProjectileImpact();

            // ensure valid creature target
            var creatureTarget = target as Creature;

            if (creatureTarget == null || target == ProjectileSource)
            {
                return;
            }

            if (player != null)
            {
                player.LastHitSpellProjectile = Spell;
            }

            // ensure caster can damage target
            var sourceCreature = ProjectileSource as Creature;

            if (sourceCreature != null && !sourceCreature.CanDamage(creatureTarget))
            {
                return;
            }

            // if player target, ensure matching PK status
            var targetPlayer = creatureTarget as Player;

            var pkError = ProjectileSource?.CheckPKStatusVsTarget(creatureTarget, Spell);

            if (pkError != null)
            {
                if (player != null)
                {
                    player.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(player.Session, pkError[0], creatureTarget.Name));
                }

                if (targetPlayer != null)
                {
                    targetPlayer.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(targetPlayer.Session, pkError[1], ProjectileSource.Name));
                }

                return;
            }

            var critical     = false;
            var critDefended = false;
            var overpower    = false;

            var damage = CalculateDamage(ProjectileSource, Caster, creatureTarget, ref critical, ref critDefended, ref overpower);

            if (damage != null)
            {
                // handle void magic DoTs:
                // instead of instant damage, add DoT to target's enchantment registry
                if (Spell.School == MagicSchool.VoidMagic && Spell.Duration > 0)
                {
                    var dot = ProjectileSource.CreateEnchantment(creatureTarget, ProjectileSource, Spell);
                    if (dot.Message != null && player != null)
                    {
                        player.Session.Network.EnqueueSend(dot.Message);
                    }

                    // corruption / corrosion playscript?
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.HealthDownVoid));
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.DirtyFightingDefenseDebuff));
                }
                else
                {
                    DamageTarget(creatureTarget, damage.Value, critical, critDefended, overpower);
                }

                if (player != null)
                {
                    Proficiency.OnSuccessUse(player, player.GetCreatureSkill(Spell.School), Spell.PowerMod);
                }

                // handle target procs
                // note that for untargeted multi-projectile spells,
                // ProjectileTarget will be null here, so procs will not apply
                if (sourceCreature != null && ProjectileTarget != null)
                {
                    // TODO figure out why cross-landblock group operations are happening here. We shouldn't need this code Mag-nus 2021-02-09
                    bool threadSafe = true;

                    if (LandblockManager.CurrentlyTickingLandblockGroupsMultiThreaded)
                    {
                        // Ok... if we got here, we're likely in the parallel landblock physics processing.
                        if (sourceCreature.CurrentLandblock == null || creatureTarget.CurrentLandblock == null || sourceCreature.CurrentLandblock.CurrentLandblockGroup != creatureTarget.CurrentLandblock.CurrentLandblockGroup)
                        {
                            threadSafe = false;
                        }
                    }

                    if (threadSafe)
                    {
                        // This can result in spell projectiles being added to either sourceCreature or creatureTargets landblock.
                        sourceCreature.TryProcEquippedItems(creatureTarget, false);
                    }
                    else
                    {
                        // sourceCreature and creatureTarget are now in different landblock groups.
                        // What has likely happened is that sourceCreature sent a projectile toward creatureTarget. Before impact, sourceCreature was teleported away.
                        // To perform this fully thread safe, we would enqueue the work onto worldManager.
                        // WorldManager.EnqueueAction(new ActionEventDelegate(() => sourceCreature.TryProcEquippedItems(creatureTarget, false)));
                        // But, to keep it simple, we will just ignore it and not bother with TryProcEquippedItems for this particular impact.
                    }
                }
            }

            // also called on resist
            if (player != null && targetPlayer == null)
            {
                player.OnAttackMonster(creatureTarget);
            }

            if (player == null && targetPlayer == null)
            {
                // check for faction combat
                if (sourceCreature != null && creatureTarget != null && (sourceCreature.AllowFactionCombat(creatureTarget) || sourceCreature.PotentialFoe(creatureTarget)))
                {
                    sourceCreature.MonsterOnAttackMonster(creatureTarget);
                }
            }
        }
Exemple #5
0
        public override void OnCollideObject(WorldObject _target)
        {
            //Console.WriteLine($"{Name}.OnCollideObject({_target.Name})");

            var player = ProjectileSource as Player;

            if (player != null)
            {
                player.LastHitSpellProjectile = Spell;
            }

            // ensure valid creature target
            // non-target objects will be excluded beforehand from collision detection
            var target = _target as Creature;

            if (target == null || player == target)
            {
                OnCollideEnvironment();
                return;
            }

            ProjectileImpact();

            // for untargeted multi-projectile war spells launched by monsters,
            // ensure monster can damage target
            var sourceCreature = ProjectileSource as Creature;

            if (sourceCreature != null && !sourceCreature.CanDamage(target))
            {
                return;
            }

            // if player target, ensure matching PK status
            var targetPlayer = target as Player;

            var pkError = CheckPKStatusVsTarget(player, targetPlayer, Spell);

            if (pkError != null)
            {
                if (player != null)
                {
                    player.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(player.Session, pkError[0], target.Name));
                }

                if (targetPlayer != null)
                {
                    targetPlayer.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(targetPlayer.Session, pkError[1], ProjectileSource.Name));
                }

                return;
            }

            var critical = false;
            var damage   = CalculateDamage(ProjectileSource, target, ref critical);

            // null damage -> target resisted; damage of -1 -> target already dead
            if (damage != null && damage != -1)
            {
                // handle void magic DoTs:
                // instead of instant damage, add DoT to target's enchantment registry
                if (Spell.School == MagicSchool.VoidMagic && Spell.Duration > 0)
                {
                    var dot = ProjectileSource.CreateEnchantment(target, ProjectileSource, Spell);
                    if (dot.Message != null && player != null)
                    {
                        player.Session.Network.EnqueueSend(dot.Message);
                    }

                    // corruption / corrosion playscript?
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, ACE.Entity.Enum.PlayScript.HealthDownVoid));
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, ACE.Entity.Enum.PlayScript.DirtyFightingDefenseDebuff));
                }
                else
                {
                    DamageTarget(target, damage, critical);
                }

                if (player != null)
                {
                    Proficiency.OnSuccessUse(player, player.GetCreatureSkill(Spell.School), Spell.PowerMod);
                }

                // handle target procs
                // note that for untargeted multi-projectile spells,
                // ProjectileTarget will be null here, so procs will not apply
                if (sourceCreature != null && ProjectileTarget != null)
                {
                    sourceCreature.TryProcEquippedItems(target, false);
                }
            }

            // also called on resist
            if (player != null && targetPlayer == null)
            {
                player.OnAttackMonster(target);
            }
        }
Exemple #6
0
        public ParabolicProjectile(Enemy enemy, GameWorld map, ProjectileSource currentProjectileSource)
        {
            this.CurrentProjectileSource = currentProjectileSource;
            this.Enemy = enemy;

            switch (currentProjectileSource)
            {
                case ProjectileSource.Snake:
                    Texture = ContentHelper.LoadTexture("Projectiles/venom_dark");
                    CollRectangle = new Rectangle(enemy.GetCollRectangle().X, enemy.GetCollRectangle().Y, 32, 32);
                   // animation = new Animation(Texture, collRectangle, 200, 0, AnimationType.Loop);
                    if (!enemy.IsFacingRight)
                    {
                        Velocity = new Vector2(-10, -15);
                        //animation.isFlipped = true;
                    }
                    else Velocity = new Vector2(10, -15);
                    break;
            }
        }
Exemple #7
0
        public override void OnCollideObject(WorldObject target)
        {
            //Console.WriteLine($"{Name}.OnCollideObject({target.Name})");

            var player = ProjectileSource as Player;

            if (Info != null && player != null && player.DebugSpell)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name}.OnCollideObject({target?.Name} ({target?.Guid}))", ChatMessageType.Broadcast));
                player.Session.Network.EnqueueSend(new GameMessageSystemChat(Info.ToString(), ChatMessageType.Broadcast));
            }

            ProjectileImpact();

            // ensure valid creature target
            var creatureTarget = target as Creature;

            if (creatureTarget == null || target == ProjectileSource)
            {
                return;
            }

            if (player != null)
            {
                player.LastHitSpellProjectile = Spell;
            }

            // ensure caster can damage target
            var sourceCreature = ProjectileSource as Creature;

            if (sourceCreature != null && !sourceCreature.CanDamage(creatureTarget))
            {
                return;
            }

            // if player target, ensure matching PK status
            var targetPlayer = creatureTarget as Player;

            var pkError = CheckPKStatusVsTarget(player, targetPlayer, Spell);

            if (pkError != null)
            {
                if (player != null)
                {
                    player.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(player.Session, pkError[0], creatureTarget.Name));
                }

                if (targetPlayer != null)
                {
                    targetPlayer.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(targetPlayer.Session, pkError[1], ProjectileSource.Name));
                }

                return;
            }

            var critical     = false;
            var critDefended = false;
            var overpower    = false;

            var damage = CalculateDamage(ProjectileSource, Caster, creatureTarget, ref critical, ref critDefended, ref overpower);

            if (damage != null)
            {
                // handle void magic DoTs:
                // instead of instant damage, add DoT to target's enchantment registry
                if (Spell.School == MagicSchool.VoidMagic && Spell.Duration > 0)
                {
                    var dot = ProjectileSource.CreateEnchantment(creatureTarget, ProjectileSource, Spell);
                    if (dot.Message != null && player != null)
                    {
                        player.Session.Network.EnqueueSend(dot.Message);
                    }

                    // corruption / corrosion playscript?
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.HealthDownVoid));
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.DirtyFightingDefenseDebuff));
                }
                else
                {
                    DamageTarget(creatureTarget, damage.Value, critical, critDefended, overpower);
                }

                if (player != null)
                {
                    Proficiency.OnSuccessUse(player, player.GetCreatureSkill(Spell.School), Spell.PowerMod);
                }

                // handle target procs
                // note that for untargeted multi-projectile spells,
                // ProjectileTarget will be null here, so procs will not apply
                if (sourceCreature != null && ProjectileTarget != null)
                {
                    sourceCreature.TryProcEquippedItems(creatureTarget, false);
                }
            }

            // also called on resist
            if (player != null && targetPlayer == null)
            {
                player.OnAttackMonster(creatureTarget);
            }
        }
Exemple #8
0
        public override void OnCollideObject(WorldObject target)
        {
            //Console.WriteLine($"{Name}.OnCollideObject({target.Name})");

            var player = ProjectileSource as Player;

            if (Info != null && player != null && player.DebugSpell)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name}.OnCollideObject({target?.Name} ({target?.Guid}))", ChatMessageType.Broadcast));
                player.Session.Network.EnqueueSend(new GameMessageSystemChat(Info.ToString(), ChatMessageType.Broadcast));
            }

            ProjectileImpact();

            // ensure valid creature target
            var creatureTarget = target as Creature;

            if (creatureTarget == null || target == ProjectileSource)
            {
                return;
            }

            if (player != null)
            {
                player.LastHitSpellProjectile = Spell;
            }

            // ensure caster can damage target
            var sourceCreature = ProjectileSource as Creature;

            if (sourceCreature != null && !sourceCreature.CanDamage(creatureTarget))
            {
                return;
            }

            // if player target, ensure matching PK status
            var targetPlayer = creatureTarget as Player;

            var pkError = CheckPKStatusVsTarget(player, targetPlayer, Spell);

            if (pkError != null)
            {
                if (player != null)
                {
                    player.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(player.Session, pkError[0], creatureTarget.Name));
                }

                if (targetPlayer != null)
                {
                    targetPlayer.Session.Network.EnqueueSend(new GameEventWeenieErrorWithString(targetPlayer.Session, pkError[1], ProjectileSource.Name));
                }

                return;
            }

            var critical     = false;
            var critDefended = false;
            var overpower    = false;

            var damage = CalculateDamage(ProjectileSource, Caster, creatureTarget, ref critical, ref critDefended, ref overpower);

            if (damage != null)
            {
                // handle void magic DoTs:
                // instead of instant damage, add DoT to target's enchantment registry
                if (Spell.School == MagicSchool.VoidMagic && Spell.Duration > 0)
                {
                    var dot = ProjectileSource.CreateEnchantment(creatureTarget, ProjectileSource, Spell);
                    if (dot.Message != null && player != null)
                    {
                        player.Session.Network.EnqueueSend(dot.Message);
                    }

                    // corruption / corrosion playscript?
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.HealthDownVoid));
                    //target.EnqueueBroadcast(new GameMessageScript(target.Guid, PlayScript.DirtyFightingDefenseDebuff));
                }
                else
                {
                    DamageTarget(creatureTarget, damage.Value, critical, critDefended, overpower);
                }

                if (player != null)
                {
                    Proficiency.OnSuccessUse(player, player.GetCreatureSkill(Spell.School), Spell.PowerMod);
                }

                // handle target procs
                // note that for untargeted multi-projectile spells,
                // ProjectileTarget will be null here, so procs will not apply
                if (sourceCreature != null && ProjectileTarget != null)
                {
                    // Ok... if we got here, we're likely in the parallel landblock physics processing.
                    // We're currently on the thread for this, but we're wanting to perform some work on sourceCreature which can result in a new spell being created
                    // and added to the sourceCreature's current landblock, which, could be on a separate thread.
                    // Any chance of a cross landblock group work (and thus cross thread), should be enqueued onto the target object to maintain thread safety.
                    if (sourceCreature.CurrentLandblock == null || sourceCreature.CurrentLandblock == CurrentLandblock)
                    {
                        sourceCreature.TryProcEquippedItems(creatureTarget, false);
                    }
                    else
                    {
                        sourceCreature.EnqueueAction(new ActionEventDelegate(() => sourceCreature.TryProcEquippedItems(creatureTarget, false)));
                    }
                }
            }

            // also called on resist
            if (player != null && targetPlayer == null)
            {
                player.OnAttackMonster(creatureTarget);
            }
        }