/// <summary> /// Updates the specified item in a thread-safe manner. /// </summary> /// <param name="oldItem"></param> /// <param name="newItem"></param> public void AppendUpdateItem(Item itemToUpdate) { lock (lockThis) { //Add new attributes to the item w/ the ID Item.CreateItem(itemToUpdate.ItemID).Clone(itemToUpdate); if (itemToUpdate.CarryingInventory != null) { Player player = itemToUpdate.CarryingInventory; byte index = player.GetInventoryIndex(itemToUpdate); player.RemoveInventoryItem(index); player.AddInventoryItem(index, itemToUpdate); } else if (itemToUpdate.CurrentPosition != null) { ThingSet tSet = gameMap.GetThingsInVicinity(itemToUpdate.CurrentPosition); byte stackpos = gameMap.GetStackPosition(itemToUpdate, itemToUpdate.CurrentPosition); foreach (Thing thing in tSet.GetThings()) { thing.UpdateItem(itemToUpdate.CurrentPosition, itemToUpdate, stackpos); } } else if (itemToUpdate.CurrentPosition == null) //In container { Container container = itemToUpdate.Parent; container.UpdateItem(itemToUpdate); } } }
/// <summary> /// Remove the specified item in a thread-safe manner. /// </summary> /// <param name="itemToRemove"></param> public void AppendRemoveItem(Item itemToRemove) { lock (lockThis) { if (itemToRemove.CarryingInventory != null) { Player player = itemToRemove.CarryingInventory; byte index = player.GetInventoryIndex(itemToRemove); player.RemoveInventoryItem(index); } else if (itemToRemove.CurrentPosition != null) { Position pos = itemToRemove.CurrentPosition; Tile mapTile = gameMap.GetTile(pos); byte stackpos = mapTile.GetStackPosition(itemToRemove); mapTile.RemoveThing(itemToRemove); ThingSet tSet = gameMap.GetThingsInVicinity(pos); foreach (Thing thing in tSet.GetThings()) { thing.RemoveThing(pos, stackpos); } } else if (itemToRemove.CurrentPosition == null) //In container { Container container = itemToRemove.Parent; container.RemoveItem(itemToRemove); } } }
/// <summary> /// A quantified message is a message that starts with a special character. For example, /// in tibia 6.4, # is a quantifier, so #y is used to yell, #w is used to whisper etc. /// </summary> /// <param name="sender">Sender of the quantified message.</param> /// <param name="msg">The message itself.</param> private void HandleQuantifiedMessage(Creature sender, string msg, ThingSet tSet) { if (!msg.StartsWith(MSG_QUANTIFIER)) { throw new Exception("Invalid call to HandleQuantifiedMessage()"); } msg = msg.Substring(1); //Remove first quanitifer char quantifierType = char.ToLower(msg[0]); switch (quantifierType) { case BROADCAST_TYPE: HandleBroadcast(sender, msg); break; case WHISPER_TYPE: gameMap.GetThingsInWhisperVicinity(sender.CurrentPosition, tSet); //msg.Substring(2) is called in order to remove quantifier type and a space HandleLocalChat(ChatLocal.WHISPER, tSet, msg.Substring(2), sender); break; case YELL_TYPE: gameMap.GetThingsInYellVacinity(sender.CurrentPosition, tSet); //msg.Substring(2) is called in order to remove quantifier type and a space HandleLocalChat(ChatLocal.YELLS, tSet, msg.Substring(2).ToUpper(), sender); break; default: #if DEBUG Log.WriteDebug("Invalid quantifier type"); #endif break; } }
/// <summary> /// Move a specified thing from the ground. /// </summary> private void MoveItemFromGround() { bool stackable = itemToMove.IsOfType(Constants.TYPE_STACKABLE) && itemToMove.Count != count; Item oldItem = null; if (!stackable) { map.RemoveThing(itemToMove, posFrom); } else { oldItem = itemToMove; oldItem.Count -= count; itemToMove = Item.CreateItem(itemToMove.ItemID); itemToMove.Count = count; } ThingSet tSet = map.GetThingsInVicinity(posFrom); foreach (Thing thing in tSet.GetThings()) { if (!stackable) { thing.RemoveThing(posFrom, stackpos); } else { thing.UpdateItem(posFrom, oldItem, stackpos); } } }
/// <summary> /// Gets all the things in the vicinity (as specified in the parameters) /// and adds them to the ThingSet specified in the parameters. /// Note: general vicinity is specified as an 18x14 box w/ the Position /// in the center at x == 6 && y == 7. /// </summary> /// <param name="position">The position for which to get the things /// in Vicinity.</param> /// <param name="tSet">The ThingSet to add all the things gotten in /// the vacanity.</param> /// <param name="leftXOffset">The left offset from the general Vicinity.</param> /// <param name="rightXOffset">The right offset from the general Vicinity.</param> /// <param name="leftYOffset">The left offset from the general Vicinity.</param> /// <param name="rightYOffset">The right offset from the gernal Vicinity</param> /// <param name="noZChange">True if only get things on the same z level or false /// in order to get things on all z levels defined in the general Vicinity.</param> public void GetThingsInVicinity(Position position, ThingSet tSet, int leftXOffset, int rightXOffset, int leftYOffset, int rightYOffset, bool noZChange) { short startZ = 0; short endZ = 0; short zStep = 1; if (noZChange) { startZ = endZ = position.z; } else { GetZIter(ref startZ, ref endZ, ref zStep, position.z); } //Original x: -9, +8, y: -7, +6 for (int x = position.x - 9 - leftXOffset; x <= position.x + 9 + rightXOffset; x++) { for (int y = position.y - 7 - leftYOffset; y <= position.y + 6 + rightYOffset; y++) { for (short z = startZ; z != endZ + zStep; z += zStep) { short offset = (short)(position.z - z); Tile mapTile = GetTile((ushort)(x + offset), (ushort)(y + offset), (byte)(z)); if (mapTile == null) { continue; } mapTile.GetThings(tSet); } } } }
/// <summary> /// Gets things in the vicinity. /// </summary> /// <param name="position">The position of the vicinity.</param> /// <param name="noZChange">True if only to get things on the same z level or false /// in order to get things on all z levels defined in the general Vicinity.</param> /// <returns>All the things in the Vicinity.</returns> public ThingSet GetThingsInVicinity(Position position, bool noZChange) { ThingSet tSet = new ThingSet(); GetThingsInVicinity(position, tSet, 0, 0, 0, 0, noZChange); return(tSet); }
public void GetThings(ThingSet tSet) { foreach (Thing thing in tileThings) { tSet.AddThing(thing); } }
/// <summary> /// Handles sending a chat message in a player's local vicinity. /// </summary> /// <param name="type">The type of chat to send.</param> /// <param name="set">The set of things in the player's local vicinity.</param> /// <param name="msg">The message to send.</param> /// <param name="sender">The sender of the message.</param> private void HandleLocalChat(ChatLocal type, ThingSet set, string msg, Creature sender) { foreach (Thing thing in set.GetThings()) { thing.AddLocalChat(type, msg, sender.CurrentPosition, sender); } }
public virtual void SendRemovePlayer(Player player, bool reset) { lock (lockThis) { ThingSet tSet = gameMap.GetThingsInVicinity(player.CurrentPosition); AppendRemovePlayer(player, reset); SendProtocolMessages(); } }
/// <summary> /// Adds a magic effect at the given position. /// </summary> /// <param name="effect">The effect to add.</param> /// <param name="position">Add effect at this position.</param> public void AddMagicEffect(MagicEffect effect, Position position) { ThingSet tSet = gameMap.GetThingsInVicinity(position); foreach (Thing thing in tSet.GetThings()) { thing.AddEffect(effect, position); } }
/// <summary> /// Updates the health status of a creature to all creatures /// in vicinity. /// </summary> /// <param name="creature">Creature whose health status to update.</param> /// <param name="tSet">The things to update for.</param> private void UpdateHealthStatus(Creature creature, Position position) { ThingSet tSet = gameMap.GetThingsInVicinity(position); foreach (Thing thing in tSet.GetThings()) { thing.UpdateHealthStatus(creature); } }
private void AddShootEffect(DistanceType type, Position origin, Position destination, ThingSet tSet) { gameMap.GetThingsInVicinity(origin, tSet); gameMap.GetThingsInVicinity(destination, tSet); foreach (Thing thing in tSet.GetThings()) { thing.AddShootEffect((byte)type, origin, destination); } }
public void AppendUpdateOutfit(Creature creature) { lock (lockThis) { ThingSet tSet = gameMap.GetThingsInVicinity(creature.CurrentPosition); foreach (Thing thing in tSet.GetThings()) { thing.UpdateOutfit(creature); } } }
public void HandleSpellCheck(Creature caster) { lock (lockThis) { Spell spell = caster.GetSpell(); if (spell != null) { ThingSet tSet = new ThingSet(); spellSystem.CastSpell(spell.Name, caster, spell, this); SendProtocolMessages(); } } }
public void AppendAddItem(Item item, Position position) { lock (lockThis) { gameMap.AddThing(item, position); byte stackpos = gameMap.GetStackPosition(item, position); ThingSet tSet = gameMap.GetThingsInVicinity(position); foreach (Thing thing in tSet.GetThings()) { thing.AddItem(item, position, stackpos); } } }
/// <summary> /// Handle a message from a creature. /// </summary> /// <param name="creature">The creature sending the message.</param> /// <param name="msg">The message sent.</param> public void HandleChat(Creature creature, string msg) { ThingSet tSet = new ThingSet(); if (msg.StartsWith(PRIVATE_MSG_INDICATOR)) { HandlePrivateMessage(creature, msg); } else if (msg.StartsWith(MSG_QUANTIFIER)) { HandleQuantifiedMessage(creature, msg, tSet); } else { tSet = gameMap.GetThingsInVicinity(creature.CurrentPosition, true); HandleLocalChat(creature.GetChatType(), tSet, msg, creature); } }
/// <summary> /// Move the specified thing to the ground. /// </summary> /// <param name="thingToMove">Thing to move.</param> /// <param name="posTo">Position to move to.</param> /// <param name="thingsPrepared">A reference to the things /// already prepared.</param> private void MoveToGround() { Thing topThing = map.GetTopThing(posTo); Item topItem = null; if (topThing.IsOfType(Constants.TYPE_STACKABLE)) { topItem = (Item)topThing; } bool stackable = false; bool addItem = true; if (topItem != null && itemToMove != null && topItem.ItemID == itemToMove.ItemID) //Both stackable items of same type { stackable = true; if (topItem.Count + itemToMove.Count > MAX_STACK_COUNT) { byte countRemainder = (byte)(MAX_STACK_COUNT - topItem.Count); topItem.Count += countRemainder; itemToMove.Count -= countRemainder; } else { topItem.Count += itemToMove.Count; addItem = false; } } ThingSet tSet = map.GetThingsInVicinity(posTo); byte stackpos = map.GetStackPosition(itemToMove, posTo); if (stackable) { foreach (Thing thing in tSet.GetThings()) { thing.UpdateItem(posTo, topItem, map.GetStackPosition(topItem, posTo)); } } if (addItem) { map.AddThing(itemToMove, posTo); foreach (Thing thing in tSet.GetThings()) { thing.AddThingToGround(itemToMove, posTo, map.GetStackPosition(itemToMove, posTo)); } } }
private void AppendAddCreature(Creature creature, Position position) { position = gameMap.GetFreePosition(position, creature); ThingSet tSet = gameMap.GetThingsInVicinity(position); AddCachedCreature(creature, position); creature.InitCreatureCheck(this); byte stackpos = gameMap.GetStackPosition(creature, position); foreach (Thing thing in tSet.GetThings()) { thing.AddScreenCreature(creature, position, stackpos); } }
//TODO: Completely rework this method... it currently sucks //A LOT... i mean it! public void CheckForRespawn() { Position pos = new Position(CenterX, CenterY, CenterZ); Monster monster = Monster.CreateMonster(MonsterName); if (monster != null && world.GetGameMap().GetTile(pos) != null) { world.AppendAddMonster(monster, pos); } return; Map map = world.GetGameMap(); ThingSet tSet = map.GetThingsInVicinity(pos); //Monster monster = Monster.CreateMonster(MonsterName); if (monster == null) { return; } if (map.GetTile(pos) != null && !map.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK)) { bool canRespawn = true; foreach (Thing thing in tSet.GetThings()) { if (thing is Player) //TODO: FIX this crap { canRespawn = false; } } if (canRespawn) { world.SendAddMonster(monster, pos); } } else { return; } // if (map.GetTile(pos) != null && // !map.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK)) { // Console.WriteLine("x: " + x++); //world.SendAddMonster(monster, pos); // } world.AddEventInCS(SpawnTime, CheckForRespawn); }
public virtual void HandleChangeDirection(Creature creature, Direction direction) { lock (lockThis) { creature.CurrentDirection = direction; ThingSet tSet = gameMap.GetThingsInVicinity(creature.CurrentPosition); byte stackpos = gameMap.GetStackPosition(creature, creature.CurrentPosition); foreach (Thing thing in tSet.GetThings()) { thing.UpdateDirection(direction, creature, stackpos); } SendProtocolMessages(); } }
/// <summary> /// Removes the creature from the game world and only /// appends the data to the ThingSet without reseting or sending it. /// </summary> /// <param name="creature">The creature to remove.</param> /// <param name="tSet">A reference for which things to notify of the /// creature's removal.</param> private void AppendRemoveCreature(Creature creature) { creaturesOnline.Remove(creature.GetID()); creature.LogedIn = false; byte stackpos = gameMap.GetStackPosition(creature, creature.CurrentPosition); ThingSet tSet = gameMap.GetThingsInVicinity(creature.CurrentPosition); foreach (Monster summon in creature.GetSummons()) { summon.SetMaster(null); } foreach (Thing thing in tSet.GetThings()) { thing.RemoveThing(creature.CurrentPosition, stackpos); } gameMap.RemoveThing(creature, creature.CurrentPosition); }
/// <summary> /// Gets things in the vicinity. /// </summary> /// <param name="position">The position of the vicinity.</param> /// <param name="tSet">The ThingSet to add to.</param> public void GetThingsInVicinity(Position position, ThingSet tSet) { GetThingsInVicinity(position, tSet, 0, 0, 0, 0, false); }
/// <summary> /// Gets a set of things are are in the vacinity of a yell. /// </summary> /// <param name="center">The center of the vacinity.</param> /// <returns>A set of things in the yell vacinity.</returns> public void GetThingsInYellVacinity(Position center, ThingSet tSet) { GetThingsInVicinity(center, tSet, 8, 7, 6, 5, false); }
/// <summary> /// Gets a set of things that are in the vacinity of a whipser. /// </summary> /// <param name="center">The center of the vacinity.</param> public void GetThingsInWhisperVicinity(Position center, ThingSet tSet) { GetThingsInVicinity(center, tSet, -8, -7, -6, -5, true); }
/// <summary> /// Gets things in the vicinity. /// </summary> /// <param name="position">The position of the vicinity.</param> /// <param name="noZChange">True if only to get things on the same z level or false /// in order to get things on all z levels defined in the general Vicinity.</param> /// <returns>All the things in the Vicinity.</returns> public ThingSet GetThingsInVicinity(Position position, bool noZChange) { ThingSet tSet = new ThingSet(); GetThingsInVicinity(position, tSet, 0, 0, 0, 0, noZChange); return tSet; }
public void AppendHandleMove(Creature creature, Position newPos, Direction direction, bool validateMove) { lock (lockThis) { Position oldPos = creature.CurrentPosition; Tile oldTile = gameMap.GetTile(oldPos); Tile newTile = gameMap.GetTile(newPos); if (validateMove) { if (newTile == null || newTile.ContainsType(Constants.TYPE_BLOCKING)) { return; } } foreach (Thing thing in oldTile.GetThings()) { bool proceed = thing.HandleWalkAction(creature, this, WalkType.WALK_OFF); if (!proceed) { return; } } foreach (Thing thing in newTile.GetThings()) { bool proceed = thing.HandleWalkAction(creature, this, WalkType.WALK_ON); if (!proceed) { return; } } if (creature.IsNextTo(newPos)) { //TODO: Finish coding speed int speed = GetGroundSpeed(creature.CurrentPosition); int duration = (100 * 90 /*speed*/) / (creature.GetSpeed()); creature.LastWalk.SetTimeInCS((uint)duration); if (!creature.LastWalk.Elapsed()) { return; } Position oldPosClone = oldPos.Clone(); if (oldPos.y > newPos.y) { direction = Direction.NORTH; oldPosClone.y--; creature.AddScreenMoveByOne(direction, oldPos, oldPosClone, gameMap); } else if (oldPos.y < newPos.y) { direction = Direction.SOUTH; oldPosClone.y++; creature.AddScreenMoveByOne(direction, oldPos, oldPosClone, gameMap); } if (oldPos.x < newPos.x) { direction = Direction.EAST; oldPosClone.x++; creature.AddScreenMoveByOne(direction, oldPos, oldPosClone, gameMap); } else if (oldPos.x > newPos.x) { direction = Direction.WEST; oldPosClone.x--; creature.AddScreenMoveByOne(direction, oldPos, oldPosClone, gameMap); } } ThingSet tSet = gameMap.GetThingsInVicinity(creature.CurrentPosition); byte oldStackPos = gameMap.GetStackPosition(creature, oldPos); gameMap.MoveThing(creature, oldPos, newPos); creature.CurrentDirection = direction; byte newStackPos = gameMap.GetStackPosition(creature, newPos); gameMap.GetThingsInVicinity(newPos, tSet); creature.HandleMove(); foreach (Thing thing in tSet.GetThings()) { thing.AddCreatureMove(direction, creature, oldPos, newPos, oldStackPos, newStackPos); } if (!creature.IsNextTo(oldPos)) { creature.AddTeleport(gameMap); } } }
public virtual void HandleChat(Creature creature, string msg) { lock (lockThis) { if (Command.IsCommand(msg, creature)) { Command.ExecuteCommand(this, gameMap, msg, creature); return; } chatSystem.HandleChat(creature, msg); if (msg == "test") //TODO: REMOVE PLX { HandleCreatureTarget(creature, creature); } else if (msg == "magic") { ((Player)creature).AppendAddManaSpent(10000); } else if (msg == "combat") { for (int i = 0; i < 1000; i++) { ((Player)creature).NotifyOfAttack(); creature.AddDamage(0, creature, false); } } else if (msg == "distance") { ((Player)creature).buggabugga(); } else if (msg == "shooteffect") { Position orig = creature.CurrentPosition; Position dest = orig.Clone(); dest.x += 4; dest.y += 2; creature.AddShootEffect((byte)DistanceType.EFFECT_ENERGY, orig, dest); SendProtocolMessages(); } else if (msg == "a") { ((Player)creature).add(); } else if (msg == "b") { ((Player)creature).remove(); } else if (msg == "!dragon") { } else if (msg == "monster") { List <Monster> monsterList = new List <Monster>(); // m.SetMaster(creature); //SendAddCreature(m, gameMap.GetFreePosition(creature.CurrentPosition, m)); //SendProtocolMessages(); return; //return; } else if (msg == "dead") { ThingSet ttSet = gameMap.GetThingsInVicinity(creature.CurrentPosition); AppendAddDamage(creature, creature, creature.CurrentHP, ImmunityType.IMMUNE_PHYSICAL, true); } else if (msg == "!up") { Position newPos = creature.CurrentPosition.Clone(); newPos.z--; //Z goes down as player goes up :D HandleMove(creature, newPos, creature.CurrentDirection); return; } else if (msg == "!down") { Position newPos = creature.CurrentPosition.Clone(); newPos.z++; HandleMove(creature, newPos, creature.CurrentDirection); return; } else if (msg == "!lighthack") { creature.SpellLightLevel = 10; creature.UpdateCreatureLight(creature); } else if (msg == "burn") { creature.Burning = new int[] { 10, 10, 10 }; creature.BurningCheck = new BurningCheck(); creature.BurningCheck.TimeInCS = 200; creature.BurningCheck.World = this; creature.BurningCheck.CurrentCreature = creature; AddEventInCS(creature.BurningCheck.TimeInCS, creature.BurningCheck.PerformCheck); } else if (msg == "position") { creature.AddAnonymousChat(ChatAnonymous.WHITE, "Your position: " + creature.CurrentPosition); } else if (msg == "knight") { ((Player)creature).CurrentVocation = Vocation.KNIGHT; } else if (msg == "sorcerer") { ((Player)creature).CurrentVocation = Vocation.SORCERER; } else if (msg == "druid") { ((Player)creature).CurrentVocation = Vocation.DRUID; } else if (msg == "paladin") { ((Player)creature).CurrentVocation = Vocation.PALADIN; } else if (msg == "hudini") { creature.CharType++; SendUpdateOutfit(creature); return; } else if (msg == "resetoutfit") { creature.CharType = 1; SendUpdateOutfit(creature); } else if (msg == "resetoutfit") { creature.CharType = 0; SendUpdateOutfit(creature); } else if (msg == "level") { ((Player)creature).AddExperienceGain(1000000); } else if (msg.ToLower().StartsWith("item")) { msg = Regex.Split(msg, "\\s+")[1]; Item item = Item.CreateItem("sword"); item.ItemID = ushort.Parse(msg); AppendAddItem(item, creature.CurrentPosition.Clone()); } else if (msg == "sd") { Item item = Item.CreateItem(2127); item.Charges = 2; AppendAddItem(item, creature.CurrentPosition.Clone()); } else if (msg == "vial") { Item item = Item.CreateItem("vial"); item.FluidType = Fluids.FLUID_MILK; AppendAddItem(item, creature.CurrentPosition.Clone()); } else if (msg == "speed") { creature.AddAnonymousChat(ChatAnonymous.WHITE, "Your speed is: " + creature.GetSpeed() + "."); } if (Spell.IsSpell(msg, SpellType.PLAYER_SAY)) { Spell spell = Spell.CreateSpell(msg, (Player)creature); spellSystem.CastSpell(msg, creature, spell, this); } SendProtocolMessages(); } }
//One huge ugly method. TODO: Split it up. public virtual void HandleAttackCheck(Creature attacker, Creature attacked) { lock (lockThis) { if (attacker == attacked) { //throw new Exception("Attacker == attacked in HandleAttackCheck()"); return; } if (attacked == null || !attacked.LogedIn) { attacker.SetCreatureAttacking(null); return; } if (attacked.CurrentPosition == null) { throw new Exception("Invalid condition in HandleAttackCheck()"); } if (attacked.CurrentHP == 0) { throw new Exception("Attacked is already dead in HandleAttack()"); } bool usingDistance = attacker.UsingDistance(); DistanceType shootEffect = DistanceType.EFFECT_NONE; if (usingDistance) { if (attacker.GetAmmo() == 0) { return; } else { shootEffect = attacker.GetDistanceType(); } } else if (!usingDistance && !attacker.IsNextTo(attacked.CurrentPosition)) { return; } ThingSet tSet = gameMap.GetThingsInVicinity(attacker.CurrentPosition); gameMap.GetThingsInVicinity(attacked.CurrentPosition, tSet); if (shootEffect != DistanceType.EFFECT_NONE) { AddShootEffect(shootEffect, attacker.CurrentPosition, attacked.CurrentPosition, tSet); } int dmg = attacked.GetDamageAmt(attacker); if (dmg == Constants.PUFF) { AddMagicEffect(MagicEffect.PUFF, attacked.CurrentPosition); dmg = 0; } else if (dmg == Constants.SPARK) { AddMagicEffect(MagicEffect.BLOCKHIT, attacked.CurrentPosition); dmg = 0; } else { AddMagicEffect(MagicEffect.DRAW_BLOOD, attacked.CurrentPosition); } AppendAddDamage(attacker, attacked, dmg, ImmunityType.IMMUNE_PHYSICAL, false); SendProtocolMessages(); } }
/// <summary> /// Use this method cast the specified spell. Note: This method only /// appends and does not send protocol data. /// </summary> /// <param name="caster">The creature casting the spell</param> /// <param name="spell">The spell to cast</param> /// <param name="tSet">The set of affected things</param> public void CastSpell(string msg, Creature caster, Spell spell, GameWorld world) { /*string error = caster.CanCastSpell(spell); * if (error != null) { * caster.AddAnonymousChat(ChatAnonymous.WHITE, error); * return; * }*///TODO: Uncomment if (spell.IsSpellValid != null && !spell.IsSpellValid(world, msg)) { world.AddMagicEffect(MagicEffect.PUFF, caster.CurrentPosition); return; } if (spell.RequiresTarget) { Tile tile = map.GetTile(spell.SpellCenter); if (tile == null || !tile.ContainsType(Constants.TYPE_CREATURE)) { world.AddMagicEffect(MagicEffect.PUFF, caster.CurrentPosition); caster.AddAnonymousChat(ChatAnonymous.WHITE, "No target selected."); return; } } //Constants. //Not the most efficient method but it is simple and works. int length = spell.SpellArea.GetLength(0); int width = spell.SpellArea.GetLength(1); Position startPos = new Position(); startPos.x = (ushort)(spell.SpellCenter.x - (width / 2)); startPos.y = (ushort)(spell.SpellCenter.y - (length / 2)); startPos.z = spell.SpellCenter.z; Position local = new Position(); List <Thing> things = new List <Thing>(); for (int i = 0; i < length; i++) { for (int j = 0; j < width; j++) { local.x = (ushort)(startPos.x + j); local.y = (ushort)(startPos.y + i); local.z = startPos.z; if (map.GetTile(local) == null /*|| !map.GetTile(local).CanMoveTo(caster) * TODO: Finish*/) { continue; } if (spell.SpellArea[i, j] && !map.GetTile(local).ContainsType(Constants.TYPE_BLOCKS_MAGIC)) { ThingSet tSet = map.GetThingsInVicinity(local); foreach (Thing thing in tSet.GetThings()) { thing.AddEffect(spell.SpellEffect, local); if (spell.HasDistanceType()) { thing.AddShootEffect((byte)spell.DistanceEffect, caster.CurrentPosition, spell.SpellCenter); } } List <Thing> localThings = map.GetTile(local).GetThings(); if (spell.Action != null) { spell.Action.Invoke(world, local, localThings); } foreach (Thing thing in map.GetTile(local).GetThings()) { things.Add(thing); } } } } foreach (Thing thing in things) { thing.AppendHandleDamage(spell.GetDamage(), caster, spell.Immunity, world, true); } //caster.NotifyOfSuccessfulCast(spell); TODO: Uncomment }
/// <summary> /// Gets all the things in the vicinity (as specified in the parameters) /// and adds them to the ThingSet specified in the parameters. /// Note: general vicinity is specified as an 18x14 box w/ the Position /// in the center at x == 6 && y == 7. /// </summary> /// <param name="position">The position for which to get the things /// in Vicinity.</param> /// <param name="tSet">The ThingSet to add all the things gotten in /// the vacanity.</param> /// <param name="leftXOffset">The left offset from the general Vicinity.</param> /// <param name="rightXOffset">The right offset from the general Vicinity.</param> /// <param name="leftYOffset">The left offset from the general Vicinity.</param> /// <param name="rightYOffset">The right offset from the gernal Vicinity</param> /// <param name="noZChange">True if only get things on the same z level or false /// in order to get things on all z levels defined in the general Vicinity.</param> public void GetThingsInVicinity(Position position, ThingSet tSet, int leftXOffset, int rightXOffset, int leftYOffset, int rightYOffset, bool noZChange) { short startZ = 0; short endZ = 0; short zStep = 1; if (noZChange) { startZ = endZ = position.z; } else { GetZIter(ref startZ, ref endZ, ref zStep, position.z); } //Original x: -9, +8, y: -7, +6 for (int x = position.x - 9 - leftXOffset; x <= position.x + 9 + rightXOffset; x++) { for (int y = position.y - 7 - leftYOffset; y <= position.y + 6 + rightYOffset; y++) { for (short z = startZ; z != endZ + zStep; z += zStep) { short offset = (short)(position.z - z); Tile mapTile = GetTile((ushort)(x + offset), (ushort)(y + offset), (byte)(z)); if (mapTile == null) continue; mapTile.GetThings(tSet); } } } }