예제 #1
0
        private void CheckForMovement(NWPlayer oPC, Location location)
        {
            if (!oPC.IsValid || oPC.IsDead)
            {
                return;
            }

            string areaResref = oPC.Area.Resref;
            Vector position   = _.GetPositionFromLocation(location);

            if (areaResref != _.GetResRef(_.GetAreaFromLocation(location)) ||
                oPC.Facing != _.GetFacingFromLocation(location) ||
                oPC.Position.m_X != position.m_X ||
                oPC.Position.m_Y != position.m_Y ||
                oPC.Position.m_Z != position.m_Z)
            {
                foreach (Effect effect in oPC.Effects)
                {
                    int type = _.GetEffectType(effect);
                    if (type == EFFECT_TYPE_DAMAGE_REDUCTION || type == EFFECT_TYPE_SANCTUARY)
                    {
                        _.RemoveEffect(oPC.Object, effect);
                    }
                }
                return;
            }

            oPC.DelayCommand(() =>
            {
                CheckForMovement(oPC, location);
            }, 1.0f);
        }
예제 #2
0
        private void RunMeditate(NWPlayer oPC, Vector originalPosition, int amount)
        {
            Vector position = oPC.Position;

            if ((position.m_X != originalPosition.m_X ||
                 position.m_Y != originalPosition.m_Y ||
                 position.m_Z != originalPosition.m_Z) ||
                !CanMeditate(oPC) ||
                !oPC.IsValid)
            {
                oPC.SendMessage("You stop meditating.");
                oPC.IsBusy = false;
                return;
            }

            _ability.RestoreMana(oPC, amount);
            Effect vfx = _.EffectVisualEffect(VFX_IMP_HEAD_MIND);

            _.ApplyEffectToObject(DURATION_TYPE_INSTANT, vfx, oPC.Object);
            oPC.AssignCommand(() =>
            {
                _.ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0f, 6.1f);
            });
            oPC.DelayCommand(() =>
            {
                RunMeditate(oPC, originalPosition, amount);
            }, 6.0f);
        }
예제 #3
0
        private void ApplySanctuaryEffects(NWPlayer oPC)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }
            if (oPC.CurrentHP <= 0)
            {
                return;
            }
            if (oPC.Area.Tag == "ooc_area")
            {
                return;
            }

            Effect sanctuary = _.EffectSanctuary(99);
            Effect dr        = _.EffectDamageReduction(50, DAMAGE_POWER_PLUS_TWENTY);

            sanctuary = _.TagEffect(sanctuary, "AREA_ENTRY_SANCTUARY");
            dr        = _.TagEffect(dr, "AREA_ENTRY_DAMAGE_REDUCTION");

            _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, sanctuary, oPC.Object);
            _.ApplyEffectToObject(DURATION_TYPE_PERMANENT, dr, oPC.Object);
            Location location = oPC.Location;

            oPC.DelayCommand(() =>
            {
                CheckForMovement(oPC, location);
            }, 3.5f);
        }
예제 #4
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;
        }
예제 #5
0
        // Starts displaying a timing bar.
        // Will run a script at the end of the timing bar, if specified.
        public void StartGuiTimingBar(NWPlayer player, float seconds, string script)
        {
            // only one timing bar at a time!
            if (_.GetLocalInt(player.Object, "NWNX_PLAYER_GUI_TIMING_ACTIVE") == 1)
            {
                return;
            }

            string sFunc = "StartGuiTimingBar";

            NWNX_PushArgumentFloat(NWNX_Player, sFunc, seconds);
            NWNX_PushArgumentObject(NWNX_Player, sFunc, player.Object);

            NWNX_CallFunction(NWNX_Player, sFunc);

            int id = _.GetLocalInt(player.Object, "NWNX_PLAYER_GUI_TIMING_ID") + 1;

            _.SetLocalInt(player.Object, "NWNX_PLAYER_GUI_TIMING_ACTIVE", id);
            _.SetLocalInt(player.Object, "NWNX_PLAYER_GUI_TIMING_ID", id);

            player.DelayCommand(() =>
            {
                StopGuiTimingBar(player, script, -1);
            }, seconds);
        }
