예제 #1
0
        public void OnImpact(NWPlayer oPC, NWObject oTarget)
        {
            int    perkLevel = _perk.GetPCPerkLevel(oPC, PerkType.Meditate);
            Vector position  = oPC.Position;
            int    amount;

            switch (perkLevel)
            {
            default:
                amount = 1;
                break;

            case 4:
            case 5:
            case 6:
                amount = 2;
                break;

            case 7:
                amount = 3;
                break;
            }
            oPC.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0f, 6.1f);
            });

            oPC.DelayCommand(() =>
            {
                RunMeditate(oPC, position, amount);
            }, 6.0f);

            oPC.SendMessage("You begin to meditate...");
            oPC.IsBusy = true;
        }
예제 #2
0
        public string Apply(NWCreature oCaster, NWObject oTarget, int effectiveLevel)
        {
            NWPlayer player = oTarget.Object;

            player.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0f, 6.1f);
            });

            player.IsBusy = true;

            string data = $"{player.Position.m_X},{player.Position.m_Y},{player.Position.m_Z}";

            return(data);
        }
예제 #3
0
        public void IncreaseHungerLevel(NWPlayer oPC, int amount, bool isTainted)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

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

            entity.CurrentHunger += amount;
            if (entity.CurrentHunger > entity.MaxHunger)
            {
                entity.CurrentHunger = entity.MaxHunger;
            }

            oPC.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE);
            });

            oPC.SendMessage("Hunger: " + _menu.BuildBar(entity.CurrentHunger, entity.MaxHunger, 100));
            _db.SaveChanges();

            if (isTainted)
            {
                if (_random.Random(100) + 1 <= 40)
                {
                    int ticks = 600 + _random.Random(300);

                    _customEffect.ApplyCustomEffect(oPC, oPC, CustomEffectType.FoodDisease, ticks, 0);
                }
            }
        }
예제 #4
0
 protected override void DoAction(NWPlayer user, float duration)
 {
     user.AssignCommand(() =>
     {
         _.ActionPlayAnimation(ANIMATION_LOOPING_DEAD_BACK, 1.0f, duration);
     });
 }
예제 #5
0
 public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
 {
     user.AssignCommand(() =>
     {
         _.ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY3);
     });
 }
예제 #6
0
        public bool Run(params object[] args)
        {
            NWCreature looter = _.GetLastDisturbed();
            NWItem     item   = _.GetInventoryDisturbItem();
            int        type   = _.GetInventoryDisturbType();

            looter.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f);
            });

            if (type == INVENTORY_DISTURB_TYPE_ADDED)
            {
                _item.ReturnItem(looter, item);
                looter.SendMessage("You cannot place items inside of corpses.");
            }
            else if (type == INVENTORY_DISTURB_TYPE_REMOVED)
            {
                NWItem copy = item.GetLocalObject("CORPSE_ITEM_COPY");

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

                item.DeleteLocalObject("CORPSE_ITEM_COPY");
            }


            return(true);
        }
예제 #7
0
 public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args)
 {
     user.AssignCommand(() =>
     {
         _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID);
     });
 }
