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); }
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); }