コード例 #1
0
ファイル: GameWorld.cs プロジェクト: brewsterl/berserker
 /// <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);
     }
 }
コード例 #2
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
 /// <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);
     }
 }
コード例 #3
0
ファイル: Item.cs プロジェクト: brewsterl/berserker
 public override bool HandleWalkAction(Creature creature, GameWorld world, WalkType type)
 {
     if (walkItems.ContainsKey(this.ItemID)) {
         return walkItems[ItemID](this, creature, world, type);
     }
     return true;
 }
コード例 #4
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
        /// <summary>
        /// Lets the creature know that it was damaged by another creature.
        /// Note: This method adjusts the damage as needed if hp less than 0 or
        /// greater than max.
        /// </summary>
        /// <param name="dmgAmt">Damage amt to add.</param>
        /// <param name="attacker">The name of the attacker, null if none.</param>
        /// <param name="magic">True if it was a magic attack, false otherwise.</param>
        public virtual void AddDamage(int dmgAmt, Creature attacker, bool magic)
        {
            if (CurrentHP - dmgAmt < 0) {
                dmgAmt = CurrentHP;
            } else if (CurrentHP - dmgAmt > MaxHP) {
                dmgAmt = -1 * (MaxHP - CurrentHP);
            }

            CurrentHP = (ushort)(CurrentHP - dmgAmt);
            if (dmgAmt > 0) {
                string loseString = "You lose " + dmgAmt + " hitpoint" +
                    (dmgAmt > 1 ? "s" : "") + ".";
                string leftString = " You have " + CurrentHP + " hitpoint" +
                    (CurrentHP > 1 ? "s" : "") + " left.";
                AddStatusMessage(loseString + leftString);
            }

            if (CurrentHP == 0) {
                CurrentHealthStatus = HealthStatus.DEAD;
            } else {
                //THE FORMULA! Lolz
                int divisor = MaxHP / 5;
                CurrentHealthStatus = (HealthStatus)((CurrentHP / divisor) + 1);

                if (CurrentHealthStatus >= HealthStatus.TOTAL_TYPES) {
                    throw new Exception("Invalid health status in AddDamage()");
                }
            }
        }
コード例 #5
0
ファイル: Pathfinder.cs プロジェクト: brewsterl/berserker
        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);
        }
コード例 #6
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
 public virtual void AppendNotifyOfDeath(Item corpse, Map gameMap)
 {
     if (CurrentHP == 0) {
         CreatureAttacking = null;
     }
 }
コード例 #7
0
ファイル: Npc.cs プロジェクト: brewsterl/berserker
 public void SetIdle()
 {
     talkingTo = null;
 }
コード例 #8
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
 /// <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);
     }
 }
コード例 #9
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
        /// <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;
            }
        }
コード例 #10
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
        public override void AddDamage(int dmgAmt, Creature attacker, bool magic)
        {
            base.AddDamage(dmgAmt, attacker, magic);
            totalDamageDealt += dmgAmt;
            if (attacker == null) {
                return;
            }

            foreach (AttackersInformation info in attackersInfoList) {
                if (info.Attacker == attacker) {
                    info.DamageByCreature += dmgAmt;
                    return;
                }
            }

            //Attacker not found in list... therefore add attacker
            attackersInfoList.Add(new AttackersInformation(attacker, dmgAmt));
        }
コード例 #11
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
 public override void AddTileCreature(Creature creature, Position position, 
     byte stackpos)
 {
     if (!creature.AttackableByMonster()) {
         return;
     }
     potentialTargets.Add(creature);
 }
