/// <summary> /// Adds the a z level of a map. /// </summary> /// <param name="pos">The floor's center position.</param> /// <param name="width">Floor weight to add.</param> /// <param name="height">Floor height to add.</param> /// <param name="offset">Floor offset relative to the player.</param> /// <param name="map">A reference to the map.</param> /// <param name="player">The player for whom the map information is sent.</param> private void AddFloorInfo(Position pos, int width, int height, short offset, Map map, Player player, ref short skipTiles) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Tile tile = map.GetTile(x + pos.x + offset, y + pos.y + offset, pos.z); if (tile != null) { if (skipTiles >= 0) { netmsg.AddByte((byte)skipTiles); netmsg.AddByte(0xFF); } skipTiles = 0; AddMapTile(tile, player); } else { skipTiles++; if (skipTiles == 0xFF) { netmsg.AddByte(0xFF); netmsg.AddByte(0xFF); skipTiles = -1; } } } } }
//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); }
/// <summary> /// Todo: Finish code. /// </summary> /// <returns></returns> public bool CanSpawn() { if (!Monster.ExistsMonster(MonsterName)) { return(false); } Position pos = new Position(CenterX, CenterY, CenterZ); Map map = world.GetGameMap(); Tile tile = map.GetTile(pos); if (tile == null || tile.ContainsType(Constants.TYPE_BLOCKS_AUTO_WALK)) { return(false); } return(true); }
/// <summary> /// Adds the a z level of a map. /// </summary> /// <param name="pos">The floor's center position.</param> /// <param name="width">Floor weight to add.</param> /// <param name="height">Floor height to add.</param> /// <param name="offset">Floor offset relative to the player.</param> /// <param name="map">A reference to the map.</param> /// <param name="player">The player for whom the map information is sent.</param> private void AddFloorInfo(Position pos, int width, int height, short offset, Map map, Player player) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Tile tile = map.GetTile(x + pos.x + offset, y + pos.y + offset, pos.z); potentialAddTiles.Add(tile); if (tile != null) { foreach (Tile potentialTile in potentialAddTiles) { AddMapTile(potentialTile, player); } potentialAddTiles.Clear(); } } } }
/// <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 }
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); } } }
/// <summary> /// Gets whether a given move is valid. Note: /// this method attemps to make a move valid such as a stackable being /// moved to inventory. /// </summary> /// <returns>True if the move is valid, false otherwise.</returns> private bool IsItemMoveValid() { /* This Method is a bit of a mess and hence is probably very * prone to bugs if not careful. However, I'm being extra careful * to ensure proper validation to avoid item dupe bugs. */ if (!itemToMove.IsOfType(Constants.TYPE_MOVEABLE) || itemToMove.Count < count) { return(false); } double weightToSubtract = 0; if (ContainerPos(posFrom)) //From container { } else if (InventoryPos(posFrom)) //From inventory { weightToSubtract += itemToMove.GetWeight(); } else //From ground { Tile tile = map.GetTile(posFrom); if (tile == null) { return(false); } if (!player.IsNextTo(posFrom)) { player.CurrentWalkSettings.Destination = posFrom; player.CurrentWalkSettings.IntendingToReachDes = false; player.CurrentDelayedAction = new MoveItemDelayed (player, posFrom, thingID, stackpos, posTo, count); return(false); } } if (ContainerPos(posTo)) //To container { int containerIndex = posTo.y - CONTAINER_HEADER; Container container = player.GetContainerByIndex(containerIndex); if (container == null) { return(false); } if (player.HasSpecificThing(container) && itemToMove.GetWeight() > player.GetCurrentCap()) { SendErrorMessage(MSG_NOT_ENOUGH_CAP); return(false); } if (itemToMove == container || container.HasAnyParent(itemToMove)) { SendErrorMessage(MSG_THIS_IS_IMPOSSIBLE); return(false); } Item item = container.GetItemByIndex(posTo.z); if (item != null && item.IsOfType(Constants.TYPE_CONTAINER)) { if (!item.HasRoom()) { SendErrorMessage(MSG_NOT_ENOUGH_ROOM); return(false); } else { return(true); } } if (!container.HasRoom()) { SendErrorMessage(MSG_NOT_ENOUGH_ROOM); return(false); } } else if (InventoryPos(posTo)) //To inventory { byte toIndex = (byte)posTo.y; if (itemToMove.GetWeight() - weightToSubtract > player.GetCurrentCap()) { SendErrorMessage(MSG_NOT_ENOUGH_CAP); return(false); } if (player.GetInventoryItem(toIndex) != null) { Item invItem = player.GetInventoryItem(toIndex); if (invItem.ItemID == itemToMove.ItemID) { if (invItem.Count + itemToMove.Count > MAX_STACK_COUNT) { count = (byte)(MAX_STACK_COUNT - invItem.Count); } } if (invItem.IsOfType(Constants.TYPE_CONTAINER)) { if (!invItem.HasRoom()) { SendErrorMessage(MSG_NOT_ENOUGH_ROOM); return(false); } else { return(true); } } if (InventoryPos(posFrom)) { return(false); } } if (!IsToInventoryValid(toIndex, itemToMove)) { return(false); } } else //Moving to ground { if (!player.CanSee(posTo)) { return(false); } return(!map.TileContainsType(posTo, Constants.TYPE_BLOCKS_ITEM)); } return(true); }