private static void OnModuleUseFeat() { NWPlayer pc = _.OBJECT_SELF; int featID = Convert.ToInt32(NWNXEvents.GetEventData("FEAT_ID")); if (featID != (int)Feat.RenameCraftedItem) { return; } pc.ClearAllActions(); bool isSetting = GetLocalBool(pc, "CRAFT_RENAMING_ITEM") == true; NWItem renameItem = NWNXObject.StringToObject(NWNXEvents.GetEventData("TARGET_OBJECT_ID")); 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; } SetLocalBool(pc, "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 static void OnModuleUseFeat() { NWPlayer pc = _.OBJECT_SELF; int featID = Convert.ToInt32(NWNXEvents.GetEventData("FEAT_ID")); if (featID != (int)Feat.ChatCommandTargeter) { return; } var target = _.StringToObject(NWNXEvents.GetEventData("TARGET_OBJECT_ID")); var targetPositionX = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_X")); var targetPositionY = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Y")); var targetPositionZ = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Z")); var targetPosition = Vector3(targetPositionX, targetPositionY, targetPositionZ); var targetArea = _.StringToObject(NWNXEvents.GetEventData("AREA_OBJECT_ID")); var targetLocation = Location(targetArea, targetPosition, 0.0f); string command = pc.GetLocalString("CHAT_COMMAND"); string args = pc.GetLocalString("CHAT_COMMAND_ARGS"); if (string.IsNullOrWhiteSpace(command)) { pc.SendMessage("Please enter a chat command and then use this feat. Type /help to learn more about the available chat commands."); return; } IChatCommand chatCommand = GetChatCommandHandler(command); ProcessChatCommand(chatCommand, pc, target, targetLocation, args); pc.DeleteLocalString("CHAT_COMMAND"); pc.DeleteLocalString("CHAT_COMMAND_ARGS"); }
/// <summary> /// Processes all feats which are linked to perks. /// </summary> private static void OnModuleUseFeat() { // Activator is the creature who used the feat. // Target is who the activator selected to use this feat on. NWCreature activator = _.OBJECT_SELF; NWCreature target = NWNXObject.StringToObject(NWNXEvents.GetEventData("TARGET_OBJECT_ID")); var featID = (Feat)Convert.ToInt32(NWNXEvents.GetEventData("FEAT_ID")); // Ensure this perk feat can be activated. if (!CanUsePerkFeat(activator, target, featID)) { return; } // Retrieve information necessary for activation of perk feat. var perkFeat = DataService.PerkFeat.GetByFeatID((int)featID); Data.Entity.Perk perk = DataService.Perk.GetByID(perkFeat.PerkID); int creaturePerkLevel = PerkService.GetCreaturePerkLevel(activator, perk.ID); var handler = PerkService.GetPerkHandler(perkFeat.PerkID); SendAOEMessage(activator, activator.Name + " readies " + perk.Name + "."); // Force Abilities (aka Spells) if (perk.ExecutionTypeID == PerkExecutionType.ForceAbility) { target.SetLocalInt(LAST_ATTACK + activator.GlobalID, ATTACK_FORCE); ActivateAbility(activator, target, perk, handler, creaturePerkLevel, PerkExecutionType.ForceAbility, perkFeat.PerkLevelUnlocked); } // Combat Abilities else if (perk.ExecutionTypeID == PerkExecutionType.CombatAbility) { target.SetLocalInt(LAST_ATTACK + activator.GlobalID, ATTACK_PHYSICAL); ActivateAbility(activator, target, perk, handler, creaturePerkLevel, PerkExecutionType.CombatAbility, perkFeat.PerkLevelUnlocked); } // Queued Weapon Skills else if (perk.ExecutionTypeID == PerkExecutionType.QueuedWeaponSkill) { target.SetLocalInt(LAST_ATTACK + activator.GlobalID, ATTACK_PHYSICAL); HandleQueueWeaponSkill(activator, perk, handler, featID); } // Stances else if (perk.ExecutionTypeID == PerkExecutionType.Stance) { target.SetLocalInt(LAST_ATTACK + activator.GlobalID, ATTACK_COMBATABILITY); ActivateAbility(activator, target, perk, handler, creaturePerkLevel, PerkExecutionType.Stance, perkFeat.PerkLevelUnlocked); } // Concentration Abilities else if (perk.ExecutionTypeID == PerkExecutionType.ConcentrationAbility) { target.SetLocalInt(LAST_ATTACK + activator.GlobalID, ATTACK_FORCE); ActivateAbility(activator, target, perk, handler, creaturePerkLevel, PerkExecutionType.ConcentrationAbility, perkFeat.PerkLevelUnlocked); } }
private static void OnModuleUseFeat() { NWPlayer pc = (OBJECT_SELF); int featID = Convert.ToInt32(NWNXEvents.GetEventData("FEAT_ID")); if (featID != (int)Feat.OpenRestMenu) { return; } pc.ClearAllActions(); DialogService.StartConversation(pc, pc, "RestMenu"); }
// ReSharper disable once UnusedMember.Local public static void Main() { // Breaking the rules for the examine event because the result of the services is used in the following // service call. We still signal an event for this, but in general all of the logic should go into this method. using (new Profiler(nameof(mod_on_examine))) { NWPlayer examiner = (_.OBJECT_SELF); NWObject examinedObject = NWNXObject.StringToObject(NWNXEvents.GetEventData("EXAMINEE_OBJECT_ID")); if (ExaminationService.OnModuleExamine(examiner, examinedObject)) { MessageHub.Instance.Publish(new OnModuleExamine()); return; } string description; if (_.GetIsPC(examinedObject.Object) == true) { // https://github.com/zunath/SWLOR_NWN/issues/853 // safest probably to get the modified (non-original) description only for players // may want to always get the modified description for later flexibility? description = _.GetDescription(examinedObject.Object, false) + "\n\n"; } else { description = _.GetDescription(examinedObject.Object, true) + "\n\n"; } if (examinedObject.IsCreature) { var racialID = Convert.ToInt32(_.Get2DAString("racialtypes", "Name", (int)_.GetRacialType(examinedObject))); string racialtype = _.GetStringByStrRef(racialID); if (!description.Contains(ColorTokenService.Green("Racial Type: ") + racialtype)) { description += ColorTokenService.Green("Racial Type: ") + racialtype; } } description = ModService.OnModuleExamine(description, examiner, examinedObject); description = ItemService.OnModuleExamine(description, examinedObject); description = DurabilityService.OnModuleExamine(description, examinedObject); if (!string.IsNullOrWhiteSpace(description)) { _.SetDescription(examinedObject.Object, description, false); _.SetDescription(examinedObject.Object, description); } } MessageHub.Instance.Publish(new OnModuleExamine()); }
private static string ProcessEventAndBuildDetails(int eventID) { string details = string.Empty; NWObject target; int amount; switch (eventID) { case 1: // Spawn Creature var area = _.StringToObject(NWNXEvents.GetEventData("AREA")); string areaName = GetName(area); NWCreature creature = _.StringToObject(NWNXEvents.GetEventData("OBJECT")); int objectTypeID = Convert.ToInt32(NWNXEvents.GetEventData("OBJECT_TYPE")); float x = (float)Convert.ToDouble(NWNXEvents.GetEventData("POS_X")); float y = (float)Convert.ToDouble(NWNXEvents.GetEventData("POS_Y")); float z = (float)Convert.ToDouble(NWNXEvents.GetEventData("POS_Z")); SetLocalBool(creature, "DM_SPAWNED", true); details = areaName + "," + creature.Name + "," + objectTypeID + "," + x + "," + y + "," + z; break; case 22: // Give XP amount = Convert.ToInt32(NWNXEvents.GetEventData("AMOUNT")); target = _.StringToObject(NWNXEvents.GetEventData("OBJECT")); details = amount + "," + target.Name; break; case 23: // Give Level amount = Convert.ToInt32(NWNXEvents.GetEventData("AMOUNT")); target = _.StringToObject(NWNXEvents.GetEventData("OBJECT")); details = amount + "," + target.Name; break; case 24: // Give Gold amount = Convert.ToInt32(NWNXEvents.GetEventData("AMOUNT")); target = _.StringToObject(NWNXEvents.GetEventData("OBJECT")); details = amount + "," + target.Name; break; } return(details); }
private static void OnItemUsed() { NWPlayer user = _.OBJECT_SELF; NWItem oItem = _.StringToObject(NWNXEvents.GetEventData("ITEM_OBJECT_ID")); NWObject target = _.StringToObject(NWNXEvents.GetEventData("TARGET_OBJECT_ID")); var targetPositionX = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_X")); var targetPositionY = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Y")); var targetPositionZ = (float)Convert.ToDouble(NWNXEvents.GetEventData("TARGET_POSITION_Z")); var targetPosition = Vector3(targetPositionX, targetPositionY, targetPositionZ); Location targetLocation = Location(user.Area, targetPosition, 0.0f); string className = oItem.GetLocalString("SCRIPT"); if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("ACTIVATE_SCRIPT"); } if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("ACTION_SCRIPT"); } if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("SCRIPT"); } // Legacy events follow. We can't remove these because of backwards compatibility issues with existing items. if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("JAVA_SCRIPT"); } if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("ACTIVATE_JAVA_SCRIPT"); } if (string.IsNullOrWhiteSpace(className)) { className = oItem.GetLocalString("JAVA_ACTION_SCRIPT"); } if (string.IsNullOrWhiteSpace(className)) { return; } // Bypass the NWN "item use" animation. NWNXEvents.SkipEvent(); user.ClearAllActions(); if (user.IsBusy) { user.SendMessage("You are busy."); return; } // Remove "Item." prefix if it exists. if (className.StartsWith("Item.")) { className = className.Substring(5); } IActionItem item = GetActionItemHandler(className); string invalidTargetMessage = item.IsValidTarget(user, oItem, target, targetLocation); if (!string.IsNullOrWhiteSpace(invalidTargetMessage)) { user.SendMessage(invalidTargetMessage); return; } // NOTE - these checks are duplicated in FinishActionItem. Keep both in sync. float maxDistance = item.MaxDistance(user, oItem, target, targetLocation); if (maxDistance > 0.0f) { NWObject owner = GetItemPossessor(target); if (target.IsValid && owner.IsValid) { // We are okay - we have targeted an item in our inventory (we can't target someone // else's inventory, so no need to actually check distance). } else if (target.Object == _.OBJECT_SELF) { // Also okay. } else if (target.IsValid && (GetDistanceBetween(user.Object, target.Object) > maxDistance || user.Area.Resref != target.Area.Resref)) { user.SendMessage("Your target is too far away."); return; } else if (!target.IsValid && (GetDistanceBetweenLocations(user.Location, targetLocation) > maxDistance || user.Area.Resref != ((NWArea)GetAreaFromLocation(targetLocation)).Resref)) { user.SendMessage("That location is too far away."); return; } } CustomData customData = item.StartUseItem(user, oItem, target, targetLocation); float delay = item.Seconds(user, oItem, target, targetLocation, customData); var animationID = item.AnimationID(); bool faceTarget = item.FaceTarget(); Vector3 userPosition = user.Position; user.AssignCommand(() => { user.IsBusy = true; if (faceTarget) { SetFacingPoint(!target.IsValid ? GetPositionFromLocation(targetLocation) : target.Position); } if (animationID > 0) { ActionPlayAnimation(animationID, 1.0f, delay); } }); if (delay > 0.0f) { NWNXPlayer.StartGuiTimingBar(user, delay, string.Empty); } var @event = new OnFinishActionItem(className, user, oItem, target, targetLocation, userPosition, customData); user.DelayEvent(delay, @event); }
public void OnItemDisturbed() { NWPlaceable bay = OBJECT_SELF; // Filer to only events created by a fuel bay, and ignore this event if it was triggered by clearing // the inventory when the bay is being destroyed. if (bay.Resref != "fuel_bay" || bay.GetLocalBool("SETUP") == true) { return; } NWItem item = StringToObject(NWNXEvents.GetEventData("ITEM")); NWPlayer player = bay.GetLocalObject("BAY_ACCESSOR"); var disturbType = NWNXEvents.GetCurrentEvent(); bool stronidiumOnly = GetLocalBool(bay, "CONTROL_TOWER_FUEL_TYPE"); string allowedResref = stronidiumOnly ? "stronidium" : "fuel_cell"; string structureID = bay.GetLocalString("PC_BASE_STRUCTURE_ID"); // Check for either fuel cells or stronidium when adding an item to the container. if (disturbType == EventType.ItemInventoryAddItemAfter) { if (item.Resref != allowedResref) { ItemService.ReturnItem(player, item); player.SendMessage("Only " + (stronidiumOnly ? "Stronidium" : "Fuel Cells") + " may be placed inside this fuel bay."); return; } } // If the item removed wasn't fuel cells or stronidium, exit early. We don't need to do anything else. else if (disturbType == EventType.ItemInventoryRemoveItemAfter) { if (item.Resref != allowedResref) { return; } } var structure = DataService.PCBaseStructure.GetByID(new Guid(structureID)); var pcBase = DataService.PCBase.GetByID(structure.PCBaseID); // Calculate how much fuel exists in the bay's inventory. int fuelCount = 0; foreach (var fuel in bay.InventoryItems) { fuelCount += fuel.StackSize; } // If there are extra units of fuel, destroy them. We will set the stack size of the first fuel later on. NWItem firstFuel = GetFirstItemInInventory(bay.Object); NWItem nextFuel = GetNextItemInInventory(bay.Object); while (nextFuel.IsValid) { nextFuel.Destroy(); nextFuel = GetNextItemInInventory(bay.Object); } int maxFuel; // Handle Stronidium fuel process if (stronidiumOnly) { maxFuel = BaseService.CalculateMaxReinforcedFuel(pcBase.ID); // For starships only: Add the ship's cargo bonus to the max stronidium amount. if (bay.Area.GetLocalInt("BUILDING_TYPE") == (int)Enumeration.BuildingType.Starship) { maxFuel += 25 * SpaceService.GetCargoBonus(SpaceService.GetCargoBay(player.Area, player), ItemPropertyType.StarshipStronidiumBonus); } // Did the player put too much fuel inside? Return the excess to their inventory. if (fuelCount > maxFuel) { int returnAmount = fuelCount - maxFuel; CreateItemOnObject("stronidium", player.Object, returnAmount); fuelCount = maxFuel; } firstFuel.StackSize = fuelCount; pcBase.ReinforcedFuel = fuelCount; if (bay.Area.GetLocalInt("BUILDING_TYPE") == (int)Enumeration.BuildingType.Starship) { // This is a starship. Update the creature object, if any, with the new fuel count. NWCreature ship = bay.Area.GetLocalObject("CREATURE"); if (ship.IsValid) { ship.SetLocalInt("STRONIDIUM", fuelCount); } } } // Handle Fuel Cell process else { maxFuel = BaseService.CalculateMaxFuel(pcBase.ID); // For starships only: Add the ship's cargo bonus to the max fuel amount. if (bay.Area.GetLocalInt("BUILDING_TYPE") == (int)Enumeration.BuildingType.Starship) { maxFuel += 25 * SpaceService.GetCargoBonus(SpaceService.GetCargoBay(player.Area, player), ItemPropertyType.StarshipFuelBonus); } // Did the player put too much fuel inside? Return the excess to their inventory. if (fuelCount > maxFuel) { int returnAmount = fuelCount - maxFuel; CreateItemOnObject("fuel_cell", player.Object, returnAmount); fuelCount = maxFuel; } firstFuel.StackSize = fuelCount; pcBase.Fuel = fuelCount; } // Submit a DB data change for the fuel or stronidium amount adjustment. DataService.SubmitDataChange(pcBase, DatabaseActionType.Update); var tower = BaseService.GetBaseControlTower(structure.PCBaseID); if (tower == null) { Console.WriteLine("Could not locate tower in Fuel Bay. PCBaseID = " + structure.PCBaseID); return; } var towerStructure = DataService.BaseStructure.GetByID(tower.BaseStructureID); if (towerStructure.BaseStructureTypeID == (int)BaseStructureType.Starship) { // This is a spaceship, so don't give the feedback message. return; } int fuelRating = towerStructure.FuelRating; // Stronidium - Every unit lasts for 6 seconds during reinforcement mode. if (stronidiumOnly) { int seconds = 6 * fuelCount; TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); player.SendMessage(ColorTokenService.Gray("Reinforcement mode will last for " + TimeService.GetTimeLongIntervals(timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, false) + " (" + fuelCount + " / " + maxFuel + " units")); } // Regular fuel cells - Every unit lasts for 45, 15, or 5 minutes depending on the size of the tower. else { int minutes; switch (fuelRating) { case 1: // Small minutes = 45; break; case 2: // Medium minutes = 15; break; case 3: // Large minutes = 5; break; default: throw new Exception("Invalid fuel rating value: " + fuelRating); } TimeSpan timeSpan = TimeSpan.FromMinutes(minutes * fuelCount); player.SendMessage(ColorTokenService.Gray("Fuel will last for " + TimeService.GetTimeLongIntervals(timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, false) + " (" + fuelCount + " / " + maxFuel + " units)")); } return; }