示例#1
0
        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;
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
            }
        }