예제 #6
0
        public bool Run(params object[] args)
        {
            NWPlaceable plc           = NWPlaceable.Wrap(Object.OBJECT_SELF);
            NWPlayer    oPC           = NWPlayer.Wrap(_.GetLastAttacker());
            NWItem      oWeapon       = NWItem.Wrap(_.GetLastWeaponUsed(oPC.Object));
            int         type          = oWeapon.BaseItemType;
            int         resourceCount = plc.GetLocalInt("RESOURCE_COUNT");

            if (resourceCount <= -1)
            {
                resourceCount = _random.Random(3) + 3;
                plc.SetLocalInt("RESOURCE_COUNT", resourceCount);
            }

            if (type == BASE_ITEM_INVALID)
            {
                oWeapon = oPC.RightHand;
            }

            int activityID = plc.GetLocalInt("RESOURCE_ACTIVITY");

            string improperWeaponMessage = "";
            bool   usingCorrectWeapon    = true;

            if (activityID == 1) // 1 = Logging
            {
                usingCorrectWeapon = oWeapon.CustomItemType == CustomItemType.Blade ||
                                     oWeapon.CustomItemType == CustomItemType.TwinBlade ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlade ||
                                     oWeapon.CustomItemType == CustomItemType.FinesseBlade ||
                                     oWeapon.CustomItemType == CustomItemType.Polearm;
                improperWeaponMessage = "You must be using a blade to harvest this object.";
            }
            else if (activityID == 2) // Mining
            {
                usingCorrectWeapon = oWeapon.CustomItemType == CustomItemType.Blade ||
                                     oWeapon.CustomItemType == CustomItemType.TwinBlade ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlade ||
                                     oWeapon.CustomItemType == CustomItemType.FinesseBlade ||
                                     oWeapon.CustomItemType == CustomItemType.Polearm ||
                                     oWeapon.CustomItemType == CustomItemType.Blunt ||
                                     oWeapon.CustomItemType == CustomItemType.HeavyBlunt;
                improperWeaponMessage = "You must be using a blade or a blunt weapon to harvest this object.";
            }

            if (!usingCorrectWeapon)
            {
                plc.IsPlot = true;
                oPC.SendMessage(_color.Red(improperWeaponMessage));
                oPC.SetLocalInt("NOT_USING_CORRECT_WEAPON", 1);
                oPC.ClearAllActions();
                oPC.DelayCommand(() => plc.IsPlot = false, 1.0f);
            }

            return(true);
        }
예제 #7
0
        public void ShowMOTD(NWPlayer player)
        {
            ServerConfiguration config = _db.ServerConfigurations.First();
            string message             = _color.Green("Welcome to " + config.ServerName + "!\n\nMOTD: ") + _color.White(config.MessageOfTheDay);

            player.DelayCommand(() =>
            {
                player.SendMessage(message);
            }, 6.5f);
        }
예제 #8
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);
        }
예제 #9
0
        private void ForceEquipFistGlove(NWPlayer oPC)
        {
            oPC.DelayCommand(() =>
            {
                if (!oPC.Arms.IsValid)
                {
                    oPC.ClearAllActions();
                    NWItem glove = NWItem.Wrap(_.CreateItemOnObject("fist", oPC.Object));
                    glove.SetLocalInt("UNBREAKABLE", 1);

                    oPC.AssignCommand(() => _.ActionEquipItem(glove.Object, INVENTORY_SLOT_ARMS));
                }
            }, 1.0f);
        }
