Beispiel #1
0
        public bool Run(params object[] args)
        {
            NWPlaceable oSite = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC   = NWPlayer.Wrap(_.GetLastAttacker(oSite.Object));
            int         constructionSiteID = _structure.GetConstructionSiteID(oSite);

            if (constructionSiteID <= 0)
            {
                oPC.FloatingText("You must select a blueprint before you can build.");
                oPC.ClearAllActions();
                return(true);
            }

            NWItem weapon     = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object));
            int    weaponType = weapon.BaseItemType;

            if (weaponType != BASE_ITEM_LIGHTHAMMER)
            {
                oPC.FloatingText("A hammer must be equipped to build this structure.");
                oPC.ClearAllActions();
                return(true);
            }

            // Offhand weapons don't contribute to building.
            if (weapon.Equals(oPC.LeftHand))
            {
                return(true);
            }

            if (!_structure.IsConstructionSiteValid(oSite))
            {
                oPC.FloatingText("Construction site is invalid. Please click the construction site to find out more.");
                oPC.ClearAllActions();
                return(true);
            }


            Data.Entities.ConstructionSite entity = _structure.GetConstructionSiteByID(constructionSiteID);


            if (weapon.CraftTierLevel < entity.StructureBlueprint.CraftTierLevel)
            {
                oPC.FloatingText("Your hammer cannot be used with this blueprint. (Required Tool Level: " + entity.StructureBlueprint.CraftTierLevel + ")");
                oPC.ClearAllActions();
                return(true);
            }

            int    rank          = _skill.GetPCSkill(oPC, SkillType.Construction).Rank;
            int    mangleChance  = CalculateMangleChance(oPC, entity.StructureBlueprint.Level, rank);
            bool   isMangle      = _random.Random(100) + 1 <= mangleChance;
            bool   foundResource = false;
            string updateMessage = "You lack the necessary resources...";

            int totalAmount = 0;

            foreach (ConstructionSiteComponent comp in entity.ConstructionSiteComponents)
            {
                if (comp.Quantity > 0 && !foundResource)
                {
                    NWItem item = NWItem.Wrap(_.GetItemPossessedBy(oPC.Object, comp.StructureComponent.Resref));
                    if (item.IsValid)
                    {
                        int reuseChance = isMangle ? 0 : _perk.GetPCPerkLevel(oPC, PerkType.ConservativeConstruction) * 2 + _perk.GetPCPerkLevel(oPC, PerkType.Lucky);
                        if (_random.Random(100) + 1 <= reuseChance)
                        {
                            oPC.SendMessage("You conserve a resource...");
                        }
                        else
                        {
                            item.ReduceItemStack();
                        }

                        if (isMangle)
                        {
                            oPC.SendMessage(_color.Red("You mangle a resource due to your lack of skill..."));
                            return(true);
                        }

                        string name = _item.GetNameByResref(comp.StructureComponent.Resref);
                        comp.Quantity--;
                        updateMessage = "You need " + comp.Quantity + " " + name + " to complete this project.";
                        foundResource = true;
                    }
                }
                totalAmount += comp.Quantity;
            }

            oPC.DelayCommand(() => oPC.SendMessage(updateMessage), 0.75f);

            if (totalAmount <= 0)
            {
                _structure.CompleteStructure(oSite);
            }
            else if (foundResource)
            {
                _structure.SaveChanges();
                _durability.RunItemDecay(oPC, weapon);

                if (entity.StructureBlueprint.GivesSkillXP)
                {
                    int xp = (int)_skill.CalculateSkillAdjustedXP(100, 0, rank);
                    _skill.GiveSkillXP(oPC, SkillType.Construction, xp);
                }

                // Speedy Builder - Grants haste for 8 seconds
                int hasteChance = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyBuilder) * 10;

                if (hasteChance > 0)
                {
                    hasteChance += _perk.GetPCPerkLevel(oPC, PerkType.Lucky) * 2;
                }

                PlayerCharacter pcEntity = _player.GetPlayerEntity(oPC);
                if (pcEntity.BackgroundID == (int)BackgroundType.ConstructionBuilder)
                {
                    hasteChance += 10;
                }

                if (_random.Random(100) + 1 <= hasteChance)
                {
                    _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectHaste(), oPC.Object, 8.0f);
                }
            }
            else
            {
                oPC.ClearAllActions();
            }
            return(true);
        }