コード例 #12
0
ファイル: Map.cs プロジェクト: brewsterl/berserker
        /// <summary>
        /// Gets a position for which a creature could be added.
        /// Returns null if all the spaces around this position are taken.
        /// </summary>
        /// <param name="curPos">The position to add the creature.</param>
        /// <param name="creatureFor">The creature to add.</param>
        /// <returns>A free space or null if all spaces are taken.</returns>
        public Position GetFreePosition(Position curPos, Creature creatureFor)
        {
            Position tempPos = curPos.Clone();

            if (!TileContainsType(curPos, Constants.TYPE_BLOCKS_AUTO_WALK)) {
                return tempPos;
            }

            for (int i = -1; i <= 1; i++) {
                for (int j = -1; j <= 1; j++) {
                    tempPos.x = (ushort)(curPos.x + i);
                    tempPos.y = (ushort)(curPos.y + j);
                    if (!TileContainsType(tempPos, Constants.TYPE_BLOCKS_AUTO_WALK)) {
                        return tempPos;
                    }
                }
            }

            return null;
        }
コード例 #13
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
 public override void AddCreatureMove(Direction direction, Creature creature,
     Position oldPos, Position newPos, byte oldStackpos, byte newStackpos)
 {
     if (!creature.AttackableByMonster()) {
         return;
     }
     potentialTargets.Add(creature);
     PerformThink();
 }
コード例 #14
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
        public void TurnTowardsTarget(Creature target)
        {
            //basic error checks
            if (target == null)
                return;

            //Here comes the formula :D
            Position oppPos = target.CurrentPosition;
            Position thisPos = this.CurrentPosition;

            Direction directionToTurn = Direction.WEST;

            if (oppPos.x < thisPos.x) {
                directionToTurn = Direction.WEST;
            } else if (oppPos.x > thisPos.x) {
                directionToTurn = Direction.EAST;
            } else if (oppPos.y < thisPos.y) {
                directionToTurn = Direction.NORTH;
            } else if (oppPos.y > thisPos.y) {
                directionToTurn = Direction.SOUTH;
            }

            if (CurrentDirection == directionToTurn) {
                //Already facing this direction...
                return;
            }

            World.HandleChangeDirection(this, directionToTurn);
        }
コード例 #15
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
 public void SetCreatureAttacking(Creature creature)
 {
     foreach (Monster summon in summons) {
         summon.SetCreatureAttacking(creature);
     }
     CreatureAttacking = creature;
 }
コード例 #16
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
        /// <summary>
        /// Gets how much damage to be done to this creature based on
        /// the attacking creature's stats.
        /// </summary>
        /// <param name="attacker">The creature attacking.</param>
        /// <returns>The damage amount if > 0 or PUFF/SPARK constants 
        /// otherwise.</returns>
        public int GetDamageAmt(Creature attacker)
        {
            int atkValue = attacker.GetAtkValue();
            int shieldValue = this.GetShieldValue();
            int netValue = atkValue - shieldValue;

            if (netValue > 0) {
                return netValue;
            } else if (netValue == 0) {
                return Constants.SPARK;
            } else {
                return Constants.PUFF;
            }
        }
コード例 #17
0
ファイル: MovingSystem.cs プロジェクト: brewsterl/berserker
 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);
 }
コード例 #18
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
 public AttackersInformation(Creature atker, int amtDealt)
 {
     Attacker = atker;
     DamageByCreature = amtDealt;
 }
コード例 #19
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
        /// <summary>
        /// Handles a broadcast made by a creature.
        /// </summary>
        /// <param name="sender">The sender of the broadcast.</param>
        /// <param name="msg">The message to broadcast.</param>
        private void HandleBroadcast(Creature sender, string msg)
        {
            if (!msg.ToLower().StartsWith(BROADCAST_TYPE + "")) {
                throw new Exception("Invalid call to HandleBroadcast()");
            }
            msg = msg.Substring(1); //Remove quantifier type

            //Invalid access level
            if (sender.Access < Constants.ACCESS_GAMEMASTER) {
                return;
            }

            foreach (KeyValuePair<string, Player> kvp in playersOnline) {
                kvp.Value.ResetNetMessages();
                kvp.Value.AddGlobalChat(ChatGlobal.BROADCAST, msg, sender.Name);
                kvp.Value.WriteToSocket();
            }
        }
