public static DatabaseActionType Add(this DatabaseActionType oldAction, DatabaseActionType newAction) { switch (oldAction) { case DatabaseActionType.Unchanged: return newAction; case DatabaseActionType.Insert: switch (newAction) { case DatabaseActionType.Insert: case DatabaseActionType.Update: return DatabaseActionType.Insert; case DatabaseActionType.Delete: return DatabaseActionType.Unchanged; } break; case DatabaseActionType.Update: switch (newAction) { case DatabaseActionType.Update: return DatabaseActionType.Update; case DatabaseActionType.Delete: return DatabaseActionType.Delete; } break; case DatabaseActionType.Delete: switch (newAction) { case DatabaseActionType.Insert: return DatabaseActionType.Unchanged; } break; } throw new InvalidOperationException("Invalid action"); }
public void GiveReward(NWPlayer player) { if (_amount <= 0 || _fameRegionID <= 0) { return; } PCRegionalFame fame = DataService.PCRegionalFame.GetByPlayerIDAndFameRegionIDOrDefault(player.GlobalID, _fameRegionID); DatabaseActionType action = DatabaseActionType.Update; if (fame == null) { fame = new PCRegionalFame { PlayerID = player.GlobalID, FameRegionID = _fameRegionID, Amount = 0 }; action = DatabaseActionType.Insert; } fame.Amount += _amount; DataService.SubmitDataChange(fame, action); }
public DatabaseArgs(DatabaseActionType type, string key, byte[] data = null, int?user = null) { Type = type; Key = key; Data = data; User = user; }
public DatabaseAction(IEntity data, DatabaseActionType action) { Data = new List <IEntity>(); Data.Add(data); DataType = data.GetType(); Action = action; IsEnumerable = false; }
public void AdjustVisibility(NWPlayer player, NWObject target, bool isVisible) { if (!player.IsPlayer) { return; } if (target.IsPlayer || target.IsDM) { return; } string visibilityObjectID = target.GetLocalString("VISIBILITY_OBJECT_ID"); if (string.IsNullOrWhiteSpace(visibilityObjectID)) { target.AssignCommand(() => { _.SpeakString("Unable to locate VISIBILITY_OBJECT_ID variable. Need this in order to adjust visibility. Notify an admin if you see this message."); }); return; } var visibility = _data.SingleOrDefault <PCObjectVisibility>(x => x.PlayerID == player.GlobalID && x.VisibilityObjectID == visibilityObjectID); DatabaseActionType action = DatabaseActionType.Update; if (visibility == null) { visibility = new PCObjectVisibility { PlayerID = player.GlobalID, VisibilityObjectID = visibilityObjectID }; action = DatabaseActionType.Insert; } visibility.IsVisible = isVisible; _data.SubmitDataChange(visibility, action); if (visibility.IsVisible) { _nwnxPlayer.SetVisibilityOverride(player, target, (int)PlayerVisibilityType.Visible); } else { _nwnxPlayer.SetVisibilityOverride(player, target, (int)PlayerVisibilityType.Hidden); } }
/// <summary> /// Sends a request to change data into the queue. Processing is asynchronous /// and you cannot reliably retrieve the data directly from the database immediately afterwards. /// However, data in the cache will be up to date as soon as a value is changed. /// </summary> /// <param name="data">The data to submit for processing</param> /// <param name="actionType">The type (Insert, Update, Delete, etc.) of change to make.</param> public void SubmitDataChange(IEntity data, DatabaseActionType actionType) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (actionType == DatabaseActionType.Insert || actionType == DatabaseActionType.Update) { SetIntoCache(data.GetType(), GetEntityKey(data), data); } else if (actionType == DatabaseActionType.Delete) { DeleteFromCache(data.GetType(), GetEntityKey(data)); } DataQueue.Enqueue(new DatabaseAction(data, actionType)); }
/// <summary> /// Sends a request to change data into the queue. Processing is asynchronous /// and you cannot reliably retrieve the data directly from the database immediately afterwards. /// However, data in the cache will be up to date as soon as a value is changed. /// </summary> /// <param name="data">The data to submit for processing</param> /// <param name="actionType">The type (Insert, Update, Delete, etc.) of change to make.</param> public static void SubmitDataChange <T>(T data, DatabaseActionType actionType) where T : class, IEntity { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (actionType == DatabaseActionType.Insert || actionType == DatabaseActionType.Update) { SetIntoCache(data); } else if (actionType == DatabaseActionType.Delete) { RemoveFromCache(data); } DataQueue.Enqueue(new DatabaseAction(data, actionType)); }
public DatabaseAction(IEnumerable <IEntity> data, DatabaseActionType action) { Data = new List <IEntity>(); foreach (var item in data) { if (DataType == null) { DataType = item.GetType(); } else if (item.GetType() != DataType) { throw new InvalidOperationException("All objects in a single database action must be of the same type."); } Data.Add(item); } Action = action; IsEnumerable = true; }
private static void SaveMapProgression(NWArea area, NWPlayer player) { var map = DataService.PCMapProgression.GetByPlayerIDAndAreaResrefOrDefault(player.GlobalID, area.Resref); DatabaseActionType action = DatabaseActionType.Update; if (map == null) { map = new PCMapProgression { PlayerID = player.GlobalID, AreaResref = area.Resref, Progression = string.Empty }; action = DatabaseActionType.Insert; } map.Progression = NWNXPlayer.GetAreaExplorationState(player, area); DataService.SubmitDataChange(map, action); }
private void SaveMapProgression(NWArea area, NWPlayer player) { var map = _data.GetAll <PCMapProgression>().SingleOrDefault(x => x.PlayerID == player.GlobalID && x.AreaResref == area.Resref); int areaSize = area.Width * area.Height; DatabaseActionType action = DatabaseActionType.Update; if (map == null || areaSize != map.Progression.Length) { if (map != null) { _data.SubmitDataChange(map, DatabaseActionType.Delete); } map = new PCMapProgression { PlayerID = player.GlobalID, AreaResref = area.Resref, Progression = string.Empty.PadLeft(areaSize, '0') }; action = DatabaseActionType.Insert; } string progression = string.Empty; for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { bool visible = _.GetTileExplored(player, area, x, y) == TRUE; progression += visible ? '1' : '0'; } } map.Progression = progression; _data.SubmitDataChange(map, action); }
public void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = _data.Single <Data.Entity.Perk>(x => x.ID == perkID); var perkLevels = _data.Where <PerkLevel>(x => x.PerkID == perkID); var pcPerk = _data.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); var player = _data.Single <Player>(x => x.ID == oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; _data.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; _data.SubmitDataChange(player, DatabaseActionType.Update); } // If a perk is activatable, create the item on the PC. // Remove any existing cast spell unique power properties and add the correct one based on the DB flag. if (!string.IsNullOrWhiteSpace(perk.ItemResref)) { if (_.GetIsObjectValid(_.GetItemPossessedBy(oPC.Object, perk.ItemResref)) == FALSE) { NWItem spellItem = (_.CreateItemOnObject(perk.ItemResref, oPC.Object)); spellItem.IsCursed = true; spellItem.SetLocalInt("ACTIVATION_PERK_ID", perk.ID); foreach (ItemProperty ipCur in spellItem.ItemProperties) { int ipType = _.GetItemPropertyType(ipCur); int ipSubType = _.GetItemPropertySubType(ipCur); if (ipType == ITEM_PROPERTY_CAST_SPELL && (ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER || ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY || ipSubType == IP_CONST_CASTSPELL_ACTIVATE_ITEM)) { _.RemoveItemProperty(spellItem.Object, ipCur); } } ItemProperty ip; if (perk.IsTargetSelfOnly) { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } else { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } _biowareXP2.IPSafeAddItemProperty(spellItem, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); } _.SetName(_.GetItemPossessedBy(oPC.Object, perk.ItemResref), perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")"); } // If a feat ID is assigned, add the feat to the player if it doesn't exist yet. else if (perk.FeatID != null && perk.FeatID > 0 && _.GetHasFeat((int)perk.FeatID, oPC.Object) == FALSE) { _nwnxCreature.AddFeatByLevel(oPC, (int)perk.FeatID, 1); var qbs = _nwnxQBS.UseFeat((int)perk.FeatID); // Try to add the new feat to the player's hotbar. if (_nwnxPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 10, qbs); } } oPC.SendMessage(_color.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); App.ResolveByInterface <IPerk>("Perk." + perk.ScriptName, (perkScript) => { if (perkScript == null) { return; } perkScript.OnPurchased(oPC, pcPerk.PerkLevel); }); } else { oPC.FloatingText(_color.Red("You cannot purchase the perk at this time.")); } }
private void TogglePermission(NWPlayer player, BasePermission permission) { var data = _base.GetPlayerTempData(GetPC()); var dbPermission = _data.SingleOrDefault <PCBasePermission>(x => x.PlayerID == player.GlobalID && x.PCBaseID == data.PCBaseID); DatabaseActionType action = DatabaseActionType.Update; if (dbPermission == null) { dbPermission = new PCBasePermission { PCBaseID = data.PCBaseID, PlayerID = player.GlobalID }; action = DatabaseActionType.Insert; } switch (permission) { case BasePermission.CanPlaceEditStructures: dbPermission.CanPlaceEditStructures = !dbPermission.CanPlaceEditStructures; break; case BasePermission.CanAccessStructureInventory: dbPermission.CanAccessStructureInventory = !dbPermission.CanAccessStructureInventory; break; case BasePermission.CanManageBaseFuel: dbPermission.CanManageBaseFuel = !dbPermission.CanManageBaseFuel; break; case BasePermission.CanExtendLease: dbPermission.CanExtendLease = !dbPermission.CanExtendLease; break; case BasePermission.CanEnterBuildings: dbPermission.CanEnterBuildings = !dbPermission.CanEnterBuildings; break; case BasePermission.CanRetrieveStructures: dbPermission.CanRetrieveStructures = !dbPermission.CanRetrieveStructures; break; case BasePermission.CanRenameStructures: dbPermission.CanRenameStructures = !dbPermission.CanRenameStructures; break; case BasePermission.CanEditPrimaryResidence: dbPermission.CanEditPrimaryResidence = !dbPermission.CanEditPrimaryResidence; break; case BasePermission.CanRemovePrimaryResidence: dbPermission.CanRemovePrimaryResidence = !dbPermission.CanRemovePrimaryResidence; break; default: throw new ArgumentOutOfRangeException(nameof(permission), permission, null); } _data.SubmitDataChange(dbPermission, action); }
public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Single <Data.Entity.Perk>(x => x.ID == perkID); var perkLevels = DataService.Where <PerkLevel>(x => x.PerkID == perkID); var pcPerk = DataService.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); var player = DataService.Single <Player>(x => x.ID == oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for any perk levels to grant. var perkFeatsToGrant = DataService.Where <PerkFeat>(x => x.PerkID == perkID && x.PerkLevelUnlocked == pcPerk.PerkLevel); // If at least one feat ID is assigned, add the feat(s) to the player if it doesn't exist yet. if (perkFeatsToGrant.Count > 0) { foreach (var perkFeat in perkFeatsToGrant) { if (_.GetHasFeat(perkFeat.FeatID, oPC.Object) == TRUE) { continue; } NWNXCreature.AddFeatByLevel(oPC, perkFeat.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat(perkFeat.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); MessageHub.Instance.Publish(new PerkUpgradedMessage(oPC, perkID)); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }
private void ApplyPCEffect(NWCreature caster, NWCreature target, int customEffectID, int ticks, int effectiveLevel, string data) { Data.Entity.CustomEffect customEffect = _data.Single <Data.Entity.CustomEffect>(x => x.ID == customEffectID); PCCustomEffect pcEffect = _data.SingleOrDefault <PCCustomEffect>(x => x.PlayerID == target.GlobalID && x.CustomEffectID == customEffectID); CustomEffectCategoryType category = (CustomEffectCategoryType)customEffect.CustomEffectCategoryID; if (category == CustomEffectCategoryType.FoodEffect) { var customEffectPC = _data.Get <Data.Entity.CustomEffect>(pcEffect.CustomEffectID); if (pcEffect != null && customEffectPC.CustomEffectCategoryID == (int)category) { caster.SendMessage("You are not hungry."); return; } } DatabaseActionType action = DatabaseActionType.Update; if (pcEffect == null) { pcEffect = new PCCustomEffect { PlayerID = target.GlobalID }; action = DatabaseActionType.Insert; } if (pcEffect.EffectiveLevel > effectiveLevel) { caster.SendMessage("A more powerful effect already exists on your target."); return; } pcEffect.CustomEffectID = customEffectID; pcEffect.EffectiveLevel = effectiveLevel; pcEffect.Ticks = ticks; pcEffect.CasterNWNObjectID = _.ObjectToString(caster); _data.SubmitDataChange(pcEffect, action); target.SendMessage(customEffect.StartMessage); App.ResolveByInterface <ICustomEffect>("CustomEffect." + customEffect.ScriptHandler, handler => { if (string.IsNullOrWhiteSpace(data)) { data = handler?.Apply(caster, target, effectiveLevel); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } pcEffect.Data = data; _data.SubmitDataChange(pcEffect, DatabaseActionType.Update); // Was already queued for removal, but got cast again. Take it out of the list to be removed. if (_cache.PCEffectsForRemoval.Contains(pcEffect.ID)) { _cache.PCEffectsForRemoval.Remove(pcEffect.ID); } }); }
/// <summary> /// Performs a perk purchase for a player. This handles deducting SP, inserting perk records, /// and adjusting hotbar slots as necessary. /// </summary> /// <param name="oPC">The player receiving the perk upgrade.</param> /// <param name="perkID">The ID number of the perk.</param> /// <param name="freeUpgrade">If true, no SP will be deducted. Otherwise, SP will be deducted from player.</param> public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Perk.GetByID(perkID); var perkLevels = DataService.PerkLevel.GetAllByPerkID(perkID); var pcPerk = DataService.PCPerk.GetByPlayerAndPerkIDOrDefault(oPC.GlobalID, perkID); var player = DataService.Player.GetByID(oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for a perk feat to grant. var perkFeatToGrant = DataService.PerkFeat.GetByPerkIDAndLevelUnlockedOrDefault(perkID, pcPerk.PerkLevel); // Add the feat(s) to the player if it doesn't exist yet. if (perkFeatToGrant != null && _.GetHasFeat((Feat)perkFeatToGrant.FeatID, oPC.Object) == false) { NWNXCreature.AddFeatByLevel(oPC, (Feat)perkFeatToGrant.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat((Feat)perkFeatToGrant.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); MessageHub.Instance.Publish(new OnPerkUpgraded(oPC, perkID)); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }
private static void OnCreatureDeath() { NWCreature creature = Object.OBJECT_SELF; int npcGroupID = creature.GetLocalInt("NPC_GROUP"); if (npcGroupID <= 0) { return; } NWObject oKiller = _.GetLastKiller(); if (!oKiller.IsPlayer) { return; } string areaResref = creature.Area.Resref; List <KeyValuePair <NWPlayer, int> > playersToAdvance = new List <KeyValuePair <NWPlayer, int> >(); NWPlayer oPC = _.GetFirstFactionMember(oKiller); while (oPC.IsValid) { if (areaResref != oPC.Area.Resref) { oPC = _.GetNextFactionMember(oKiller); continue; } if (_.GetDistanceBetween(creature, oPC) <= 0.0f || _.GetDistanceBetween(creature, oPC) > 20.0f) { oPC = _.GetNextFactionMember(oKiller); continue; } var playerID = oPC.GlobalID; var killTargets = DataService.Where <PCQuestKillTargetProgress>(x => x.PlayerID == playerID && x.NPCGroupID == npcGroupID).ToList(); foreach (var kt in killTargets) { var questStatus = DataService.Get <PCQuestStatus>(kt.PCQuestStatusID); var quest = DataService.Get <Quest>(questStatus.QuestID); var npcGroup = DataService.Get <NPCGroup>(kt.NPCGroupID); kt.RemainingToKill--; string targetGroupName = npcGroup.Name; string updateMessage = "[" + quest.Name + "] " + targetGroupName + " remaining: " + kt.RemainingToKill; DatabaseActionType action = DatabaseActionType.Update; if (kt.RemainingToKill <= 0) { updateMessage += " " + ColorTokenService.Green(" {COMPLETE}"); playersToAdvance.Add(new KeyValuePair <NWPlayer, int>(oPC, quest.ID)); action = DatabaseActionType.Delete; } DataService.SubmitDataChange(kt, action); var pc = oPC; _.DelayCommand(1.0f, () => { pc.SendMessage(updateMessage); }); string ruleName = quest.OnKillTargetRule; if (!string.IsNullOrWhiteSpace(ruleName)) { var pcCopy = oPC; var rule = GetQuestRule(ruleName); string[] args = null; if (!string.IsNullOrWhiteSpace(quest.OnKillTargetArgs)) { args = quest.OnKillTargetArgs.Split(','); } rule.Run(pcCopy, creature, quest.ID, args); } } oPC = _.GetNextFactionMember(oKiller); } foreach (var player in playersToAdvance) { AdvanceQuestState(player.Key, null, player.Value); } }
/// <summary> /// Initializes a new instance of <see cref="DatabaseAction{T}"/>. /// </summary> /// <param name="item">The item to perform the required action with.</param> /// <param name="actionType">The type of action to perform.</param> public DatabaseAction(T item, DatabaseActionType actionType) { _item = item; _actionType = actionType; }
private static void ApplyPCEffect(NWCreature caster, NWCreature target, int customEffectID, int ticks, int effectiveLevel, string data) { PCCustomEffect pcEffect = DataService.PCCustomEffect.GetByPlayerIDAndCustomEffectIDOrDefault(target.GlobalID, customEffectID); ICustomEffectHandler handler = GetCustomEffectHandler(customEffectID); CustomEffectCategoryType category = handler.CustomEffectCategoryType; if (category == CustomEffectCategoryType.FoodEffect) { var customEffectPC = DataService.CustomEffect.GetByID(pcEffect.CustomEffectID); if (customEffectPC != null) { var foodHandler = GetCustomEffectHandler(customEffectPC.ID); if (foodHandler.CustomEffectCategoryType == category) { caster.SendMessage("You are not hungry."); } return; } } DatabaseActionType action = DatabaseActionType.Update; if (pcEffect == null) { pcEffect = new PCCustomEffect { PlayerID = target.GlobalID }; action = DatabaseActionType.Insert; } if (pcEffect.EffectiveLevel > effectiveLevel) { caster.SendMessage("A more powerful effect already exists on your target."); return; } pcEffect.CustomEffectID = customEffectID; pcEffect.EffectiveLevel = effectiveLevel; pcEffect.Ticks = ticks; pcEffect.CasterNWNObjectID = _.ObjectToString(caster); DataService.SubmitDataChange(pcEffect, action); target.SendMessage(handler.StartMessage); if (string.IsNullOrWhiteSpace(data)) { data = handler?.Apply(caster, target, effectiveLevel); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } pcEffect.Data = data; DataService.SubmitDataChange(pcEffect, DatabaseActionType.Update); // Was already queued for removal, but got cast again. Take it out of the list to be removed. if (AppCache.PCEffectsForRemoval.Contains(pcEffect.ID)) { AppCache.PCEffectsForRemoval.Remove(pcEffect.ID); } }
public bool Run(params object[] args) { NWPlaceable container = Object.OBJECT_SELF; NWObject owner = container.GetLocalObject("QUEST_OWNER"); NWPlayer player = _.GetLastDisturbed(); NWItem item = _.GetInventoryDisturbItem(); int disturbType = _.GetInventoryDisturbType(); string crafterPlayerID = item.GetLocalString("CRAFTER_PLAYER_ID"); Guid? crafterPlayerGUID = null; if (!string.IsNullOrWhiteSpace(crafterPlayerID)) { crafterPlayerGUID = new Guid(crafterPlayerID); } if (disturbType == INVENTORY_DISTURB_TYPE_ADDED) { int questID = container.GetLocalInt("QUEST_ID"); PCQuestStatus status = _data.Single <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID); PCQuestItemProgress progress = _data.SingleOrDefault <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID && x.Resref == item.Resref); DatabaseActionType action = DatabaseActionType.Update; if (progress == null) { _.CopyItem(item, player, TRUE); player.SendMessage(_color.Red("That item is not required for this quest.")); } else if (progress.MustBeCraftedByPlayer && crafterPlayerGUID != player.GlobalID) { _.CopyItem(item, player, TRUE); player.SendMessage(_color.Red("You may only submit items which you have personally created for this quest.")); } else { progress.Remaining--; if (progress.Remaining <= 0) { var progressCopy = progress; progress = _data.Single <PCQuestItemProgress>(x => x.ID == progressCopy.ID); action = DatabaseActionType.Delete; } _data.SubmitDataChange(progress, action); // Recalc the remaining items needed. int remainingCount = _data.GetAll <PCQuestItemProgress>().Count(x => x.PCQuestStatusID == status.ID); if (remainingCount <= 0) { _quest.AdvanceQuestState(player, owner, questID); } player.SendMessage("You need " + progress.Remaining + " " + item.Name + " for this quest."); } item.Destroy(); var questItemProgresses = _data.Where <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID); if (!questItemProgresses.Any()) { string conversation = _.GetLocalString(owner, "CONVERSATION"); if (!string.IsNullOrWhiteSpace(conversation)) { _dialog.StartConversation(player, owner, conversation); } else { player.AssignCommand(() => { _.ActionStartConversation(owner, "", TRUE, FALSE); }); } } } return(true); }
/// <summary> /// Updates a player's quest status if the creature is part of an ongoing quest. /// Progresses the player to the next state if all requirements are met. /// </summary> private static void OnCreatureDeath() { NWCreature creature = _.OBJECT_SELF; int npcGroupID = creature.GetLocalInt("NPC_GROUP"); if (npcGroupID <= 0) { return; } NWObject oKiller = GetLastKiller(); if (!oKiller.IsPlayer) { return; } string areaResref = creature.Area.Resref; List <KeyValuePair <NWPlayer, int> > playersToAdvance = new List <KeyValuePair <NWPlayer, int> >(); NWPlayer oPC = GetFirstFactionMember(oKiller); while (oPC.IsValid) { if (areaResref != oPC.Area.Resref) { oPC = GetNextFactionMember(oKiller); continue; } if (GetDistanceBetween(creature, oPC) <= 0.0f || GetDistanceBetween(creature, oPC) > 40.0f) { oPC = GetNextFactionMember(oKiller); continue; } var playerID = oPC.GlobalID; var killTargets = DataService.PCQuestKillTargetProgress.GetAllByPlayerIDAndNPCGroupID(playerID, npcGroupID).ToList(); foreach (var kt in killTargets) { var questStatus = DataService.PCQuestStatus.GetByID(kt.PCQuestStatusID); var quest = GetQuestByID(questStatus.QuestID); var npcGroup = DataService.NPCGroup.GetByID(kt.NPCGroupID); kt.RemainingToKill--; string targetGroupName = npcGroup.Name; string updateMessage = "[" + quest.Name + "] " + targetGroupName + " remaining: " + kt.RemainingToKill; DatabaseActionType action = DatabaseActionType.Update; if (kt.RemainingToKill <= 0) { updateMessage += " " + ColorTokenService.Green(" {COMPLETE}"); playersToAdvance.Add(new KeyValuePair <NWPlayer, int>(oPC, quest.QuestID)); action = DatabaseActionType.Delete; } DataService.SubmitDataChange(kt, action); var pc = oPC; DelayCommand(1.0f, () => { pc.SendMessage(updateMessage); }); } oPC = GetNextFactionMember(oKiller); } foreach (var player in playersToAdvance) { var quest = GetQuestByID(player.Value); quest.Advance(player.Key, creature); } }
private void TogglePermission(Guid playerID, BasePermission permission, bool isPublicPermission) { var data = BaseService.GetPlayerTempData(GetPC()); var dbPermission = isPublicPermission ? DataService.SingleOrDefault <PCBasePermission>(x => x.PCBaseID == data.PCBaseID && x.IsPublicPermission) : DataService.SingleOrDefault <PCBasePermission>(x => x.PlayerID == playerID && x.PCBaseID == data.PCBaseID && !x.IsPublicPermission); DatabaseActionType action = DatabaseActionType.Update; if (dbPermission == null) { dbPermission = new PCBasePermission { PCBaseID = data.PCBaseID, PlayerID = playerID, IsPublicPermission = isPublicPermission }; action = DatabaseActionType.Insert; } switch (permission) { case BasePermission.CanPlaceEditStructures: dbPermission.CanPlaceEditStructures = !dbPermission.CanPlaceEditStructures; break; case BasePermission.CanAccessStructureInventory: dbPermission.CanAccessStructureInventory = !dbPermission.CanAccessStructureInventory; break; case BasePermission.CanManageBaseFuel: dbPermission.CanManageBaseFuel = !dbPermission.CanManageBaseFuel; break; case BasePermission.CanExtendLease: dbPermission.CanExtendLease = !dbPermission.CanExtendLease; break; case BasePermission.CanEnterBuildings: dbPermission.CanEnterBuildings = !dbPermission.CanEnterBuildings; break; case BasePermission.CanRetrieveStructures: dbPermission.CanRetrieveStructures = !dbPermission.CanRetrieveStructures; break; case BasePermission.CanRenameStructures: dbPermission.CanRenameStructures = !dbPermission.CanRenameStructures; break; case BasePermission.CanEditPrimaryResidence: dbPermission.CanEditPrimaryResidence = !dbPermission.CanEditPrimaryResidence; break; case BasePermission.CanRemovePrimaryResidence: dbPermission.CanRemovePrimaryResidence = !dbPermission.CanRemovePrimaryResidence; break; case BasePermission.CanChangeStructureMode: dbPermission.CanChangeStructureMode = !dbPermission.CanChangeStructureMode; break; case BasePermission.CanAdjustPublicPermissions: dbPermission.CanAdjustPublicPermissions = !dbPermission.CanAdjustPublicPermissions; break; case BasePermission.CanFlyStarship: dbPermission.CanFlyStarship = !dbPermission.CanFlyStarship; break; case BasePermission.CanDockStarship: dbPermission.CanDockStarship = !dbPermission.CanDockStarship; break; default: throw new ArgumentOutOfRangeException(nameof(permission), permission, null); } DataService.SubmitDataChange(dbPermission, action); }
public static void CompleteQuest(NWPlayer player, NWObject questOwner, int questID, ItemVO selectedItem) { if (!player.IsPlayer) { return; } Quest quest = DataService.Single <Quest>(x => x.ID == questID); PCQuestStatus pcState = DataService.Single <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID); QuestState finalState = DataService.GetAll <QuestState>().Where(x => x.QuestID == questID).OrderBy(o => o.Sequence).Last(); if (finalState == null) { player.SendMessage("Could not find final state of quest. Please notify an admin this quest is bugged. (QuestID: " + questID + ")"); return; } pcState.CurrentQuestStateID = finalState.ID; pcState.CompletionDate = DateTime.UtcNow; if (selectedItem == null) { var rewardItems = DataService.Where <QuestRewardItem>(x => x.QuestID == questID); foreach (QuestRewardItem reward in rewardItems) { _.CreateItemOnObject(reward.Resref, player.Object, reward.Quantity); } } else { _.CreateItemOnObject(selectedItem.Resref, player.Object, selectedItem.Quantity); } if (quest.RewardGold > 0) { _.GiveGoldToCreature(player.Object, quest.RewardGold); } if (quest.RewardKeyItemID != null) { KeyItemService.GivePlayerKeyItem(player, (int)quest.RewardKeyItemID); } if (quest.RemoveStartKeyItemAfterCompletion && quest.StartKeyItemID != null) { KeyItemService.RemovePlayerKeyItem(player, (int)quest.StartKeyItemID); } if (!string.IsNullOrWhiteSpace(quest.MapNoteTag)) { MapPinService.DeleteMapPin(player, "QST_MAP_NOTE_" + questID); } if (quest.RewardFame > 0) { PCRegionalFame fame = DataService.SingleOrDefault <PCRegionalFame>(x => x.PlayerID == player.GlobalID && x.FameRegionID == quest.FameRegionID); DatabaseActionType action = DatabaseActionType.Update; if (fame == null) { fame = new PCRegionalFame { PlayerID = player.GlobalID, FameRegionID = quest.FameRegionID, Amount = 0 }; action = DatabaseActionType.Insert; } fame.Amount += quest.RewardFame; DataService.SubmitDataChange(fame, action); } player.SendMessage("Quest '" + quest.Name + "' complete!"); DataService.SubmitDataChange(pcState, DatabaseActionType.Update); _.RemoveJournalQuestEntry(quest.JournalTag, player, FALSE); if (!string.IsNullOrWhiteSpace(quest.OnCompleteRule) && questOwner != null) { var rule = GetQuestRule(quest.OnCompleteRule); string[] args = null; if (!string.IsNullOrWhiteSpace(quest.OnCompleteArgs)) { args = quest.OnCompleteArgs.Split(','); } rule.Run(player, questOwner, questID, args); } MessageHub.Instance.Publish(new QuestCompletedMessage(player, questID)); }
public void Main() { NWPlaceable container = NWGameObject.OBJECT_SELF; NWObject owner = container.GetLocalObject("QUEST_OWNER"); NWPlayer player = _.GetLastDisturbed(); NWItem item = _.GetInventoryDisturbItem(); int disturbType = _.GetInventoryDisturbType(); string crafterPlayerID = item.GetLocalString("CRAFTER_PLAYER_ID"); Guid? crafterPlayerGUID = null; if (!string.IsNullOrWhiteSpace(crafterPlayerID)) { crafterPlayerGUID = new Guid(crafterPlayerID); } if (disturbType == _.INVENTORY_DISTURB_TYPE_ADDED) { int questID = container.GetLocalInt("QUEST_ID"); PCQuestStatus status = DataService.PCQuestStatus.GetByPlayerAndQuestID(player.GlobalID, questID); PCQuestItemProgress progress = DataService.PCQuestItemProgress.GetByPCQuestStatusIDAndResrefOrDefault(status.ID, item.Resref); DatabaseActionType action = DatabaseActionType.Update; if (progress == null) { _.CopyItem(item, player, _.TRUE); player.SendMessage(ColorTokenService.Red("That item is not required for this quest.")); } else if (progress.MustBeCraftedByPlayer && crafterPlayerGUID != player.GlobalID) { _.CopyItem(item, player, _.TRUE); player.SendMessage(ColorTokenService.Red("You may only submit items which you have personally created for this quest.")); } else { progress.Remaining--; if (progress.Remaining <= 0) { var progressCopy = progress; progress = DataService.PCQuestItemProgress.GetByID(progressCopy.ID); action = DatabaseActionType.Delete; } DataService.SubmitDataChange(progress, action); // Recalc the remaining items needed. int remainingCount = DataService.PCQuestItemProgress.GetCountByPCQuestStatusID(status.ID); if (remainingCount <= 0) { QuestService.AdvanceQuestState(player, owner, questID); } player.SendMessage("You need " + progress.Remaining + "x " + item.Name + " for this quest."); } item.Destroy(); var questItemProgresses = DataService.PCQuestItemProgress.GetAllByPCQuestStatusID(status.ID); if (!questItemProgresses.Any()) { string conversation = _.GetLocalString(owner, "CONVERSATION"); // Either start a SWLOR conversation if (!string.IsNullOrWhiteSpace(conversation)) { DialogService.StartConversation(player, owner, conversation); } // Or a regular NWN conversation. else { player.AssignCommand(() => { _.ActionStartConversation(owner, "", _.TRUE, _.FALSE); }); } } } }