public static void HandleQueueWeaponSkill(NWPlayer pc, Data.Entity.Perk entity, IPerkHandler ability, int spellFeatID) { int? cooldownCategoryID = ability.CooldownCategoryID(pc, entity.CooldownCategoryID, spellFeatID); var cooldownCategory = DataService.Get <CooldownCategory>(cooldownCategoryID); string queueUUID = Guid.NewGuid().ToString(); pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.ID); pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID); pc.SetLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID", spellFeatID); pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack."); ApplyCooldown(pc, cooldownCategory, ability, spellFeatID); // Player must attack within 30 seconds after queueing or else it wears off. _.DelayCommand(30f, () => { if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID) { pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued."); } }); }
public void OnModuleEnter() { NWPlayer player = _.GetEnteringObject(); if (!player.IsPlayer) { return; } var dbPlayer = _data.Single <Player>(x => x.ID == player.GlobalID); player.SetLocalInt("DISPLAY_HOLONET", dbPlayer.DisplayHolonet ? TRUE : FALSE); player.SetLocalInt("DISPLAY_DISCORD", dbPlayer.DisplayDiscord ? TRUE : FALSE); }
private static void OnModuleUseFeat() { NWPlayer pc = Object.OBJECT_SELF; int featID = NWNXEvents.OnFeatUsed_GetFeatID(); if (featID != (int)CustomFeatType.RenameCraftedItem) { return; } pc.ClearAllActions(); bool isSetting = pc.GetLocalInt("CRAFT_RENAMING_ITEM") == TRUE; NWItem renameItem = NWNXEvents.OnFeatUsed_GetTarget().Object; if (isSetting) { pc.SendMessage("You are no longer naming an item."); pc.DeleteLocalInt("CRAFT_RENAMING_ITEM"); pc.DeleteLocalObject("CRAFT_RENAMING_ITEM_OBJECT"); return; } string crafterPlayerID = renameItem.GetLocalString("CRAFTER_PLAYER_ID"); if (string.IsNullOrWhiteSpace(crafterPlayerID) || new Guid(crafterPlayerID) != pc.GlobalID) { pc.SendMessage("You may only rename items which you have personally crafted."); return; } pc.SetLocalInt("CRAFT_RENAMING_ITEM", TRUE); pc.SetLocalObject("CRAFT_RENAMING_ITEM_OBJECT", renameItem); pc.SendMessage("Please enter in a name for this item. Length should be between 3 and 64 characters. Use this feat again to cancel this procedure."); }
private void LoadHeader() { NWPlayer player = GetPC(); player.SetLocalInt("ITEM_RENAMING_LISTENING", TRUE); NWItem item = player.GetLocalObject("ITEM_BEING_RENAMED"); string originalName = item.GetLocalString("RENAMED_ITEM_ORIGINAL_NAME"); if (string.IsNullOrWhiteSpace(originalName)) { originalName = item.Name; } string currentName = item.Name; string renamingName = player.GetLocalString("RENAMED_ITEM_NEW_NAME"); if (string.IsNullOrWhiteSpace(renamingName)) { renamingName = "{UNSPECIFIED}"; } string header = "You are renaming an item.\n\n"; header += ColorTokenService.Green("Original Name: ") + originalName + "\n"; header += ColorTokenService.Green("Current Name: ") + currentName + "\n"; header += ColorTokenService.Green("New Name: ") + renamingName + "\n"; header += "Type in a new name, click 'Refresh', and then select 'Change Name' to make the changes. Click 'Reset Name' to switch back to the item's original name."; SetPageHeader("MainPage", header); }
private static void CheckForSpellInterruption(NWPlayer pc, string spellUUID, Vector position) { if (pc.GetLocalInt(spellUUID) == (int)SpellStatusType.Completed) { return; } Vector currentPosition = pc.Position; if (currentPosition.m_X != position.m_X || currentPosition.m_Y != position.m_Y || currentPosition.m_Z != position.m_Z) { var effect = pc.Effects.SingleOrDefault(x => _.GetEffectTag(x) == "ACTIVATION_VFX"); if (effect != null) { _.RemoveEffect(pc, effect); } NWNXPlayer.StopGuiTimingBar(pc, "", -1); pc.IsBusy = false; pc.SetLocalInt(spellUUID, (int)SpellStatusType.Interrupted); pc.SendMessage("Your ability has been interrupted."); return; } _.DelayCommand(0.5f, () => { CheckForSpellInterruption(pc, spellUUID, position); }); }
public static void SetMapPin(NWPlayer oPC, string text, float positionX, float positionY, NWArea area, string tag) { int numberOfMapPins = GetNumberOfMapPins(oPC); int storeAtIndex = -1; for (int index = 0; index < numberOfMapPins; index++) { MapPin mapPin = GetMapPin(oPC, index); if (string.IsNullOrWhiteSpace(mapPin.Text)) { storeAtIndex = index; break; } } if (storeAtIndex == -1) { numberOfMapPins++; storeAtIndex = numberOfMapPins - 1; } storeAtIndex++; oPC.SetLocalString("NW_MAP_PIN_NTRY_" + storeAtIndex, text); oPC.SetLocalFloat("NW_MAP_PIN_XPOS_" + storeAtIndex, positionX); oPC.SetLocalFloat("NW_MAP_PIN_YPOS_" + storeAtIndex, positionY); oPC.SetLocalObject("NW_MAP_PIN_AREA_" + storeAtIndex, area.Object); oPC.SetLocalInt("NW_TOTAL_MAP_PINS", numberOfMapPins); if (tag != null) { oPC.SetLocalString("CUSTOM_NW_MAP_PIN_TAG_" + storeAtIndex, tag); } }
public bool Run(params object[] args) { NWPlayer player = GetEnteringPlayer(); if (player.IsDM) { App.GetAppState().ConnectedDMs.Add(player); } player.DeleteLocalInt("IS_CUSTOMIZING_ITEM"); _.ExecuteScript("dmfi_onclienter ", Object.OBJECT_SELF); // DMFI also calls "x3_mod_def_enter" _playerValidation.OnModuleEnter(); _player.InitializePlayer(player); _data.CachePlayerData(player); _skill.OnModuleEnter(); _player.LoadCharacter(player); _migration.OnModuleEnter(); _player.ShowMOTD(player); ApplyGhostwalk(); _quest.OnClientEnter(); _activityLogging.OnModuleClientEnter(); ApplyScriptEvents(player); _mapPin.OnModuleClientEnter(); _objectVisibility.OnClientEnter(); _customEffect.OnModuleEnter(); _chatText.OnModuleEnter(); _race.OnModuleEnter(); player.SetLocalInt("LOGGED_IN_ONCE", TRUE); return(true); }
public void OnImpact(NWPlayer player, NWObject target, int perkLevel, int spellFeatID) { float minimum = player.Facing - 20; float maximum = player.Facing + 20; if (target.Facing >= minimum && target.Facing <= maximum) { // Mark the player as committing a sneak attack. // This is later picked up in the OnApplyDamage event. player.SetLocalInt("SNEAK_ATTACK_ACTIVE", 1); } else { player.SetLocalInt("SNEAK_ATTACK_ACTIVE", 2); } }
public void OnImpact(NWPlayer oPC, NWObject oTarget) { float minimum = oPC.Facing - 20; float maximum = oPC.Facing + 20; if (oTarget.Facing >= minimum && oTarget.Facing <= maximum) { // Mark the player as committing a sneak attack. // This is later picked up in the OnApplyDamage event. oPC.SetLocalInt("SNEAK_ATTACK_ACTIVE", 1); } else { oPC.SetLocalInt("SNEAK_ATTACK_ACTIVE", 2); } }
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); }
private void BuildTurnOptions(NWPlayer pc) { // Draw a card. int score = pc == game.player1 ? game.player1Score : game.player2Score; int card = game.DrawCard(); score += card; game.lastCardPlayed = card; pc.FloatingText("You drew a " + card + " putting your score at " + score); if (pc == game.player1) { game.player1Score = score; } else { game.player2Score = score; } // Since we're having a turn, we can't be the one standing... bool bStand = game.player1Standing || game.player2Standing; string header = "Your score is at " + score + ". " + (bStand ? "The other player is standing. " : "") + "What do you want to do?"; SpeakString(pc.Name + " draws a " + card + " from the deck. Their score is now " + score); if (pc.GetLocalInt("PAZAAK_REMINDED") == 0) { pc.SendMessage("(Pazaak Rules Reminder: highest score under 21 wins, ending your turn at 21+ loses you the round. You may play up to one card from your hand each turn. A standing player does not get to play again, but ending your turn means you will have to draw at least one more card.)"); pc.SetLocalInt("PAZAAK_REMINDED", 1); } SetPageHeader("MainPage", header); ClearPageResponses("MainPage"); List <int> sideDeck = pc == game.player1 ? game.player1SideDeck : game.player2SideDeck; // Build options from the side deck. foreach (int sideCard in sideDeck) { if ((sideCard > 100 && sideCard < 107) || sideCard == 203) { // Card can be played either of two ways. AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard) + " as positive", true, sideCard); AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard) + " as negative", true, sideCard); } else { AddResponseToPage("MainPage", "Play card from side deck: " + PazaakService.Display(sideCard), true, sideCard); } } AddResponseToPage("MainPage", "End Turn", score < 21); AddResponseToPage("MainPage", "Stand"); }
public static void OnActionsTaken(int nodeID) { NWPlayer player = (_.GetPCSpeaker()); PlayerDialog dialog = LoadPlayerDialog(player.GlobalID); using (new Profiler(nameof(DialogService) + "." + nameof(OnActionsTaken) + "." + dialog.ActiveDialogName)) { IConversation convo = GetConversation(dialog.ActiveDialogName); int selectionNumber = nodeID + 1; int responseID = nodeID + (NumberOfResponsesPerPage * dialog.PageOffset); if (selectionNumber == NumberOfResponsesPerPage + 1) // Next page { dialog.PageOffset = dialog.PageOffset + 1; } else if (selectionNumber == NumberOfResponsesPerPage + 2) // Previous page { dialog.PageOffset = dialog.PageOffset - 1; } else if (selectionNumber == NumberOfResponsesPerPage + 3) // Back { string currentPageName = dialog.CurrentPageName; var previous = dialog.NavigationStack.Pop(); // This might be a little confusing but we're passing the active page as the "old page" to the Back() method. // This is because we need to run any dialog-specific clean up prior to moving the conversation backwards. convo.Back(player, currentPageName, previous.PageName); // Previous page was in a different conversation. Switch to it. if (previous.DialogName != dialog.ActiveDialogName) { LoadConversation(player, dialog.DialogTarget, previous.DialogName, dialog.DialogNumber); dialog = LoadPlayerDialog(player.GlobalID); dialog.ResetPage(); dialog.CurrentPageName = previous.PageName; dialog.PageOffset = 0; // ActiveDialogName will have changed by this point. Get the new conversation. convo = GetConversation(dialog.ActiveDialogName); convo.Initialize(); player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1); } // Otherwise it's in the same conversation. Switch to that. else { dialog.CurrentPageName = previous.PageName; dialog.PageOffset = 0; } } else if (selectionNumber != NumberOfResponsesPerPage + 4) // End { convo.DoAction(player, dialog.CurrentPageName, responseID + 1); } } }
private static void OnModuleEnter() { NWPlayer player = _.GetEnteringObject(); if (!player.IsPlayer) { return; } var dbPlayer = DataService.Player.GetByID(player.GlobalID); player.SetLocalInt("DISPLAY_HOLONET", dbPlayer.DisplayHolonet ? TRUE : FALSE); }
public void OnImpact(NWPlayer player, NWObject target, int perkLevel) { // Mark the player as performing a recovery blast. // This is later picked up in the OnApplyDamage event to reduce all damage to 0. player.SetLocalInt("RECOVERY_BLAST_ACTIVE", 1); var members = player.PartyMembers.Where(x => _.GetDistanceBetween(x, target) <= 10.0f); int luck = _perk.GetPCPerkLevel(player, PerkType.Lucky); foreach (var member in members) { HealTarget(member, perkLevel, luck); } }
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); } }
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); }
// ReSharper disable once UnusedMember.Local private static void Main() { // The order of the following procedures matters. NWPlayer player = _.GetEnteringObject(); using (new Profiler(nameof(mod_on_enter) + ":AddDMToCache")) { if (player.IsDM) { AppCache.ConnectedDMs.Add(player); } } using (new Profiler(nameof(mod_on_enter) + ":BiowareDefault")) { player.DeleteLocalInt("IS_CUSTOMIZING_ITEM"); _.ExecuteScript("dmfi_onclienter ", NWGameObject.OBJECT_SELF); // DMFI also calls "x3_mod_def_enter" } using (new Profiler(nameof(mod_on_enter) + ":PlayerValidation")) { PlayerValidationService.OnModuleEnter(); } using (new Profiler(nameof(mod_on_enter) + ":InitializePlayer")) { PlayerService.InitializePlayer(player); } using (new Profiler(nameof(mod_on_enter) + ":CachePlayerData")) { //DataService.CachePlayerData(player); } using (new Profiler(nameof(mod_on_enter) + ":SkillServiceEnter")) { SkillService.OnModuleEnter(); } using (new Profiler(nameof(mod_on_enter) + ":PerkServiceEnter")) { PerkService.OnModuleEnter(); } MessageHub.Instance.Publish(new OnModuleEnter()); player.SetLocalInt("LOGGED_IN_ONCE", _.TRUE); }
private void RequestRewardSelectionFromPC(NWPlayer player, NWObject questGiver) { if (!player.IsPlayer) { return; } if (AllowRewardSelection) { player.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", QuestID); DialogService.StartConversation(player, player, "QuestRewardSelection"); } else { Complete(player, questGiver, null); } }
public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { var player = _data.Get <Player>(user.GlobalID); player.DisplayDiscord = !player.DisplayDiscord; user.SetLocalInt("DISPLAY_DISCORD", player.DisplayDiscord ? 1 : 0); _data.SubmitDataChange(player, DatabaseActionType.Update); if (player.DisplayDiscord) { user.SendMessage("Discord chat: " + _color.Green("ENABLED")); } else { user.SendMessage("Discord chat: " + _color.Red("DISABLED")); } }
public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { var player = DataService.Player.GetByID(user.GlobalID); player.DisplayHolonet = !player.DisplayHolonet; user.SetLocalInt("DISPLAY_HOLONET", player.DisplayHolonet ? 1 : 0); DataService.SubmitDataChange(player, DatabaseActionType.Update); if (player.DisplayHolonet) { user.SendMessage("Holonet chat: " + ColorTokenService.Green("ENABLED")); } else { user.SendMessage("Holonet chat: " + ColorTokenService.Red("DISABLED")); } }
private static void RequestRewardSelectionFromPC(NWPlayer oPC, NWObject questOwner, int questID) { if (!oPC.IsPlayer) { return; } Quest quest = DataService.Single <Quest>(x => x.ID == questID); if (quest.AllowRewardSelection) { oPC.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", questID); DialogService.StartConversation(oPC, oPC, "QuestRewardSelection"); } else { CompleteQuest(oPC, questOwner, questID, null); } }
private void RequestRewardSelectionFromPC(NWPlayer oPC, int questID) { if (!oPC.IsPlayer) { return; } Quest quest = _db.Quests.Single(x => x.QuestID == questID); if (quest.AllowRewardSelection) { oPC.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", questID); _dialog.StartConversation(oPC, oPC, "QuestRewardSelection"); } else { QuestState lastState = quest.QuestStates.ElementAt(quest.QuestStates.Count - 1); _.AddJournalQuestEntry(quest.JournalTag, lastState.JournalStateID, oPC.Object, FALSE); CompleteQuest(oPC, questID, null); } }
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); }
private static void OnModuleClientEnter() { NWPlayer oPC = (_.GetEnteringObject()); if (!oPC.IsPlayer) { return; } if (oPC.GetLocalInt("MAP_PINS_LOADED") == 1) { return; } List <PCMapPin> pins = DataService.Where <PCMapPin>(x => x.PlayerID == oPC.GlobalID).ToList(); foreach (PCMapPin pin in pins) { NWArea area = (_.GetObjectByTag(pin.AreaTag)); SetMapPin(oPC, pin.NoteText, (float)pin.PositionX, (float)pin.PositionY, area); } oPC.SetLocalInt("MAP_PINS_LOADED", 1); }
public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { if (!user.IsPlayer) { return; } //Checks if the player has Plasma Cell if (!_.GetHasFeat(Feat.PlasmaCell, user)) { user.SendMessage(ColorTokenService.Red("You do not have the perk: Plasma Cell.")); return; } //Checks if the player has toggled plasma cell off if (user.GetLocalBool("PLASMA_CELL_TOGGLE_OFF") == false) { user.SetLocalInt("PLASMA_CELL_TOGGLE_OFF", 1); user.SendMessage(ColorTokenService.Red("Plasma Cell is now toggled off.")); return; } //Checks if plasma cell has been toggled off else if (user.GetLocalInt("PLASMA_CELL_TOGGLE_OFF") > 0) { user.DeleteLocalInt("PLASMA_CELL_TOGGLE_OFF"); user.SendMessage(ColorTokenService.Green("Plasma Cell is now toggled on!")); return; } //If the above aren't working, this should appear and debugging required else { user.SendMessage(ColorTokenService.Red("Something's wrong, contact a code contributor!")); return; } }
public static string TranslateSnippetForListener(NWObject speaker, NWObject listener, SkillType language, string snippet) { Dictionary <SkillType, Type> map = new Dictionary <SkillType, Type> { { SkillType.Bothese, typeof(TranslatorBothese) }, { SkillType.Catharese, typeof(TranslatorCatharese) }, { SkillType.Cheunh, typeof(TranslatorCheunh) }, { SkillType.Dosh, typeof(TranslatorDosh) }, { SkillType.Droidspeak, typeof(TranslatorDroidspeak) }, { SkillType.Huttese, typeof(TranslatorHuttese) }, { SkillType.Mandoa, typeof(TranslatorMandoa) }, { SkillType.Shyriiwook, typeof(TranslatorShyriiwook) }, { SkillType.Twileki, typeof(TranslatorTwileki) }, { SkillType.Zabraki, typeof(TranslatorZabraki) }, { SkillType.Mirialan, typeof(TranslatorMirialan) }, { SkillType.MonCalamarian, typeof(TranslatorMonCalamarian) }, { SkillType.Ugnaught, typeof(TranslatorUgnaught) } }; Type type = typeof(TranslatorGeneric); map.TryGetValue(language, out type); ITranslator translator = (ITranslator)Activator.CreateInstance(type); if (speaker.IsPC && !speaker.IsDM) { // Get the rank and max rank for the speaker, and garble their English text based on it. NWPlayer speakerAsPlayer = speaker.Object; int speakerSkillRank = SkillService.GetPCSkillRank(speakerAsPlayer, language); int speakerSkillMaxRank = SkillService.GetSkill(language).MaxRank; if (speakerSkillRank != speakerSkillMaxRank) { int garbledChance = 100 - (int)(((float)speakerSkillRank / (float)speakerSkillMaxRank) * 100); string[] split = snippet.Split(' '); for (int i = 0; i < split.Length; ++i) { if (RandomService.Random(100) <= garbledChance) { split[i] = new string(split[i].ToCharArray().OrderBy(s => (RandomService.Random(2) % 2) == 0).ToArray()); } } snippet = split.Aggregate((a, b) => a + " " + b); } } if (!listener.IsPC || listener.IsDM) { // Short circuit for a DM or NPC - they will always understand the text. return(snippet); } // Let's grab the max rank for the listener skill, and then we roll for a successful translate based on that. NWPlayer listenerAsPlayer = listener.Object; int rank = SkillService.GetPCSkillRank(listenerAsPlayer, language); int maxRank = SkillService.GetSkill(language).MaxRank; // Check for the Comprehend Speech concentration ability. Player dbPlayer = DataService.Player.GetByID(listenerAsPlayer.GlobalID); bool grantSenseXP = false; if (dbPlayer.ActiveConcentrationPerkID == (int)PerkType.ComprehendSpeech) { int bonus = 5 * dbPlayer.ActiveConcentrationTier; rank += bonus; grantSenseXP = true; } // Ensure we don't go over the maximum. if (rank > maxRank) { rank = maxRank; } if (rank == maxRank || speaker == listener) { // Guaranteed success - return original. return(snippet); } string textAsForeignLanguage = translator.Translate(snippet); if (rank != 0) { int englishChance = (int)(((float)rank / (float)maxRank) * 100); string[] originalSplit = snippet.Split(' '); string[] foreignSplit = textAsForeignLanguage.Split(' '); StringBuilder endResult = new StringBuilder(); // WARNING: We're making the assumption that originalSplit.Length == foreignSplit.Length. // If this assumption changes, the below logic needs to change too. for (int i = 0; i < originalSplit.Length; ++i) { if (RandomService.Random(100) <= englishChance) { endResult.Append(originalSplit[i]); } else { endResult.Append(foreignSplit[i]); } endResult.Append(" "); } textAsForeignLanguage = endResult.ToString(); } long now = DateTime.Now.Ticks; int lastSkillUpLow = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW"); int lastSkillUpHigh = listenerAsPlayer.GetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH"); long lastSkillUp = lastSkillUpHigh; lastSkillUp = (lastSkillUp << 32) | (uint)lastSkillUpLow; long differenceInSeconds = (now - lastSkillUp) / 10000000; if (differenceInSeconds / 60 >= 2) { int amount = Math.Max(10, Math.Min(150, snippet.Length) / 3); // Reward exp towards the language - we scale this with character count, maxing at 50 exp for 150 characters. SkillService.GiveSkillXP(listenerAsPlayer, language, amount); // Grant Sense XP if player is concentrating Comprehend Speech. if (grantSenseXP) { SkillService.GiveSkillXP(listenerAsPlayer, SkillType.ForceSense, amount * 10); } listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_LOW", (int)(now & 0xFFFFFFFF)); listenerAsPlayer.SetLocalInt("LAST_LANGUAGE_SKILL_INCREASE_HIGH", (int)((now >> 32) & 0xFFFFFFFF)); } return(textAsForeignLanguage); }
public static bool OnAppearsWhen(int nodeType, int nodeID) { NWPlayer player = (_.GetPCSpeaker()); bool hasDialog = HasPlayerDialog(player.GlobalID); if (!hasDialog) { return(false); } PlayerDialog dialog = LoadPlayerDialog(player.GlobalID); using (new Profiler(nameof(DialogService) + "." + nameof(OnAppearsWhen) + "." + dialog.ActiveDialogName)) { DialogPage page = dialog.CurrentPage; var convo = GetConversation(dialog.ActiveDialogName); int currentSelectionNumber = nodeID + 1; bool displayNode = false; string newNodeText = string.Empty; int dialogOffset = (NumberOfResponsesPerPage + 1) * (dialog.DialogNumber - 1); if (currentSelectionNumber == NumberOfResponsesPerPage + 1) // Next page { int displayCount = page.NumberOfResponses - (NumberOfResponsesPerPage * dialog.PageOffset); if (displayCount > NumberOfResponsesPerPage) { displayNode = true; } } else if (currentSelectionNumber == NumberOfResponsesPerPage + 2) // Previous Page { if (dialog.PageOffset > 0) { displayNode = true; } } else if (currentSelectionNumber == NumberOfResponsesPerPage + 3) // Back { if (dialog.NavigationStack.Count > 0 && dialog.EnableBackButton) { displayNode = true; } } else if (nodeType == 2) { int responseID = (dialog.PageOffset * NumberOfResponsesPerPage) + nodeID; if (responseID + 1 <= page.NumberOfResponses) { DialogResponse response = page.Responses[responseID]; if (response != null) { newNodeText = response.Text; displayNode = response.IsActive; } } } else if (nodeType == 1) { if (player.GetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN") != 1) { convo.Initialize(); player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1); } if (dialog.IsEnding) { convo.EndDialog(); RemovePlayerDialog(player.GlobalID); player.DeleteLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN"); return(false); } page = dialog.CurrentPage; newNodeText = page.Header; _.SetCustomToken(90000 + dialogOffset, newNodeText); return(true); } _.SetCustomToken(90001 + nodeID + dialogOffset, newNodeText); return(displayNode); } }
public bool Run(params object[] args) { int nodeID = (int)args[0]; NWPlayer player = (_.GetPCSpeaker()); PlayerDialog dialog = _dialogService.LoadPlayerDialog(player.GlobalID); int selectionNumber = nodeID + 1; int responseID = nodeID + (_dialogService.NumberOfResponsesPerPage * dialog.PageOffset); if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 1) // Next page { dialog.PageOffset = dialog.PageOffset + 1; } else if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 2) // Previous page { dialog.PageOffset = dialog.PageOffset - 1; } else if (selectionNumber == _dialogService.NumberOfResponsesPerPage + 3) // Back { string currentPageName = dialog.CurrentPageName; var previous = dialog.NavigationStack.Pop(); // This might be a little confusing but we're passing the active page as the "old page" to the Back() method. // This is because we need to run any dialog-specific clean up prior to moving the conversation backwards. App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo => { convo.Back(player, currentPageName, previous.PageName); }); // Previous page was in a different conversation. Switch to it. if (previous.DialogName != dialog.ActiveDialogName) { _dialogService.LoadConversation(player, dialog.DialogTarget, previous.DialogName, dialog.DialogNumber); dialog = _dialogService.LoadPlayerDialog(player.GlobalID); dialog.ResetPage(); dialog.CurrentPageName = previous.PageName; dialog.PageOffset = 0; App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo => { convo.Initialize(); player.SetLocalInt("DIALOG_SYSTEM_INITIALIZE_RAN", 1); }); } // Otherwise it's in the same conversation. Switch to that. else { dialog.CurrentPageName = previous.PageName; dialog.PageOffset = 0; } } else if (selectionNumber != _dialogService.NumberOfResponsesPerPage + 4) // End { App.ResolveByInterface <IConversation>("Conversation." + dialog.ActiveDialogName, convo => { convo.DoAction(player, dialog.CurrentPageName, responseID + 1); }); } return(true); }
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; })); }
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); }