예제 #8
0
        public void OnChestDisturbed(NWPlaceable oChest)
        {
            NWPlayer oPC = (_.GetLastDisturbed());

            if (!oPC.IsPlayer && !oPC.IsDM)
            {
                return;
            }

            string pcName      = oPC.Name;
            NWItem oItem       = (_.GetInventoryDisturbItem());
            int    disturbType = _.GetInventoryDisturbType();

            if (disturbType == NWScript.INVENTORY_DISTURB_TYPE_ADDED)
            {
                _.CopyItem(oItem.Object, oPC.Object, NWScript.TRUE);
                oItem.Destroy();
            }
            else if (disturbType == NWScript.INVENTORY_DISTURB_TYPE_REMOVED)
            {
                SaveChestInventory(oPC, oChest, false);
                string itemName = oItem.Name;
                if (string.IsNullOrWhiteSpace(itemName))
                {
                    itemName = "money";
                }

                float minSearchSeconds = 1.5f;
                float maxSearchSeconds = 4.5f;
                float searchDelay      = _random.RandomFloat() * (maxSearchSeconds - minSearchSeconds) + minSearchSeconds;

                oPC.AssignCommand(() =>
                {
                    _.ActionPlayAnimation(NWScript.ANIMATION_LOOPING_GET_LOW, 1.0f, searchDelay);
                });

                _.ApplyEffectToObject(NWScript.DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), oPC.Object, searchDelay);

                // Notify party members in the vicinity

                NWPlayer player = (_.GetFirstPC());
                while (player.IsValid)
                {
                    if (_.GetDistanceBetween(oPC.Object, player.Object) <= 20.0f &&
                        player.Area.Equals(oPC.Area) &&
                        _.GetFactionEqual(player.Object, oPC.Object) == NWScript.TRUE)
                    {
                        player.SendMessage(pcName + " found " + itemName + ".");
                    }

                    player = (_.GetNextPC());
                }
            }
        }
예제 #9
0
        public void CraftItem(NWPlayer oPC, NWPlaceable device)
        {
            var            model     = GetPlayerCraftingData(oPC);
            CraftBlueprint blueprint = _db.CraftBlueprints.Single(x => x.CraftBlueprintID == model.BlueprintID);

            if (blueprint == null)
            {
                return;
            }

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            if (!model.CanBuildItem)
            {
                oPC.SendMessage("You are missing one or more components...");
                return;
            }

            oPC.IsBusy = true;

            float modifiedCraftDelay = CalculateCraftingDelay(oPC, blueprint.SkillID);

            _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), oPC.Object, modifiedCraftDelay + 0.1f);
            oPC.AssignCommand(() =>
            {
                _.ClearAllActions();
                _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, modifiedCraftDelay);
            });
            device.DelayCommand(() =>
            {
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), device.Object);
            }, 1.0f * (modifiedCraftDelay / 2.0f));

            _nwnxPlayer.StartGuiTimingBar(oPC, modifiedCraftDelay, "");

            oPC.DelayCommand(() =>
            {
                try
                {
                    RunCreateItem(oPC, device);
                    oPC.IsBusy = false;
                }
                catch (Exception ex)
                {
                    _error.LogError(ex);
                }
            }, modifiedCraftDelay);
        }
예제 #10
0
        public void OnImpact(NWPlayer player, NWObject target, int perkLevel)
        {
            NWCreature npc = (target.Object);
            Effect     vfx = _.EffectVisualEffect(NWScript.VFX_IMP_CHARM);

            _.ApplyEffectToObject(NWScript.DURATION_TYPE_INSTANT, vfx, target.Object);

            player.AssignCommand(() =>
            {
                _.ActionPlayAnimation(NWScript.ANIMATION_FIREFORGET_TAUNT, 1f, 1f);
            });

            _enmity.AdjustEnmity(npc, player, 120);
        }
예제 #11
0
        public void CraftItem(NWPlayer oPC, NWPlaceable device)
        {
            var            model     = GetPlayerCraftingData(oPC);
            CraftBlueprint blueprint = _data.Single <CraftBlueprint>(x => x.ID == model.BlueprintID);

            if (blueprint == null)
            {
                return;
            }

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            if (!model.CanBuildItem)
            {
                oPC.SendMessage("You are missing one or more components...");
                return;
            }

            oPC.IsBusy = true;

            int   atmosphere         = CalculateAreaAtmosphereBonus(oPC.Area);
            float modifiedCraftDelay = CalculateCraftingDelay(oPC, blueprint.SkillID, atmosphere);

            oPC.AssignCommand(() =>
            {
                _.ClearAllActions();
                _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, modifiedCraftDelay);
            });
            _.DelayCommand(1.0f * (modifiedCraftDelay / 2.0f), () =>
            {
                _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), device.Object);
            });
            Effect immobilize = _.EffectCutsceneImmobilize();

            immobilize = _.TagEffect(immobilize, "CRAFTING_IMMOBILIZATION");
            _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, immobilize, oPC.Object);

            _nwnxPlayer.StartGuiTimingBar(oPC, modifiedCraftDelay, "");

            oPC.DelayEvent <CraftCreateItem>(
                modifiedCraftDelay,
                oPC);
        }
