public static uint MeleePlayerVsMonster(Entities.Character Attacker, Entities.Monster Attacked) { uint Damage = (uint)Program.Random.Next(Attacker.MinAttack, Attacker.MaxAttack); Damage = (uint)((double)Damage * (1 + (Attacker.DragonGemBonus / 100))); if (Attacked.Info.Defense >= Damage) { Damage = 1; } else { Damage -= Attacked.Info.Defense; } if (Attacker.Level > Attacked.Info.Level) { int dLvl = Attacker.Level - Attacked.Info.Level; if (dLvl >= 3 && dLvl <= 5) { Damage = (uint)(Damage * 1.5); } else if (dLvl > 5 && dLvl <= 10) { Damage *= 2; } else if (dLvl > 10 && dLvl <= 20) { Damage *= 3; } else if (dLvl > 20) { Damage = (uint)(Damage * (1 + (.3 * dLvl / 5))); } } return(Math.Max(1, Damage)); }
/// <summary> /// Does damage to a monster. /// </summary> /// <param name="AttackedMob">The monster being attacked</param> /// <param name="Damage">The damage being done</param> /// <param name="AType">The type of attack being done</param> /// <param name="CSocket">The ClientSocket Attacking</param> /// <returns>true if the monster dies, false if not.</returns> public static bool doMonster(Monster AttackedMob, int Damage, int AType, ClientSocket CSocket) { Character Attacker = CSocket.Client; if (Damage < AttackedMob.CurrentHP) { if (AType != 21) EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.ID, AttackedMob.UID, Attacker.X, Attacker.Y, Damage, AType), AttackedMob.X, AttackedMob.Y, (int)AttackedMob.Map, 0, 0); Interlocked.Add(ref AttackedMob.CurrentHP, (Damage * -1)); if (AttackedMob.Info.Name != "CoEmuGuard" && AttackedMob.Info.Name != "GuardReviver" && AttackedMob.Info.Name != "CoEmuPatrol" && AttackedMob.Info.Name != "GuildPatrol") { GiveExp(CSocket, AttackedMob, Damage, false); } return false; } else { if (AType != 21) EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.ID, AttackedMob.UID, Attacker.X, Attacker.Y, Damage, AType), AttackedMob.X, AttackedMob.Y, AttackedMob.Map, 0, 0); EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.ID, AttackedMob.UID, Attacker.X, Attacker.Y, Damage, 14), AttackedMob.X, AttackedMob.Y, (int)AttackedMob.Map, 0, 0); //lock(MainGS.Monsters) //{ try { Monitor.Enter(MainGS.Monsters); MainGS.Monsters.Remove(AttackedMob.UID); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { Monitor.Exit(MainGS.Monsters); } //} AttackedMob.Die(CSocket.Client.ID); if (AttackedMob.Info.Name != "CoEmuGuard" && AttackedMob.Info.Name != "GuardReviver" && AttackedMob.Info.Name != "CoEmuPatrol" && AttackedMob.Info.Name != "GuildPatrol") { GiveExp(CSocket, AttackedMob, Damage, true); } if (MainGS.MonsterSpawns.ContainsKey(AttackedMob.SpawnID)) Interlocked.Add(ref MainGS.MonsterSpawns[AttackedMob.SpawnID].SpawnNumber, -1); return true; } }
public static bool doPlayer(Monster Attacker, ClientSocket ASocket, int Damage, int AType) { Character AttackedChar = ASocket.Client; if (Damage < AttackedChar.CurrentHP) { if (AType != 21) EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.UID, AttackedChar.ID, Attacker.X, Attacker.Y, Damage, AType), Attacker.X, Attacker.Y, (int)Attacker.Map, 0, 0); Interlocked.Add(ref AttackedChar.CurrentHP, (Damage * -1)); ASocket.Send(EudemonPacket.Status(ASocket, 2, AttackedChar.CurrentHP, Struct.StatusTypes.Hp)); return false; } else { if (AType != 21) EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.UID, AttackedChar.ID, Attacker.X, Attacker.Y, Damage, AType), Attacker.X, Attacker.Y, (int)Attacker.Map, 0, 0); EudemonPacket.ToLocal(EudemonPacket.Attack(Attacker.UID, AttackedChar.ID, AttackedChar.X, AttackedChar.Y, Damage, 14), Attacker.X, Attacker.Y, (int)Attacker.Map, 0, 0); EudemonPacket.ToLocal(EudemonPacket.Status(ASocket, 2, AttackedChar.GhostModel, Struct.StatusTypes.Model), AttackedChar.X, AttackedChar.Y, (int)AttackedChar.Map, 0, 0); EudemonPacket.ToLocal(EudemonPacket.Status(ASocket, 2, 1024, Struct.StatusTypes.StatusEffect), AttackedChar.X, AttackedChar.Y, (int)AttackedChar.Map, 0, 0); ASocket.Client.Dead = true; return true; } }
public static int Damage(Character Attacker, Monster Attacked, int AType, int MagicID, int MagicLevel) { if (Attacker.MinAttack > Attacker.MaxAttack) { return 0; } //TODO: Magic, Archer if (AType == 2) { int Damage = MainGS.Rand.Next(Attacker.MinAttack, Attacker.MaxAttack); if (Attacked.Info.Name != "CoEmuGuard" && Attacked.Info.Name != "CoEmuPatrol" && Attacked.Info.Name != "GuildPatrol" && Attacked.Info.Name != "GuardReviver") { int Leveldiff = (Attacker.Level + 2) - Attacked.Level; int Damageadd = (int)Math.Floor(1 + (Leveldiff / 5) * 0.8); if (Damageadd > 1) Damage = Damageadd * Damage; } Damage -= Attacked.Info.Defense; if (Damage < 0) Damage = 1; //TODO: Superman return Damage; } else if (AType == 21) { int Damage = AddedMagicDamage(MagicID, MagicLevel); Damage += Attacker.MagicAttack; if (Attacked.Info.MDefense > 0) { double MDef = (Attacked.Info.MDefense * 0.01); Damage = (int)Math.Floor(Damage - (Damage * MDef)); } if (Attacked.Info.Name != "CoEmuGuard" && Attacked.Info.Name != "CoEmuPatrol" && Attacked.Info.Name != "GuildPatrol" && Attacked.Info.Name != "GuardReviver") { int Leveldiff = (Attacker.Level + 2) - Attacked.Level; int Damageadd = (int)Math.Floor(1 + (Leveldiff / 5) * 0.8); if (Damageadd > 1) Damage = Damageadd * Damage; } if (Damage < 0) Damage = 1; return Damage; } else if (AType == 25) { int Damage = MainGS.Rand.Next(Attacker.MinAttack, Attacker.MaxAttack); if (Attacked.Info.Dodge > 0) { double Dodge = Attacked.Info.Dodge * 0.01; Damage = (int)Math.Floor(Damage - (Damage * Dodge)); } if (Attacked.Info.Name != "CoEmuGuard" && Attacked.Info.Name != "CoEmuPatrol" && Attacked.Info.Name != "GuildPatrol" && Attacked.Info.Name != "GuardReviver") { int Leveldiff = (Attacker.Level + 2) - Attacked.Level; int Damageadd = (int)Math.Floor(1 + (Leveldiff / 5) * 0.8); if (Damageadd > 1) Damage = Damageadd * Damage; } if (Damage < 0) Damage = 1; return Damage; } return 0; }
public static void LoadMonsters() { Database.Database.LoadMonsters(); Database.Database.LoadMonsterSpawns(); foreach (KeyValuePair<int, MonsterSpawn> Spawn in MainGS.MonsterSpawns) { MonsterSpawn Mob = Spawn.Value; MonsterInfo MobInfo = null; if (MainGS.BaseMonsters.ContainsKey(Mob.MobID)) { MobInfo = MainGS.BaseMonsters[Mob.MobID]; } if (MobInfo != null) { if (Mob.MaxSpawnNumber > 0) { for (int x = 0; x < Mob.MaxSpawnNumber; x++) { bool ValidMap = false; int X = Mob.X; int XStop = Mob.X + Mob.XStop; int Y = Mob.Y; int YStop = Mob.Y + Mob.YStop; int MobX = 0; int MobY = 0; int UID = 0; //TODO: Dmaps //Mon.X = MainGS.Rand.Next(X, XStop); //Mon.Y = MainGS.Rand.Next(Y, YStop); //Mon.X = Mon.SpawnX; //Mon.Y = Mon.SpawnY; MobX = MainGS.Rand.Next(Mob.X, (Mob.X + Mob.XStop)); MobY = MainGS.Rand.Next(Mob.Y, (Mob.Y + Mob.YStop)); if (MainGS.Maps.ContainsKey(Mob.Map)) { DmapData Map = MainGS.Maps[Mob.Map]; while (!Map.CheckLoc((ushort)MobX, (ushort)MobY)) { MobX = MainGS.Rand.Next(Mob.X, (Mob.X + Mob.XStop)); MobY = MainGS.Rand.Next(Mob.Y, (Mob.Y + Mob.YStop)); } ValidMap = true; } if (ValidMap) { Monster Mon = new Monster(); UID = MainGS.Rand.Next(400000, 600000); while (MainGS.Monsters.ContainsKey(UID)) { UID = MainGS.Rand.Next(400000, 600000); } Mon.CurrentHP = MobInfo.MaxHP; Mon.MaxHP = MobInfo.MaxHP; Mon.UID = UID; Mon.Direction = 0; Mon.ID = MobInfo.ID; Mon.Info = MobInfo; Mon.Level = MobInfo.Level; Mon.Map = Mob.Map; Mon.X = MobX; Mon.SpawnX = MobX; Mon.Y = MobY; Mon.SpawnY = MobY; Mon.SpawnID = Mob.SpawnID; if (!MainGS.Monsters.ContainsKey(Mon.UID)) { MainGS.Monsters.Add(Mon.UID, Mon); } else { while (MainGS.Monsters.ContainsKey(Mon.UID)) { Mon.UID = MainGS.Rand.Next(400000, 600000); } MainGS.Monsters.Add(Mon.UID, Mon); } } } } int RespawnTimer = MainGS.Rand.Next(7000, 15000); Mob.RespawnTimer = new System.Timers.Timer(); Mob.RespawnTimer.Interval = RespawnTimer; Mob.RespawnTimer.Elapsed += delegate { Mob.Respawn(); }; Mob.RespawnTimer.Start(); } } Console.WriteLine("[GameServer] Spawned " + MainGS.Monsters.Count + " monsters into the world. "); }
public void Respawn() { if (MainGS.BaseMonsters.ContainsKey(MobID)) { MonsterInfo MobInfo = MainGS.BaseMonsters[MobID]; if (SpawnNumber != MaxSpawnNumber) { while (SpawnNumber < MaxSpawnNumber) { Monster Mon = new Monster(); int MobX = 0; int MobY = 0; int UID = 0; MobX = MainGS.Rand.Next(X, (X + XStop)); MobY = MainGS.Rand.Next(Y, (Y + YStop)); if (MainGS.Maps.ContainsKey(Map)) { Structs.Struct.DmapData Mapping = MainGS.Maps[Map]; while (!Mapping.CheckLoc((ushort)MobX, (ushort)MobY)) { MobX = MainGS.Rand.Next(X, (X + XStop)); MobY = MainGS.Rand.Next(Y, (Y + YStop)); } } UID = MainGS.Rand.Next(400000, 600000); while (MainGS.Monsters.ContainsKey(UID)) { UID = MainGS.Rand.Next(400000, 600000); } Mon.CurrentHP = MobInfo.MaxHP; Mon.MaxHP = MobInfo.MaxHP; Mon.UID = UID; //Mon.Direction = MainGS.Rand.Next(1,7); //@TODO: Fix Monster Directions.. Mon.Direction = 2; Mon.ID = MobInfo.ID; Mon.Info = MobInfo; Mon.Level = MobInfo.Level; Mon.Map = Map; Mon.X = MobX; Mon.SpawnX = MobX; Mon.Y = MobY; Mon.SpawnY = MobY; Mon.SpawnID = SpawnID; if (!MainGS.Monsters.ContainsKey(Mon.UID)) { try { Monitor.Enter(MainGS.Monsters); MainGS.Monsters.Add(Mon.UID, Mon); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { Monitor.Exit(MainGS.Monsters); } } else { while (MainGS.Monsters.ContainsKey(Mon.UID)) { Mon.UID = MainGS.Rand.Next(400000, 600000); } try { Monitor.Enter(MainGS.Monsters); MainGS.Monsters.Add(Mon.UID, Mon); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { Monitor.Exit(MainGS.Monsters); } } EudemonPacket.ToLocal(EudemonPacket.SpawnMonster(Mon.UID, MobInfo.Mesh, Mon.X, Mon.Y, MobInfo.Name, Mon.CurrentHP, Mon.Level, Mon.Direction), Mon.X, Mon.Y, Mon.Map, 0, 0); EudemonPacket.ToLocal(EudemonPacket.General(Mon.UID, (ushort)Mon.X, (ushort)Mon.Y, (ushort)Mon.Direction, Structs.Struct.DataType.actionSoundEffect, Mon.ID), Mon.X, Mon.Y, Mon.Map, 0, 0);//Spawns Monster Effect. Interlocked.Add(ref SpawnNumber, 1); } } } }
public static uint MagicPlayerVsMonster(Entities.Character Attacker, Entities.Monster Attacked, Skills.Skill Skill) { uint Damage = 0; switch (Skill.SkillInfo.DamageType) { #region Magic case Enums.DamageType.Magic: { Damage = Skill.SkillInfo.Damage; Damage = (uint)((double)(Damage + Attacker.MagicAttack) * (1 + ((double)Attacker.PhoenixGemBonus / 100))); if (Attacked.Info.MagicDefense >= Damage) { Damage = 1; } else { Damage -= Attacked.Info.MagicDefense; } Damage = (uint)((double)(Damage * Skill.SkillInfo.EffectValue)); break; } #endregion #region Ranged case Enums.DamageType.Ranged: { Damage = (uint)Program.Random.Next(Attacker.MinAttack, Attacker.MaxAttack); Damage = (uint)((double)Damage * (1 + (Attacker.DragonGemBonus / 100))); Damage = (uint)((double)Damage * ((double)(210 - Attacked.Info.Dodge) / 100)); Damage = (uint)((double)Damage * Skill.SkillInfo.EffectValue); Damage = (uint)(Math.Min(1, Damage * (Attacked.Info.Dodge * .01))); break; } #endregion #region Melee case Enums.DamageType.Melee: { Damage = (uint)Program.Random.Next(Attacker.MinAttack, Attacker.MaxAttack); Damage = (uint)((double)Damage * (1 + (Attacker.DragonGemBonus / 100))); if (Attacked.Info.Defense >= Damage) { Damage = 1; } else { Damage -= Attacked.Info.Defense; } Damage = (uint)((double)Damage * Skill.SkillInfo.EffectValue); break; } #endregion #region HealHP case Enums.DamageType.HealHP: return(Skill.SkillInfo.Damage); #endregion #region HealMP case Enums.DamageType.HealMP: return(Skill.SkillInfo.Damage); #endregion default: break; } if (Attacker.Level > Attacked.Info.Level) { int dLvl = Attacker.Level - Attacked.Info.Level; if (dLvl >= 3 && dLvl <= 5) { Damage = (uint)(Damage * 1.5); } else if (dLvl > 5 && dLvl <= 10) { Damage *= 2; } else if (dLvl > 10 && dLvl <= 20) { Damage *= 3; } else if (dLvl > 20) { Damage = (uint)(Damage * (1 + (.3 * dLvl / 5))); } } return(Math.Max(1, Damage)); }