/// <summary> /// Gets the thing with the specified parameters or /// null if such a thing can't be found. Note: The thing /// must be visible for the player. /// </summary> /// <param name="player">The player for whom to get the item.</param> /// <param name="pos">The position of the item.</param> /// <param name="stackpos">The stackposition of the thing.</param> /// <param name="usePosZ">Use position.z for index instead of stackpos.</param> /// <returns>The thing or null if can't be found.</returns> public Thing GetThing(Player player, Position pos, byte stackpos, bool usePosZ) { //container/inventory if (CarryingPos(pos)) { if (ContainerPos(pos)) { //From container int containerIndex = pos.y - CONTAINER_HEADER; int itemIndex = usePosZ ? pos.z : stackpos; Container container = player.GetContainerByIndex(containerIndex); if (container == null) { return null; } return container.GetItemByIndex(itemIndex); } else { //inventory return player.GetInventoryItem((byte)pos.y); } } else if (player.CanSee(pos)) { //ground if (stackpos == Constants.STACKPOS_TOP_ITEM) { return map.GetTopThing(pos); } else { Tile tile = map.GetTile(pos); if (tile == null) { return null; } return tile.GetThing(stackpos); } } return null; }
/// <summary> /// Adds a creature to a single tile with only the /// most basic information. Note: Used for speeding up /// loading spawns. /// </summary> /// <param name="creature">Creature to add.</param> /// <param name="position">Position to add creature.</param> public void AddCachedCreature(Creature creature, Position position) { lock (lockThis) { creature.World = this; creaturesOnline.Add(creature.GetID(), creature); creature.Finder = pathFinder; creature.LogedIn = true; gameMap.AddThing(creature, position); } }
public Spell() { //Number of vocations int vocationsTotal = Enum.GetValues(typeof(Vocation)).Length; Name = "None"; RequiredMLevel = 0; Immunity = ImmunityType.IMMUNE_PHYSICAL; DistanceEffect = DistanceType.EFFECT_NONE; SpellEffect = MagicEffect.YELLOW_RINGS; SpellCenter = new Position(0, 0, 0); MinDmg = 0; MaxDmg = 0; Rand = new Random(DateTime.Now.Millisecond); Rune = null; RequiresTarget = false; }
/// <summary> /// Given an old position and a direction, this method returns /// a new position based on that direction. /// </summary> /// <param name="oldPos">The old position.</param> /// <param name="direction">The direction to move.</param> /// <returns>The new position.</returns> public static Position GetNewPosition(Position oldPos, Direction direction) { Position pos = oldPos.Clone(); switch (direction) { case Direction.NORTH: pos.y--; break; case Direction.EAST: pos.x++; break; case Direction.SOUTH: pos.y++; break; case Direction.WEST: pos.x--; break; default: Log.WriteLine("Unknown direction: " + direction); break; } return pos; }
/// <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; }
public static Spell CreateCreatureSpell(string name, string argument, Creature creature, int min, int max, Position spellCenter) { Spell spell = new Spell(); otherSpells[name.ToLower()].InitDelegate.Invoke (new object[] { name, creature, min, max, spellCenter, spell, argument }); return spell; }
/// <summary> /// Gets the next bytes in the buffer and treats them as a position. /// </summary> /// <returns> /// The position as specified by the buffer. /// </returns> public Position GetPosition() { Position pos = new Position(); pos.x = GetU16(); pos.y = GetU16(); pos.z = GetByte(); return pos; }
/// <summary> /// Tests if the specified position indicates /// a move to/from an inventory position. /// </summary> /// <param name="pos">The position to test.</param> /// <returns>True if to/from inventory, false otherwise.</returns> private bool InventoryPos(Position pos) { return CarryingPos(pos) && !ContainerPos(pos); }
public UseItemAction(Player player, byte itemType, Position pos, ushort itemID, byte stackpos) { this.player = player; this.itemType = itemType; this.pos = pos; this.itemID = itemID; this.stackpos = stackpos; }
public MoveItemDelayed(Player player, Position posFrom, ushort thingID, byte stackpos, Position posTo, byte count) { this.player = player; this.posFrom = posFrom; this.thingID = thingID; this.stackpos = stackpos; this.posTo = posTo; this.count = count; }
public bool GetPathTo(Creature creature, Position destPos, List<byte> listDir, Int32 maxSearchDist, bool allowZChange, bool intendingToReachDes) { if (intendingToReachDes && gameMap.TileContainsType(destPos, Constants.TYPE_BLOCKS_AUTO_WALK)) { listDir.Clear(); return false; } listDir.Clear(); Position startPos = creature.CurrentPosition; Position endPos = destPos; if (endPos == null) { return false; } if (startPos.z != endPos.z) return false; AStarNodes nodes = new AStarNodes(); AStarNode startNode = nodes.CreateOpenNode(); startNode.x = startPos.x; startNode.y = startPos.y; startNode.g = 0; startNode.h = nodes.GetEstimatedDistance (startPos.x, startPos.y, endPos.x, endPos.y); startNode.f = startNode.g + startNode.h; startNode.parent = null; Position pos = new Position(); pos.z = startPos.z; short[,] neighbourOrderList = { {-1, 0}, {0, 1}, {1, 0}, {0, -1}, //diagonal {-1, -1}, {1, -1}, {1, 1}, {-1, 1}, }; //MapTile tile = null; AStarNode found = null; while (nodes.CountClosedNodes() < 100) { AStarNode n = nodes.GetBestNode(); if (n == null) { listDir.Clear(); return false; //No path found } if (n.x == endPos.x && n.y == endPos.y) { found = n; break; } else { for (int i = 0; i < 8; i++) { if (i > 3 && (allowZChange || intendingToReachDes)) { continue; } //Console.WriteLine("neighbourhood["+i+", 1]" + neighbourOrderList[i, 0]); pos.x = (ushort)(n.x + neighbourOrderList[i, 0]); pos.y = (ushort)(n.y + neighbourOrderList[i, 1]); int endPosX = endPos.x; int endPosY = endPos.y; int posX = pos.x; int posY = pos.y; bool outOfRange = false; if (Math.Abs(endPosX - posX) > maxSearchDist || Math.Abs(endPosY - posY) > maxSearchDist) { outOfRange = true; } if ((!outOfRange) && (!gameMap.TileContainsType(pos, Constants.TYPE_BLOCKS_AUTO_WALK)) || (destPos.x == pos.x && destPos.y == pos.y)) { if (i > 3 && !destPos.Equals(pos)) { nodes.CloseNode(n); continue; } int cost = 0; int extraCost = 0; int newg = n.g + cost + extraCost; AStarNode neighbourNode = nodes.GetNodeInList(pos.x, pos.y); if (neighbourNode != null) { if (neighbourNode.g <= newg) { continue; } nodes.OpenNode(neighbourNode); } else { neighbourNode = nodes.CreateOpenNode(); if (neighbourNode == null) { listDir.Clear(); return false; } } neighbourNode.x = pos.x; neighbourNode.y = pos.y; neighbourNode.parent = n; neighbourNode.g = newg; neighbourNode.h = (nodes.GetEstimatedDistance((int)neighbourNode.x, (int)neighbourNode.y, (int)endPos.x, (int)endPos.y)); neighbourNode.f = neighbourNode.g + neighbourNode.h; } } nodes.CloseNode(n); } } int prevX = endPos.x; int prevY = endPos.y; int dx, dy; while (found != null) { pos.x = (ushort)found.x; pos.y = (ushort)found.y; found = found.parent; dx = pos.x - prevX; dy = pos.y - prevY; prevX = pos.x; prevY = pos.y; if (dx == 1) listDir.Insert(0, (byte)Direction.WEST); else if (dx == -1) listDir.Insert(0, (byte)Direction.EAST); else if (dy == 1) listDir.Insert(0, (byte)Direction.NORTH); else if (dy == -1) listDir.Insert(0, (byte)Direction.SOUTH); } bool empty = true; if (listDir.Count == 0) empty = false; return (!empty); }
public bool GetPathTo(Creature creature, Position destPos, List<byte> listDir, Int32 maxSearchDist, bool allowZChange) { return GetPathTo(creature, destPos, listDir, maxSearchDist, allowZChange, false); }
public bool GetPathTo(Creature creature, Position destPos, ref List<byte> listDir, Int32 maxSearchDist) { return GetPathTo(creature, destPos, listDir, 12, false); }
public override void RemoveThing(Position position, byte stackpos) { PerformThink(); }
public override void AddTileCreature(Creature creature, Position position, byte stackpos) { if (!creature.AttackableByMonster()) { return; } potentialTargets.Add(creature); }
/// <summary> /// Tests if the specified position indicates /// a move to/from a container position. /// </summary> /// <param name="pos">The position to test.</param> /// <returns>True if to/from container, false otherwise.</returns> private bool ContainerPos(Position pos) { return CarryingPos(pos) && (pos.y & CONTAINER_HEADER) != 0; }
private void HandlePush(Player player, Position posFrom, ushort thingID, byte stackpos, Position posTo, byte count) { this.player = player; this.posFrom = posFrom; this.thingID = thingID; this.stackpos = stackpos; this.posTo = posTo; this.count = count; }
/// <summary> /// Sends the protocol data for adding itself to the ground. /// </summary> /// <param name="proto">A reference to the protocol.</param> /// <param name="player">The player for whom to add this to.</param> /// <param name="stackPos">The stack position of this thing.</param> public override void AddThisToGround(ProtocolSend proto, Player player, Position pos, byte stackPos) { proto.AddItem(pos, this, stackPos); }
/// <summary> /// Swap the items. Note: The posTo must be to an inventory location /// and the posFrom must not be an inventory item and the items /// to swap must both be equipable. /// </summary> /// <param name="invItem">The inventory item to swap.</param> /// <param name="invIndex">The index for which to swap in the inventory.</param> private void SwapItem(Item invItem, byte invIndex) { byte origCount = count; Item otherItem = itemToMove; Position oldPos = posFrom.Clone(); posFrom = posTo; itemToMove = invItem; count = invItem.Count; MoveItemFromInventory(); itemToMove = invItem; count = invItem.Count; posTo = oldPos; if (ContainerPos(posTo)) { MoveItemToContainer(); } else { MoveToGround(); } posTo = posFrom; itemToMove = otherItem; count = origCount; MoveItemToInventory(); /*Thing thingToMove = otherItem; count = otherItem.Count; Position temp = posFrom.Clone(); if (ContainerPos(posFrom)) { MoveFromContainer(ref thingToMove); } else { //From ground Console.WriteLine("from ground called"); MoveFromGround(ref thingToMove); } /* thingToMove = invItem; count = invItem.Count; posFrom.y = invIndex; MoveFromInventory(ref thingToMove); Position temp2 = posTo.Clone(); posTo = temp.Clone(); if (ContainerPos(posTo)) { MoveToContainer(thingToMove); } else { MoveToGround(thingToMove); } thingToMove = otherItem; posTo = temp2.Clone(); MoveToInventory(thingToMove); foreach (Thing thing in thingsPrepared) { thing.Finish(); }*/ }
public override void AppendHandlePush(Player player, Position posFrom, ushort thingID, byte stackpos, Position posTo, byte count, GameWorld world) { world.GetMovingSystem().HandlePush(player, posFrom, thingID, stackpos, posTo, count, this); }
/// <summary> /// Adds the specified position to the buffer. /// </summary> /// <param name="pos"> /// The position to add. /// </param> public void AddPosition(Position pos) { AddU16(pos.x); AddU16(pos.y); AddByte(pos.z); }
public override void UseThingWith(Player user, Position posWith, GameWorld world, byte stackposWith) { string attr = GetAttribute(Constants.ATTRIBUTE_RUNES_SPELL_NAME); if (attr != null) { Spell spell = Spell.CreateRuneSpell(attr, user, posWith); spell.Rune = this; spell.UseWithPos = posWith; spell.UseWithStackpos = stackposWith; world.GetSpellSystem().CastSpell(spell.Name, user, spell, world); return; } if (useItemsWith.ContainsKey(ItemID)) { useItemsWith[ItemID](this, user, world, posWith, stackposWith); } }
/// <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> /// See GetThing()'s overloaded method. /// </summary> /// <param name="player"></param> /// <param name="?"></param> /// <param name="stackpos"></param> /// <returns></returns> public Thing GetThing(Player player, Position pos, byte stackpos) { return GetThing(player, pos, stackpos, false); }
public static Spell CreateRuneSpell(string name, Player player, Position pos) { Spell spell = new Spell(); otherSpells[name.ToLower()].InitDelegate.Invoke (new object[] { name, player, pos, spell }); return spell; }
public void HandlePush(Player player, Position posFrom, ushort thingID, byte stackpos, Position posTo, byte count, Creature creatureMoved) { HandlePush(player, posFrom, thingID, stackpos, posTo, count); creatureToMove = creatureMoved; if (!creatureMoved.IsOfType(Constants.TYPE_MOVEABLE) || map.GetTile(posTo) == null) { return; } if (map.GetTile(posTo).ContainsType(Constants.TYPE_BLOCKS_AUTO_WALK) || !creatureToMove.IsNextTo(posTo) || !player.IsNextTo(posFrom)) { return; } world.HandleMove(creatureMoved, posTo, creatureToMove.CurrentDirection); }
public override void AddLocalChat(ChatLocal chatType, string message, Position pos, Creature creatureFrom) { if (creatureFrom == this) { return; } lastMessage = message.ToLower(); lastMessage = lastMessage.Replace(".", ""); lastMessage = lastMessage.Replace("?", ""); lastCreatureSay = creatureFrom; HandleMessage(); }
/// <summary> /// Handle moving from a player. Note: This method is not thread-safe! /// </summary> /// <param name="player">The player moving the thing.</param> /// <param name="posFrom">The position where the thing current is.</param> /// <param name="thingID">The thing's id.</param> /// <param name="stackpos">The thing's stackpos.</param> /// <param name="posTo">The new position to place the item.</param> /// <param name="count">How much of the thing to move, if applicable.</param> public void HandlePush(Player player, Position posFrom, ushort thingID, byte stackpos, Position posTo, byte count, Item itemMoved) { HandlePush(player, posFrom, thingID, stackpos, posTo, count); itemToMove = itemMoved; //TODO: Finish validating moves... if (!IsItemMoveValid()) { return; } HandleItemMove(); }
//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> /// Tests if the specified position indicates /// a move to/from a carrying position. /// </summary> /// <param name="pos">The position to test.</param> /// <returns>True if to/from carrying, false otherwise.</returns> private bool CarryingPos(Position pos) { return pos.x == CARRYING_HEADER; }