/// <summary> /// Applies the boost from the consumable, broadcasts the sound, /// sends message to player, and consumes from inventory /// </summary> public void ApplyConsumable(Player player) { if (player.IsDead) { return; } // trying to use a dispel potion while pk timer is active // send error message and cancel - do not consume item if (SpellDID != null) { var spell = new Spell(SpellDID.Value); if (spell.MetaSpellType == SpellType.Dispel && !VerifyDispelPKStatus(this, player)) { return; } } if (BoosterEnum != PropertyAttribute2nd.Undef) { BoostVital(player); } if (SpellDID != null) { CastSpell(player); } var soundEvent = new GameMessageSound(player.Guid, GetUseSound(), 1.0f); player.EnqueueBroadcast(soundEvent); player.TryConsumeFromInventoryWithNetworking(this, 1); }
/// <summary> /// Applies the boost from the consumable, broadcasts the sound, /// sends message to player, and consumes from inventory /// </summary> public void ApplyConsumable(Player player) { var buffType = (ConsumableBuffType)BoosterEnum; GameMessageSystemChat buffMessage = null; // spells if (buffType == ConsumableBuffType.Spell) { var spellID = SpellDID ?? 0; var result = player.CreateSingleSpell(spellID); if (result) { var spell = new Server.Entity.Spell(spellID); buffMessage = new GameMessageSystemChat($"{Name} casts {spell.Name} on you.", ChatMessageType.Magic); } else { buffMessage = new GameMessageSystemChat($"{Name} has invalid spell id {spellID}", ChatMessageType.Broadcast); } } // vitals else { var vital = player.GetCreatureVital(BoosterEnum); if (vital != null) { var vitalChange = (uint)Math.Abs(player.UpdateVitalDelta(vital, BoostValue)); if (BoosterEnum == PropertyAttribute2nd.Health) { if (BoostValue >= 0) { player.DamageHistory.OnHeal(vitalChange); } else { player.DamageHistory.Add(this, DamageType.Health, vitalChange); } } var verb = BoostValue >= 0 ? "restores" : "takes"; buffMessage = new GameMessageSystemChat($"The {Name} {verb} {vitalChange} points of your {BoosterEnum}.", ChatMessageType.Broadcast); } else { buffMessage = new GameMessageSystemChat($"{Name} ({Guid}) contains invalid vital {BoosterEnum}", ChatMessageType.Broadcast); } } var soundEvent = new GameMessageSound(player.Guid, GetUseSound(), 1.0f); player.EnqueueBroadcast(soundEvent); player.Session.Network.EnqueueSend(buffMessage); player.TryConsumeFromInventoryWithNetworking(this, 1); }
public void UseGem(Player player) { if (player.IsDead) { return; } if (RareUsesTimer) { var currentTime = Time.GetUnixTime(); player.LastRareUsedTimestamp = currentTime; // local broadcast usage player.EnqueueBroadcast(new GameMessageSystemChat($"{player.Name} used the rare item {Name}", ChatMessageType.Broadcast)); } if (SpellDID.HasValue) { var spell = new Spell((uint)SpellDID); TryCastSpell(spell, player, this, false); } if (UseCreateContractId > 0) { if (!player.ContractManager.Add(UseCreateContractId.Value)) { return; } // this wasn't in retail, but the lack of feedback when using a contract gem just seems jarring so... player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name} accepted. Click on the quill icon in the lower right corner to open your contract tab to view your active contracts.", ChatMessageType.Broadcast)); } if (UseCreateItem > 0) { if (!HandleUseCreateItem(player)) { return; } } if (UseSound > 0) { player.Session.Network.EnqueueSend(new GameMessageSound(player.Guid, UseSound)); } if ((GetProperty(PropertyBool.UnlimitedUse) ?? false) == false) { player.TryConsumeFromInventoryWithNetworking(this, 1); } }
/// <summary> /// Applies the boost from the consumable, broadcasts the sound, /// sends message to player, and consumes from inventory /// </summary> public void ApplyConsumable(Player player) { if (player.IsDead) { return; } if (BoosterEnum != PropertyAttribute2nd.Undef) { BoostVital(player); } if (SpellDID != null) { CastSpell(player); } var soundEvent = new GameMessageSound(player.Guid, GetUseSound(), 1.0f); player.EnqueueBroadcast(soundEvent); player.TryConsumeFromInventoryWithNetworking(this, 1); }
public static void UseUnlocker(Player player, WorldObject unlocker, WorldObject target) { ActionChain chain = new ActionChain(); chain.AddAction(player, () => { if (unlocker.WeenieType == WeenieType.Lockpick && player.Skills[Skill.Lockpick].AdvancementClass != SkillAdvancementClass.Trained && player.Skills[Skill.Lockpick].AdvancementClass != SkillAdvancementClass.Specialized) { player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouArentTrainedInLockpicking)); return; } if (target is Lock @lock) { UnlockResults result = UnlockResults.IncorrectKey; var difficulty = 0; if (unlocker.WeenieType == WeenieType.Lockpick) { var effectiveLockpickSkill = GetEffectiveLockpickSkill(player, unlocker); result = @lock.Unlock(player.Guid.Full, effectiveLockpickSkill, ref difficulty); } else if (unlocker is Key woKey) { if (target is Door woDoor) { if (woDoor.LockCode == "") // the door isn't to be opened with keys { player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouCannotLockOrUnlockThat)); return; } } result = @lock.Unlock(player.Guid.Full, woKey); } switch (result) { case UnlockResults.UnlockSuccess: if (unlocker.WeenieType == WeenieType.Lockpick) { // the source guid for this sound must be the player, else the sound will not play // which differs from PicklockFail and LockSuccess being in the target sound table player.EnqueueBroadcast(new GameMessageSound(player.Guid, Sound.Lockpicking, 1.0f)); var lockpickSkill = player.GetCreatureSkill(Skill.Lockpick); Proficiency.OnSuccessUse(player, lockpickSkill, difficulty); } ConsumeUnlocker(player, unlocker, target, true); break; case UnlockResults.Open: player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouCannotLockWhatIsOpen)); break; case UnlockResults.AlreadyUnlocked: player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.LockAlreadyUnlocked)); break; case UnlockResults.PickLockFailed: target.EnqueueBroadcast(new GameMessageSound(target.Guid, Sound.PicklockFail, 1.0f)); ConsumeUnlocker(player, unlocker, target, false); break; case UnlockResults.CannotBePicked: player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouCannotLockOrUnlockThat)); break; case UnlockResults.IncorrectKey: player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.KeyDoesntFitThisLock)); break; } } else { player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouCannotLockOrUnlockThat)); } }); chain.EnqueueChain(); }
public void UseGem(Player player) { if (player.IsDead) { return; } // trying to use a dispel potion while pk timer is active // send error message and cancel - do not consume item if (SpellDID != null) { var spell = new Spell(SpellDID.Value); if (spell.MetaSpellType == SpellType.Dispel && !VerifyDispelPKStatus(this, player)) { return; } } if (RareUsesTimer) { var currentTime = Time.GetUnixTime(); player.LastRareUsedTimestamp = currentTime; // local broadcast usage player.EnqueueBroadcast(new GameMessageSystemChat($"{player.Name} used the rare item {Name}", ChatMessageType.Broadcast)); } if (SpellDID.HasValue) { var spell = new Spell((uint)SpellDID); // should be 'You cast', instead of 'Item cast' // omitting the item caster here, so player is also used for enchantment registry caster, // which could prevent some scenarios with spamming enchantments from multiple gem sources to protect against dispels // TODO: figure this out better if (spell.MetaSpellType == SpellType.PortalSummon) { TryCastSpell(spell, player, this, false); } else { player.TryCastSpell(spell, player, this, false); } } if (UseCreateContractId > 0) { if (!player.ContractManager.Add(UseCreateContractId.Value)) { return; } // this wasn't in retail, but the lack of feedback when using a contract gem just seems jarring so... player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{Name} accepted. Click on the quill icon in the lower right corner to open your contract tab to view your active contracts.", ChatMessageType.Broadcast)); } if (UseCreateItem > 0) { if (!HandleUseCreateItem(player)) { return; } } if (UseSound > 0) { player.Session.Network.EnqueueSend(new GameMessageSound(player.Guid, UseSound)); } if ((GetProperty(PropertyBool.UnlimitedUse) ?? false) == false) { player.TryConsumeFromInventoryWithNetworking(this, 1); } }