예제 #12
0
        private void StartSmelt(NWPlaceable forge, NWPlayer pc, NWItem item)
        {
            int charges = forge.GetLocalInt("FORGE_CHARGES");

            if (item.Resref == "power_core")
            {
                item.Destroy();
                charges += 10 + CalculatePerkCoalBonusCharges(pc) + GetPowerCoreDurability(item) * 2;
                forge.SetLocalInt("FORGE_CHARGES", charges);

                NWPlaceable flames = (forge.GetLocalObject("FORGE_FLAMES"));
                if (!flames.IsValid)
                {
                    Vector   flamePosition = _biowarePosition.GetChangedPosition(forge.Position, 0.36f, forge.Facing);
                    Location flameLocation = _.Location(forge.Area.Object, flamePosition, 0.0f);
                    flames = (_.CreateObject(NWScript.OBJECT_TYPE_PLACEABLE, "forge_flame", flameLocation));
                    forge.SetLocalObject("FORGE_FLAMES", flames.Object);
                }

                return;
            }
            else if (charges <= 0)
            {
                ReturnItemToPC(pc, item, "You must power the refinery with a power unit before refining.");
                return;
            }

            // Ready to smelt
            float baseCraftDelay = 18.0f - (18.0f * _perk.GetPCPerkLevel(pc, PerkType.SpeedyRefining) * 0.1f);

            pc.IsBusy = true;
            _nwnxPlayer.StartGuiTimingBar(pc, baseCraftDelay, string.Empty);

            // Any component bonuses on the ore get applied to the end product.
            var itemProperties = item.ItemProperties.Where(x =>
                                                           _.GetItemPropertyType(x) == (int)CustomItemPropertyType.ComponentBonus ||
                                                           _.GetItemPropertyType(x) == (int)CustomItemPropertyType.RecommendedLevel).ToList();

            string itemResref = item.Resref;

            pc.DelayEvent <CompleteSmelt>(baseCraftDelay, pc, itemResref, itemProperties);

            _.ApplyEffectToObject(NWScript.DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), pc.Object, baseCraftDelay);
            pc.AssignCommand(() => _.ActionPlayAnimation(NWScript.ANIMATION_LOOPING_GET_MID, 1.0f, baseCraftDelay));
            item.Destroy();
        }
예제 #13
0
        private void startSmelt(NWPlaceable forge, NWPlayer pc, NWItem item)
        {
            int charges = forge.GetLocalInt("FORGE_CHARGES");

            if (item.Resref == "coal")
            {
                item.Destroy();
                charges += 10 + CalculatePerkCoalBonusCharges(pc);
                forge.SetLocalInt("FORGE_CHARGES", charges);

                NWPlaceable flames = NWPlaceable.Wrap(forge.GetLocalObject("FORGE_FLAMES"));
                if (!flames.IsValid)
                {
                    Vector   flamePosition = _biowarePosition.GetChangedPosition(forge.Position, 0.36f, forge.Facing);
                    Location flameLocation = _.Location(forge.Area.Object, flamePosition, 0.0f);
                    flames = NWPlaceable.Wrap(_.CreateObject(OBJECT_TYPE_PLACEABLE, "forge_flame", flameLocation));
                    forge.SetLocalObject("FORGE_FLAMES", flames.Object);
                }

                return;
            }
            else if (charges <= 0)
            {
                ReturnItemToPC(pc, item, "You must light the forge with coal before smelting.");
                return;
            }
            item.Destroy();

            // Ready to smelt
            float baseCraftDelay = 18.0f - (_perk.GetPCPerkLevel(pc, PerkType.SpeedySmelter) * 0.1f);

            pc.IsBusy = true;
            forge.SetLocalObject("FORGE_USER", pc.Object);
            pc.SetLocalObject("FORGE", forge.Object);
            forge.SetLocalString("FORGE_ORE", item.Resref);

            _nwnxPlayer.StartGuiTimingBar(pc, baseCraftDelay, "cft_finish_smelt");

            _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), pc.Object, baseCraftDelay);
            pc.AssignCommand(() => _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, baseCraftDelay));
        }
