Beispiel #1
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            Location effectLocation;
            NWPlayer player = (user.Object);

            if (!string.IsNullOrWhiteSpace(target.GetLocalString("RESOURCE_RESREF")))
            {
                ScanResource(user, target);
                DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(0.05f, 0.1f));
                effectLocation = target.Location;
            }
            else
            {
                user.FloatingText("You cannot scan that object with this type of scanner.");
                return;
            }

            _.ApplyEffectAtLocation(DurationType.Instant, _.EffectVisualEffect(VisualEffect.Vfx_Fnf_Summon_Monster_3), effectLocation);

            if (user.IsPlayer && GetLocalBool(user, target.GlobalID.ToString()) == false)
            {
                int scanningBonus = item.ScanningBonus;
                SkillService.GiveSkillXP(player, SkillType.Harvesting, 150);
                user.SetLocalInt(target.GlobalID.ToString(), 1 + scanningBonus);
            }
        }
Beispiel #2
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            Location effectLocation;
            NWPlayer player = (user.Object);

            // Targeted a location or self. Locate nearest resource.
            if (!target.IsValid || Equals(user, target))
            {
                ScanArea(user, targetLocation);
                DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(0.02f, 0.08f));
                effectLocation = targetLocation;
            }
            else if (!string.IsNullOrWhiteSpace(target.GetLocalString("RESOURCE_RESREF")))
            {
                ScanResource(user, target);
                DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(0.05f, 0.1f));
                effectLocation = target.Location;
            }
            else
            {
                user.FloatingText("You cannot scan that object with this type of scanner.");
                return;
            }

            _.ApplyEffectAtLocation(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), effectLocation);

            if (user.IsPlayer && user.GetLocalInt(target.GlobalID.ToString()) == FALSE)
            {
                int scanningBonus = item.ScanningBonus;
                SkillService.GiveSkillXP(player, SkillType.Harvesting, 150);
                user.SetLocalInt(target.GlobalID.ToString(), 1 + scanningBonus);
            }
        }
Beispiel #3
0
        public string CanApply(NWPlayer player, NWItem target, params string[] args)
        {
            var maxDurability = DurabilityService.GetMaxDurability(target);

            if (maxDurability >= 100)
            {
                return("You cannot improve that item's maximum durability any further.");
            }

            return(null);
        }
        public void DurabilityService_SetDurability_InvalidArguments_ShouldThrowException()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);

            Assert.Throws(typeof(ArgumentNullException), () =>
            {
                service.SetMaxDurability(null, 0.0f);
            });
        }
        public void DurabilityService_GetDurability_InvalidArguments_ShouldThrowException()
        {
            INWScript          script       = Substitute.For <INWScript>();
            IColorTokenService color        = Substitute.For <IColorTokenService>();
            INWNXProfiler      nwnxProfiler = Substitute.For <INWNXProfiler>();
            DurabilityService  service      = new DurabilityService(script, color, nwnxProfiler);

            Assert.Throws(typeof(ArgumentNullException), () =>
            {
                service.GetDurability(null);
            });
        }
        // ReSharper disable once UnusedMember.Local
        public static void Main()
        {
            // Breaking the rules for the examine event because the result of the services is used in the following
            // service call. We still signal an event for this, but in general all of the logic should go into this method.

            using (new Profiler(nameof(mod_on_examine)))
            {
                NWPlayer examiner       = (_.OBJECT_SELF);
                NWObject examinedObject = NWNXObject.StringToObject(NWNXEvents.GetEventData("EXAMINEE_OBJECT_ID"));
                if (ExaminationService.OnModuleExamine(examiner, examinedObject))
                {
                    MessageHub.Instance.Publish(new OnModuleExamine());
                    return;
                }

                string description;

                if (_.GetIsPC(examinedObject.Object) == true)
                {
                    // https://github.com/zunath/SWLOR_NWN/issues/853
                    // safest probably to get the modified (non-original) description only for players
                    // may want to always get the modified description for later flexibility?
                    description = _.GetDescription(examinedObject.Object, false) + "\n\n";
                }
                else
                {
                    description = _.GetDescription(examinedObject.Object, true) + "\n\n";
                }

                if (examinedObject.IsCreature)
                {
                    var    racialID   = Convert.ToInt32(_.Get2DAString("racialtypes", "Name", (int)_.GetRacialType(examinedObject)));
                    string racialtype = _.GetStringByStrRef(racialID);
                    if (!description.Contains(ColorTokenService.Green("Racial Type: ") + racialtype))
                    {
                        description += ColorTokenService.Green("Racial Type: ") + racialtype;
                    }
                }

                description = ModService.OnModuleExamine(description, examiner, examinedObject);
                description = ItemService.OnModuleExamine(description, examinedObject);
                description = DurabilityService.OnModuleExamine(description, examinedObject);

                if (!string.IsNullOrWhiteSpace(description))
                {
                    _.SetDescription(examinedObject.Object, description, false);
                    _.SetDescription(examinedObject.Object, description);
                }
            }

            MessageHub.Instance.Publish(new OnModuleExamine());
        }
        public void DurabilityService_GetMaxDurability_ShouldReturnDefault()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            NWItem             item    = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_LONGSWORD);

            float result = service.GetMaxDurability(item);

            Assert.AreEqual(30.0f, result);
        }
        public void DurabilityService_GetMaxDurability_InvalidType_ShouldReturnNegative1()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            NWItem             item    = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_BLANK_SCROLL);

            float result = service.GetMaxDurability(item);

            Assert.AreEqual(-1.0f, result);
        }
        public void DurabilityService_GetDurability_ShouldReturn6Point23()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            NWItem             item    = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_LONGSWORD);
            item.GetLocalFloat(Arg.Any <string>()).Returns(6.23f);

            float result = service.GetDurability(item);

            Assert.AreEqual(6.23f, result);
        }
