public override TaskState Process() { IEnumerable <IPlayable> entities = IncludeTask.GetEntities(Type, Controller, Source, Target, Playables); foreach (IPlayable p in entities) { var m = p as Minion; int atk = m.AttackDamage; int health = m.Health; if (Game.History) { Enchantment instance = Enchantment.GetInstance(Controller, (IPlayable)Source, p, _enchantmentCard); instance[GameTag.TAG_SCRIPT_DATA_NUM_1] = atk; instance[GameTag.TAG_SCRIPT_DATA_NUM_2] = health; } new Effect(GameTag.ATK, EffectOperator.SET, health).Apply(p); new Effect(GameTag.HEALTH, EffectOperator.SET, atk).Apply(p); } return(TaskState.COMPLETE); }
private void enchantRandomItem(Quest theQuest) { ItemStack newRelic = theQuest.determineRelic(); if (newRelic != null) { //Debug.Log("Genie is enchanting an item"); newRelic = QuestManager.makeRelic(newRelic, this, theQuest.heroName); //Debug.Log("Enchanting a(n) " + newRelic.item.name); Item item; // = Items.getRandom(theQuest.questRand); bool ret = true; int loopcount = 0; do { loopcount++; item = Items.getRandom(theQuest.questRand); Enchantment ench = GameRegistry.GetEnchantmentByItem(item); //Debug.Log("Trying... " + ench.name); if (ench == null) { continue; } if (newRelic.enchants.Count > 0) { bool maxed = false; if (newRelic.enchants.Contains(ench)) { int count = 0; foreach (Enchantment ench1 in newRelic.enchants) { if (ench1 == ench) { count++; } } maxed = count >= ench.maxConcurrent; } if (maxed || newRelic.relicData == null || newRelic.relicData.Count < newRelic.enchants.Count) { //Debug.Log("This item is maxed out already. Weird."); goto baditem; } } else if ((newRelic.item.equipType & ench.enchantSlotRestriction) > 0) { //Debug.Log("Applied!"); newRelic.applyEnchantment(ench); ret = false; } } while(ret && loopcount < 30); //shouldn't need to try *30* times. if (loopcount >= 30) { goto baditem; } if (!theQuest.inventory.Contains(newRelic)) { theQuest.inventory.Add(newRelic); } //allRelics.Add(newRelic); //availableRelics.Add(newRelic); StatisticsTracker.relicsMade.addValue(1); if (StatisticsTracker.relicsMade.value == 1) { StatisticsTracker.maxQuestDifficulty.addValue(1); } if (!StatisticsTracker.relicFromGenie.isAchieved()) { StatisticsTracker.relicFromGenie.setAchieved(); } return; baditem: ChallengeTypes.Loot.AddRareResource(theQuest); ChallengeTypes.Loot.AddRareResource(theQuest); } else { ChallengeTypes.Loot.AddRareResource(theQuest); ChallengeTypes.Loot.AddRareResource(theQuest); } }
/// <summary> /// Add/update an enchantment in this object's registry /// </summary> public virtual (StackType stackType, Entity.Spell surpass) Add(Enchantment enchantment, WorldObject caster) { StackType result = StackType.Undef; Entity.Spell surpass = null; // check for existing spell in this category var entries = GetEnchantments(enchantment.Spell.Category); // if none, add new record if (entries.Count == 0) { var newEntry = BuildEntry(enchantment.Spell.Id, caster); newEntry.LayerId = enchantment.Layer; WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock); WorldObject.ChangesDetected = true; return(StackType.Initial, null); } // Check for existing spells in registry that are superior foreach (var entry in entries) { if (enchantment.Spell.Power < entry.PowerLevel) { // superior existing spell surpass = new Entity.Spell(entry.SpellId); result = StackType.Surpassed; } } if (result != StackType.Surpassed) { // Check for existing spells in registry that are equal to foreach (var entry in entries) { if (enchantment.Spell.Power == entry.PowerLevel) { if (entry.Duration == -1) { result = StackType.None; break; } // item cast spell of equal power should override an existing spell, especially one with a duration if ((caster as Creature) == null) { enchantment.Layer = entry.LayerId; // Should be a higher layer than existing enchant var newEntry = BuildEntry(enchantment.Spell.Id, caster); newEntry.LayerId = enchantment.Layer; WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock); WorldObject.ChangesDetected = true; result = StackType.Refresh; break; } // refresh existing spell entry.StartTime = 0; result = StackType.Refresh; break; } } // Previous check didn't return any result if (result == StackType.Undef) { ushort layerBuffer = 1; // Check for highest existing spell in registry that is inferior foreach (var entry in entries) { if (enchantment.Spell.Power > entry.PowerLevel) { // surpass existing spell surpass = new Entity.Spell((uint)entry.SpellId); layerBuffer = entry.LayerId; } } enchantment.Layer = (ushort)(layerBuffer + 1); // Should be a higher layer than existing enchant var newEntry = BuildEntry(enchantment.Spell.Id, caster); newEntry.LayerId = enchantment.Layer; WorldObject.Biota.AddEnchantment(newEntry, WorldObject.BiotaDatabaseLock); WorldObject.ChangesDetected = true; result = StackType.Surpass; } } return(result, surpass); }
public EnchantmentData(Enchantment enchantment) { type = enchantment.type; }
public void Serialize(EnchantmentRecipe recipe, Enchantment enchantment) { Name = enchantment.Name; RecipeID = recipe.RecipeID; TimeOfDay = recipe.TimeOfDay; Temperatures = recipe.Temperature; WindAltarActivated = recipe.WindAltarActivated; Regions = recipe.Region; if (recipe.QuestEvent?.Event != null) { var qEvt = recipe.QuestEvent.Event; QuestEvent = qEvt.EventName + " (" + qEvt.Description + ")"; } CompatibleEquipment = new EquipmentData(); if (recipe.CompatibleEquipments.EquipmentTag != null && recipe.CompatibleEquipments.EquipmentTag.Tag != Tag.None) { CompatibleEquipment.EquipmentTag = recipe.CompatibleEquipments.EquipmentTag.Tag.TagName; } if (recipe.CompatibleEquipments.CompatibleEquipments != null) { var list = new List <IngredientData>(); foreach (var equip in recipe.CompatibleEquipments.CompatibleEquipments) { var data = new IngredientData { Type = equip.Type }; if (equip.Type == EnchantmentRecipe.IngredientData.IngredientType.Generic) { data.IngredientTag = equip.IngredientTag.Tag.TagName; } else { data.SpecificItemID = equip.SpecificIngredient.ItemID; } list.Add(data); } CompatibleEquipment.CompatibleEquipments = list.ToArray(); } if (recipe.PillarDatas != null) { var list = new List <PillarData>(); foreach (var pillarData in recipe.PillarDatas) { var pillar = new PillarData { Direction = pillarData.Direction, IsFar = pillarData.IsFar, }; var ingList = new List <IngredientData>(); foreach (var ingredient in pillarData.CompatibleIngredients) { var ing = new IngredientData { Type = ingredient.Type, }; if (ingredient.Type == EnchantmentRecipe.IngredientData.IngredientType.Generic) { ing.IngredientTag = ingredient.IngredientTag.Tag.TagName; } else { ing.SpecificItemID = ingredient.SpecificIngredient.ItemID; } ingList.Add(ing); } pillar.CompatibleIngredients = ingList.ToArray(); list.Add(pillar); } PillarDatas = list.ToArray(); } if (recipe.Weather != null) { var weatherList = new List <WeatherCondition>(); foreach (var weather in recipe.Weather) { weatherList.Add(new WeatherCondition { Invert = weather.Invert, WeatherType = weather.Weather }); } Weather = weatherList.ToArray(); } Result = DM_Enchantment.ParseEnchantment(enchantment); }
public override TaskState Process() { Minion target = (Minion)Target; if (target == null) { return(TaskState.STOP); } Minion source = (Minion)Source; if (source.Zone?.Type != Zone.PLAY) { return(TaskState.STOP); } var tags = new EntityData.Data { { GameTag.CREATOR, Source.Id }, }; if (Game.History) { tags.Add(GameTag.PREMIUM, target[GameTag.PREMIUM]); } Minion copy = (Minion)Entity.FromCard(Controller, target.Card, tags); Trigger trigger = target.ActivatedTrigger; IAura aura = target.OngoingEffect; // LINKED_ENTITY if (source == Game.CurrentEventData.EventSource) { Game.CurrentEventData.EventSource = copy; } source.Controller.BoardZone.Replace(source, copy); // Copy Enchantments if (target.AppliedEnchantments != null) { foreach (Enchantment e in target.AppliedEnchantments) { Enchantment instance = Enchantment.GetInstance(Controller, copy, copy, e.Card); if (e[GameTag.TAG_SCRIPT_DATA_NUM_1] > 0) { instance[GameTag.TAG_SCRIPT_DATA_NUM_1] = e[GameTag.TAG_SCRIPT_DATA_NUM_1]; if (e[GameTag.TAG_SCRIPT_DATA_NUM_2] > 0) { instance[GameTag.TAG_SCRIPT_DATA_NUM_2] = e[GameTag.TAG_SCRIPT_DATA_NUM_2]; } } } } foreach (KeyValuePair <GameTag, int> kvp in target._data.Tags) { switch (kvp.Key) { case GameTag.ENTITY_ID: case GameTag.CONTROLLER: case GameTag.ZONE: case GameTag.ZONE_POSITION: case GameTag.CREATOR: case GameTag.PREMIUM: case GameTag.EXHAUSTED: continue; default: copy._data.Tags.Add(kvp.Key, kvp.Value); break; } } if (aura != null && copy.OngoingEffect == null) { aura.Clone(copy); } if (!target.HasCharge) { copy.IsExhausted = true; } if (_addToStack) { Playables = new List <IPlayable> { copy } } ; return(TaskState.COMPLETE); }
/// <summary> /// Broadcasts the player death animation, updates vitae, and sends network messages for player death /// Queues the action to call TeleportOnDeath and enter portal space soon /// </summary> protected override void Die(WorldObject lastDamager, WorldObject topDamager) { UpdateVital(Health, 0); NumDeaths++; DeathLevel = Level; // for calculating vitae XP VitaeCpPool = 0; // reset vitae XP earned // killer = top damager for looting rights if (topDamager != null) { Killer = topDamager.Guid.Full; } // broadcast death animation var deathAnim = new Motion(MotionStance.NonCombat, MotionCommand.Dead); EnqueueBroadcastMotion(deathAnim); // killer death message = last damager var killerMsg = lastDamager != null ? " to " + lastDamager.Name : ""; var currentDeathMessage = $"died{killerMsg}."; // create network messages for player death var msgHealthUpdate = new GameMessagePrivateUpdateAttribute2ndLevel(this, Vital.Health, 0); // TODO: death sounds? seems to play automatically in client // var msgDeathSound = new GameMessageSound(Guid, Sound.Death1, 1.0f); var msgNumDeaths = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.NumDeaths, NumDeaths ?? 0); var msgDeathLevel = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.DeathLevel, DeathLevel ?? 0); var msgVitaeCpPool = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.VitaeCpPool, VitaeCpPool.Value); var msgPurgeEnchantments = new GameEventMagicPurgeEnchantments(Session); // send network messages for player death Session.Network.EnqueueSend(msgHealthUpdate, msgNumDeaths, msgDeathLevel, msgVitaeCpPool, msgPurgeEnchantments); // update vitae // players who died in a PKLite fight do not accrue vitae var pkLiteKiller = GetKiller_PKLite(); if (pkLiteKiller == null) { var vitae = EnchantmentManager.UpdateVitae(); var spellID = (uint)SpellId.Vitae; var spell = new Spell(spellID); var vitaeEnchantment = new Enchantment(this, Guid, spellID, spell.Duration, 0, (EnchantmentMask)spell.StatModType, vitae); Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(Session, vitaeEnchantment)); } // wait for the death animation to finish var dieChain = new ActionChain(); var animLength = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId).GetAnimationLength(MotionCommand.Dead); dieChain.AddDelaySeconds(animLength + 1.0f); // enter portal space dieChain.AddAction(this, CreateCorpse); dieChain.AddAction(this, TeleportOnDeath); dieChain.AddAction(this, SetLifestoneProtection); dieChain.AddAction(this, SetMinimumTimeSincePK); dieChain.EnqueueChain(); }
public static LootFunction ApplyBonus(Enchantment ench, BonusFormula formula) { return(New("apply_bonus").Set("enchantment", ench).MergeWith(formula.ToNBT() as NBT)); }
public EnchantmentData(Enchantment par1Enchantment, int par2) : base(par1Enchantment.GetWeight()) { Enchantmentobj = par1Enchantment; EnchantmentLevel = par2; }
static void WriteEnchantments(BinaryWriter writer, Enchantment item) { item.Pack(writer); }
/// <summary> /// Creates a armor from the inputs /// </summary> /// <param name="name"></param> /// <param name="level"></param> /// <param name="value"></param> /// <param name="rarity"></param> /// <param name="itemPrefabName"></param> /// <param name="defence"></param> /// <param name="enchantment"></param> /// <returns>returns the armor</returns> public static Armor CreateArmor(string name, int level, int value, ItemRarity rarity, string itemPrefabName, float defence, Enchantment enchantment) { ArmorPrefab armorPrefab = Resources.Load <ArmorPrefab>("Items/Armor/" + itemPrefabName); Armor armor = new Armor { name = name, level = level, value = value, rarity = rarity, itemPrefabName = itemPrefabName, sprite = armorPrefab.sprite, model = armorPrefab.model, defence = defence, enchantment = enchantment, type = armorPrefab.type }; return(armor); }
/// <summary> /// Creates a weapon from the inputs /// </summary> /// <param name="name"></param> /// <param name="level"></param> /// <param name="value"></param> /// <param name="rarity"></param> /// <param name="itemPrefabName"></param> /// <param name="damage"></param> /// <param name="enchantment"></param> /// <returns>returns the weapon</returns> public static Weapon CreateWeapon(string name, int level, int value, ItemRarity rarity, string itemPrefabName, float damage, Enchantment enchantment) { WeaponPrefab weaponPrefab = Resources.Load <WeaponPrefab>("Items/Weapons/" + itemPrefabName); Weapon weapon = new Weapon { name = name, level = level, value = value, rarity = rarity, itemPrefabName = itemPrefabName, model = weaponPrefab.model, sprite = weaponPrefab.sprite, damage = damage, enchantment = enchantment, type = weaponPrefab.weaponType, isDualWielded = weaponPrefab.isDualWelded }; return(weapon); }
public void Enchant(Enchantment enchantment) { this.enchantment = enchantment; }
public GameEventMagicUpdateEnchantment(Session session, Enchantment enchantment) : base(GameEventType.MagicUpdateEnchantment, GameMessageGroup.UIQueue, session) { Writer.Write(enchantment); }
public Database.Models.World.Spell Surpass; // retval /// <summary> /// Add/update an enchantment in this object's registry /// </summary> public StackType Add(Enchantment enchantment, bool castByItem) { // check for existing spell in this category var entry = GetCategory(enchantment.Spell.Category); /* * if (enchantment.Spell.Power > entry.PowerLevel) * { * // surpass existing spell * Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId); * Remove(entry, false); * entry = BuildEntry(enchantment.Spell.SpellId); * entry.Duration = -1; * entry.StartTime = 0; * entry.LayerId = enchantment.Layer; * WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry); * return StackType.Surpass; * } * * // TODO: the refresh spell case may need some additional functionality to get working correctly * if (enchantment.Spell.Power == entry.PowerLevel) * { * if (entry.Duration != -1) * { * // refresh existing spell with a no countdown timer * entry.LayerId++; * entry.Duration = -1; * entry.StartTime = 0; * return StackType.Refresh; * } * * return StackType.None; * } * * // superior existing spell * Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId); * return StackType.Surpassed; * } */ // if none, add new record if (entry == null) { entry = BuildEntry(enchantment.Spell.SpellId, castByItem); entry.LayerId = enchantment.Layer; var type = (EnchantmentTypeFlags)entry.StatModType; WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry); return(StackType.Initial); } if (enchantment.Spell.Power > entry.PowerLevel) { // surpass existing spell Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId); Remove(entry, false); entry = BuildEntry(enchantment.Spell.SpellId, castByItem); entry.LayerId = enchantment.Layer; WorldObject.Biota.BiotaPropertiesEnchantmentRegistry.Add(entry); return(StackType.Surpass); } if (enchantment.Spell.Power == entry.PowerLevel) { if (entry.Duration != -1) { // refresh existing spell entry.LayerId++; entry.StartTime = 0; return(StackType.Refresh); } return(StackType.None); } // superior existing spell Surpass = DatabaseManager.World.GetCachedSpell((uint)entry.SpellId); return(StackType.Surpassed); }
public override void Update() { var m = (Minion)Owner; // Remove this EnrageEffect from the target if (!On) { Game.Auras.Remove(this); if (!_enraged) { return; } // Spiteful Smith if (Type == AuraType.WEAPON) { Weapon weapon = m.Controller.Hero.Weapon; if (weapon == null) { return; } if (_target != weapon) { return; } } foreach (IEffect eff in EnchantmentCard.Power.Enchant.Effects) { eff.RemoveFrom(_target); } _currentInstance?.Remove(); //if (_target != null) // for (int i = 0; i < Effects.Length; i++) // Effects[i].RemoveFrom(_target.AuraEffects); } if (Type == AuraType.WEAPON) { Weapon weapon = m.Controller.Hero.Weapon; if (weapon == null) { return; } if (_target != weapon) { _currentInstance?.Remove(); _currentInstance = null; _target = weapon; } } if (!_enraged) { if (m.Damage == 0) { return; } //if (_target != null) // for (int i = 0; i < Effects.Length; i++) // Effects[i].ApplyTo(_target.AuraEffects); Generic.AddEnchantmentBlock.Invoke(m.Controller, EnchantmentCard, m, _target, 0, 0, 0); if (Game.History) { _currentInstance = _target.AppliedEnchantments.Last(); } _enraged = true; } else { if (m.Damage != 0) { return; } for (int i = 0; i < EnchantmentCard.Power.Enchant.Effects.Length; i++) { EnchantmentCard.Power.Enchant.Effects[i].RemoveFrom(m); } _currentInstance?.Remove(); _enraged = false; } }
public void ActOnUseContract(Player player) { ContractTracker contractTracker = new ContractTracker((uint)UseCreateContractId, player.Guid.Full) { Stage = 0, TimeWhenDone = 0, TimeWhenRepeats = 0, DeleteContract = 0, SetAsDisplayContract = 1 }; if (CooldownId != null && player.LastUseTracker.TryGetValue(CooldownId.Value, out var lastUse)) { var timeRemaining = lastUse.AddSeconds(CooldownDuration ?? 0.00).Subtract(DateTime.Now); if (timeRemaining.Seconds > 0) { ChatPacket.SendServerMessage(player.Session, "You cannot use another contract for " + timeRemaining.Seconds + " seconds", ChatMessageType.Broadcast); return; } } // We need to see if we are tracking this quest already. Also, I cannot be used on world, so I must have a container id if (!player.TrackedContracts.ContainsKey((uint)UseCreateContractId) && ContainerId != null) { player.TrackedContracts.Add((uint)UseCreateContractId, contractTracker); // This will track our use for each contract using the shared cooldown server side. if (CooldownId != null) { // add or update. if (!player.LastUseTracker.ContainsKey(CooldownId.Value)) { player.LastUseTracker.Add(CooldownId.Value, DateTime.Now); } else { player.LastUseTracker[CooldownId.Value] = DateTime.Now; } } player.Session.Network.EnqueueSend(new GameEventSendClientContractTracker(player.Session, contractTracker)); ChatPacket.SendServerMessage(player.Session, "You just added " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); // TODO: Add sending the 02C2 message UpdateEnchantment. They added a second use to this existing system // so they could show the delay on the client side - it is not really an enchantment but the they overloaded the use. Og II // Thanks Slushnas for letting me know about this as well as an awesome pcap that shows it all in action. // TODO: there is a lot of work to do here. I am stubbing this in for now to send the right message. Lots of magic numbers at the moment. Debug.Assert(CooldownId != null, "CooldownId != null"); Debug.Assert(CooldownDuration != null, "CooldownDuration != null"); //const ushort layer = 0x10000; // FIXME: we need to track how many layers of the exact same spell we have in effect. const ushort layer = 1; //const uint spellCategory = 0x8000; // FIXME: Not sure where we get this from var spellBase = new SpellBase(0, CooldownDuration.Value, 0, -666); // cooldown not being used in network packet? var gem = new Enchantment(player, spellBase, layer, /*CooldownId.Value,*/ EnchantmentMask.Cooldown); player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem)); // Ok this was not known to us, so we used the contract - now remove it from inventory. // HandleActionRemoveItemFromInventory is has it's own action chain. player.TryConsumeFromInventoryWithNetworking(this, 1); } else { ChatPacket.SendServerMessage(player.Session, "You already have this quest tracked: " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); } }
/// <summary> /// This is raised by Player.HandleActionUseItem.<para /> /// The item should be in the players possession. /// /// The OnUse method for this class is to use a contract to add a tracked quest to our quest panel. /// This gives the player access to information about the quest such as starting and ending NPC locations, /// and shows our progress for kill tasks as well as any timing information such as when we can repeat the /// quest or how much longer we have to complete it in the case of at timed quest. Og II /// </summary> public override void UseItem(Player player) { // TODO: verify use requirements if (UseCreateContractId == null) { //var spell = new Spell((uint)SpellDID); /* * //These if statements are to catch spells with an apostrophe in the dat file which throws off the client in reading it from the dat. * if (spell.MetaSpellId == 3810) * castMessage = "The gem casts Asheron's Benediction on you"; * if (spell.MetaSpellId == 3811) * castMessage = "The gem casts Blackmoor's Favor on you"; * if (spell.MetaSpellId == 3953) * castMessage = "The gem casts Carraida's Benediction on you"; * if (spell.MetaSpellId == 4024) * castMessage = "The gem casts Asheron's Lesser Benediction on you"; */ player.CreateItemSpell(this, (uint)SpellDID); if ((GetProperty(PropertyBool.UnlimitedUse) ?? false) == false) { player.TryConsumeFromInventoryWithNetworking(this); } player.SendUseDoneEvent(); return; } ContractTracker contractTracker = new ContractTracker((uint)UseCreateContractId, player.Guid.Full) { Stage = 0, TimeWhenDone = 0, TimeWhenRepeats = 0, DeleteContract = 0, SetAsDisplayContract = 1 }; if (CooldownId != null && player.LastUseTracker.TryGetValue(CooldownId.Value, out var lastUse)) { var timeRemaining = lastUse.AddSeconds(CooldownDuration ?? 0.00).Subtract(DateTime.Now); if (timeRemaining.Seconds > 0) { ChatPacket.SendServerMessage(player.Session, "You cannot use another contract for " + timeRemaining.Seconds + " seconds", ChatMessageType.Broadcast); player.SendUseDoneEvent(); return; } } // We need to see if we are tracking this quest already. Also, I cannot be used on world, so I must have a container id if (!player.TrackedContracts.ContainsKey((uint)UseCreateContractId) && ContainerId != null) { player.TrackedContracts.Add((uint)UseCreateContractId, contractTracker); // This will track our use for each contract using the shared cooldown server side. if (CooldownId != null) { // add or update. if (!player.LastUseTracker.ContainsKey(CooldownId.Value)) { player.LastUseTracker.Add(CooldownId.Value, DateTime.Now); } else { player.LastUseTracker[CooldownId.Value] = DateTime.Now; } } GameEventSendClientContractTracker contractMsg = new GameEventSendClientContractTracker(player.Session, contractTracker); player.Session.Network.EnqueueSend(contractMsg); ChatPacket.SendServerMessage(player.Session, "You just added " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); // TODO: Add sending the 02C2 message UpdateEnchantment. They added a second use to this existing system // so they could show the delay on the client side - it is not really an enchantment but the they overloaded the use. Og II // Thanks Slushnas for letting me know about this as well as an awesome pcap that shows it all in action. // TODO: there is a lot of work to do here. I am stubbing this in for now to send the right message. Lots of magic numbers at the moment. Debug.Assert(CooldownId != null, "CooldownId != null"); Debug.Assert(CooldownDuration != null, "CooldownDuration != null"); //const ushort layer = 0x10000; // FIXME: we need to track how many layers of the exact same spell we have in effect. const ushort layer = 1; //const uint spellCategory = 0x8000; // FIXME: Not sure where we get this from var spellBase = new SpellBase(0, CooldownDuration.Value, 0, -666); // cooldown not being used in network packet? var gem = new Enchantment(player, player.Guid.Full, spellBase, spellBase.Duration, layer, /*CooldownId.Value,*/ EnchantmentMask.Cooldown); player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem)); // Ok this was not known to us, so we used the contract - now remove it from inventory. // HandleActionRemoveItemFromInventory is has it's own action chain. player.TryConsumeFromInventoryWithNetworking(this, 1); } else { ChatPacket.SendServerMessage(player.Session, "You already have this quest tracked: " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); } // No mater any condition we need to send the use done event to clear the hour glass from the client. player.SendUseDoneEvent(); }
public BitmapImage?imageSourceForEnchantment(Enchantment enchantment) { return(imageSourceForEnchantment(enchantment.Id)); }
/// <summary> /// Generic method use to calculate modifiers of offensive or defensive enchantment values. /// </summary> public void CalculateModifier(Enchantment par1Enchantment, int par2) { DamageModifier += par1Enchantment.CalcModifierDamage(par2, DamageSource); }
/// <summary> /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para /> /// The actor of the ActionChain is the player using the item.<para /> /// The item should be in the players possession. /// /// The OnUse method for this class is to use a contract to add a tracked quest to our quest panel. /// This gives the player access to information about the quest such as starting and ending NPC locations, /// and shows our progress for kill tasks as well as any timing information such as when we can repeat the /// quest or how much longer we have to complete it in the case of at timed quest. Og II /// </summary> public override void UseItem(Player player, ActionChain actionChain) { if (UseCreateContractId == null) { var spellTable = DatManager.PortalDat.SpellTable; if (!spellTable.Spells.ContainsKey((uint)SpellDID)) { return; } var spellBase = DatManager.PortalDat.SpellTable.Spells[(uint)SpellDID]; var spell = DatabaseManager.World.GetCachedSpell((uint)SpellDID); string castMessage = "The gem casts " + spell.Name + " on you"; ////These if statements are to catch spells with an apostrophe in the dat file which throws off the client in reading it from the dat. if (spell.MetaSpellId == 3810) { castMessage = "The gem casts Asheron's Benediction on you"; } if (spell.MetaSpellId == 3811) { castMessage = "The gem casts Blackmoor's Favor on you"; } if (spell.MetaSpellId == 3953) { castMessage = "The gem casts Carraida's Benediction on you"; } if (spell.MetaSpellId == 4024) { castMessage = "The gem casts Asheron's Lesser Benediction on you"; } castMessage += "."; // If not refreshing/surpassing/less than active spell, which I will check for in the very near future when I get the active enchantment list implemented. player.Session.Network.EnqueueSend(new GameMessageSystemChat(castMessage, ChatMessageType.Magic)); player.PlayParticleEffect((PlayScript)spellBase.TargetEffect, player.Guid); const ushort layer = 1; // FIXME: This will be tracked soon, once a list is made to track active enchantments var gem = new Enchantment(player, SpellDID.Value, (double)spell.Duration, layer, spell.Category); player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem)); // add to enchantment registry player.EnchantmentManager.Add(gem, false); ////session.Player.HandleActionRemoveItemFromInventory(Guid.Full, (uint)ContainerId, 1); This is commented out to aid in testing. Will be uncommented later. player.SendUseDoneEvent(); return; } ContractTracker contractTracker = new ContractTracker((uint)UseCreateContractId, player.Guid.Full) { Stage = 0, TimeWhenDone = 0, TimeWhenRepeats = 0, DeleteContract = 0, SetAsDisplayContract = 1 }; if (CooldownId != null && player.LastUseTracker.TryGetValue(CooldownId.Value, out var lastUse)) { var timeRemaining = lastUse.AddSeconds(CooldownDuration ?? 0.00).Subtract(DateTime.Now); if (timeRemaining.Seconds > 0) { ChatPacket.SendServerMessage(player.Session, "You cannot use another contract for " + timeRemaining.Seconds + " seconds", ChatMessageType.Broadcast); player.SendUseDoneEvent(); return; } } // We need to see if we are tracking this quest already. Also, I cannot be used on world, so I must have a container id if (!player.TrackedContracts.ContainsKey((uint)UseCreateContractId) && ContainerId != null) { player.TrackedContracts.Add((uint)UseCreateContractId, contractTracker); // This will track our use for each contract using the shared cooldown server side. if (CooldownId != null) { // add or update. if (!player.LastUseTracker.ContainsKey(CooldownId.Value)) { player.LastUseTracker.Add(CooldownId.Value, DateTime.Now); } else { player.LastUseTracker[CooldownId.Value] = DateTime.Now; } } GameEventSendClientContractTracker contractMsg = new GameEventSendClientContractTracker(player.Session, contractTracker); player.Session.Network.EnqueueSend(contractMsg); ChatPacket.SendServerMessage(player.Session, "You just added " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); // TODO: Add sending the 02C2 message UpdateEnchantment. They added a second use to this existing system // so they could show the delay on the client side - it is not really an enchantment but the they overloaded the use. Og II // Thanks Slushnas for letting me know about this as well as an awesome pcap that shows it all in action. // TODO: there is a lot of work to do here. I am stubbing this in for now to send the right message. Lots of magic numbers at the moment. Debug.Assert(CooldownId != null, "CooldownId != null"); Debug.Assert(CooldownDuration != null, "CooldownDuration != null"); //const ushort layer = 0x10000; // FIXME: we need to track how many layers of the exact same spell we have in effect. const ushort layer = 1; //const uint spellCategory = 0x8000; // FIXME: Not sure where we get this from var spellBase = new SpellBase(0, CooldownDuration.Value, 0, -666); // cooldown not being used in network packet? var gem = new Enchantment(player, spellBase, spellBase.Duration, layer, /*CooldownId.Value,*/ (uint)EnchantmentTypeFlags.Cooldown); player.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(player.Session, gem)); // Ok this was not known to us, so we used the contract - now remove it from inventory. // HandleActionRemoveItemFromInventory is has it's own action chain. player.TryRemoveItemFromInventoryWithNetworking(this, 1); } else { ChatPacket.SendServerMessage(player.Session, "You already have this quest tracked: " + contractTracker.ContractDetails.ContractName, ChatMessageType.Broadcast); } // No mater any condition we need to send the use done event to clear the hour glass from the client. player.SendUseDoneEvent(); }
/// <summary> /// Determines if the enchantment passed can be applyied together with this enchantment. /// </summary> public override bool CanApplyTogether(Enchantment par1Enchantment) { return(base.CanApplyTogether(par1Enchantment) && par1Enchantment.EffectId != Fortune.EffectId); }
public DiscoverTask(DiscoverType discoverType, Enchantment enchantment = null) { DiscoverType = discoverType; Enchantment = enchantment; }
static bool Prefix(ItemDetailsDisplay __instance) { int _index = 0; if ((bool)(UnityEngine.Object)__instance.m_lastItem && __instance.m_lastItem.IsEnchanted && __instance.m_lastItem is Equipment lastItem) { for (int i = 0; i < lastItem.ActiveEnchantments.Count; ++i) { Enchantment activeEnchantment = lastItem.ActiveEnchantments[i]; if (lastItem is Weapon weapon && (activeEnchantment.PresetID == 3 || activeEnchantment.PresetID == 4)) { int num1; switch (weapon.Type) { case Weapon.WeaponType.Dagger_OH: num1 = VampiricTransmutationTable.DAGGER_THIRST_THRESHOLD; break; case Weapon.WeaponType.Bow: num1 = VampiricTransmutationTable.BOW_THIRST_THRESHOLD; break; default: num1 = VampiricTransmutationTable.DEFAULT_THIRST_THRESHOLD; break; } float num2 = (float)weapon.DamageDealtTracking / (float)num1; if ((double)num2 >= 0.0 && (double)num2 < 0.330000013113022) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("Vampiric_01"), ""); ++_index; } else if ((double)num2 >= 0.330000013113022 && (double)num2 < 0.660000026226044) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("Vampiric_02"), ""); ++_index; } else if ((double)num2 >= 0.660000026226044 && (double)num2 < 1.0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("Vampiric_03"), ""); ++_index; } else if ((double)num2 >= 1.0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("Vampiric_04"), ""); ++_index; } if (MenuManager.Instance.DisplayDebugInfo) { __instance.GetEnchantmentRow(_index).SetInfo("DEBUG Damage", (float)weapon.DamageDealtTracking); ++_index; } } DamageList _damages1 = new DamageList(); for (int index = 0; index < activeEnchantment.Effects.Length; ++index) { if (activeEnchantment.Effects[index] is AddStatusEffectBuildUp effect) { string loc = LocalizationManager.Instance.GetLoc("EnchantmentDescription_InflictStatus", string.Empty); __instance.GetEnchantmentRow(_index).SetInfo(loc, effect.Status.StatusName); ++_index; } else if (activeEnchantment.Effects[index] is AffectStatusEffectBuildUpResistance effect1) { string loc = LocalizationManager.Instance.GetLoc("EnchantmentDescription_StatusResist", effect1.StatusEffect.StatusName); __instance.GetEnchantmentRow(_index).SetInfo(loc, effect1.Value.ToString() + "%"); ++_index; } else if (activeEnchantment.Effects[index] is ShootEnchantmentBlast effect2 && lastItem is Weapon weapon1) { DamageType.Types overrideDtype = effect2.BaseBlast.GetComponentInChildren <WeaponDamage>().OverrideDType; float _damage = weapon1.GetDisplayedDamage().TotalDamage *effect2.DamageMultiplier; _damages1.Add(new DamageType(overrideDtype, _damage)); } } if (_damages1.Count > 0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("EnchantmentDescription_Blast"), _damages1); ++_index; } DamageList _damages2 = new DamageList(); if (lastItem is Weapon weapon2) { _damages2 = weapon2.GetEnchantmentDamageBonuses(); } if (_damages2.Count > 0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_Damage"), _damages2); ++_index; } if (activeEnchantment.DamageModifier.Count != 0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_DamageModifier"), activeEnchantment.DamageModifier, _displayPercent: true); ++_index; } if (activeEnchantment.ElementalResistances.Count != 0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_DamageResistance"), activeEnchantment.ElementalResistances); ++_index; } if ((double)activeEnchantment.GlobalStatusResistance != 0.0) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_StatusResist"), activeEnchantment.GlobalStatusResistance); ++_index; } if ((double)activeEnchantment.ManaAbsorbRatio != 0.0) { string loc = LocalizationManager.Instance.GetLoc("EnchantmentDescription_Absorb", activeEnchantment.ManaAbsorbRatio.ToString(), LocalizationManager.Instance.GetLoc("CharacterStat_Mana")); __instance.GetEnchantmentRow(_index).SetInfo(loc, ""); ++_index; } if ((double)activeEnchantment.HealthAbsorbRatio != 0.0) { string loc = LocalizationManager.Instance.GetLoc("EnchantmentDescription_Absorb", activeEnchantment.HealthAbsorbRatio.ToString(), LocalizationManager.Instance.GetLoc("CharacterStat_Health")); __instance.GetEnchantmentRow(_index).SetInfo(loc, ""); ++_index; } if ((double)activeEnchantment.StaminaAbsorbRatio != 0.0) { string loc = LocalizationManager.Instance.GetLoc("EnchantmentDescription_Absorb", activeEnchantment.StaminaAbsorbRatio.ToString(), LocalizationManager.Instance.GetLoc("CharacterStat_Stamina")); __instance.GetEnchantmentRow(_index).SetInfo(loc, ""); ++_index; } for (int index = 0; index < activeEnchantment.StatModifications.Count; ++index) { float num = activeEnchantment.StatModifications[index].Value; if (activeEnchantment.StatModifications[index].Name == Enchantment.Stat.CooldownReduction) { num = -num; } string _dataValue = ((double)num > 0.0 ? "+" : "") + num.ToString(); if (activeEnchantment.StatModifications[index].Type == Enchantment.StatModification.BonusType.Modifier) { _dataValue += "%"; } switch (activeEnchantment.StatModifications[index].Name) { case Enchantment.Stat.Weight: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_Weight"), _dataValue); ++_index; break; case Enchantment.Stat.Durability: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_Durability"), _dataValue); ++_index; break; case Enchantment.Stat.ManaCostReduction: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_ManaCost"), _dataValue.Replace("+", "-")); ++_index; break; case Enchantment.Stat.StaminaCostReduction: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_StaminaCost"), _dataValue.Replace("+", "-")); ++_index; break; case Enchantment.Stat.CooldownReduction: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_CooldownReduction"), _dataValue); ++_index; break; case Enchantment.Stat.MovementSpeed: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_MovementPenalty"), _dataValue); ++_index; break; case Enchantment.Stat.AttackSpeed: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_AttackSpeed"), _dataValue); ++_index; break; case Enchantment.Stat.Impact: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_Impact"), _dataValue); ++_index; break; case Enchantment.Stat.StabilityRegen: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_StabilityRegen"), _dataValue); ++_index; break; case Enchantment.Stat.HealthRegen: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_HealthRegen"), _dataValue); ++_index; break; case Enchantment.Stat.ManaRegen: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_ManaRegen"), _dataValue); ++_index; break; case Enchantment.Stat.Protection: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_Defense_Protection"), _dataValue); ++_index; break; case Enchantment.Stat.CorruptionResistance: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_CorruptionResistance"), _dataValue); ++_index; break; case Enchantment.Stat.FoodDepletionRate: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_FoodEfficiency"), _dataValue); ++_index; break; case Enchantment.Stat.DrinkDepletionRate: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_DrinkEfficiency"), _dataValue); ++_index; break; case Enchantment.Stat.SleepDepletionRate: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_SleepEfficiency"), _dataValue); ++_index; break; case Enchantment.Stat.PouchCapacity: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_PouchCapacity"), _dataValue); ++_index; break; case Enchantment.Stat.ImpactResistance: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("CharacterStat_Defense_ImpactResistance"), _dataValue); ++_index; break; case Enchantment.Stat.HeatProtection: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_HeatProtection"), _dataValue); ++_index; break; case Enchantment.Stat.ColdProtection: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_ColdProtection"), _dataValue); ++_index; break; case Enchantment.Stat.Barrier: __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("ItemStat_Barrier"), _dataValue); ++_index; break; } } if (activeEnchantment.Indestructible) { __instance.GetEnchantmentRow(_index).SetInfo(LocalizationManager.Instance.GetLoc("EnchantmentDescription_Indestructible"), ""); ++_index; } } } for (int index = _index; index < __instance.m_enchantmentDetailRows.Count; ++index) { if (__instance.m_enchantmentDetailRows[index].IsDisplayed) { __instance.m_enchantmentDetailRows[index].Hide(); } } return(false); }
/// <summary> /// Generic method use to calculate modifiers of offensive or defensive enchantment values. /// </summary> public void CalculateModifier(Enchantment par1Enchantment, int par2) { LivingModifier += par1Enchantment.CalcModifierLiving(par2, EntityLiving); }
public AddEnchantmentTask(EntityType type, Enchantment enchantment, bool activate = false) { Type = type; Enchantment = enchantment; Activate = activate; }
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public override TaskState Process() { if (Controller.BoardZone.IsFull) { return(TaskState.STOP); } IList <IPlayable> entities = IncludeTask.GetEntities(Type, Controller, Source, Target, Playables).ToList(); if (entities.Count < 1) { return(TaskState.STOP); } // shuffle list randomly if needed entities = RandomFlag ? entities.OrderBy(x => Util.Random.Next()).ToList() : entities; if (RandomFlag) { Game.OnRandomHappened(true); } int space = Controller.BoardZone.MaxSize - Controller.BoardZone.Count; space = entities.Count > space ? space : entities.Count; if (entities[0].Zone == null || entities[0].Zone.Type != Enums.Zone.PLAY) { for (int i = 0; i < space; i++) { // clone task here var task = new SummonTask(_side, entities[i].Card) { Game = Controller.Game, Controller = Controller, Source = Source as IPlayable, Target = Target as IPlayable }; Controller.Game.TaskQueue.Enqueue(task); } } else { for (int i = 0; i < entities.Count; i++) { if (Controller.BoardZone.IsFull) { break; } Minion target = (Minion)entities[i]; var tags = new EntityData.Data((EntityData.Data)target.NativeTags); if (target.Controller != Controller) { tags[GameTag.CONTROLLER] = Controller.PlayerId; } IPlayable copy = Entity.FromCard(Controller, target.Card, tags, Controller.BoardZone); target.AppliedEnchantments?.ForEach(e => { Enchantment instance = Enchantment.GetInstance(Controller, copy, copy, e.Card); if (e[GameTag.TAG_SCRIPT_DATA_NUM_1] > 0) { instance[GameTag.TAG_SCRIPT_DATA_NUM_1] = e[GameTag.TAG_SCRIPT_DATA_NUM_1]; if (e[GameTag.TAG_SCRIPT_DATA_NUM_2] > 0) { instance[GameTag.TAG_SCRIPT_DATA_NUM_2] = e[GameTag.TAG_SCRIPT_DATA_NUM_2]; } } }); if (target.OngoingEffect != null && copy.OngoingEffect == null) { target.OngoingEffect.Clone(copy); } if (_addToStack) { Playables.Add(copy); } } } return(TaskState.COMPLETE); }
/// <summary> /// Broadcasts the player death animation, updates vitae, and sends network messages for player death /// Queues the action to call TeleportOnDeath and enter portal space soon /// </summary> protected override void Die(WorldObject lastDamager, WorldObject topDamager) { UpdateVital(Health, 0); NumDeaths++; DeathLevel = Level; // for calculating vitae XP VitaeCpPool = 0; // reset vitae XP earned // killer = top damager for looting rights if (topDamager != null) { Killer = topDamager.Guid.Full; } // broadcast death animation var deathAnim = new UniversalMotion(MotionStance.NonCombat, new MotionItem(MotionCommand.Dead)); EnqueueBroadcastMotion(deathAnim); // killer death message = last damager var killerMsg = lastDamager != null ? " to " + lastDamager.Name : ""; var currentDeathMessage = $"died{killerMsg}."; // create network messages for player death var msgHealthUpdate = new GameMessagePrivateUpdateAttribute2ndLevel(this, Vital.Health, 0); // TODO: death sounds? seems to play automatically in client // var msgDeathSound = new GameMessageSound(Guid, Sound.Death1, 1.0f); var msgYourDeath = new GameEventYourDeath(Session, $"You have {currentDeathMessage}"); var msgNumDeaths = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.NumDeaths, NumDeaths ?? 0); var msgDeathLevel = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.DeathLevel, DeathLevel ?? 0); var msgVitaeCpPool = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.VitaeCpPool, VitaeCpPool.Value); var msgPurgeEnchantments = new GameEventPurgeAllEnchantments(Session); // update vitae var vitae = EnchantmentManager.UpdateVitae(); var spellID = (uint)Network.Enum.Spell.Vitae; var spellBase = DatManager.PortalDat.SpellTable.Spells[spellID]; var spell = DatabaseManager.World.GetCachedSpell(spellID); var vitaeEnchantment = new Enchantment(this, Guid, spellID, (double)spell.Duration, 0, spell.StatModType, vitae); var msgVitaeEnchantment = new GameEventMagicUpdateEnchantment(Session, vitaeEnchantment); // send network messages for player death Session.Network.EnqueueSend(msgHealthUpdate, msgYourDeath, msgNumDeaths, msgDeathLevel, msgVitaeCpPool, msgPurgeEnchantments, msgVitaeEnchantment); // wait for the death animation to finish var dieChain = new ActionChain(); var animLength = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId).GetAnimationLength(MotionCommand.Dead); dieChain.AddDelaySeconds(animLength + 1.0f); // enter portal space dieChain.AddAction(this, CreateCorpse); dieChain.AddAction(this, TeleportOnDeath); dieChain.EnqueueChain(); // if the player's lifestone is in a different landblock, also broadcast their demise to that landblock if (Sanctuary != null && Location.Landblock != Sanctuary.Landblock) { var killerGuid = lastDamager != null ? lastDamager.Guid : Guid; ActionBroadcastKill($"{Name} has {currentDeathMessage}", Guid, killerGuid); } DamageHistory.Reset(); }
private void WindowFunction(int id) { GUI.DragWindow(new Rect(0, 0, m_rect.width - 35, 23)); if (GUI.Button(new Rect(m_rect.width - 30, 2, 30, 20), "X")) { ShowMenu = false; return; } GUILayout.BeginArea(new Rect(5, 20, m_rect.width - 10, m_rect.height - 15)); GUILayout.Space(20); if (SelectedEnchant != null) { if (GUILayout.Button("< Back to Enchantments")) { SelectedEnchant = null; } GUILayout.Label("Selected Enchant: <b><color=orange>" + SelectedEnchant.Name + "</color></b>"); } GUILayout.BeginHorizontal(); GUILayout.Label("Selected Slot: " + SelectedSlot.ToString(), GUILayout.Width(m_rect.width - 70)); if (GUILayout.Button("<", GUILayout.Width(25))) { SetEnum(ref SelectedSlot, -1); } if (GUILayout.Button(">", GUILayout.Width(25))) { SetEnum(ref SelectedSlot, 1); } GUILayout.EndHorizontal(); var character = CharacterManager.Instance.GetFirstLocalCharacter(); if (character) { var equipment = (Equipment)character.Inventory.GetEquippedItem(SelectedSlot); if (equipment) { GUILayout.Label("<b>Equipped:</b> <color=orange>" + equipment.Name + "</color>"); if (equipment.IsEnchanted) { GUI.color = Color.red; var enchant = equipment.GetComponentInChildren <Enchantment>(); if (GUILayout.Button("Remove Enchantment (" + enchant.Name + ")")) { enchant.UnapplyEnchantment(); var ids = (List <int>)At.GetValue(typeof(Equipment), equipment, "m_enchantmentIDs"); ids.Clear(); At.Call(typeof(Equipment), equipment, "RefreshEnchantmentModifiers", null, new object[0]); } } else if (SelectedEnchant != null) { GUI.color = Color.green; if (GUILayout.Button("Apply Selected Enchant")) { equipment.AddEnchantment(SelectedEnchant.PresetID, false); } } GUI.color = Color.white; } else { GUI.color = Color.red; GUILayout.Label("No item equipped in " + SelectedSlot.ToString() + " slot!"); } } GUI.color = Color.white; if (SelectedEnchant == null) { GUILayout.Label("Enter an Enchantment ID to search for..."); SearchText = GUILayout.TextField(SearchText); GUILayout.BeginVertical(GUI.skin.box); scroll = GUILayout.BeginScrollView(scroll); var search = SearchText.ToLower(); foreach (var entry in m_cachedEnchantments) { if (search == "" || entry.Key.ToLower().Contains(search)) { if (GUILayout.Button(entry.Key)) { SelectedEnchant = entry.Value; } } } GUILayout.EndScrollView(); GUILayout.EndVertical(); } GUILayout.EndArea(); }
/// <summary> /// Creates an enchantment and interacts with the Enchantment registry. /// Used by Life, Creature, Item, and Void magic /// </summary> /// <param name="target"></param> /// <param name="spell"></param> /// <param name="spellStatMod"></param> /// <param name="castByItem"></param> /// <returns></returns> private string CreateEnchantment(WorldObject target, SpellBase spell, Database.Models.World.Spell spellStatMod, bool castByItem) { double duration; if (castByItem) { duration = -1; } else { duration = spell.Duration; } // create enchantment var enchantment = new Enchantment(target, spellStatMod.SpellId, duration, 1, (uint)EnchantmentMask.CreatureSpells); var stackType = target.EnchantmentManager.Add(enchantment, castByItem); var player = this as Player; var playerTarget = target as Player; var creatureTarget = target as Creature; // build message var suffix = ""; switch (stackType) { case StackType.Refresh: suffix = $", refreshing {spell.Name}"; break; case StackType.Surpass: suffix = $", surpassing {target.EnchantmentManager.Surpass.Name}"; break; case StackType.Surpassed: suffix = $", but it is surpassed by {target.EnchantmentManager.Surpass.Name}"; break; } var targetName = this == target ? "yourself" : target.Name; string message; if (castByItem == true) { message = $"An item casts {spell.Name} on you"; } else { message = $"You cast {spell.Name} on {targetName}{suffix}"; } if (target is Player) { if (stackType != StackType.Surpassed) { playerTarget.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(playerTarget.Session, enchantment)); } if (playerTarget != this) { playerTarget.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name} cast {spell.Name} on you{suffix}", ChatMessageType.Magic)); } } return(message); }