예제 #14
0
        public void OnImpact(NWPlayer oPC, NWObject oTarget)
        {
            NWCreature npc = NWCreature.Wrap(oTarget.Object);
            Effect     vfx = _.EffectVisualEffect(VFX_IMP_CHARM);

            _.ApplyEffectToObject(DURATION_TYPE_INSTANT, vfx, oTarget.Object);

            oPC.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT, 1f, 1f);
            });

            _enmity.AdjustEnmity(npc, oPC, 120);

            // todo debugging
            EnmityTable table = _enmity.GetEnmityTable(npc);

            foreach (var x in table.Values)
            {
                Console.WriteLine(npc.Name + ", " + x.TargetObject.Name + ": Volatile = " + x.VolatileAmount + ", Cumulative: " + x.CumulativeAmount);
            }
            // todo end debugging
        }
예제 #15
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);
        }
예제 #16
0
        public void OnModuleActivatedItem()
        {
            NWPlayer user           = (_.GetItemActivator());
            NWItem   oItem          = (_.GetItemActivated());
            NWObject target         = (_.GetItemActivatedTarget());
            Location targetLocation = _.GetItemActivatedTargetLocation();

            string className = oItem.GetLocalString("JAVA_SCRIPT");

            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("ACTIVATE_JAVA_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("JAVA_ACTION_SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                className = oItem.GetLocalString("SCRIPT");
            }
            if (string.IsNullOrWhiteSpace(className))
            {
                return;
            }

            user.ClearAllActions();

            if (user.IsBusy)
            {
                user.SendMessage("You are busy.");
                return;
            }

            // Remove "Item." prefix if it exists.
            if (className.StartsWith("Item."))
            {
                className = className.Substring(5);
            }

            App.ResolveByInterface <IActionItem>("Item." + className, (item) =>
            {
                string invalidTargetMessage = item.IsValidTarget(user, oItem, target, targetLocation);
                if (!string.IsNullOrWhiteSpace(invalidTargetMessage))
                {
                    user.SendMessage(invalidTargetMessage);
                    return;
                }

                float maxDistance = item.MaxDistance(user, oItem, target, targetLocation);
                if (maxDistance > 0.0f)
                {
                    if (target.IsValid &&
                        (_.GetDistanceBetween(user.Object, target.Object) > maxDistance ||
                         user.Area.Resref != target.Area.Resref))
                    {
                        user.SendMessage("Your target is too far away.");
                        return;
                    }
                    else if (!target.IsValid &&
                             (_.GetDistanceBetweenLocations(user.Location, targetLocation) > maxDistance ||
                              user.Area.Resref != ((NWArea)_.GetAreaFromLocation(targetLocation)).Resref))
                    {
                        user.SendMessage("That location is too far away.");
                        return;
                    }
                }

                CustomData customData = item.StartUseItem(user, oItem, target, targetLocation);
                float delay           = item.Seconds(user, oItem, target, targetLocation, customData);
                int animationID       = item.AnimationID();
                bool faceTarget       = item.FaceTarget();
                Vector userPosition   = user.Position;

                user.AssignCommand(() =>
                {
                    user.IsBusy = true;
                    if (faceTarget)
                    {
                        _.SetFacingPoint(!target.IsValid ? _.GetPositionFromLocation(targetLocation) : target.Position);
                    }
                    if (animationID > 0)
                    {
                        _.ActionPlayAnimation(animationID, 1.0f, delay);
                    }
                });

                _nwnxPlayer.StartGuiTimingBar(user, delay, string.Empty);
                user.DelayEvent <FinishActionItem>(
                    delay,
                    className,
                    user,
                    oItem,
                    target,
                    targetLocation,
                    userPosition,
                    customData);
            });
        }