Beispiel #10
0
        private void DoPlaceStructure()
        {
            var    data = BaseService.GetPlayerTempData(GetPC());
            string canPlaceStructure = BaseService.CanPlaceStructure(GetPC(), data.StructureItem, data.TargetLocation, data.BaseStructureID);
            var    baseStructure     = DataService.BaseStructure.GetByID(data.BaseStructureID);

            if (!string.IsNullOrWhiteSpace(canPlaceStructure))
            {
                GetPC().SendMessage(canPlaceStructure);
                return;
            }

            var position        = _.GetPositionFromLocation(data.TargetLocation);
            int?interiorStyleID = data.StructureItem.GetLocalInt("STRUCTURE_BUILDING_INTERIOR_ID");
            int?exteriorStyleID = data.StructureItem.GetLocalInt("STRUCTURE_BUILDING_EXTERIOR_ID");

            interiorStyleID = interiorStyleID <= 0 ? null : interiorStyleID;
            exteriorStyleID = exteriorStyleID <= 0 ? null : exteriorStyleID;

            var structure = new PCBaseStructure
            {
                BaseStructureID         = data.BaseStructureID,
                Durability              = DurabilityService.GetDurability(data.StructureItem),
                LocationOrientation     = _.GetFacingFromLocation(data.TargetLocation),
                LocationX               = position.m_X,
                LocationY               = position.m_Y,
                LocationZ               = position.m_Z,
                PCBaseID                = data.PCBaseID,
                InteriorStyleID         = interiorStyleID,
                ExteriorStyleID         = exteriorStyleID,
                CustomName              = string.Empty,
                ParentPCBaseStructureID = data.ParentStructureID,
                StructureBonus          = data.StructureItem.StructureBonus,
                StructureModeID         = baseStructure.DefaultStructureModeID
            };

            DataService.SubmitDataChange(structure, DatabaseActionType.Insert);

            // Placing a control tower. Set base shields to 100%
            if (baseStructure.BaseStructureTypeID == (int)BaseStructureType.ControlTower)
            {
                var pcBase = DataService.PCBase.GetByID(data.PCBaseID);
                pcBase.ShieldHP = BaseService.CalculateMaxShieldHP(structure);
                DataService.SubmitDataChange(pcBase, DatabaseActionType.Update);
            }

            BaseService.SpawnStructure(data.TargetArea, structure.ID);
            data.StructureItem.Destroy();
            EndConversation();
        }
        public void DurabilityService_SetDurability_InvalidType_ShouldNotRunOnce()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            bool   ranOnce             = false;
            NWItem item = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_BLANK_SCROLL);
            item.When(x => x.SetLocalFloat(Arg.Any <string>(), Arg.Any <float>()))
            .Do(x => ranOnce = true);

            service.SetDurability(item, 999.0f);
            Assert.AreEqual(false, ranOnce);
        }
        public void DurabilityService_SetDurability_ShouldSetToDefaultValue()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            float  value = 0.0f;
            NWItem item  = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_LONGSWORD);
            item.When(x => x.SetLocalFloat(Arg.Any <string>(), Arg.Any <float>()))
            .Do(x => value = x.ArgAt <float>(1));

            service.SetDurability(item, -50.0f);
            Assert.AreEqual(0.0f, value);
        }
        public void DurabilityService_SetDurability_ShouldSetToSpecifiedValue()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            float  value = 0.0f;
            NWItem item  = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => BASE_ITEM_LONGSWORD);
            item.When(x => x.SetLocalFloat("DURABILITY_CURRENT", Arg.Any <float>()))
            .Do(x => value = x.ArgAt <float>(1));

            service.SetDurability(item, 12.52f);
            Assert.AreEqual(12.52f, value);
        }
        public void DurabilityService_GetMaxDurability_ShouldReturn4()
        {
            INWScript          script       = Substitute.For <INWScript>();
            IColorTokenService color        = Substitute.For <IColorTokenService>();
            INWNXProfiler      nwnxProfiler = Substitute.For <INWNXProfiler>();
            DurabilityService  service      = new DurabilityService(script, color, nwnxProfiler);
            NWItem             item         = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(x => NWScript.BASE_ITEM_LONGSWORD);
            item.GetLocalInt(Arg.Any <string>()).Returns(4);

            float result = service.GetMaxDurability(item);

            Assert.AreEqual(4, result);
        }
Beispiel #15
0
        public void Apply(NWPlayer player, NWItem target, params string[] args)
        {
            var maxDurability = DurabilityService.GetMaxDurability(target);
            var curDurability = DurabilityService.GetDurability(target);

            int   value    = Convert.ToInt32(args[0]);
            float newValue = maxDurability + value;

            if (newValue > 100)
            {
                newValue = 100;
            }
            maxDurability  = newValue;
            curDurability += value;

            DurabilityService.SetMaxDurability(target, maxDurability);
            DurabilityService.SetDurability(target, curDurability);
        }
