예제 #1
0
        public void AddObject(MapObject obj, bool spawn = false)
        {
            if (Objects.ContainsKey(obj.MapObjectID))
            {
                Log.WriteLine(LogLevel.Warn, "Duplicate object id in sector {0}:{1}", Y, X);
                Objects.Remove(obj.MapObjectID);
            }
            Objects.Add(obj.MapObjectID, obj);
            obj.MapSector = this;

            if (spawn)
            {
                //broadcast mob to map
                //broadcast other players to map (port code from Map.CharacterEnteredMap to here)

                // If Player: Spawn all Mobs and Players in range to Player, and Whole NPC list
                // If Mob: Spawn Mob to all Players in range
                // If NPC: Lolwut

                if (obj is ZoneCharacter)
                {
                    Map.SendCharacterEnteredMap(obj as ZoneCharacter);
                }
                else if (obj is Mob)
                {
                    using (var spawnpacket = obj.Spawn())
                    {
                        Broadcast(spawnpacket);
                    }
                }
            }
        }
예제 #2
0
 public AttackSequence(MapObject att, uint min, uint max, ushort skillid, uint x = 0, uint y = 0)
     : this(att, null, min, max, skillid, true)
 {
     this.X = x;
     this.Y = y;
     this._nextAction = Program.CurrentTime.AddMilliseconds(skillInfo.CastTime);
     this.State = AnimationState.AoEShow;
 }
예제 #3
0
 public AttackSequence(MapObject att, MapObject vict, uint min, uint max, ushort skillid, bool derp)
     : this(att, vict, min, max, 0)
 {
     this.skillid = skillid;
     this.MinDamage += skillInfo.MinDamage;
     this.MaxDamage += skillInfo.MaxDamage;
     this.X = 0;
     this.Y = 0;
 }
예제 #4
0
 public AttackSequence__(MapObject from, MapObject to, ushort skill = 0xFFFF, ushort attackspeed = 1400)
 {
     From = from;
     To = to;
     _ToID = to.MapObjectID;
     State = AnimationState.Running;
     _nextSequence = Program.CurrentTime;
     attackSpeed = attackspeed;
     skillid = skill;
 }
예제 #5
0
 public AttackSequence(MapObject att, MapObject vict, uint min, uint max, ushort attackspeed)
 {
     this.State = AnimationState.Starting;
     this.attacker = att;
     this.victim = vict;
     this.MinDamage = min;
     this.MaxDamage = max;
     this.attackspeed = attackspeed;
     this._nextAction = Program.CurrentTime;
     this.skillid = NoSkill;
     this.AnimationID = att.UpdateCounter;
     this.State = AnimationState.Running;
 }
예제 #6
0
파일: Drop.cs 프로젝트: iFeddy/SolarFiesta
 public Drop(Item item, MapObject dropper, int x, int y, int secondsToLive)
 {
     if (item is Equip)
     {
         Item = new DroppedEquip(item as Equip);
     }
     else
     {
         Item = new DroppedItem(item);
     }
     DroppedBy = dropper;
     Position = new Vector2(x, y);
     Expire = Program.CurrentTime.AddSeconds(secondsToLive);
     CanTake = true;
 }
예제 #7
0
        public static void SendAttackAnimation(MapObject from, ushort objectID, ushort attackspeed, byte stance)
        {
            using (var packet = new Packet(SH9Type.AttackAnimation))
            {
                packet.WriteUShort(from.MapObjectID);
                packet.WriteUShort(objectID);
                packet.WriteByte(stance);

                packet.WriteUShort(attackspeed);

                packet.WriteByte(4);
                packet.WriteByte(100);
                from.MapSector.Broadcast(packet);
            }
        }
예제 #8
0
 public static Packet RemoveObject(MapObject obj)
 {
     Packet packet = new Packet(SH7Type.RemoveObject);
     packet.WriteUShort(obj.MapObjectID);
     return packet;
 }
