private void HandleRegenerationTick(NWPlayer oPC, PlayerCharacter entity) { entity.RegenerationTick = entity.RegenerationTick - 1; int rate = 20; int amount = entity.HPRegenerationAmount; if (entity.RegenerationTick <= 0) { if (entity.CurrentHunger <= 20) { oPC.SendMessage("You are hungry and not recovering HP naturally. Eat food to start recovering again."); } else if (oPC.CurrentHP < oPC.MaxHP) { // CON bonus int con = oPC.ConstitutionModifier; if (con > 0) { amount += con; } entity = _food.DecreaseHungerLevel(entity, oPC, 3); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(amount), oPC.Object); } entity.RegenerationTick = rate; } }
public bool Run(params object[] args) { NWPlayer player = NWPlayer.Wrap(Object.OBJECT_SELF); NWPlaceable forge = NWPlaceable.Wrap(player.GetLocalObject("FORGE")); string resref = forge.GetLocalString("FORGE_ORE"); forge.DeleteLocalObject("FORGE_USER"); player.DeleteLocalObject("FORGE"); forge.DeleteLocalString("FORGE_ORE"); player.IsBusy = false; PCSkill pcSkill = _skill.GetPCSkill(player, SkillType.Engineering); int level = _craft.GetIngotLevel(resref); string ingotResref = _craft.GetIngotResref(resref); if (pcSkill == null || level < 0 || string.IsNullOrWhiteSpace(ingotResref)) { return(false); } int delta = pcSkill.Rank - level; int count = 2; if (delta > 2) { count = delta; } if (count > 6) { count = 6; } if (_random.Random(100) + 1 <= _perk.GetPCPerkLevel(player, PerkType.Lucky)) { count++; } if (_random.Random(100) + 1 <= _perk.GetPCPerkLevel(player, PerkType.ProcessingEfficiency) * 10) { count++; } for (int x = 1; x <= count; x++) { _.CreateItemOnObject(ingotResref, player.Object); } int xp = (int)_skill.CalculateRegisteredSkillLevelAdjustedXP(100, level, pcSkill.Rank); _skill.GiveSkillXP(player, SkillType.Engineering, xp); if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(player, 1); } return(true); }
public void OnHitCastSpell(NWPlayer oPC) { if (!oPC.IsPlayer) { return; } NWItem oSpellOrigin = NWItem.Wrap(_.GetSpellCastItem()); NWCreature oTarget = NWCreature.Wrap(_.GetSpellTargetObject()); int skillID = GetWeaponSkillID(oSpellOrigin); if (skillID <= -1) { return; } if (oTarget.IsPlayer || oTarget.IsDM) { return; } if (oTarget.ObjectType != OBJECT_TYPE_CREATURE) { return; } CreatureSkillRegistration reg = GetCreatureSkillRegistration(oTarget.GlobalID); reg.AddSkillRegistrationPoint(oPC, skillID, oSpellOrigin.RecommendedLevel); // Add a registration point if a shield is equipped. This is to prevent players from swapping out a weapon for a shield // just before they kill an enemy. NWItem oShield = oPC.LeftHand; if (oShield.BaseItemType == BASE_ITEM_SMALLSHIELD || oShield.BaseItemType == BASE_ITEM_LARGESHIELD || oShield.BaseItemType == BASE_ITEM_TOWERSHIELD) { reg.AddSkillRegistrationPoint(oPC, (int)SkillType.Shields, oShield.RecommendedLevel); } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(oPC, 1); } }
public bool Run(params object[] args) { NWPlaceable point = NWPlaceable.Wrap(Object.OBJECT_SELF); const int baseChanceToFullyHarvest = 50; bool alwaysDestroys = point.GetLocalInt("FORAGE_POINT_ALWAYS_DESTROYS") == 1; NWPlayer oPC = NWPlayer.Wrap(_.GetLastOpenedBy()); bool hasBeenSearched = point.GetLocalInt("FORAGE_POINT_FULLY_HARVESTED") == 1; if (hasBeenSearched) { oPC.SendMessage("There's nothing left to harvest here..."); return(true); } // Not fully harvested but the timer hasn't counted down yet. int refillTick = point.GetLocalInt("FORAGE_POINT_REFILL_TICKS"); if (refillTick > 0) { oPC.SendMessage("You couldn't find anything new here. Check back later..."); return(true); } if (!oPC.IsPlayer && !oPC.IsDM) { return(false); } PCSkill pcSkill = _skill.GetPCSkill(oPC, SkillType.Forage); if (pcSkill == null) { return(false); } int lootTableID = point.GetLocalInt("FORAGE_POINT_LOOT_TABLE_ID"); int level = point.GetLocalInt("FORAGE_POINT_LEVEL"); int rank = pcSkill.Rank; int delta = level - rank; if (delta > 8) { oPC.SendMessage("You aren't skilled enough to forage through this. (Required Level: " + (level - 8) + ")"); oPC.AssignCommand(() => _.ActionInteractObject(point.Object)); return(true); } int dc = 6 + delta; if (dc <= 4) { dc = 4; } int searchAttempts = 1 + CalculateSearchAttempts(oPC); int luck = _perk.GetPCPerkLevel(oPC, PerkType.Lucky) + oPC.EffectiveLuckBonus; if (_random.Random(100) + 1 <= luck / 2) { dc--; } oPC.AssignCommand(() => _.ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 2.0f)); for (int attempt = 1; attempt <= searchAttempts; attempt++) { int roll = _random.Random(20) + 1; if (roll >= dc) { oPC.FloatingText(_color.SkillCheck("Search: *success*: (" + roll + " vs. DC: " + dc + ")")); ItemVO spawnItem = _loot.PickRandomItemFromLootTable(lootTableID); if (spawnItem == null) { return(false); } if (!string.IsNullOrWhiteSpace(spawnItem.Resref) && spawnItem.Quantity > 0) { _.CreateItemOnObject(spawnItem.Resref, point.Object, spawnItem.Quantity); } float xp = _skill.CalculateRegisteredSkillLevelAdjustedXP(50, level, rank); _skill.GiveSkillXP(oPC, SkillType.Forage, (int)xp); } else { oPC.FloatingText(_color.SkillCheck("Search: *failure*: (" + roll + " vs. DC: " + dc + ")")); float xp = _skill.CalculateRegisteredSkillLevelAdjustedXP(10, level, rank); _skill.GiveSkillXP(oPC, SkillType.Forage, (int)xp); } dc += _random.Random(3) + 1; } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(oPC, 1); } // Chance to destroy the forage point. int chanceToFullyHarvest = baseChanceToFullyHarvest - (_perk.GetPCPerkLevel(oPC, PerkType.CarefulForager) * 5); int growingPlantID = point.GetLocalInt("GROWING_PLANT_ID"); if (growingPlantID > 0) { Data.Entities.GrowingPlant growingPlant = _farming.GetGrowingPlantByID(growingPlantID); chanceToFullyHarvest = chanceToFullyHarvest - (growingPlant.LongevityBonus); } if (chanceToFullyHarvest <= 5) { chanceToFullyHarvest = 5; } if (alwaysDestroys || _random.Random(100) + 1 <= chanceToFullyHarvest) { point.SetLocalInt("FORAGE_POINT_FULLY_HARVESTED", 1); oPC.SendMessage("This resource has been fully harvested..."); } // Otherwise the forage point will be refilled in 10-20 minutes. else { point.SetLocalInt("FORAGE_POINT_REFILL_TICKS", 100 + _random.Random(100)); } point.SetLocalInt("FORAGE_POINT_DESPAWN_TICKS", 30); return(true); }
private void CastSpell(NWPlayer pc, NWObject target, Data.Entities.Perk entity, IPerk perk, CooldownCategory cooldown) { string spellUUID = Guid.NewGuid().ToString(); int itemBonus = pc.CastingSpeed; float baseCastingTime = perk.CastingTime(pc, (float)entity.BaseCastingTime); float castingTime = baseCastingTime; // Casting Bonus % - Shorten casting time. if (itemBonus < 0) { float castingPercentageBonus = Math.Abs(itemBonus) * 0.01f; castingTime = castingTime - (castingTime * castingPercentageBonus); } // Casting Penalty % - Increase casting time. else if (itemBonus > 0) { float castingPercentageBonus = Math.Abs(itemBonus) * 0.01f; castingTime = castingTime + (castingTime * castingPercentageBonus); } if (castingTime < 0.5f) { castingTime = 0.5f; } // Heavy armor increases casting time by 2x the base casting time if (pc.Chest.CustomItemType == CustomItemType.HeavyArmor) { castingTime = baseCastingTime * 2; } if (_.GetActionMode(pc.Object, ACTION_MODE_STEALTH) == 1) { _.SetActionMode(pc.Object, ACTION_MODE_STEALTH, 0); } _.ClearAllActions(); _biowarePosition.TurnToFaceObject(target, pc); _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_DUR_ELEMENTAL_SHIELD), pc.Object, castingTime + 0.2f); float animationTime = castingTime; pc.AssignCommand(() => _.ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1, 1.0f, animationTime - 0.1f)); pc.IsBusy = true; CheckForSpellInterruption(pc, spellUUID, pc.Position); pc.SetLocalInt(spellUUID, SPELL_STATUS_STARTED); _nwnxPlayer.StartGuiTimingBar(pc, (int)castingTime, ""); pc.DelayCommand(() => { if (pc.GetLocalInt(spellUUID) == SPELL_STATUS_INTERRUPTED || // Moved during casting pc.CurrentHP < 0 || pc.IsDead) // Or is dead/dying { pc.DeleteLocalInt(spellUUID); pc.SendMessage("Your spell has been interrupted."); return; } pc.DeleteLocalInt(spellUUID); if ((PerkExecutionType)entity.ExecutionTypeID == PerkExecutionType.Spell || (PerkExecutionType)entity.ExecutionTypeID == PerkExecutionType.CombatAbility) { perk.OnImpact(pc, target); } else { HandleQueueWeaponSkill(pc, entity, perk); } // Adjust mana only if spell cost > 0 PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == pc.GlobalID); if (perk.ManaCost(pc, entity.BaseManaCost) > 0) { pcEntity.CurrentMana = pcEntity.CurrentMana - perk.ManaCost(pc, entity.BaseManaCost); _db.SaveChanges(); pc.SendMessage(_color.Custom("Mana: " + pcEntity.CurrentMana + " / " + pcEntity.MaxMana, 32, 223, 219)); } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(pc, 1); } // Mark cooldown on category ApplyCooldown(pc, cooldown, perk); pc.IsBusy = false; }, castingTime + 0.5f); }
private void RunCreateItem(NWPlayer oPC, NWPlaceable device, int blueprintID) { NWPlaceable tempStorage = NWPlaceable.Wrap(device.GetLocalObject("CRAFT_TEMP_STORAGE")); NWItem tools = NWItem.Wrap(device.GetLocalObject("CRAFT_DEVICE_TOOLS")); CraftBlueprint blueprint = _db.CraftBlueprints.Single(x => x.CraftBlueprintID == blueprintID); PCSkill pcSkill = _db.PCSkills.Single(x => x.PlayerID == oPC.GlobalID && x.SkillID == blueprint.SkillID); int pcEffectiveLevel = CalculatePCEffectiveLevel(oPC, device, pcSkill.Rank); float chance = CalculateChanceToCreateItem(pcEffectiveLevel, blueprint.Level); float roll = _random.RandomFloat() * 100.0f; float xpModifier; if (roll <= chance) { // Success! foreach (NWItem item in tempStorage.InventoryItems) { item.Destroy(); } NWItem craftedItem = NWItem.Wrap(_.CreateItemOnObject(blueprint.ItemResref, oPC.Object, blueprint.Quantity)); craftedItem.IsIdentified = true; // If item isn't stackable, loop through and create as many as necessary. if (craftedItem.StackSize < blueprint.Quantity) { for (int x = 2; x <= blueprint.Quantity; x++) { craftedItem = NWItem.Wrap(_.CreateItemOnObject(blueprint.ItemResref, oPC.Object)); craftedItem.IsIdentified = true; } } oPC.SendMessage("You created " + blueprint.Quantity + "x " + blueprint.ItemName + "!"); xpModifier = 1.0f; } else { // Failure... int chanceToLoseItems = 20; foreach (NWItem item in tempStorage.InventoryItems) { if (_random.Random(100) > chanceToLoseItems) { _.CopyItem(item.Object, device.Object, TRUE); } item.Destroy(); } oPC.SendMessage("You failed to create that item..."); xpModifier = 0.2f; } float xp = _skill.CalculateSkillAdjustedXP(250, blueprint.Level, pcSkill.Rank) * xpModifier; tempStorage.Destroy(); _skill.GiveSkillXP(oPC, blueprint.SkillID, (int)xp); if (tools.IsValid) { float min = 0.05f; float max = 0.1f; float reduceDurability = min + _random.RandomFloat() * (max - min); _durability.RunItemDecay(oPC, tools, reduceDurability); } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(oPC, 1); } }