Beispiel #16
0
        // ReSharper disable once UnusedMember.Local
        private static void Main()
        {
            // Breaking the rules for the examine event because the result of the services is used in the following
            // service call. We still signal an event for this, but in general all of the logic should go into this method.

            using (new Profiler(nameof(mod_on_examine)))
            {
                NWPlayer examiner       = (Object.OBJECT_SELF);
                NWObject examinedObject = NWNXEvents.OnExamineObject_GetTarget();
                if (ExaminationService.OnModuleExamine(examiner, examinedObject))
                {
                    MessageHub.Instance.Publish(new OnModuleExamine());
                    return;
                }

                string description = _.GetDescription(examinedObject.Object, _.TRUE) + "\n\n";

                if (examinedObject.IsCreature)
                {
                    int    racialID   = Convert.ToInt32(_.Get2DAString("racialtypes", "Name", _.GetRacialType(examinedObject)));
                    string racialtype = _.GetStringByStrRef(racialID);
                    description += ColorTokenService.Green("Racial Type: ") + racialtype;
                }

                description = ModService.OnModuleExamine(description, examiner, examinedObject);
                description = ItemService.OnModuleExamine(description, examiner, examinedObject);
                description = DurabilityService.OnModuleExamine(description, examinedObject);
                description = FarmingService.OnModuleExamine(description, examinedObject);

                if (!string.IsNullOrWhiteSpace(description))
                {
                    _.SetDescription(examinedObject.Object, description, _.FALSE);
                    _.SetDescription(examinedObject.Object, description);
                }
            }

            MessageHub.Instance.Publish(new OnModuleExamine());
        }
Beispiel #17
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            int lootTableID = GetLootTable(targetLocation);

            if (lootTableID <= 0)
            {
                return;
            }

            NWArea area  = _.GetAreaFromLocation(targetLocation);
            var    items = DataService.LootTableItem.GetAllByLootTableID(lootTableID)
                           .OrderByDescending(o => o.Weight);
            string sector     = BaseService.GetSectorOfLocation(targetLocation);
            string sectorName = "Unknown";

            switch (sector)
            {
            case "NW": sectorName = "Northwest"; break;

            case "NE": sectorName = "Northeast"; break;

            case "SW": sectorName = "Southwest"; break;

            case "SE": sectorName = "Southeast"; break;
            }

            user.SendMessage(area.Name + "(" + sectorName + ")");
            user.SendMessage("Scanning results: ");

            foreach (var lti in items)
            {
                string name = ItemService.GetNameByResref(lti.Resref);
                user.SendMessage(name + " [Density: " + lti.Weight + "]");
            }

            DurabilityService.RunItemDecay(user.Object, item, RandomService.RandomFloat(0.02f, 0.08f));
        }
Beispiel #18
0
        public string IsValidTarget(NWCreature user, NWItem item, NWObject target, Location targetLocation)
        {
            NWItem targetItem    = target.Object;
            float  maxDurability = DurabilityService.GetMaxDurability(targetItem);
            float  durability    = DurabilityService.GetDurability(targetItem);

            if (target.ObjectType != OBJECT_TYPE_ITEM)
            {
                return("Only items may be targeted by repair kits.");
            }

            if (targetItem.CustomItemType != (CustomItemType)item.GetLocalInt("REPAIR_CUSTOM_ITEM_TYPE_ID"))
            {
                return("You cannot repair that item with this repair kit.");
            }

            if (maxDurability <= 0.0f ||
                durability >= maxDurability)
            {
                return("That item does not need to be repaired.");
            }

            if (durability <= 0.0f)
            {
                return("That item is broken and cannot be repaired.");
            }

            if (maxDurability <= 0.1f)
            {
                return("You cannot repair that item any more.");
            }

            SkillType skillType = GetSkillType(item);
            int       techLevel = item.GetLocalInt("TECH_LEVEL");

            return(null);
        }