예제 #9
0
 public static void SendSkillStartOthers(MapObject user, ushort skillid, ushort victim, ushort animid)
 {
     // 9 79 | [9A 26] [06 06] [8A 27] [97 2D]
     using (var packet = new Packet(SH9Type.SkillUsePrepareOthers))
     {
         packet.WriteUShort(user.MapObjectID);
         packet.WriteUShort(skillid);
         packet.WriteUShort(victim);
         packet.WriteUShort(animid);
         user.MapSector.Broadcast(packet, user.MapObjectID);
     }
 }
예제 #10
0
 public static void SendSkillNoVictim(MapObject user, ushort animid)
 {
     // 9 82 | [75 70] [32 29] [00]
     using (var packet = new Packet(SH9Type.SkillAnimationTarget))
     {
         packet.WriteUShort(animid);
         packet.WriteUShort(user.MapObjectID);
         packet.WriteBool(false);
         user.MapSector.Broadcast(packet);
     }
 }
예제 #11
0
 public static void SendSkill(MapObject user, ushort animid, List<SkillVictim> victims)
 {
     using (var packet = new Packet(SH9Type.SkillAnimationTarget))
     {
         packet.WriteUShort(animid);
         packet.WriteUShort(user.MapObjectID);
         packet.WriteByte((byte)(victims.Count > 255 ? 255 : victims.Count));
         for (byte i = 0; i < victims.Count && i != 255; i++)
         {
             var victim = victims[i];
             packet.WriteUShort(victim.MapObjectID);
             packet.WriteByte(victim.Stance1);
             packet.WriteByte(victim.Stance2);
             packet.WriteUInt(victim.Damage);
             packet.WriteUInt(victim.HPLeft);
             packet.WriteUShort(victim.HPCounter);
         }
         user.MapSector.Broadcast(packet);
     }
 }
예제 #12
0
 public static void SendDieAnimation(MapObject from, ushort objectID)
 {
     // DO NOT SEND THIS TO THE DYING PLAYER, LOL
     using (var packet = new Packet(SH9Type.DieAnimation))
     {
         packet.WriteUShort(objectID);
         packet.WriteUShort(from.MapObjectID);
         from.MapSector.Broadcast(packet, objectID);
     }
 }
예제 #13
0
파일: Mob.cs 프로젝트: iFeddy/SolarFiesta
        public void Die()
        {
            HP = 0;
            Moving = false;
            boundryLT = null;
            boundryRB = null;
            AttackingSequence = null;
            Target = null;
            DeathTriggered = true;

            if (Spawnplace != null)
            {
                Spawnplace.CurrentMobs--;
            }
            _nextUpdate = Program.CurrentTime.AddSeconds(3);
        }
예제 #14
0
파일: Mob.cs 프로젝트: iFeddy/SolarFiesta
        public override void AttackSkill(ushort skillid, MapObject victim)
        {
            base.AttackSkill(skillid, victim); // lol

            if (AttackingSequence != null) return;
            AttackingSequence = new AttackSequence(this, victim, 0, InfoServer.Str, skillid, true);
            Target = victim;
        }
예제 #15
0
파일: Mob.cs 프로젝트: iFeddy/SolarFiesta
        public override void Attack(MapObject victim)
        {
            base.Attack(victim); // lol

            if (AttackingSequence != null) return;
            AttackingSequence = new AttackSequence(this, victim, 0, InfoServer.Str, 1400);
            Target = victim;
        }
예제 #16
0
파일: Map.cs 프로젝트: iFeddy/SolarFiesta
 public bool FullAddObject(MapObject obj)
 {
     Log.WriteLine(LogLevel.Debug, "Added {0} to the map.", obj.GetType().ToString());
     if (AssignObjectID(obj))
     {
         return FinalizeAdd(obj);
     }
     else return false;
 }