예제 #10
0
        private void HandleTriggerAndPlaceableQuestLogic(NWPlayer oPC, NWObject oObject)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }
            string questMessage  = oObject.GetLocalString("QUEST_MESSAGE");
            int    questID       = oObject.GetLocalInt("QUEST_ID");
            int    questSequence = oObject.GetLocalInt("QUEST_SEQUENCE");

            if (questID <= 0)
            {
                oPC.SendMessage("QUEST_ID variable not set on object. Please inform admin this quest is bugged.");
                return;
            }

            if (questSequence <= 0)
            {
                oPC.SendMessage("QUEST_SEQUENCE variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            PCQuestStatus pcQuestStatus = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            if (pcQuestStatus == null)
            {
                return;
            }

            QuestState questState = pcQuestStatus.CurrentQuestState;

            if (questState.Sequence == questSequence ||
                (questState.QuestTypeID != (int)QuestType.UseObject &&
                 questState.QuestTypeID != (int)QuestType.ExploreArea))
            {
                return;
            }


            if (!string.IsNullOrWhiteSpace(questMessage))
            {
                oPC.DelayCommand(() =>
                {
                    oPC.SendMessage(questMessage);
                }, 1.0f);
            }

            AdvanceQuestState(oPC, questID);
        }
예제 #11
0
        private void PerformMigration(NWPlayer oPC)
        {
            PlayerCharacter entity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);

            for (int version = entity.VersionNumber + 1; version <= PlayerVersionNumber; version++)
            {
                Dictionary <string, PCMigrationItem> itemMap = new Dictionary <string, PCMigrationItem>();
                List <int>  stripItemList = new List <int>();
                PCMigration migration     = _db.PCMigrations.Single(x => x.PCMigrationID == version);

                foreach (PCMigrationItem item in migration.PCMigrationItems)
                {
                    if (!string.IsNullOrWhiteSpace(item.CurrentResref))
                    {
                        itemMap[item.CurrentResref] = item;
                    }
                    else if (item.BaseItemTypeID > -1 && item.StripItemProperties)
                    {
                        stripItemList.Add(item.BaseItemTypeID);
                    }
                }

                for (int slot = 0; slot < NUM_INVENTORY_SLOTS; slot++)
                {
                    NWItem item = NWItem.Wrap(_.GetItemInSlot(slot, oPC.Object));
                    ProcessItem(oPC, item, itemMap, stripItemList);
                }

                foreach (NWItem item in oPC.InventoryItems)
                {
                    ProcessItem(oPC, item, itemMap, stripItemList);
                }

                RunCustomMigrationProcess(oPC, version);
                entity = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID);
                entity.VersionNumber = version;
                _db.SaveChanges();
                oPC.SetLocalInt("MIGRATION_SYSTEM_LOGGED_IN_ONCE", TRUE);

                long   overflowCount = _db.PCOverflowItems.LongCount(x => x.PlayerID == oPC.GlobalID);
                string message       = _color.Green("Your character has been updated!" +
                                                    (overflowCount > 0 ? " Items which could not be created have been placed into overflow inventory. You can access this from the rest menu." : ""));

                oPC.DelayCommand(() =>
                {
                    oPC.FloatingText(message);
                }, 8.0f);
            }
        }
예제 #12
0
        private void CheckForSpellInterruption(NWPlayer pc, string spellUUID, Vector position)
        {
            Vector currentPosition = pc.Position;

            if (currentPosition.m_X != position.m_X ||
                currentPosition.m_Y != position.m_Y ||
                currentPosition.m_Z != position.m_Z)
            {
                _nwnxPlayer.StopGuiTimingBar(pc, "", -1);
                pc.IsBusy = false;
                pc.SetLocalInt(spellUUID, SPELL_STATUS_INTERRUPTED);
                return;
            }

            pc.DelayCommand(() => CheckForSpellInterruption(pc, spellUUID, position), 1.0f);
        }