Beispiel #19
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            DateTime now            = DateTime.UtcNow;
            DateTime unlockDateTime = now;

            if (string.IsNullOrWhiteSpace(GetLocalString(user, "GRENADE_UNLOCKTIME")))
            {
                unlockDateTime = unlockDateTime.AddSeconds(-1);
            }
            else
            {
                unlockDateTime = DateTime.ParseExact(GetLocalString(user, "GRENADE_UNLOCKTIME"), "yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture);
            }
            //Console.WriteLine("IsValidTarget - Current Time = " + now.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            //Console.WriteLine("IsValidTarget - Unlocktime = " + unlockDateTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            //Console.WriteLine("IsValidTarget - DateTime.Compare = " + DateTime.Compare(unlockDateTime, now));

            // Check if we've passed the unlock date. Exit early if we have not.
            if (DateTime.Compare(unlockDateTime, now) > 0 || unlockDateTime > now)
            {
                string timeToWait = TimeService.GetTimeToWaitLongIntervals(now, unlockDateTime, false);
                //Console.WriteLine("IsValidTarget - That ability can be used in " + timeToWait + ".");
                SendMessageToPC(user, "That ability can be used in " + timeToWait + ".");
                return;
            }

            Effect impactEffect = null;
            var    spellId      = Spell.Invalid;
            string soundName    = null;
            int    perkLevel    = 1 + PerkService.GetCreaturePerkLevel(user, PerkType.GrenadeProficiency);
            int    skillLevel   = 5 + SkillService.GetPCSkillRank((NWPlayer)user, SkillType.Throwing);

            if (perkLevel == 0)
            {
                perkLevel += 1;
            }

            if (GetIsObjectValid(target) == true)
            {
                targetLocation = GetLocation(target);
            }
            string grenadeType = item.GetLocalString("TYPE");
            //Console.WriteLine("Throwing " + grenadeType + " grenade at perk level " + perkLevel);
            Location originalLocation = targetLocation;

            int roll = RandomService.D100(1);

            SendMessageToPC(user, roll + " vs. DC " + (100 - skillLevel));
            if (roll < (100 - skillLevel))
            {
                if (RandomService.D20(1) == 1)
                {
                    SendMessageToPC(user, "You threw... poorly.");
                    //targetLocation = VectorService.MoveLocation(targetLocation, GetFacing(user), (RandomService.D6(4) - 10) * 1.0f,
                    targetLocation = VectorService.MoveLocation(user.Location, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) * 1.0f,
                                                                RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1));
                    int count = 0;
                    while ((GetSurfaceMaterial(targetLocation) == 0 ||
                            LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false) &&
                           count < 10)
                    {
                        count         += 1;
                        targetLocation = VectorService.MoveLocation(user.Location, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) * 1.0f,
                                                                    RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1));
                    }
                }
                else
                {
                    SendMessageToPC(user, "Your throw was a bit off the mark.");
                    //targetLocation = VectorService.MoveLocation(targetLocation, GetFacing(user), (RandomService.D6(4) - 10) * 1.0f,
                    targetLocation = VectorService.MoveLocation(targetLocation, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) /*(RandomService.D6(4) - 10) */ * 1.0f,
                                                                RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1));
                    int count = 0;
                    while ((GetSurfaceMaterial(targetLocation) == 0 ||
                            LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false) &&
                           count < 10)
                    {
                        count         += 1;
                        targetLocation = VectorService.MoveLocation(targetLocation, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) /*(RandomService.D6(4) - 10) */ * 1.0f,
                                                                    RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1));
                    }
                }

                if (GetSurfaceMaterial(targetLocation) == 0 ||
                    LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false)
                {
                    targetLocation = originalLocation;
                }
            }

            switch (grenadeType)
            {
            case "FRAG":
                impactEffect = EffectVisualEffect(VisualEffect.Fnf_Fireball);
                // force a specific spell id (for projectile model) for this grenade.
                spellId   = Spell.Grenade10;
                soundName = "explosion2";
                break;

            case "CONCUSSION":
                impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Sound_Burst_Silent);
                impactEffect = EffectLinkEffects(EffectVisualEffect(VisualEffect.Vfx_Fnf_Screen_Shake), impactEffect);
                spellId      = Spell.Grenade10;
                soundName    = "explosion1";
                break;

            case "FLASHBANG":
                impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Mystical_Explosion);
                spellId      = Spell.Grenade10;
                soundName    = "explosion1";
                break;

            case "ION":
                impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Electric_Explosion);
                spellId      = Spell.Grenade10;
                soundName    = "explosion1";
                break;

            case "BACTA":
                impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Gas_Explosion_Nature);
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            case "ADHESIVE":
                impactEffect = EffectVisualEffect(VisualEffect.Fnf_Dispel_Greater);
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            case "SMOKE":
                impactEffect = null;
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            case "BACTABOMB":
                impactEffect = null;
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            case "INCENDIARY":
                impactEffect = null;
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            case "GAS":
                impactEffect = null;
                spellId      = Spell.Grenade10;
                //soundName = "explosion1";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(grenadeType));
            }

            if (spellId == 0)
            {
                // start 974 through 979 in spells.2da for grenades
                // lets randomly assign a projectile appearance for flavor?
                spellId = (Spell)(RandomService.D6(1) + 973);
            }

            float delay = GetDistanceBetweenLocations(user.Location, targetLocation) / 18.0f + 0.75f;

            delay += 0.4f; // added for animation
            user.ClearAllActions();
            //user.AssignCommand(() => _.ActionPlayAnimation(32));
            //user.DelayAssignCommand(() => _.ActionPlayAnimation(32), 0.0f);
            user.AssignCommand(() =>
            {
                ActionPlayAnimation(Animation.LoopingCustom12);
                ActionCastSpellAtLocation(spellId, targetLocation, MetaMagic.Any, true, ProjectilePathType.Ballistic, true);
                //ActionCastFakeSpellAtLocation(spellId, targetLocation, PROJECTILE_PATH_TYPE_BALLISTIC);
            });

            if (soundName != null)
            {
                user.DelayAssignCommand(() =>
                {
                    PlaySound(soundName);
                }, delay);
            }

            if (impactEffect != null)
            {
                user.DelayAssignCommand(() =>
                {
                    ApplyEffectAtLocation(DurationType.Instant, impactEffect, targetLocation);
                }, delay);
            }

            user.DelayAssignCommand(
                () =>
            {
                DoImpact(user, item, targetLocation, grenadeType, perkLevel, RadiusSize.Large, ObjectType.Creature);
            }, delay + 0.75f);


            perkLevel = PerkService.GetCreaturePerkLevel(user, PerkType.GrenadeProficiency);

            now = DateTime.UtcNow;
            DateTime unlockTime = now;

            if (perkLevel < 5)
            {
                unlockTime = unlockTime.AddSeconds(6);
            }
            else if (perkLevel < 10)
            {
                unlockTime = unlockTime.AddSeconds(3);
            }
            else
            {
                unlockTime = unlockTime.AddSeconds(2);
            }

            SetLocalString(user, "GRENADE_UNLOCKTIME", unlockTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            //Console.WriteLine("StartUseItem - Current Time = " + now.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            //Console.WriteLine("StartUseItem - Unlocktime Set To = " + unlockTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            if (user.IsCreature)
            {
                DurabilityService.RunItemDecay((NWPlayer)user, item, 1.0f);
            }
        }