예제 #17
0
파일: Map.cs 프로젝트: iFeddy/SolarFiesta
 public bool FinalizeAdd(MapObject obj)
 {
     Sector sector = GetSectorByPos(obj.Position);
     sector.AddObject(obj, true);
     return Objects.TryAdd(obj.MapObjectID, obj);
 }
예제 #18
0
파일: Map.cs 프로젝트: iFeddy/SolarFiesta
 public bool AssignObjectID(MapObject obj)
 {
     bool result = false;
     lock (availableLifeKeys)
     {
         if (availableLifeKeys.Count == 0)
         {
             if (lifeIndexer == ushort.MaxValue)
             {
                 Log.WriteLine(LogLevel.Warn, "Map is having map object id overflow (cannot handler more than {0})", ushort.MaxValue);
                 result = false;
             }
             else
             {
                 ushort key = lifeIndexer;
                 ++lifeIndexer;
                 obj.MapObjectID = key;
                 result = true;
             }
         }
         else
         {
             ushort key = availableLifeKeys.Dequeue();
             obj.MapObjectID = key;
             result = true;
         }
         if (result)
             obj.Map = this;
         return result;
     }
 }
예제 #19
0
        private void Handle()
        {
            if (To != null)
            {
                ushort seed = (ushort)Program.Randomizer.Next(0, 100); //we use one seed & base damage on it

                ushort Damage = (ushort)Program.Randomizer.Next(0, seed);
                bool Crit = seed >= 80;
                stance = (byte)(Program.Randomizer.Next(0, 3));
                To.Damage(From, Damage);
                Handler9.SendAttackAnimation(From, _ToID, attackSpeed, stance);
                Handler9.SendAttackDamage(From, _ToID, Damage, Crit, GetHPLeft(), To.UpdateCounter);

                if (To.IsDead)
                {
                    if (To is Mob && From is ZoneCharacter)
                    {
                        uint exp = (To as Mob).InfoServer.MonEXP;
                        (From as ZoneCharacter).GiveEXP(exp, _ToID);
                    }
                    Handler9.SendDieAnimation(From, _ToID);
                    State = AnimationState.Ended;
                    To = null;
                }
                else
                {
                    SetNewSequenceTime(attackSpeed);
                }
            }
        }