예제 #13
0
        private void HandleQueueWeaponSkill(NWPlayer pc, Data.Entities.Perk entity, IPerk ability)
        {
            string queueUUID = Guid.NewGuid().ToString();

            pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.PerkID);
            pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID);
            pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack.");

            ApplyCooldown(pc, entity.CooldownCategory, ability);

            // Player must attack within 30 seconds after queueing or else it wears off.
            pc.DelayCommand(() =>
            {
                if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID)
                {
                    pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL");
                    pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID");
                    pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued.");
                }
            }, 30.0f);
        }
예제 #14
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);
        }
예제 #15
0
        private void DeathFunction(NWPlayer oPC, int nDC)
        {
            if (!oPC.IsValid)
            {
                return;
            }
            int iHP = oPC.CurrentHP;

            //Player Rolls a random number between 1 and 20+ConMod
            int iRoll = 20 + oPC.ConstitutionModifier;

            iRoll = _random.Random(iRoll) + 1;

            //Sanity Check
            if (nDC > 30)
            {
                nDC = 30;
            }
            else if (nDC < 4)
            {
                nDC = 4;
            }

            if (iHP <= 0)
            {
                if (iRoll >= nDC) //Stabilize
                {
                    nDC -= 2;
                    _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(1), oPC.Object);
                    oPC.DelayCommand(() =>
                    {
                        DeathFunction(oPC, nDC);
                    }, 3.0f);
                }
                else  //Failed!
                {
                    if (_random.Random(2) + 1 == 1)
                    {
                        nDC++;
                    }
                    Effect eResult = _.EffectDamage(1);

                    //Death!
                    if (iHP <= -9)
                    {
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_IMP_DEATH), oPC.Object);
                        _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectDeath(), oPC.Object);
                        return;
                    }
                    else
                    {
                        oPC.SendMessage(_color.Orange("You failed to stabilize this round."));
                    }
                    _.ApplyEffectToObject(DURATION_TYPE_INSTANT, eResult, oPC.Object);

                    oPC.DelayCommand(() =>
                    {
                        DeathFunction(oPC, nDC);
                    }, 3.0f);
                }
            }
        }
예제 #16
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);
        }
예제 #17
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..."));
            }
        }
예제 #18
0
        public void InitializePlayer(NWPlayer player)
        {
            if (player == null)
            {
                throw new ArgumentNullException(nameof(player));
            }
            if (player.Object == null)
            {
                throw new ArgumentNullException(nameof(player.Object));
            }
            if (!player.IsPlayer)
            {
                return;
            }

            if (!player.IsInitializedAsPlayer)
            {
                player.DestroyAllInventoryItems();
                player.InitializePlayer();
                _.AssignCommand(player.Object, () => _.TakeGoldFromCreature(_.GetGold(player.Object), player.Object, 1));

                player.DelayCommand(() =>
                {
                    _.GiveGoldToCreature(player.Object, 100);
                }, 0.5f);


                NWItem knife = NWItem.Wrap(_.CreateItemOnObject("survival_knife", player.Object));
                knife.Name          = player.Name + "'s Survival Knife";
                knife.IsCursed      = true;
                knife.MaxDurability = 5;
                knife.Durability    = 5;

                NWItem darts = NWItem.Wrap(_.CreateItemOnObject("nw_wthdt001", player.Object, 50)); // 50x Dart
                darts.Name     = "Starting Darts";
                darts.IsCursed = true;

                NWItem book = NWItem.Wrap(_.CreateItemOnObject("player_guide", player.Object));
                book.Name     = player.Name + "'s Player Guide";
                book.IsCursed = true;

                NWItem dyeKit = NWItem.Wrap(_.CreateItemOnObject("tk_omnidye", player.Object));
                dyeKit.IsCursed = true;

                int numberOfFeats = _nwnxCreature.GetFeatCount(player);
                for (int currentFeat = numberOfFeats; currentFeat >= 0; currentFeat--)
                {
                    _nwnxCreature.RemoveFeat(player, _nwnxCreature.GetFeatByIndex(player, currentFeat - 1));
                }

                _nwnxCreature.SetClassByPosition(player, 0, CLASS_TYPE_FIGHTER);
                _nwnxCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_LIGHT, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_MEDIUM, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_ARMOR_PROFICIENCY_HEAVY, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_SHIELD_PROFICIENCY, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_EXOTIC, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_MARTIAL, 1);
                _nwnxCreature.AddFeatByLevel(player, FEAT_WEAPON_PROFICIENCY_SIMPLE, 1);
                _nwnxCreature.AddFeatByLevel(player, (int)CustomFeatType.StructureTool, 1);
                _nwnxCreature.AddFeatByLevel(player, (int)CustomFeatType.OpenRestMenu, 1);

                for (int iCurSkill = 1; iCurSkill <= 27; iCurSkill++)
                {
                    _nwnxCreature.SetSkillRank(player, iCurSkill - 1, 0);
                }
                _.SetFortitudeSavingThrow(player.Object, 0);
                _.SetReflexSavingThrow(player.Object, 0);
                _.SetWillSavingThrow(player.Object, 0);

                int classID = _.GetClassByPosition(1, player.Object);

                for (int index = 0; index <= 255; index++)
                {
                    _nwnxCreature.RemoveKnownSpell(player, classID, 0, index);
                }

                PlayerCharacter entity = player.ToEntity();
                _db.PlayerCharacters.Add(entity);
                _db.SaveChanges();

                _db.StoredProcedure("InsertAllPCSkillsByID",
                                    new SqlParameter("PlayerID", player.GlobalID));

                _skill.ApplyStatChanges(player, null, true);

                _.DelayCommand(1.0f, () => _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectHeal(999), player.Object));

                InitializeHotBar(player);
            }
        }