예제 #17
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);
        }
예제 #18
0
 public void DoAction(NWPlayer user, params string[] args)
 {
     user.AssignCommand(() => _.ActionPlayAnimation(NWScript.ANIMATION_LOOPING_SIT_CROSS, 1.0f, 9999));
 }
예제 #19
0
        public bool Run(params object[] args)
        {
            NWPlayer pc          = (NWPlayer)args[0];
            string   spellUUID   = Convert.ToString(args[1]);
            int      perkID      = (int)args[2];
            NWObject target      = (NWObject)args[3];
            int      pcPerkLevel = (int)args[4];

            Data.Entity.Perk  entity        = _data.Single <Data.Entity.Perk>(x => x.ID == perkID);
            CooldownCategory  cooldown      = _data.SingleOrDefault <CooldownCategory>(x => x.ID == entity.CooldownCategoryID);
            PerkExecutionType executionType = (PerkExecutionType)entity.ExecutionTypeID;

            return(App.ResolveByInterface <IPerk, bool>("Perk." + entity.ScriptName, perk =>
            {
                if (pc.GetLocalInt(spellUUID) == (int)SpellStatusType.Interrupted || // Moved during casting
                    pc.CurrentHP < 0 || pc.IsDead)                                   // Or is dead/dying
                {
                    pc.DeleteLocalInt(spellUUID);
                    return false;
                }

                pc.DeleteLocalInt(spellUUID);

                if (executionType == PerkExecutionType.ForceAbility ||
                    executionType == PerkExecutionType.CombatAbility ||
                    executionType == PerkExecutionType.Stance)
                {
                    perk.OnImpact(pc, target, pcPerkLevel);

                    if (entity.CastAnimationID != null && entity.CastAnimationID > 0)
                    {
                        pc.AssignCommand(() =>
                        {
                            _.ActionPlayAnimation((int)entity.CastAnimationID, 1f, 1f);
                        });
                    }

                    if (target.IsNPC)
                    {
                        _ability.ApplyEnmity(pc, (target.Object), entity);
                    }
                }
                else if (executionType == PerkExecutionType.QueuedWeaponSkill)
                {
                    _ability.HandleQueueWeaponSkill(pc, entity, perk);
                }


                // Adjust FP only if spell cost > 0
                Data.Entity.Player pcEntity = _data.Single <Data.Entity.Player>(x => x.ID == pc.GlobalID);
                if (perk.FPCost(pc, entity.BaseFPCost) > 0)
                {
                    pcEntity.CurrentFP = pcEntity.CurrentFP - perk.FPCost(pc, entity.BaseFPCost);
                    _data.SubmitDataChange(pcEntity, DatabaseActionType.Update);
                    pc.SendMessage(_color.Custom("FP: " + pcEntity.CurrentFP + " / " + pcEntity.MaxFP, 32, 223, 219));
                }

                bool hasChainspell = _customEffect.DoesPCHaveCustomEffect(pc, CustomEffectType.Chainspell) &&
                                     executionType == PerkExecutionType.ForceAbility;

                if (!hasChainspell)
                {
                    // Mark cooldown on category
                    _ability.ApplyCooldown(pc, cooldown, perk);
                }
                pc.IsBusy = false;
                pc.SetLocalInt(spellUUID, (int)SpellStatusType.Completed);

                return true;
            }));
        }