예제 #20
0
파일: Mob.cs 프로젝트: iFeddy/SolarFiesta
        public override void Update(DateTime date)
        {
            if (Position == null)
            {
                return;
            }

            if (IsDead)
            {
                if (!DeathTriggered)
                {
                    Die();
                    return; // Wait till 3 seconds are over, then remove
                }
                else if (_nextUpdate <= date)
                {
                    Map.RemoveObject(this.MapObjectID);
                    Position = null;
                    return;
                }
                return;
            }

            if (AttackingSequence != null && Target != null)
            {
                if (Vector2.Distance(Target.Position, Position) < 50)
                {
                    AttackingSequence.Update(date);
                    if (AttackingSequence.State == AttackSequence.AnimationState.Ended)
                    {
                        AttackingSequence = null;
                        Target = null;

                    }
                }
                else
                {
                    _nextUpdate = _nextUpdate.AddDays(-1);
                }
            }

            if (_nextUpdate > date) return;

            if (Target != null)
            {
                _nextUpdate = Program.CurrentTime.AddSeconds(1);

                // Try to move to target's pos
                // Might glitch the f**k out. lol
                if (Target.Map != Map)
                {
                    Target = null; // Stop aggro-ing >:(
                }
                else
                {
                    if (Vector2.Distance(Target.Position, Position) < 800)
                    {
                        if (Map.Block.CanWalk(Target.Position.X, Target.Position.Y))
                        {
                            Move(Position.X, Position.Y, Target.Position.X, Target.Position.Y, false, false);
                        }
                    }
                    else
                    {
                        Target = null; // Stop aggro-ing >:(
                    }
                }
                return;
            }
            else
            {
                _nextUpdate = Program.CurrentTime.AddSeconds(Program.Randomizer.Next(10, 60)); // Around 10 seconds to 1 minute before new movement is made

                // Move to random spot.
                Vector2 newpos = new Vector2(Position);
                bool ok = false;
                for (int i = 1; i <= 20; i++)
                {
                    // Generate new position, and check if it's in valid bounds, else recheck
                    newpos = Vector2.GetRandomSpotAround(Program.Randomizer, newpos, 60);
                    if (newpos.X > 0 && newpos.Y > 0 && Map.Block.CanWalk(newpos.X, newpos.Y) && PositionIsInBoundries(newpos))
                    {
                        ok = true;
                        break;
                    }
                    /*
                    int t = Program.Randomizer.Next() % 11;

                    if (t <= 2)
                    {
                        // All +

                        newx += Program.Randomizer.Next(MinMovement, MaxMovement);
                        newy += Program.Randomizer.Next(MinMovement, MaxMovement);
                    }
                    else if (t <= 5)
                    {
                        newx -= Program.Randomizer.Next(MinMovement, MaxMovement);
                        newy += Program.Randomizer.Next(MinMovement, MaxMovement);
                    }
                    else if (t <= 8)
                    {
                        newx += Program.Randomizer.Next(MinMovement, MaxMovement);
                        newy -= Program.Randomizer.Next(MinMovement, MaxMovement);
                    }
                    else
                    {
                        newx -= Program.Randomizer.Next(MinMovement, MaxMovement);
                        newy -= Program.Randomizer.Next(MinMovement, MaxMovement);
                    }
                    Vector2 test = newpos + new Vector2(newx, newy);
                    if (Map.Block.CanWalk(test.X, test.Y) && PositionIsInBoundries(test))
                    {
                        newpos = test;
                        break;
                    }
                    */
                }

                if (ok)
                {
                    Move(Position.X, Position.Y, newpos.X, newpos.Y, false, false);
                }
            }
        }
예제 #21
0
 public static void SendSkill(MapObject user, ushort animid, ushort victimid, uint damage, uint newhp, ushort counter, byte special1 = 0x10, byte special2 = 0x00)
 {
     // 9 82 | [E5 3F] [8A 27] [01] [8A 27] [10 00] [09 00 00 00] [5E 00 00 00] [A7 4C]
     // 9 82 | [9A 35] [8A 27] [01] [C2 05] [10 00] [0A 00 00 00] [1D 01 00 00] [73 37]
     // 9 82 | [43 3C] [42 15] [01] [AC 4C] [01 01] [7A 02 00 00] [00 00 00 00] [35 09]
     // 9 82 | [0E 39] [42 15] [01] [00 4A] [21 01] [1C 03 00 00] [00 00 00 00] [8C 0E]
     using (var packet = new Packet(SH9Type.SkillAnimationTarget))
     {
         packet.WriteUShort(animid);
         packet.WriteUShort(user.MapObjectID);
         packet.WriteBool(true);
         packet.WriteUShort(victimid);
         packet.WriteByte(special1);
         packet.WriteByte(special2);
         packet.WriteUInt(damage);
         packet.WriteUInt(newhp);
         packet.WriteUShort(counter);
         user.MapSector.Broadcast(packet);
     }
 }
예제 #22
0
파일: Mob.cs 프로젝트: iFeddy/SolarFiesta
        private void Init()
        {
            Info = DataProvider.Instance.GetMobInfo(ID);
            MobInfoServer temp;
            DataProvider.Instance.MobData.TryGetValue(Info.Name, out temp);
            InfoServer = temp;
            Moving = false;
            Target = null;
            Spawnplace = null;
            _nextUpdate = Program.CurrentTime;
            DeathTriggered = false;

            HP = MaxHP;
            SP = MaxSP;
            Level = Info.Level;
        }