Beispiel #20
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            NWPlayer        player     = user.Object;
            ResourceQuality quality    = (ResourceQuality)target.GetLocalInt("RESOURCE_QUALITY");
            int             tier       = target.GetLocalInt("RESOURCE_TIER");
            int             remaining  = target.GetLocalInt("RESOURCE_COUNT") - 1;
            string          itemResref = target.GetLocalString("RESOURCE_RESREF");
            int             gemChance  = ResourceService.CalculateChanceForComponentBonus(player, tier, quality);
            int             roll       = RandomService.Random(1, 100);
            int             rank       = SkillService.GetPCSkillRank(player, SkillType.Harvesting);

            if (item.RecommendedLevel < rank)
            {
                rank = item.RecommendedLevel;
            }

            int difficulty = (tier - 1) * 10 + ResourceService.GetDifficultyAdjustment(quality);
            int delta      = difficulty - rank;

            int baseXP = 0;

            if (delta >= 6)
            {
                baseXP = 400;
            }
            else if (delta == 5)
            {
                baseXP = 350;
            }
            else if (delta == 4)
            {
                baseXP = 325;
            }
            else if (delta == 3)
            {
                baseXP = 300;
            }
            else if (delta == 2)
            {
                baseXP = 250;
            }
            else if (delta == 1)
            {
                baseXP = 225;
            }
            else if (delta == 0)
            {
                baseXP = 200;
            }
            else if (delta == -1)
            {
                baseXP = 150;
            }
            else if (delta == -2)
            {
                baseXP = 100;
            }
            else if (delta == -3)
            {
                baseXP = 50;
            }
            else if (delta == -4)
            {
                baseXP = 25;
            }

            int itemHarvestBonus = item.HarvestingBonus;
            int scanningBonus    = user.GetLocalInt(target.GlobalID.ToString());

            gemChance += itemHarvestBonus * 2 + scanningBonus * 2;

            baseXP = baseXP + scanningBonus * 5;

            // Spawn the normal resource.
            NWItem resource = CreateItemOnObject(itemResref, player);

            user.SendMessage("You harvest " + resource.Name + ".");

            // If player meets the chance to acquire a gem, create one and modify its properties.
            if (quality > ResourceQuality.Low && roll <= gemChance)
            {
                // Gemstone quality is determined by the quality of the vein.
                switch (quality)
                {
                case ResourceQuality.Normal:
                    resource = CreateItemOnObject("flawed_gemstone", player);
                    break;

                case ResourceQuality.High:
                    resource = CreateItemOnObject("gemstone", player);
                    break;

                case ResourceQuality.VeryHigh:
                    resource = CreateItemOnObject("perfect_gemstone", player);
                    break;
                }

                var ip = ResourceService.GetRandomComponentBonusIP(quality);
                BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true);

                switch (ip.Item2)
                {
                case 0:
                    resource.Name = ColorTokenService.Green(resource.Name);
                    break;

                case 1:
                    resource.Name = ColorTokenService.Blue(resource.Name);
                    break;

                case 2:
                    resource.Name = ColorTokenService.Purple(resource.Name);
                    break;

                case 3:
                    resource.Name = ColorTokenService.Orange(resource.Name);
                    break;

                case 4:
                    resource.Name = ColorTokenService.LightPurple(resource.Name);
                    break;

                case 5:
                    resource.Name = ColorTokenService.Yellow(resource.Name);
                    break;

                case 6:
                    resource.Name = ColorTokenService.Red(resource.Name);
                    break;

                case 7:
                    resource.Name = ColorTokenService.Cyan(resource.Name);
                    break;
                }

                user.SendMessage("You harvest " + resource.Name + ".");
            }

            float decayMinimum = 0.03f;
            float decayMaximum = 0.07f;

            if (delta > 0)
            {
                decayMinimum += delta * 0.1f;
                decayMaximum += delta * 0.1f;
            }

            DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(decayMinimum, decayMaximum));
            int xp = baseXP;

            SkillService.GiveSkillXP(player, SkillType.Harvesting, xp);

            if (remaining <= 0)
            {
                NWPlaceable prop = target.GetLocalObject("RESOURCE_PROP_OBJ");

                if (prop.IsValid)
                {
                    prop.Destroy();
                }

                target.Destroy();
                user.DeleteLocalInt(target.GlobalID.ToString());
            }
            else
            {
                target.SetLocalInt("RESOURCE_COUNT", remaining);
            }

            ApplyEffectAtLocation(DurationType.Instant, EffectVisualEffect(VisualEffect.Vfx_Fnf_Summon_Monster_3), target.Location);
        }