예제 #20
0
        private void ActivateAbility(NWPlayer pc,
                                     NWObject target,
                                     Data.Entity.Perk entity,
                                     IPerk perk,
                                     int pcPerkLevel,
                                     PerkExecutionType executionType)
        {
            string uuid               = Guid.NewGuid().ToString();
            var    effectiveStats     = _playerStat.GetPlayerItemEffectiveStats(pc);
            int    itemBonus          = effectiveStats.CastingSpeed;
            float  baseActivationTime = perk.CastingTime(pc, (float)entity.BaseCastingTime);
            float  activationTime     = baseActivationTime;
            int    vfxID              = -1;
            int    animationID        = -1;

            // Activation Bonus % - Shorten activation time.
            if (itemBonus < 0)
            {
                float activationBonus = Math.Abs(itemBonus) * 0.01f;
                activationTime = activationTime - activationTime * activationBonus;
            }
            // Activation Penalty % - Increase activation time.
            else if (itemBonus > 0)
            {
                float activationPenalty = Math.Abs(itemBonus) * 0.01f;
                activationTime = activationTime + activationTime * activationPenalty;
            }

            if (baseActivationTime > 0f && activationTime < 0.5f)
            {
                activationTime = 0.5f;
            }

            // Force ability armor penalties
            if (executionType == PerkExecutionType.ForceAbility)
            {
                float  armorPenalty   = 0.0f;
                string penaltyMessage = string.Empty;
                foreach (var item in pc.EquippedItems)
                {
                    if (item.CustomItemType == CustomItemType.HeavyArmor)
                    {
                        armorPenalty   = 2;
                        penaltyMessage = "Heavy armor slows your force activation speed by 100%.";
                        break;
                    }
                    else if (item.CustomItemType == CustomItemType.LightArmor)
                    {
                        armorPenalty   = 1.25f;
                        penaltyMessage = "Light armor slows your force activation speed by 25%.";
                    }
                }

                if (armorPenalty > 0.0f)
                {
                    activationTime = baseActivationTime * armorPenalty;
                    pc.SendMessage(penaltyMessage);
                }
            }

            if (_.GetActionMode(pc.Object, ACTION_MODE_STEALTH) == 1)
            {
                _.SetActionMode(pc.Object, ACTION_MODE_STEALTH, 0);
            }

            _.ClearAllActions();
            _biowarePosition.TurnToFaceObject(target, pc);

            if (executionType == PerkExecutionType.ForceAbility)
            {
                vfxID       = VFX_DUR_IOUNSTONE_YELLOW;
                animationID = ANIMATION_LOOPING_CONJURE1;
            }

            if (vfxID > -1)
            {
                var vfx = _.EffectVisualEffect(vfxID);
                vfx = _.TagEffect(vfx, "ACTIVATION_VFX");
                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, vfx, pc.Object, activationTime + 0.2f);
            }

            if (animationID > -1)
            {
                pc.AssignCommand(() => _.ActionPlayAnimation(animationID, 1.0f, activationTime - 0.1f));
            }

            pc.IsBusy = true;
            CheckForSpellInterruption(pc, uuid, pc.Position);
            pc.SetLocalInt(uuid, (int)SpellStatusType.Started);

            _nwnxPlayer.StartGuiTimingBar(pc, (int)activationTime, "");

            int perkID = entity.ID;

            pc.DelayEvent <FinishAbilityUse>(
                activationTime + 0.2f,
                pc,
                uuid,
                perkID,
                target,
                pcPerkLevel);
        }