예제 #23
0
 public static void SendSkillAnimationForPlayer(MapObject user, ushort skillid, ushort animid)
 {
     // 9 87 | [E5 3F] [8A 27] [04 06]
     // 9 87 | [97 2D] [9A 26] [06 06]
     using (var packet = new Packet(SH9Type.SkillAnimation))
     {
         packet.WriteUShort(animid);
         packet.WriteUShort(user.MapObjectID);
         packet.WriteUShort(skillid);
         user.MapSector.Broadcast(packet);
     }
 }
예제 #24
0
        public void Update(DateTime now)
        {
            if (this.State == AnimationState.Ended) return;
            if (this.attacker == null || this.attacker.IsDead)
            {
                this.State = AnimationState.Ended;
                return;
            }
            if (!IsAoE && (this.victim == null || this.victim.IsDead))
            {
                this.State = AnimationState.Ended;
                return;
            }
            if (this._nextAction > now) return;

            if (IsSkill)
            {
                if (IsAoE)
                {
                    if (this.State == AnimationState.AoEShow)
                    {
                        Handler9.SendSkillPosition(attacker, AnimationID, skillid, X, Y);
                        Handler9.SendSkillAnimationForPlayer(attacker, skillid, AnimationID);
                        this._nextAction = Program.CurrentTime.AddMilliseconds(skillInfo.SkillAniTime);
                        this.State = AnimationState.AoEDo;
                    }
                    else if (this.State == AnimationState.AoEDo)
                    {
                        // Lets create an AoE skill @ X Y
                        List<SkillVictim> victims = new List<SkillVictim>();
                        var pos = new Vector2((int)X, (int)Y);
                        // Find victims
                        foreach (var v in attacker.Map.GetObjectsBySectors(attacker.MapSector.SurroundingSectors))
                        {
                            if (attacker == v) continue;
                            if (v is ZoneCharacter) continue;
                            if (Vector2.Distance(v.Position, pos) > skillInfo.Range) continue;
                            // Calculate dmg

                            uint dmg = (uint)Program.Randomizer.Next((int)MinDamage, (int)MaxDamage);
                            if (dmg > v.HP)
                            {
                                v.HP = 0;
                            }

                            if (!v.IsDead)
                            {
                                v.Attack(attacker);
                            }
                            else
                            {
                                if (v is Mob && attacker is ZoneCharacter)
                                {
                                    uint exp = (v as Mob).InfoServer.MonEXP;
                                    (attacker as ZoneCharacter).GiveEXP(exp, v.MapObjectID);
                                }
                            }

                            victims.Add(new SkillVictim(v.MapObjectID, dmg, v.HP, 0x01, 0x01, v.UpdateCounter));
                            if (victims.Count == skillInfo.MaxTargets) break;
                        }

                        Handler9.SendSkill(attacker, AnimationID, victims);
                        foreach (var v in victims)
                        {
                            if (v.HPLeft == 0)
                            {
                                Handler9.SendDieAnimation(attacker, v.MapObjectID);
                            }
                        }

                        victims.Clear();
                        State = AnimationState.Ended;
                    }
                }
                else
                {
                    // Normal skill parsing
                    State = AnimationState.Ended;
                }
            }
            else
            {
                // Just attacking...
                if (victim == null || victim.IsDead)
                {
                    victim = null;
                    attacker = null;
                    State = AnimationState.Ended;
                }
                else
                {
                    // Calculate some damage to do
                    ushort dmg = (ushort)Program.Randomizer.Next((int)MinDamage, (int)MaxDamage);
                    if (dmg > victim.HP)
                    {
                        victim.HP = 0;
                    }
                    bool Crit = Program.Randomizer.Next() % 100 >= 80;
                    byte stance = (byte)(Program.Randomizer.Next(0, 3));
                    victim.Damage(attacker, dmg);
                    Handler9.SendAttackAnimation(attacker, victim.MapObjectID, attackspeed, stance);
                    Handler9.SendAttackDamage(attacker, victim.MapObjectID, dmg, Crit, victim.HP, victim.UpdateCounter);

                    if (victim.IsDead)
                    {
                        if (victim is Mob && attacker is ZoneCharacter)
                        {
                            uint exp = (victim as Mob).InfoServer.MonEXP;
                            (attacker as ZoneCharacter).GiveEXP(exp, victim.MapObjectID);
                        }

                        Handler9.SendDieAnimation(attacker, victim.MapObjectID);
                        victim = null;
                        State = AnimationState.Ended;
                    }
                    else
                    {
                        _nextAction = now.AddMilliseconds(attackspeed);
                    }
                }
            }
        }