コード例 #20
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
 /// <summary>
 /// Sends a private message to another player.
 /// </summary>
 /// <param name="sender">The creature sending.</param>
 /// <param name="recipient">The recipient's name (player).</param>
 /// <param name="msg">The message to send.</param>
 private void AppendPrivateMessage(Creature sender, string recipient, string msg)
 {
     recipient = recipient.ToLower();
     foreach (KeyValuePair<string, Player> kvp in playersOnline) {
         if (kvp.Key.StartsWith(recipient)) {
             kvp.Value.AddGlobalChat(ChatGlobal.PRIVATE_MSG, msg, sender.Name);
             sender.AddStatusMessage("Message sent to " + kvp.Value.Name + ".");
             return;
         }
     }
     sender.AddStatusMessage("A player with this name is not online.");
 }
コード例 #21
0
ファイル: ChatSystem.cs プロジェクト: brewsterl/berserker
        /// <summary>
        /// This method handles a private message.
        /// </summary>
        /// <param name="sender">The sender of the message.</param>
        /// <param name="msg">The message itself.</param>
        private void HandlePrivateMessage(Creature sender, string msg)
        {
            // Valid format: *name* msg

            if (!msg.StartsWith(PRIVATE_MSG_INDICATOR)) {
                throw new Exception("Invalid call to HandlePrivateMessage()");
            }

            bool isName = true;
            string name = "";
            string message = "";
            for (int i = 1; i < msg.Length; i++) {
                string charAt = msg[i] + "";
                if (charAt == PRIVATE_MSG_INDICATOR) {
                    isName = false;
                    continue; //Skip adding PRIVATE_MSG_INDICATOR to message
                }

                if (isName) {
                    name += charAt;
                } else {
                    message += charAt;
                }
            }

            //Remove starting space, if applicable;
            if (message.StartsWith(EMPTY_SPACE)) {
            #if DEBUG
                Log.WriteDebug("Message started with empty space.");
            #endif
                message = message.Substring(1);
            }

            AppendPrivateMessage(sender, name, message);
        }
コード例 #22
0
ファイル: Spell.cs プロジェクト: brewsterl/berserker
 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;
 }
コード例 #23
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
 /// <summary>
 /// Set the master for this monster thus making it
 /// a summoned/convinced creature. To make this monster wild (again),
 /// send null as the argument.
 /// </summary>
 /// <param name="creature">Creature to set as the master.</param>
 public void SetMaster(Creature creature)
 {
     if (creature != null) {
         creature.AddSummon(this);
     }
     Master = creature;
 }
コード例 #24
0
ファイル: Creature.cs プロジェクト: brewsterl/berserker
 public override void AppendHandleDamage(int dmgAmt, Creature attacker, ImmunityType type,
     GameWorld world, bool magic)
 {
     world.AppendAddDamage(attacker, this, dmgAmt, type, magic);
 }
コード例 #25
0
ファイル: SpellSystem.cs プロジェクト: brewsterl/berserker
        /// <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
        }
コード例 #26
0
ファイル: Monster.cs プロジェクト: brewsterl/berserker
 private bool ExistsPath(Creature creature)
 {
     List<byte> dir = new List<byte>();
     Finder.GetPathTo(this, creature.CurrentPosition, dir, 12, false, false);
     return dir.Count > 0;
 }
コード例 #27
0
ファイル: Npc.cs プロジェクト: brewsterl/berserker
 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();
 }
コード例 #28
0
ファイル: Pathfinder.cs プロジェクト: brewsterl/berserker
 public bool GetPathTo(Creature creature, Position destPos,
     ref List<byte> listDir, Int32 maxSearchDist)
 {
     return GetPathTo(creature, destPos, listDir, 12, false);
 }
コード例 #29
0
ファイル: Npc.cs プロジェクト: brewsterl/berserker
 public void SetTalkingTo()
 {
     talkingTo = lastCreatureSay;
 }
コード例 #30
0
ファイル: Pathfinder.cs プロジェクト: brewsterl/berserker
 public bool GetPathTo(Creature creature, Position destPos,
     List<byte> listDir, Int32 maxSearchDist, bool allowZChange)
 {
     return GetPathTo(creature, destPos, listDir, maxSearchDist, allowZChange, false);
 }