예제 #21
0
        public void OnModuleActivatedItem()
        {
            NWPlayer oPC            = NWPlayer.Wrap(_.GetItemActivator());
            NWItem   oItem          = NWItem.Wrap(_.GetItemActivated());
            NWObject oTarget        = NWObject.Wrap(_.GetItemActivatedTarget());
            Location targetLocation = _.GetItemActivatedTargetLocation();

            string className = oItem.GetLocalString("JAVA_SCRIPT");

            if (className == string.Empty)
            {
                className = oItem.GetLocalString("ACTIVATE_JAVA_SCRIPT");
            }
            if (className == string.Empty)
            {
                className = oItem.GetLocalString("JAVA_ACTION_SCRIPT");
            }
            if (className == string.Empty)
            {
                className = oItem.GetLocalString("SCRIPT");
            }
            if (className == string.Empty)
            {
                return;
            }

            oPC.ClearAllActions();

            // Remove "Item." prefix if it exists.
            if (className.StartsWith("Item."))
            {
                className = className.Substring(5);
            }

            IActionItem item = App.ResolveByInterface <IActionItem>("Item." + className);

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are busy.");
                return;
            }

            string invalidTargetMessage = item.IsValidTarget(oPC, oItem, oTarget, targetLocation);

            if (!string.IsNullOrWhiteSpace(invalidTargetMessage))
            {
                oPC.SendMessage(invalidTargetMessage);
                return;
            }

            if (item.MaxDistance() > 0.0f)
            {
                if (_.GetDistanceBetween(oPC.Object, oTarget.Object) > item.MaxDistance() ||
                    oPC.Area.Resref != oTarget.Area.Resref)
                {
                    oPC.SendMessage("Your target is too far away.");
                    return;
                }
            }

            CustomData customData   = item.StartUseItem(oPC, oItem, oTarget, targetLocation);
            float      delay        = item.Seconds(oPC, oItem, oTarget, targetLocation, customData);
            int        animationID  = item.AnimationID();
            bool       faceTarget   = item.FaceTarget();
            Vector     userPosition = oPC.Position;

            oPC.AssignCommand(() =>
            {
                oPC.IsBusy = true;
                if (faceTarget)
                {
                    _.SetFacingPoint(oTarget.Position);
                }
                if (animationID > 0)
                {
                    _.ActionPlayAnimation(animationID, 1.0f, delay);
                }
            });

            _nwnxPlayer.StartGuiTimingBar(oPC, delay, string.Empty);
            oPC.DelayCommand(() =>
            {
                FinishActionItem(item, oPC, oItem, oTarget, targetLocation, userPosition, customData);
            }, delay);
        }
예제 #22
0
        public void CraftItem(NWPlayer oPC, NWPlaceable device, int blueprintID)
        {
            CraftBlueprint blueprint = _db.CraftBlueprints.Single(x => x.CraftBlueprintID == blueprintID);

            if (blueprint == null)
            {
                return;
            }
            bool requiresTools = false;
            bool foundTools    = false;

            if (oPC.IsBusy)
            {
                oPC.SendMessage("You are too busy right now.");
                return;
            }

            // Check for tools, if necessary.
            if (blueprint.CraftTierLevel > 0)
            {
                requiresTools = true;
                NWItem tools = NWItem.Wrap(device.GetLocalObject("CRAFT_DEVICE_TOOLS"));
                if (tools.IsValid)
                {
                    foundTools = true;
                }
            }

            if (requiresTools != foundTools)
            {
                oPC.SendMessage(_color.Red("Tools were not found. Please place the tools you wish to use inside the crafting device."));
                oPC.IsBusy = false;
                return;
            }
            oPC.IsBusy = true;

            bool allComponentsFound = CheckItemCounts(oPC, device, blueprint.CraftBlueprintComponents);

            if (allComponentsFound)
            {
                float modifiedCraftDelay = CalculateCraftingDelay(oPC, blueprint.SkillID);

                _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectCutsceneImmobilize(), oPC.Object, modifiedCraftDelay + 0.1f);
                oPC.AssignCommand(() =>
                {
                    _.ClearAllActions();
                    _.ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0f, modifiedCraftDelay);
                });
                device.DelayCommand(() =>
                {
                    _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM), device.Object);
                }, 1.0f * (modifiedCraftDelay / 2.0f));

                _nwnxPlayer.StartGuiTimingBar(oPC, modifiedCraftDelay, "");

                oPC.DelayCommand(() =>
                {
                    try
                    {
                        RunCreateItem(oPC, device, blueprintID);
                        oPC.IsBusy = false;
                    }
                    catch (Exception ex)
                    {
                        _error.LogError(ex);
                    }
                }, modifiedCraftDelay);
            }
            else
            {
                oPC.SendMessage(_color.Red("You are missing required components..."));
            }
        }