Beispiel #2
0
        public bool Run(params object[] args)
        {
            NWPlaceable resource = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC      = NWPlayer.Wrap(_.GetLastDamager(resource.Object));

            if (oPC.GetLocalInt("NOT_USING_CORRECT_WEAPON") == 1)
            {
                oPC.DeleteLocalInt("NOT_USING_CORRECT_WEAPON");
                return(true);
            }

            PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);

            NWItem    oWeapon            = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object));
            Location  location           = oPC.Location;
            string    resourceItemResref = resource.GetLocalString("RESOURCE_RESREF");
            int       activityID         = resource.GetLocalInt("RESOURCE_ACTIVITY");
            string    resourceName       = resource.GetLocalString("RESOURCE_NAME");
            int       resourceCount      = resource.GetLocalInt("RESOURCE_COUNT");
            int       difficultyRating   = resource.GetLocalInt("RESOURCE_DIFFICULTY_RATING");
            int       weaponChanceBonus;
            SkillType skillType;
            int       perkChanceBonus;
            int       secondResourceChance;
            int       durabilityChanceReduction = 0;
            int       hasteChance;
            int       lucky = _perk.GetPCPerkLevel(oPC, PerkType.Lucky) + oPC.EffectiveLuckBonus;
            bool      hasBaggerPerk;

            if (activityID == 1) // 1 = Logging
            {
                weaponChanceBonus = oWeapon.LoggingBonus;
                if (weaponChanceBonus > 0)
                {
                    weaponChanceBonus        += _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 5;
                    durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.LoggingAxeExpert) * 10 + lucky;
                }

                skillType            = SkillType.Logging;
                perkChanceBonus      = _perk.GetPCPerkLevel(oPC, PerkType.Lumberjack) * 5 + lucky;
                secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionLogging) * 10;
                hasteChance          = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyLogger) * 10 + lucky;

                if (pcEntity.BackgroundID == (int)BackgroundType.Lumberjack)
                {
                    hasteChance += 10;
                }

                hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.WoodBagger) > 0;
            }
            else if (activityID == 2) // Mining
            {
                weaponChanceBonus = oWeapon.MiningBonus;
                if (weaponChanceBonus > 0)
                {
                    weaponChanceBonus        += _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 5;
                    durabilityChanceReduction = _perk.GetPCPerkLevel(oPC, PerkType.PickaxeExpert) * 10 + lucky;
                }
                skillType            = SkillType.Mining;
                perkChanceBonus      = _perk.GetPCPerkLevel(oPC, PerkType.Miner) * 5 + lucky;
                secondResourceChance = _perk.GetPCPerkLevel(oPC, PerkType.PrecisionMining) * 10;
                hasteChance          = _perk.GetPCPerkLevel(oPC, PerkType.SpeedyMiner) * 10 + lucky;

                if (pcEntity.BackgroundID == (int)BackgroundType.Miner)
                {
                    hasteChance += 10;
                }

                hasBaggerPerk = _perk.GetPCPerkLevel(oPC, PerkType.OreBagger) > 0;
            }
            else
            {
                return(false);
            }
            PCSkill skill = _skill.GetPCSkillByID(oPC.GlobalID, (int)skillType);
            int     durabilityLossChance = 100 - durabilityChanceReduction;

            if (_random.Random(100) <= durabilityLossChance)
            {
                _durability.RunItemDecay(oPC, oWeapon);
            }

            int baseChance = 10;
            int chance     = baseChance + weaponChanceBonus;

            chance += CalculateSuccessChanceDeltaModifier(difficultyRating, skill.Rank);
            chance += perkChanceBonus;

            bool givePityItem = false;

            if (chance > 0)
            {
                if (_random.Random(100) + 1 <= hasteChance)
                {
                    _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectHaste(), oPC.Object, 8.0f);
                }

                // Give an item if the player hasn't gotten anything after 6-8 attempts.
                int      attemptFailureCount = oPC.GetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT") + 1;
                NWObject failureResource     = NWObject.Wrap(oPC.GetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT"));

                if (!failureResource.IsValid || !Equals(failureResource, resource))
                {
                    failureResource     = resource;
                    attemptFailureCount = 1;
                }

                int pityItemChance = 0;
                if (attemptFailureCount == 6)
                {
                    pityItemChance = 60;
                }
                else if (attemptFailureCount == 7)
                {
                    pityItemChance = 80;
                }
                else if (attemptFailureCount >= 8)
                {
                    pityItemChance = 100;
                }

                if (_random.Random(100) + 1 <= pityItemChance)
                {
                    givePityItem        = true;
                    attemptFailureCount = 0;
                }

                oPC.SetLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT", attemptFailureCount);
                oPC.SetLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT", failureResource.Object);
            }

            if (chance <= 0)
            {
                oPC.FloatingText("You do not have enough skill to harvest this resource...");
            }
            else if (_random.Random(100) <= chance || givePityItem)
            {
                if (hasBaggerPerk)
                {
                    _.CreateItemOnObject(resourceItemResref, oPC.Object);
                }
                else
                {
                    _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location);
                }


                oPC.FloatingText("You break off some " + resourceName + ".");
                resource.SetLocalInt("RESOURCE_COUNT", --resourceCount);
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(10000), resource.Object);

                if (_random.Random(100) + 1 <= secondResourceChance)
                {
                    oPC.FloatingText("You break off a second piece.");

                    if (hasBaggerPerk)
                    {
                        _.CreateItemOnObject(resourceItemResref, oPC.Object);
                    }
                    else
                    {
                        _.CreateObject(OBJECT_TYPE_ITEM, resourceItemResref, location);
                    }
                }

                float deltaModifier = CalculateXPDeltaModifier(difficultyRating, skill.Rank);
                float baseXP        = (100 + _random.Random(20)) * deltaModifier;
                int   xp            = (int)_skill.CalculateRegisteredSkillLevelAdjustedXP(baseXP, oWeapon.RecommendedLevel, skill.Rank);
                _skill.GiveSkillXP(oPC, skillType, xp);

                oPC.DeleteLocalInt("RESOURCE_ATTEMPT_FAILURE_COUNT");
                oPC.DeleteLocalObject("RESOURCE_ATTEMPT_FAILURE_OBJECT");
            }

            if (resourceCount <= 0)
            {
                SpawnSeed(resource, oPC);

                NWObject prop = NWObject.Wrap(resource.GetLocalObject("RESOURCE_PROP_OBJ"));
                if (prop.IsValid)
                {
                    prop.Destroy();
                }
                resource.Destroy();
            }
            return(true);
        }