public Inventory CreateItem(InventoryItem newItem, Character character) { short Slot = -1; IEnumerable<InventoryItem> slotfree = null; Inventory inv = null; if (ServerManager.GetItem(newItem.ItemVNum).Type != 0) { slotfree = character.LoadBySlotAllowed(newItem.ItemVNum, newItem.Amount); inv = getFirstSlot(slotfree); } bool modified = false; Inventory newInventory = null; if (inv != null) { Slot = inv.Slot; newItem.Amount = (short)(newItem.Amount + inv.InventoryItem.Amount); modified = true; } else Slot = getFirstPlace(ServerManager.GetItem(newItem.ItemVNum).Type, character.BackPack, newItem); if (Slot != -1) { if (modified == false) newInventory = new Inventory() { CharacterId = character.CharacterId, InventoryItemId = newItem.InventoryItemId, Slot = Slot, Type = ServerManager.GetItem(newItem.ItemVNum).Type, InventoryItem = newItem, InventoryId = generateInventoryId(), }; else newInventory = new Inventory() { CharacterId = character.CharacterId, InventoryItemId = newItem.InventoryItemId, Slot = Slot, Type = ServerManager.GetItem(newItem.ItemVNum).Type, InventoryItem = newItem, InventoryId = inv.InventoryId, }; InsertOrUpdate(ref newInventory); } return newInventory; }
public void MoveItem(Character character, short type, short slot, short amount, short destslot, out Inventory inv, out Inventory invdest) { inv = LoadBySlotAndType(slot, type); invdest = LoadBySlotAndType(destslot, type); if (amount <= inv.InventoryItem.Amount) { if (invdest == null) { if (inv.InventoryItem.Amount == amount) { inv.Slot = destslot; InsertOrUpdate(ref inv); } else { inv.InventoryItem.Amount = (short)(inv.InventoryItem.Amount - amount); InventoryItem itemDest = new InventoryItem { Amount = amount, Color = inv.InventoryItem.Color, Concentrate = inv.InventoryItem.Concentrate, CriticalLuckRate = inv.InventoryItem.CriticalLuckRate, CriticalRate = inv.InventoryItem.CriticalRate, DamageMaximum = inv.InventoryItem.DamageMaximum, DamageMinimum = inv.InventoryItem.DamageMinimum, DarkElement = inv.InventoryItem.DarkElement, DistanceDefence = inv.InventoryItem.DistanceDefence, DistanceDefenceDodge = inv.InventoryItem.DistanceDefenceDodge, DefenceDodge = inv.InventoryItem.DefenceDodge, ElementRate = inv.InventoryItem.ElementRate, FireElement = inv.InventoryItem.FireElement, HitRate = inv.InventoryItem.HitRate, ItemVNum = inv.InventoryItem.ItemVNum, LightElement = inv.InventoryItem.LightElement, MagicDefence = inv.InventoryItem.MagicDefence, RangeDefence = inv.InventoryItem.RangeDefence, Rare = inv.InventoryItem.Rare, SlDefence = inv.InventoryItem.SlDefence, SlElement = inv.InventoryItem.SlElement, SlHit = inv.InventoryItem.SlHit, SlHP = inv.InventoryItem.SlHP, Upgrade = inv.InventoryItem.Upgrade, WaterElement = inv.InventoryItem.WaterElement, InventoryItemId = generateInventoryItemId(), }; InsertOrUpdate(ref inv); Inventory invDest = new Inventory { CharacterId = character.CharacterId, InventoryItemId = itemDest.InventoryItemId, Slot = destslot, Type = inv.Type, InventoryId = generateInventoryId(), InventoryItem = itemDest, }; InsertOrUpdate(ref invDest); invdest = invDest; } } else { if (invdest.InventoryItem.ItemVNum == inv.InventoryItem.ItemVNum && inv.Type != 0) { if (invdest.InventoryItem.Amount + amount > 99) { short saveItemCount = invdest.InventoryItem.Amount; invdest.InventoryItem.Amount = 99; inv.InventoryItem.Amount = (short)(saveItemCount + inv.InventoryItem.Amount - 99); InsertOrUpdate(ref inv); InsertOrUpdate(ref invdest); } else { short saveItemCount = invdest.InventoryItem.Amount; invdest.InventoryItem.Amount = (short)(saveItemCount + amount); inv.InventoryItem.Amount = (short)(inv.InventoryItem.Amount - amount); InsertOrUpdate(ref inv); InsertOrUpdate(ref invdest); } } else { invdest.Slot = inv.Slot; inv.Slot = 99; InsertOrUpdate(ref inv); InsertOrUpdate(ref invdest); inv.Slot = destslot; InsertOrUpdate(ref inv); } } } inv = LoadBySlotAndType(slot, type); invdest = LoadBySlotAndType(destslot, type); }
public static int GetDistance(Character character1, Character character2) { return GetDistance(new MapCell() { MapId = character1.MapId, X = character1.MapX, Y = character1.MapY }, new MapCell() { MapId = character2.MapId, X = character2.MapX, Y = character2.MapY }); }
public long? GetNextOrderedCharacterId(Character character) { lock (this) { _order++; List<ClientSession> sessions = Characters.Where(s => Map.GetDistance(s.Character, character) < 50).ToList(); if (_order > sessions.Count() - 1) // if order wents out of amount of ppl, reset it -> zero based index { _order = 0; } if (!sessions.Any()) // group seems to be empty { return null; } return sessions[_order].Character.CharacterId; } }
public void SetCharacter(Character character) { Character = character; // register WCF events ServiceFactory.Instance.CommunicationCallback.CharacterConnectedEvent += CommunicationCallback_CharacterConnectedEvent; ServiceFactory.Instance.CommunicationCallback.CharacterDisconnectedEvent += CommunicationCallback_CharacterDisconnectedEvent; HasSelectedCharacter = true; // register for servermanager ServerManager.Instance.RegisterSession(this); Character.SetSession(this); }
/// <summary> /// Generate the Monster -> Character Damage /// </summary> /// <param name="targetCharacter"></param> /// <param name="skill"></param> /// <param name="hitmode"></param> /// <returns></returns> internal int GenerateDamage(Character targetCharacter, Skill skill, ref int hitmode) { //Warning: This code contains a huge amount of copypasta! #region Definitions if (targetCharacter == null) { return 0; } short distanceX = (short)(MapX - targetCharacter.MapX); short distanceY = (short)(MapY - targetCharacter.MapY); Random random = new Random(); int generated = random.Next(0, 100); int playerDefense = 0; byte playerDefenseUpgrade = 0; int playerDodge = 0; WearableInstance playerArmor = targetCharacter.Inventory.LoadBySlotAndType<WearableInstance>((byte)Domain.EquipmentType.Armor, Domain.InventoryType.Wear); if (playerArmor != null) { playerDefenseUpgrade = playerArmor.Upgrade; } short mainUpgrade = Monster.AttackUpgrade; int mainCritChance = Monster.CriticalChance; int mainCritHit = Monster.CriticalRate; int mainMinDmg = Monster.DamageMinimum; int mainMaxDmg = Monster.DamageMaximum; int mainHitRate = Monster.Concentrate; //probably missnamed, check later if (mainMaxDmg == 0) { mainMinDmg = Monster.Level * 8; mainMaxDmg = Monster.Level * 12; mainCritChance = 10; mainCritHit = 120; mainHitRate = (Monster.Level / 2) + 1; } #endregion #region Get Player defense switch (Monster.AttackClass) { case 0: playerDefense = targetCharacter.Defence; playerDodge = targetCharacter.DefenceRate; break; case 1: playerDefense = targetCharacter.DistanceDefence; playerDodge = targetCharacter.DistanceDefenceRate; break; case 2: playerDefense = targetCharacter.MagicalDefence; break; default: throw new Exception(String.Format("Monster.AttackClass {0} not implemented", Monster.AttackClass)); } #endregion #region Basic Damage Data Calculation #warning TODO: Implement BCard damage boosts, see Issue mainUpgrade -= playerDefenseUpgrade; if (mainUpgrade < -10) { mainUpgrade = -10; } else if (mainUpgrade > 10) { mainUpgrade = 10; } #endregion #region Detailed Calculation #region Dodge double multiplier = playerDodge / mainHitRate; if (multiplier > 5) { multiplier = 5; } double chance = -0.25 * Math.Pow(multiplier, 3) - 0.57 * Math.Pow(multiplier, 2) + 25.3 * multiplier - 1.41; if (chance <= 1) { chance = 1; } if (Monster.AttackClass == 0 || Monster.AttackClass == 1) { if (random.Next(0, 100) <= chance) { hitmode = 1; return 0; } } #endregion #region Base Damage int baseDamage = new Random().Next(mainMinDmg, mainMaxDmg + 1); baseDamage += Monster.Level - targetCharacter.Level; int elementalDamage = 0; // placeholder for BCard etc... if (skill != null) { baseDamage += (skill.Damage / 4); elementalDamage += (skill.ElementalDamage / 4); } switch (mainUpgrade) { case -10: playerDefense += (int)(playerDefense * 2); break; case -9: playerDefense += (int)(playerDefense * 1.2); break; case -8: playerDefense += (int)(playerDefense * 0.9); break; case -7: playerDefense += (int)(playerDefense * 0.65); break; case -6: playerDefense += (int)(playerDefense * 0.54); break; case -5: playerDefense += (int)(playerDefense * 0.43); break; case -4: playerDefense += (int)(playerDefense * 0.32); break; case -3: playerDefense += (int)(playerDefense * 0.22); break; case -2: playerDefense += (int)(playerDefense * 0.15); break; case -1: playerDefense += (int)(playerDefense * 0.1); break; case 0: break; case 1: baseDamage += (int)(baseDamage * 0.1); break; case 2: baseDamage += (int)(baseDamage * 0.15); break; case 3: baseDamage += (int)(baseDamage * 0.22); break; case 4: baseDamage += (int)(baseDamage * 0.32); break; case 5: baseDamage += (int)(baseDamage * 0.43); break; case 6: baseDamage += (int)(baseDamage * 0.54); break; case 7: baseDamage += (int)(baseDamage * 0.65); break; case 8: baseDamage += (int)(baseDamage * 0.9); break; case 9: baseDamage += (int)(baseDamage * 1.2); break; case 10: baseDamage += (int)(baseDamage * 2); break; } #endregion #region Elementary Damage #region Calculate Elemental Boost + Rate double elementalBoost = 0; int playerRessistance = 0; switch (Monster.Element) { case 0: break; case 1: playerRessistance = targetCharacter.FireResistance; switch (targetCharacter.Element) { case 0: elementalBoost = 1.3; // Damage vs no element break; case 1: elementalBoost = 1; // Damage vs fire break; case 2: elementalBoost = 2; // Damage vs water break; case 3: elementalBoost = 1; // Damage vs light break; case 4: elementalBoost = 1.5; // Damage vs darkness break; } break; case 2: playerRessistance = targetCharacter.WaterResistance; switch (targetCharacter.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 2; break; case 2: elementalBoost = 1; break; case 3: elementalBoost = 1.5; break; case 4: elementalBoost = 1; break; } break; case 3: playerRessistance = targetCharacter.LightResistance; switch (targetCharacter.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 1.5; break; case 2: elementalBoost = 1; break; case 3: elementalBoost = 1; break; case 4: elementalBoost = 3; break; } break; case 4: playerRessistance = targetCharacter.DarkResistance; switch (targetCharacter.Element) { case 0: elementalBoost = 1.3; break; case 1: elementalBoost = 1; break; case 2: elementalBoost = 1.5; break; case 3: elementalBoost = 3; break; case 4: elementalBoost = 1; break; } break; } #endregion; if (Monster.Element == 0) { if (elementalBoost == 0.5) { elementalBoost = 0; } else if (elementalBoost == 1) { elementalBoost = 0.05; } else if (elementalBoost == 1.3) { elementalBoost = 0; } else if (elementalBoost == 1.5) { elementalBoost = 0.15; } else if (elementalBoost == 2) { elementalBoost = 0.2; } else if (elementalBoost == 3) { elementalBoost = 0.2; } } elementalDamage = (int)((elementalDamage + ((elementalDamage + baseDamage) * ((Monster.ElementRate) / 100D))) * elementalBoost); elementalDamage = elementalDamage / 100 * (100 - playerRessistance); #endregion #region Critical Damage if (random.Next(100) <= mainCritChance) { if (Monster.AttackClass == 2) { } else { baseDamage += (int)(baseDamage * ((mainCritHit / 100D))); hitmode = 3; } } #endregion #region Total Damage int totalDamage = baseDamage + elementalDamage - playerDefense; if (totalDamage < 5) { totalDamage = random.Next(1, 6); } #endregion #endregion #region Minimum damage if (Monster.Level < 45) { //no minimum damage } else if (Monster.Level < 55) { totalDamage += Monster.Level; } else if (Monster.Level < 60) { totalDamage += Monster.Level * 2; } else if (Monster.Level < 65) { totalDamage += Monster.Level * 3; } else if (Monster.Level < 70) { totalDamage += Monster.Level * 4; } else { totalDamage += Monster.Level * 5; } #endregion return totalDamage; }