Beispiel #21
0
        private void RunCreateItem(NWPlayer player)
        {
            foreach (var effect in player.Effects)
            {
                if (_.GetEffectTag(effect) == "CRAFTING_IMMOBILIZATION")
                {
                    _.RemoveEffect(player, effect);
                }
            }

            var model = CraftService.GetPlayerCraftingData(player);

            CraftBlueprint blueprint     = DataService.CraftBlueprint.GetByID(model.BlueprintID);
            BaseStructure  baseStructure = blueprint.BaseStructureID == null ? null : DataService.BaseStructure.GetByID(Convert.ToInt32(blueprint.BaseStructureID));
            PCSkill        pcSkill       = SkillService.GetPCSkill(player, blueprint.SkillID);

            int   pcEffectiveLevel = CraftService.CalculatePCEffectiveLevel(player, pcSkill.Rank, (SkillType)blueprint.SkillID);
            int   itemLevel        = model.AdjustedLevel;
            int   atmosphereBonus  = CraftService.CalculateAreaAtmosphereBonus(player.Area);
            float chance           = CalculateBaseChanceToAddProperty(pcEffectiveLevel, itemLevel, atmosphereBonus);
            float equipmentBonus   = CalculateEquipmentBonus(player, (SkillType)blueprint.SkillID);

            if (chance <= 1.0f)
            {
                player.FloatingText(ColorTokenService.Red("Critical failure! You don't have enough skill to create that item. All components were lost."));
                CraftService.ClearPlayerCraftingData(player, true);
                return;
            }

            int    luckyBonus   = PerkService.GetCreaturePerkLevel(player, PerkType.Lucky);
            var    craftedItems = new List <NWItem>();
            NWItem craftedItem  = (_.CreateItemOnObject(blueprint.ItemResref, player.Object, blueprint.Quantity));

            craftedItem.IsIdentified = true;
            craftedItems.Add(craftedItem);

            // 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 = (_.CreateItemOnObject(blueprint.ItemResref, player.Object));
                    craftedItem.IsIdentified = true;
                    craftedItems.Add(craftedItem);
                }
            }

            // Recommended level gets set regardless if all item properties make it on the final product.
            // Also mark who crafted the item. This is later used for display on the item's examination event.
            foreach (var item in craftedItems)
            {
                item.RecommendedLevel = itemLevel < 0 ? 0 : itemLevel;
                item.SetLocalString("CRAFTER_PLAYER_ID", player.GlobalID.ToString());

                BaseService.ApplyCraftedItemLocalVariables(item, baseStructure);
            }

            if (RandomService.Random(1, 100) <= luckyBonus)
            {
                chance += RandomService.Random(1, luckyBonus);
            }

            int successAmount = 0;

            foreach (var component in model.MainComponents)
            {
                var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems);
                successAmount += result.Item1;
                chance         = result.Item2;
            }
            foreach (var component in model.SecondaryComponents)
            {
                var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems);
                successAmount += result.Item1;
                chance         = result.Item2;
            }
            foreach (var component in model.TertiaryComponents)
            {
                var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems);
                successAmount += result.Item1;
                chance         = result.Item2;
            }
            foreach (var component in model.EnhancementComponents)
            {
                var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems);
                successAmount += result.Item1;
                chance         = result.Item2;
            }

            // Structures gain increased durability based on the blueprint
            if (baseStructure != null)
            {
                foreach (var item in craftedItems)
                {
                    var maxDur = DurabilityService.GetMaxDurability(item);
                    maxDur += (float)baseStructure.Durability;
                    DurabilityService.SetMaxDurability(item, maxDur);
                    DurabilityService.SetDurability(item, maxDur);
                }
            }

            player.SendMessage("You created " + blueprint.Quantity + "x " + blueprint.ItemName + "!");
            int   baseXP = 750 + successAmount * RandomService.Random(1, 50);
            float xp     = SkillService.CalculateRegisteredSkillLevelAdjustedXP(baseXP, model.AdjustedLevel, pcSkill.Rank);

            bool exists = DataService.PCCraftedBlueprint.ExistsByPlayerIDAndCraftedBlueprintID(player.GlobalID, blueprint.ID);

            if (!exists)
            {
                xp = xp * 1.50f;
                player.SendMessage("You receive an XP bonus for crafting this item for the first time.");

                var pcCraftedBlueprint = new PCCraftedBlueprint
                {
                    CraftBlueprintID = blueprint.ID,
                    DateFirstCrafted = DateTime.UtcNow,
                    PlayerID         = player.GlobalID
                };

                DataService.SubmitDataChange(pcCraftedBlueprint, DatabaseActionType.Insert);
            }

            SkillService.GiveSkillXP(player, blueprint.SkillID, (int)xp);
            CraftService.ClearPlayerCraftingData(player, true);
            player.SetLocalInt("LAST_CRAFTED_BLUEPRINT_ID_" + blueprint.CraftDeviceID, blueprint.ID);
        }
Beispiel #22
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            SkillType skillType  = GetSkillType(item);
            NWItem    targetitem = (target.Object);
            int       tech       = item.GetLocalInt("TECH_LEVEL");
            float     maxDurabilityReductionPenalty = item.GetLocalFloat("MAX_DURABILITY_REDUCTION_PENALTY");
            int       repairAmount = tech * 2;
            int       skillRank;
            int       level  = targetitem.RecommendedLevel;
            int       delta  = 0;
            int       baseXP = 0;

            if (skillType == SkillType.Armorsmith)
            {
                skillRank     = (SkillService.GetPCSkillRank(user.Object, skillType));
                repairAmount += item.CraftBonusArmorsmith + (PerkService.GetPCPerkLevel(user.Object, PerkType.ArmorRepair) * 2);
                delta         = level - skillRank;
            }
            else if (skillType == SkillType.Weaponsmith)
            {
                skillRank     = (SkillService.GetPCSkillRank(user.Object, skillType));
                repairAmount += item.CraftBonusWeaponsmith + (PerkService.GetPCPerkLevel(user.Object, PerkType.WeaponRepair) * 2);
                delta         = level - skillRank;
            }
            else if (skillType == SkillType.Engineering)
            {
                skillRank     = (SkillService.GetPCSkillRank(user.Object, skillType));
                repairAmount += item.CraftBonusEngineering + (PerkService.GetPCPerkLevel(user.Object, PerkType.ElectronicRepair) * 2);
                delta         = level - skillRank;
            }
            float minReduction    = 0.05f * tech;
            float maxReduction    = 0.15f * tech;
            float reductionAmount = RandomService.RandomFloat(minReduction, maxReduction);

            if (delta >= 6)
            {
                baseXP = 400;
            }
            else if (delta == 5)
            {
                baseXP = 350;
            }
            else if (delta == 4)
            {
                baseXP = 325;
            }
            else if (delta == 3)
            {
                baseXP = 300;
            }
            else if (delta == 2)
            {
                baseXP = 250;
            }
            else if (delta == 1)
            {
                baseXP = 225;
            }
            else if (delta == 0)
            {
                baseXP = 200;
            }
            else if (delta == -1)
            {
                baseXP = 150;
            }
            else if (delta == -2)
            {
                baseXP = 100;
            }
            else if (delta == -3)
            {
                baseXP = 50;
            }
            else if (delta == -4)
            {
                baseXP = 25;
            }
            SkillService.GiveSkillXP(user.Object, skillType, baseXP);
            DurabilityService.RunItemRepair(user.Object, target.Object, repairAmount, reductionAmount + maxDurabilityReductionPenalty);
        }