예제 #25
0
 public static void SendSkillPosition(MapObject user, ushort animid, ushort skillid, uint x, uint y)
 {
     // 9 81 | [32 29] [B8 10] [56 0A 00 00] [3A 27 00 00] [75 70]
     using (var packet = new Packet(SH9Type.SkillAnimationPosition))
     {
         packet.WriteUShort(user.MapObjectID);
         packet.WriteUShort(skillid);
         packet.WriteUInt(x);
         packet.WriteUInt(y);
         packet.WriteUShort(animid);
         user.MapSector.Broadcast(packet);
     }
 }
예제 #26
0
        public virtual void Damage(MapObject bully, uint amount, bool isSP = false)
        {
            if (isSP)
            {
                if (SP < amount) SP = 0;
                else SP -= amount;
            }
            else
            {
                if (HP < amount) HP = 0;
                else HP -= amount;
            }

            if (bully == null)
            {
                if (this is ZoneCharacter)
                {
                    ZoneCharacter character = this as ZoneCharacter;
                    if (isSP)
                        Handler9.SendUpdateSP(character);
                    else
                        Handler9.SendUpdateHP(character);
                }
            }
            else
            {
                if (this is Mob && ((Mob)this).AttackingSequence == null)
                {
                    ((Mob)this).Attack(bully);
                }
                else if (this is ZoneCharacter && !((ZoneCharacter)this).IsAttacking)
                {
                    ((ZoneCharacter)this).Attack(bully);
                }
            }
        }
예제 #27
0
 public static void SendStatsUpdate(MapObject pObject, ZoneClient to, bool selectedby)
 {
     using (var packet = new Packet(SH9Type.StatUpdate))
     {
         packet.WriteBool(selectedby);
         packet.WriteUShort(pObject.MapObjectID);
         if (pObject is ZoneCharacter)
         {
             ((ZoneCharacter)pObject).WriteUpdateStats(packet);
         }
         else
         {
             ((Mob)pObject).WriteUpdateStats(packet);
         }
         to.SendPacket(packet);
     }
 }
예제 #28
0
 public static Packet MoveObject(MapObject obj, int oldx, int oldy, bool walk, ushort speed = 115)
 {
     Packet packet = new Packet(walk ? SH8Type.Walk : SH8Type.Move);
     packet.WriteUShort(obj.MapObjectID);
     packet.WriteInt(oldx);
     packet.WriteInt(oldy);
     packet.WriteInt(obj.Position.X);
     packet.WriteInt(obj.Position.Y);
     packet.WriteUShort(speed);
     return packet;
 }
예제 #29
0
        public static void SendAttackDamage(MapObject from, ushort objectID, ushort damage, bool crit, uint hpleft, ushort counter)
        {
            using (var packet = new Packet(SH9Type.AttackDamage))
            {
                packet.WriteUShort(from.MapObjectID);
                packet.WriteUShort(objectID);
                packet.WriteBool(crit);
                packet.WriteUShort(damage);
                packet.WriteUInt(hpleft);
                packet.WriteUShort(counter);
                packet.WriteByte(4);
                packet.WriteByte(100);

                from.MapSector.Broadcast(packet);
            }
        }
예제 #30
0
 public static Packet StopObject(MapObject obj)
 {
     Packet packet = new Packet(SH8Type.StopTele);
     packet.WriteUShort(obj.MapObjectID);
     packet.WriteInt(obj.Position.X);
     packet.WriteInt(obj.Position.Y);
     return packet;
 }