예제 #19
0
        public void OnCreatureDeath(NWCreature creature)
        {
            int npcGroupID = creature.GetLocalInt("NPC_GROUP");

            if (npcGroupID <= 0)
            {
                return;
            }

            NWObject oKiller = NWObject.Wrap(_.GetLastKiller());

            if (_.GetIsPC(oKiller.Object) == FALSE || _.GetIsDM(oKiller.Object) == TRUE)
            {
                return;
            }

            string areaResref = creature.Area.Resref;

            NWPlayer oPC = NWPlayer.Wrap(_.GetFirstFactionMember(oKiller.Object));

            while (oPC.IsValid)
            {
                if (areaResref != oPC.Area.Resref)
                {
                    continue;
                }
                if (_.GetDistanceBetween(creature.Object, oPC.Object) == 0.0f || _.GetDistanceBetween(creature.Object, oPC.Object) > 20.0f)
                {
                    continue;
                }

                List <PCQuestKillTargetProgress> killTargets = _db.PCQuestKillTargetProgresses.Where(x => x.PlayerID == oPC.GlobalID && x.NPCGroupID == npcGroupID).ToList();

                foreach (PCQuestKillTargetProgress kt in killTargets)
                {
                    kt.RemainingToKill--;
                    string targetGroupName = kt.NPCGroup.Name;
                    string questName       = kt.PcQuestStatus.Quest.Name;
                    string updateMessage   = "[" + questName + "] " + targetGroupName + " remaining: " + kt.RemainingToKill;

                    if (kt.RemainingToKill <= 0)
                    {
                        _db.PCQuestKillTargetProgresses.Remove(kt);
                        updateMessage += " " + _color.Green(" {COMPLETE}");

                        if (kt.PcQuestStatus.PCQuestKillTargetProgresses.Count - 1 <= 0)
                        {
                            AdvanceQuestState(oPC, kt.PcQuestStatus.QuestID);
                        }
                    }

                    _db.SaveChanges();
                    string finalMessage = updateMessage;
                    var    pc           = oPC;
                    oPC.DelayCommand(() =>
                    {
                        pc.SendMessage(finalMessage);
                    }, 1.0f);
                }

                oPC = NWPlayer.Wrap(_.GetNextFactionMember(oKiller.Object));
            }
        }
예제 #20
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);
        }