Beispiel #23
0
        public void Main()
        {
            NWCreature      attacker    = (_.GetLastDamager(_.OBJECT_SELF));
            NWPlaceable     tower       = (_.OBJECT_SELF);
            NWItem          weapon      = (_.GetLastWeaponUsed(attacker.Object));
            int             damage      = _.GetTotalDamageDealt();
            var             structureID = tower.GetLocalString("PC_BASE_STRUCTURE_ID");
            PCBaseStructure structure   = DataService.PCBaseStructure.GetByID(new Guid(structureID));
            int             maxShieldHP = BaseService.CalculateMaxShieldHP(structure);
            PCBase          pcBase      = DataService.PCBase.GetByID(structure.PCBaseID);
            var             playerIDs   = DataService.PCBasePermission.GetAllByHasPrivatePermissionToBase(structure.PCBaseID)
                                          .Select(s => s.PlayerID);
            var      toNotify = NWModule.Get().Players.Where(x => playerIDs.Contains(x.GlobalID));
            DateTime timer    = DateTime.UtcNow.AddSeconds(30);
            string   clock    = timer.ToString(CultureInfo.InvariantCulture);
            string   sector   = BaseService.GetSectorOfLocation(attacker.Location);

            if (DateTime.UtcNow <= DateTime.Parse(clock))
            {
                foreach (NWPlayer player in toNotify)
                {
                    player.SendMessage("Your base in " + attacker.Area.Name + " " + sector + " is under attack!");
                }
            }

            // Apply damage to the shields. Never fall below 0.
            pcBase.ShieldHP -= damage;
            if (pcBase.ShieldHP <= 0)
            {
                pcBase.ShieldHP = 0;
            }

            // Calculate the amount of shield percentage remaining. If the tower is in reinforced mode, HP
            // will always be set back to 25% of shields.
            float hpPercentage = (float)pcBase.ShieldHP / (float)maxShieldHP * 100.0f;

            if (hpPercentage <= 25.0f && pcBase.ReinforcedFuel > 0)
            {
                pcBase.IsInReinforcedMode = true;
                pcBase.ShieldHP           = (int)(maxShieldHP * 0.25f);
                hpPercentage = (float)pcBase.ShieldHP / (float)maxShieldHP * 100.0f;
            }

            // Notify the attacker.
            attacker.SendMessage("Tower Shields: " + hpPercentage.ToString("0.00") + "%");
            if (pcBase.IsInReinforcedMode)
            {
                attacker.SendMessage("Control tower is in reinforced mode and cannot be damaged. Reinforced mode will be disabled when the tower runs out of fuel.");
            }

            // HP is tracked in the database. Heal the placeable so it doesn't get destroyed.
            _.ApplyEffectToObject(DurationType.Instant, _.EffectHeal(9999), tower.Object);

            if (attacker.IsPlayer)
            {
                DurabilityService.RunItemDecay(attacker.Object, weapon, RandomService.RandomFloat(0.01f, 0.03f));
            }

            // If the shields have fallen to zero, the tower will begin to take structure damage.
            if (pcBase.ShieldHP <= 0)
            {
                pcBase.ShieldHP = 0;

                structure.Durability -= RandomService.RandomFloat(0.5f, 2.0f);
                if (structure.Durability < 0.0f)
                {
                    structure.Durability = 0.0f;
                }
                attacker.SendMessage("Structure Durability: " + structure.Durability.ToString("0.00"));

                // If the structure durability drops to zero, destroy everything in the base.
                if (structure.Durability <= 0.0f)
                {
                    structure.Durability = 0.0f;
                    BaseService.ClearPCBaseByID(pcBase.ID, true, false);
                    MessageHub.Instance.Publish(new OnBaseDestroyed(pcBase, attacker));
                    return;
                }
            }

            DataService.SubmitDataChange(pcBase, DatabaseActionType.Update);
            DataService.SubmitDataChange(structure, DatabaseActionType.Update);
        }
        public void DurabilityService_IsValidDurabilityType_ShouldBeFalse()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            NWItem             item    = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(BASE_ITEM_TORCH);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_AMULET);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_ARROW);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCSMALL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BOLT);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BULLET);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCMEDIUM);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_DART);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCLARGE);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HEALERSKIT);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCTALL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MAGICROD);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MAGICSTAFF);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MAGICWAND);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_POTIONS);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_RING);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SCROLL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SHURIKEN);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_THIEVESTOOLS);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_TRAPKIT);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_KEY);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LARGEBOX);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCWIDE);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CSLASHWEAPON);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CPIERCWEAPON);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CBLUDGWEAPON);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CSLSHPRCWEAP);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CREATUREITEM);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BOOK);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SPELLSCROLL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GOLD);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GEM);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MISCTHIN);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GRENADE);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BLANK_POTION);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BLANK_SCROLL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BLANK_WAND);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_ENCHANTED_POTION);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_ENCHANTED_SCROLL);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_ENCHANTED_WAND);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CRAFTMATERIALMED);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CRAFTMATERIALSML);
            Assert.IsFalse(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_INVALID);
            Assert.IsFalse(service.IsValidDurabilityType(item));
        }
