示例#1
0
        public bool Event_OnMove(ComponentEvent e)
        {
            EMove   moveEvent = (EMove)e;
            Vector2 moveDir   = moveEvent.direction;

            Vector2 currentPos = owner.position;
            Vector2 targetPos  = currentPos + moveDir;

            // first check if the tile is passable
            AreaMap map = Engine.instance.world.currentMap;

            if (map.CanMoveTo(targetPos.X, targetPos.Y))
            {
                // next check if there is an entity there that can be attacked
                Entity[] targets = map.GetAllObjectsAt(targetPos.X, targetPos.Y);
                bool     canPass = true;

                // check if the target blocks passage, and if so try to attack it
                if (targets.Length > 0)
                {
                    foreach (Entity target in targets)
                    {
                        EGetBlockState blocks = (EGetBlockState)target.FireEvent(new EGetBlockState()
                        {
                            asker    = owner,
                            blocking = false
                        });

                        if (blocks.blocking)
                        {
                            // first see if it can be opened
                            var openEvent = (EOpen)target.FireEvent(new EOpen {
                                asker = owner
                            });

                            // if it was not able to be opened, try attacking it
                            if (!openEvent.wasOpened)
                            {
                                owner.FireEvent(new EDoAttack()
                                {
                                    target = target
                                });
                            }

                            canPass = false;
                        }
                    }
                }

                if (canPass)
                {
                    map.MoveEntity(owner, targetPos);
                }
            }

            return(true);
        }
示例#2
0
        public bool Event_ThrowItem(ComponentEvent e)
        {
            AreaMap map        = Engine.instance.world.currentMap;
            var     throwEvent = ((EThrowItem)e);
            string  itemType   = throwEvent.itemName;

            // try to find the item on the entity to throw it
            var consumeItemEvent = (EConsumeItem)owner.FireEvent(new EConsumeItem()
            {
                itemName = itemType
            });

            if (!consumeItemEvent.hasItem)
            {
                return(true);
            }

            // This enttiy did have the item to throw
            Entity projectile = consumeItemEvent.consumedItem;

            // Get the thrwoer strength and item weight, in order to calc both damage and max throw distance
            var getStrength = (EGetAttributeLevel)owner.FireEvent(new EGetAttributeLevel()
            {
                target = "strength"
            });
            int   strength = getStrength.level;
            float strRatio = (strength / 100.0f);

            var getWeight    = (EGetWeight)owner.FireEvent(new EGetWeight());
            int thrownWeight = getWeight.weight;

            float maxDistance = CombatEngine.GetThrowRange(owner, projectile);
            int   throwDamage = (int)(strRatio * thrownWeight);

            // if the target position is farther than the max distance, select the nearest point in that direction
            Vector2 targetLoc = throwEvent.targetLocation;
            Vector2 toTarget  = targetLoc - owner.position;

            if (toTarget.Magnitude() > maxDistance)
            {
                Vector2 dir = toTarget.Normalized();
                targetLoc = owner.position + (dir * maxDistance);
            }

            // check where the item hits, if there is something in the way
            Vector2 hitNormal;
            Vector2 endPosition = map.CollisionPointFromTo(owner.position, targetLoc, out hitNormal);

            // find the target to hit, and apply some damage and knock them back
            Entity[] targets = map.GetAllObjectsAt(endPosition.X, endPosition.Y);
            foreach (Entity hit in targets)
            {
                CombatInstance combat = new CombatInstance(owner, hit)
                {
                    { "damage", throwDamage },
                    { "weapon", projectile }
                };

                CombatEngine.ProcessCombat(combat);
            }

            // the thrown item ends up next to the target location, or the nearest valid location
            toTarget    = Vector2.OrthoNormal(toTarget);
            endPosition = endPosition - toTarget;
            endPosition = map.GetNearestValidMove(endPosition);
            Engine.instance.world.SpawnExisting(projectile, endPosition);

            return(true);
        }