Beispiel #25
0
        public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData)
        {
            NWPlayer        player        = user.Object;
            ResourceQuality quality       = (ResourceQuality)target.GetLocalInt("RESOURCE_QUALITY");
            int             tier          = target.GetLocalInt("RESOURCE_TIER");
            int             remaining     = target.GetLocalInt("RESOURCE_COUNT") - 1;
            string          itemResref    = target.GetLocalString("RESOURCE_RESREF");
            int             ipBonusChance = ResourceService.CalculateChanceForComponentBonus(player, tier, quality);
            int             roll          = RandomService.Random(1, 100);
            int             rank          = SkillService.GetPCSkillRank(player, SkillType.Harvesting);

            if (item.RecommendedLevel < rank)
            {
                rank = item.RecommendedLevel;
            }

            int difficulty = (tier - 1) * 10 + ResourceService.GetDifficultyAdjustment(quality);
            int delta      = difficulty - rank;

            int baseXP = 0;

            if (delta >= 6)
            {
                baseXP = 400;
            }
            else if (delta == 5)
            {
                baseXP = 350;
            }
            else if (delta == 4)
            {
                baseXP = 325;
            }
            else if (delta == 3)
            {
                baseXP = 300;
            }
            else if (delta == 2)
            {
                baseXP = 250;
            }
            else if (delta == 1)
            {
                baseXP = 225;
            }
            else if (delta == 0)
            {
                baseXP = 200;
            }
            else if (delta == -1)
            {
                baseXP = 150;
            }
            else if (delta == -2)
            {
                baseXP = 100;
            }
            else if (delta == -3)
            {
                baseXP = 50;
            }
            else if (delta == -4)
            {
                baseXP = 25;
            }

            int itemHarvestBonus = item.HarvestingBonus;
            int scanningBonus    = user.GetLocalInt(target.GlobalID.ToString());

            ipBonusChance += itemHarvestBonus * 2 + scanningBonus * 2;

            baseXP = baseXP + scanningBonus * 5;

            NWItem resource = _.CreateItemOnObject(itemResref, player.Object);

            if (roll <= ipBonusChance)
            {
                var ip = ResourceService.GetRandomComponentBonusIP(quality);
                BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true);

                switch (ip.Item2)
                {
                case 0:
                    resource.Name = ColorTokenService.Green(resource.Name);
                    break;

                case 1:
                    resource.Name = ColorTokenService.Blue(resource.Name);
                    break;

                case 2:
                    resource.Name = ColorTokenService.Purple(resource.Name);
                    break;

                case 3:
                    resource.Name = ColorTokenService.Orange(resource.Name);
                    break;
                }
            }

            float decayMinimum = 0.03f;
            float decayMaximum = 0.07f;

            if (delta > 0)
            {
                decayMinimum += delta * 0.1f;
                decayMaximum += delta * 0.1f;
            }

            user.SendMessage("You harvest " + resource.Name + ".");
            DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(decayMinimum, decayMaximum));
            int xp = baseXP;

            SkillService.GiveSkillXP(player, SkillType.Harvesting, xp);

            if (remaining <= 0)
            {
                NWPlaceable prop = target.GetLocalObject("RESOURCE_PROP_OBJ");

                if (prop.IsValid)
                {
                    prop.Destroy();
                }

                target.Destroy();
                user.DeleteLocalInt(target.GlobalID.ToString());
            }
            else
            {
                target.SetLocalInt("RESOURCE_COUNT", remaining);
            }

            _.ApplyEffectAtLocation(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), target.Location);
        }
        public void DurabilityService_IsValidDurabilityType_ShouldBeTrue()
        {
            INWScript          script  = Substitute.For <INWScript>();
            IColorTokenService color   = Substitute.For <IColorTokenService>();
            DurabilityService  service = new DurabilityService(script, color);
            NWItem             item    = Substitute.For <NWItem>(script, service);

            item.BaseItemType.Returns(BASE_ITEM_ARMOR);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BASTARDSWORD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BATTLEAXE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BELT);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BOOTS);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_BRACER);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CLOAK);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_CLUB);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_DAGGER);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_DIREMACE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_DOUBLEAXE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_DWARVENWARAXE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GLOVES);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GREATAXE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_GREATSWORD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HALBERD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HANDAXE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HEAVYCROSSBOW);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HEAVYFLAIL);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_HELMET);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_KAMA);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_KATANA);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_KUKRI);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LARGESHIELD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LIGHTCROSSBOW);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LIGHTFLAIL);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LIGHTHAMMER);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LIGHTMACE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LONGBOW);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_LONGSWORD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_MORNINGSTAR);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_QUARTERSTAFF);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_RAPIER);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SCIMITAR);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SCYTHE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SHORTBOW);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SHORTSPEAR);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SHORTSWORD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SICKLE);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SLING);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_SMALLSHIELD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_TOWERSHIELD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_TRIDENT);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_TWOBLADEDSWORD);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_WARHAMMER);
            Assert.IsTrue(service.IsValidDurabilityType(item));
            item.BaseItemType.Returns(BASE_ITEM_WHIP);
            Assert.IsTrue(service.IsValidDurabilityType(item));
        }