/// <summary> /// Make a new point (only if it is not already there) /// </summary> /// <param name="X"></param> /// <param name="Y"></param> private void makePoint(int X, int Y) { SFX.YATT.Tools.Vector <float> coor = findAreaCoor(X, Y, areaViewer.Area); if (coor != null) { Pair <double, double> p = new Pair <double, double>(coor[0], coor[1]); Point id = new Point((int)Math.Floor(coor[0]), (int)Math.Floor(coor[1])); if (!pointsAlready.ContainsKey(id)) { pointsAlready[id] = "1"; // Get the current area NWN2Toolset.NWN2.Views.NWN2AreaViewer viewer = getAreaViewer(); NWN2Toolset.NWN2ToolsetMainForm mainForm = NWN2Toolset.NWN2ToolsetMainForm.App; NWN2GameArea area = viewer.Area; // Make waypoint NWN2Toolset.NWN2.Data.Instances.NWN2WaypointInstance wayPoint = new NWN2Toolset.NWN2.Data.Instances.NWN2WaypointInstance(); wayPoint.Tag = WAYPOINT_TAG; wayPoint.Position = new Vector3(coor[0], coor[1], coor[2]); area.AddInstance(wayPoint); debugOut("Point: " + p + " added"); } } }
/// <summary> /// Paint a line given the 2 points /// </summary> /// <param name="points"></param> private void makeLine(LinkedList <Pair <double, double> > points) { NWN2Toolset.NWN2.Views.NWN2AreaViewer viewer = getAreaViewer(); NWN2Toolset.NWN2ToolsetMainForm mainForm = NWN2Toolset.NWN2ToolsetMainForm.App; NWN2GameArea area = viewer.Area; TRN trn = new SFX.YATT.DAL.TRN(new System.IO.BinaryReader(area.TerrainResource.GetStream(false)), area.Name); Pair <Pair <double, double>, Pair <double, double> > resultPair = findUpperAndLower(points); Pair <double, double> upper = resultPair.X; Pair <double, double> lower = resultPair.Y; trn = ApplyLine(area, trn, upper, lower); System.IO.Stream stream = area.TerrainResource.GetStream(true); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); trn.Save(writer); stream.Flush(); stream.Close(); areaViewer.SaveContents(true, OEIShared.UI.OEIMessageBoxResult.OK); mainForm.WaitForPanelsToSave(); mainForm.CloseViewer(areaViewer, true); }
/// <summary> /// Raises an event indicating that a game object has been added to an area. /// </summary> protected void InstanceInsertedIntoCollection(OEICollectionWithEvents cList, int index, object value) { INWN2Instance ins = (INWN2Instance)value; NWN2GameArea area = (NWN2GameArea)cList.Tag; OnInstanceAdded(cList, new InstanceEventArgs(ins, area)); }
private void paintTriangles(LinkedList <Triangle> triangles) { NWN2Toolset.NWN2.Views.NWN2AreaViewer viewer = getAreaViewer(); if (viewer != null) { NWN2Toolset.NWN2ToolsetMainForm mainForm = NWN2Toolset.NWN2ToolsetMainForm.App; NWN2GameArea area = viewer.Area; TRN trn = new SFX.YATT.DAL.TRN(new System.IO.BinaryReader(area.TerrainResource.GetStream(false)), area.Name); // The random object we are going to use for all the instances Random ran = new Random(); area.Demand(); area.RefreshTerrainResource(); System.IO.Stream stream = area.TerrainResource.GetStream(true); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); foreach (Triangle triangle in triangles) { trn = ApplyTriangle(area, trn, triangle, triangle.getUpper(), triangle.getLower(), ran); } trn.Save(writer); stream.Flush(); stream.Close(); viewer.SaveContents(true, OEIShared.UI.OEIMessageBoxResult.OK); mainForm.WaitForPanelsToSave(); mainForm.CloseViewer(viewer, true); } }
/// <summary> /// Raises events based on which viewer has been opened. /// </summary> protected void ViewerOpened(int index, object value) { TabPage page = (TabPage)value; INWN2Viewer viewer = page.Control as INWN2Viewer; if (viewer == null) { return; } if (viewer.ViewedResource is NWN2GameScript) { OnScriptOpened(page.Parent, new ScriptEventArgs((NWN2GameScript)viewer.ViewedResource)); } else if (viewer.ViewedResource is NWN2GameConversation) { OnConversationOpened(page.Parent, new ConversationEventArgs((NWN2GameConversation)viewer.ViewedResource)); } else if (viewer.ViewedResource is NWN2GameArea) { NWN2GameArea area = (NWN2GameArea)viewer.ViewedResource; OnAreaOpened(page.Parent, new AreaEventArgs(area)); OEICollectionWithEvents.ChangeHandler cAdded = new OEICollectionWithEvents.ChangeHandler(InstanceInsertedIntoCollection); OEICollectionWithEvents.ChangeHandler cRemoved = new OEICollectionWithEvents.ChangeHandler(InstanceRemovedFromCollection); foreach (NWN2InstanceCollection instances in area.AllInstances) { instances.Inserted += cAdded; instances.Removed += cRemoved; } } }
protected void Watch(NWN2GameArea area) { if (area != null) { area.NameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { OnAreaNameChanged(oObject, eArgs); }; } }
/// <summary> /// Constructs a new <see cref="Area"/> instance. /// </summary> public AreaFacade(NWN2GameArea area) { if (area == null) { throw new ArgumentNullException("area"); } this.nwn2Area = area; }
public ObjectBlock GetBlock(Nwn2Address address) { if (address == null) { throw new ArgumentNullException("address"); } if (session.GetModule() == null) { throw new InvalidOperationException("No module is open."); } if (address.TargetType == Nwn2Type.Module) { return(blocks.CreateModuleBlock()); } else if (address.TargetType == Nwn2Type.Area) { NWN2GameArea area = session.GetArea(address.AreaTag); if (area == null) { throw new ArgumentException("No such area in the current module.", "area"); } else { return(blocks.CreateAreaBlock(area)); } } else { NWN2ObjectType type = Nwn2ScriptSlot.GetObjectType(address.TargetType).Value; INWN2Blueprint blueprint = session.GetBlueprint(address.InstanceTag, type); if (blueprint != null) { return(blocks.CreateInstanceBlockFromBlueprint(blueprint)); } foreach (NWN2AreaViewer viewer in NWN2Toolset.NWN2ToolsetMainForm.App.GetAllAreaViewers()) { NWN2InstanceCollection instances = session.GetObjectsByAddressInArea(address, viewer.Area.Tag); if (instances.Count > 0) { INWN2Instance instance = instances[0]; return(blocks.CreateInstanceBlock(instance)); } } return(null); } }
/// <summary> /// Creates an ObjectBlock representing a given area. /// </summary> /// <param name="area">The area to represent.</param> /// <returns>An ObjectBlock representing the given area.</returns> public ObjectBlock CreateAreaBlock(NWN2GameArea area) { if (area == null) { throw new ArgumentNullException("area"); } AreaBehaviour behaviour = CreateAreaBehaviour(area); ObjectBlock block = CreateAreaBlock(behaviour); return(block); }
public ObjectBlock CreateInstanceBlock(INWN2Instance instance, NWN2GameArea area) { if (instance == null) { throw new ArgumentNullException("instance"); } InstanceBehaviour behaviour = CreateInstanceBehaviour(instance, area); ObjectBlock block = CreateInstanceBlock(behaviour); return(block); }
/// <summary> /// Raises an event indicating that a script, area, or conversation has been added to the module. /// </summary> protected void ResourceInsertedIntoCollection(OEIDictionaryWithEvents cDictionary, object key, object value) { if (value is NWN2GameScript) { OnScriptAdded(cDictionary, new ScriptEventArgs((NWN2GameScript)value)); } else if (value is NWN2GameConversation) { OnConversationAdded(cDictionary, new ConversationEventArgs((NWN2GameConversation)value)); } else if (value is NWN2GameArea) { NWN2GameArea area = (NWN2GameArea)value; OnAreaAdded(cDictionary, new AreaEventArgs(area)); } }
public AreaBehaviour CreateAreaBehaviour(NWN2GameArea area) { if (area == null) { throw new ArgumentNullException("area"); } string tag = area.Tag; string displayName = area.DisplayName.GetSafeString(OEIShared.Utils.BWLanguages.CurrentLanguage).Value; if (String.IsNullOrEmpty(displayName)) { displayName = tag; } return(new AreaBehaviour(tag, displayName, area.HasTerrain)); }
public InstanceBehaviour CreateInstanceBehaviour(INWN2Instance instance, NWN2GameArea area) { if (instance == null) { throw new ArgumentNullException("instance"); } string tag = ((INWN2Object)instance).Tag; string displayName = GetDisplayName(instance); if (displayName == String.Empty) { displayName = tag; } string areaTag; if (area != null) { areaTag = area.Tag; } else if (instance.Area != null) { areaTag = instance.Area.Tag; } else { areaTag = String.Empty; } string resRef = instance.Template.ResRef.Value; string icon; if (instance is NWN2ItemInstance) { icon = ((NWN2ItemInstance)instance).Icon.ToString(); } else { icon = String.Empty; } return(new InstanceBehaviour(tag, displayName, instance.ObjectType, areaTag, resRef, icon)); }
/// <summary> /// This method finds the coordinates that have been clicked on the area (not the coordinates that have been clicked on in the toolset). /// </summary> /// <param name="X">The X coordinates from the toolset panel</param> /// <param name="Y">The Y coordinates from the toolset panel</param> /// <param name="area">The area we are working on</param> /// <returns></returns> private SFX.YATT.Tools.Vector <float> findAreaCoor(int X, int Y, NWN2GameArea area) { try { NWN2NetDisplayManager manager = NWN2NetDisplayManager.Instance; byte[] cMessage = null; bool flag = false; Random ran = new Random(); manager.BeginSynchronizedOperation(); int iMessageID = manager.PlanePick(areaViewer.AreaNetDisplayWindow, X, Y, NWN2ToolsetMainForm.App.TerrainEditor.TerrainValue); manager.WaitForMessageSynchronous(NetDisplayMessageType.TerrainPickResults, out cMessage, iMessageID); manager.EndSynchronizedOperation(); if (!flag) { BinaryReader reader = new BinaryReader(new MemoryStream(cMessage)); if (reader.ReadInt32() != areaViewer.AreaNetDisplayWindow.Scene.ID) { throw new Exception("Reader Error"); } int num = reader.ReadInt32(); // The coordinates from the mouse float valueX = reader.ReadSingle(); float valueY = reader.ReadSingle(); float valueZ = reader.ReadSingle(); SFX.YATT.Tools.Vector <float> vec = new SFX.YATT.Tools.Vector <float>(valueX, valueY, valueZ); return(vec); } else { return(null); } } catch (Exception e) { debugOut("Problem with finding the coordinates: " + e.Message); throw new Exception("Problem with finding the coordinates: " + e.Message); } }
protected void CreateInstancesFromArea(NWN2GameArea area) { if (!Utils.Nwn2ToolsetFunctions.ToolsetIsOpen()) { return; } if (area == null) { throw new ArgumentNullException("area"); } if (!NWN2Toolset.NWN2ToolsetMainForm.App.Module.Areas.Contains(area)) { throw new ArgumentException("Given area is not part of this module.", "area"); } if (!area.Loaded) { throw new ArgumentException("Area must be open in the toolset to create instances from it.", "area"); } foreach (NWN2ObjectType type in Enum.GetValues(typeof(NWN2ObjectType))) { string bag = String.Format(InstanceBagNamingFormat, type.ToString()); if (!manager.HasBag(bag)) { continue; } NWN2InstanceCollection instances = area.GetInstancesForObjectType(type); if (instances == null) { return; } foreach (INWN2Instance instance in instances) { ObjectBlock block = blocks.CreateInstanceBlock(instance, area); manager.AddMoveable(bag, block); } } }
/// <summary> /// Given the number of points selected, this part allows us to take the selected points and paint them with the selected information /// </summary> public void drawPolygon() { pointsAlready.Clear(); LinkedList <Pair <double, double> > points = new LinkedList <Pair <double, double> >(); NWN2AreaViewer view = getAreaViewer(); NWN2GameArea area = view.Area; foreach (NWN2Toolset.NWN2.Data.Instances.NWN2WaypointInstance waypoint in area.Waypoints) { if (waypoint.Tag.Equals(WAYPOINT_TAG)) { Vector3 vector = waypoint.Position; points.AddLast(new Pair <double, double>(vector.X, vector.Y)); } } if (points.Count < 2) { debugOut("1 or 0 points"); } else if (points.Count == 2) { debugOut("2 points"); makeLine(points); } else { debugOut("3 or more points"); LinkedList <Triangle> triangles = makeTriangles(points); if (triangles != null) { paintTriangles(triangles); } else { debugOut("The triangles are null!"); } } }
/// <summary> /// Constructor using an area /// </summary> /// <param name="area">The game area from where the actors will come from</param> public AreaContainer(NWN2GameArea area) { NWN2GameArea gameArea = area; gameArea.Demand(); tag = gameArea.Tag; Actor act; foreach (NWN2CreatureInstance creature in gameArea.Creatures) { act = new Actor(creature, EnumTypes.actorType.Creature); creaturePrints.AddLast(act); } foreach (NWN2DoorInstance door in gameArea.Doors) { act = new Actor(door, EnumTypes.actorType.Door); doorPrints.AddLast(act); } foreach (NWN2PlaceableInstance place in gameArea.Placeables) { act = new Actor(place, EnumTypes.actorType.Placeable); placePrints.AddLast(act); } foreach (NWN2TriggerInstance trigger in gameArea.Triggers) { act = new Actor(trigger, EnumTypes.actorType.TriggerRegion); triggerPrints.AddLast(act); } foreach (NWN2ItemInstance item in gameArea.Items) { act = new Actor(item, EnumTypes.actorType.Item); itemPrints.AddLast(act); } }
/// <summary> /// Raises an event indicating that a game object has been removed from an area. /// </summary> protected void InstanceRemovedFromCollection(OEICollectionWithEvents cList, int index, object value) { INWN2Instance ins = (INWN2Instance)value; try { foreach (NWN2GameArea a in NWN2Toolset.NWN2ToolsetMainForm.App.Module.Areas.Values) { foreach (NWN2InstanceCollection collection in a.AllInstances) { if (collection == cList) { OnInstanceRemoved(cList, new InstanceEventArgs(ins, a)); return; } } } } catch (Exception) {} // Always null when the instance has been removed: NWN2GameArea area = (NWN2GameArea)cList.Tag; OnInstanceRemoved(cList, new InstanceEventArgs(ins, area)); }
/// <summary> /// Constructs a new <see cref="Sussex.Flip.Games.NeverwinterNightsTwo.Utils.AreaEventArgs"/> instance. /// </summary> /// <param name="area">The area relating to this event.</param> public AreaEventArgs(NWN2GameArea area) { this.area = area; }
protected void UpdateScriptsFollowingTagChange(object obj, string oldName, string newName, bool createNewCopy) { if (obj == null) { throw new ArgumentNullException("obj"); } if (oldName == null) { throw new ArgumentNullException("oldName"); } if (newName == null) { throw new ArgumentNullException("newName"); } foreach (System.Reflection.PropertyInfo property in obj.GetType().GetProperties()) { if (property.Name.StartsWith("On")) { try { NWN2GameArea area = obj as NWN2GameArea; if (area != null && !session.AreaIsOpen(area)) { area.Demand(); } OEIShared.IO.IResourceEntry res = property.GetValue(obj, null) as OEIShared.IO.IResourceEntry; if (res != null) { NWN2GameScript script = new NWN2GameScript(res); if (ScriptHelper.WasCreatedByFlip(script)) { if (!script.Loaded) { script.Demand(); } string flipCode, address, naturalLanguage; AbstractScriptWriter.ParseNWScript(script.Data, out flipCode, out address, out naturalLanguage); string newAddress = address.Replace(oldName, newName); string newData = script.Data.Replace(address, newAddress); if (createNewCopy) // for instances, create a new copy of the existing script and point at that { NWN2GameScript newScript = session.AddScript(attacher.GetUnusedName(), newData); property.SetValue(obj, newScript.Resource, null); } else // for areas, change the existing script { string n = script.Name; session.DeleteScript(n); NWN2GameScript newScript = session.AddScript(n, newData); property.SetValue(obj, newScript.Resource, null); } } } } catch (Exception x) { MessageBox.Show("Something went wrong when trying to update the scripts on " + newName + ".\n" + x); } } } }
public void UpdateBlockWithNewTag(NWN2PropertyValueChangedEventArgs e) { try { if (tracking.Contains(e.PropertyName) && e.NewValue != e.OldValue) { foreach (object o in e.ChangedObjects) { if (o is INWN2Instance) { INWN2Instance instance = (INWN2Instance)o; InstanceBehaviour behaviour = blocks.CreateInstanceBehaviour(instance); string bag = String.Format(Nwn2MoveableProvider.InstanceBagNamingFormat, instance.ObjectType); if (window.BlockBox.HasBag(bag)) { UIElementCollection existingBlocks = window.BlockBox.GetMoveables(bag); // If it's the tag that's changed, use the old tag to search, otherwise use the current one: string tag; if (e.PropertyName == "Tag") { tag = e.OldValue as string; } else { tag = ((INWN2Object)instance).Tag; } bool updated = false; foreach (UIElement u in existingBlocks) { ObjectBlock existing = u as ObjectBlock; if (existing == null) { continue; } InstanceBehaviour existingBehaviour = existing.Behaviour as InstanceBehaviour; if (existingBehaviour == null) { continue; } // If you find an instance of the same type, resref and tag, replace its behaviour to update it: if (existingBehaviour.ResRef == behaviour.ResRef && existingBehaviour.Nwn2Type == behaviour.Nwn2Type && existingBehaviour.Tag == tag) { existing.Behaviour = behaviour; updated = true; break; } } if (!updated) { ObjectBlock block = blocks.CreateInstanceBlock(behaviour); window.BlockBox.AddMoveable(bag, block, false); } } if (e.PropertyName == "Tag") { UpdateScriptsFollowingTagChange(instance, (string)e.OldValue, (string)e.NewValue, true); } } else if (o is NWN2GameArea) { NWN2GameArea area = (NWN2GameArea)o; // Refuse changes to tags or areas unless they are to match the resource name: if (e.PropertyName == "Tag" && ((string)e.NewValue) != area.Name) { area.Tag = area.Name; return; } else if (e.PropertyName == "Display Name" && (Nwn2Strings.GetStringFromOEIString((OEIShared.Utils.OEIExoLocString)e.NewValue) != area.Name)) { area.DisplayName = Nwn2Strings.GetOEIStringFromString(area.Name); return; } AreaBehaviour behaviour = blocks.CreateAreaBehaviour(area); if (window.BlockBox.HasBag(Nwn2MoveableProvider.AreasBagName)) { UIElementCollection existingBlocks = window.BlockBox.GetMoveables(Nwn2MoveableProvider.AreasBagName); string tag; if (e.PropertyName == "Tag") { tag = e.OldValue as string; } else { tag = area.Tag; } bool updated = false; foreach (UIElement u in existingBlocks) { ObjectBlock existing = u as ObjectBlock; if (existing == null) { continue; } AreaBehaviour existingBehaviour = existing.Behaviour as AreaBehaviour; if (existingBehaviour == null) { continue; } // If you find an area with the same tag, replace its behaviour to update it: if (existingBehaviour.Tag == tag) { existing.Behaviour = behaviour; updated = true; break; } } if (!updated) { ObjectBlock block = blocks.CreateAreaBlock(behaviour); window.BlockBox.AddMoveable(Nwn2MoveableProvider.AreasBagName, block, false); } } } } } } catch (Exception x) { MessageBox.Show("Something went wrong when updating a block.\n\n" + x); } }
protected void TrackToolsetChanges(ToolsetEventReporter reporter) { if (!reporter.IsRunning) { reporter.Start(); } reporter.ModuleChanged += delegate(object oSender, ModuleChangedEventArgs eArgs) { /* Fires when a module closes, but that doesn't mean that the new module has * been fully opened yet... usually takes a while! */ Action action = new Action ( delegate() { if (manager != null) { manager.EmptyBag(AreasBagName); foreach (NWN2ObjectType type in Enum.GetValues(typeof(NWN2ObjectType))) { string bag = String.Format(InstanceBagNamingFormat, type); if (manager.HasBag(bag)) { manager.EmptyBag(bag); } } manager.AddMoveable("Creatures", blocks.CreatePlayerBlock()); } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); }; reporter.InstanceAdded += delegate(object sender, InstanceEventArgs e) { if (manager == null) { return; } string bag = String.Format(InstanceBagNamingFormat, e.Instance.ObjectType.ToString()); if (!manager.HasBag(bag)) { return; } ObjectBlock block = blocks.CreateInstanceBlock(e.Instance, e.Area); manager.AddMoveable(bag, block); }; reporter.InstanceRemoved += delegate(object sender, InstanceEventArgs e) { if (manager == null || e.Instance == null) { return; } string bag = String.Format(InstanceBagNamingFormat, Nwn2ScriptSlot.GetNwn2Type(e.Instance.ObjectType)); if (!manager.HasBag(bag)) { return; } try { UIElementCollection collection = manager.GetMoveables(bag); ObjectBlock lost = blocks.CreateInstanceBlock(e.Instance, e.Area); foreach (ObjectBlock block in collection) { if (block.Equals(lost)) { manager.RemoveMoveable(bag, block); return; } } } catch (Exception) {} }; reporter.BlueprintAdded += delegate(object sender, BlueprintEventArgs e) { if (manager == null || e.Blueprint == null) { return; } if (nt.CreatedByNarrativeThreads(e.Blueprint)) { Thread thread = new Thread(new ParameterizedThreadStart(CreateNarrativeThreadsBlock)); thread.IsBackground = true; thread.Start(e.Blueprint); } if (loadBlueprints) { Action action = new Action ( delegate() { string bag = String.Format(BlueprintBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock block = blocks.CreateBlueprintBlock(e.Blueprint); manager.AddMoveable(bag, block); } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } }; reporter.BlueprintRemoved += delegate(object sender, BlueprintEventArgs e) { if (manager == null || e.Blueprint == null) { return; } if (nt.CreatedByNarrativeThreads(e.Blueprint)) { Action action = new Action ( delegate() { string bag = String.Format(InstanceBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock lost = blocks.CreateInstanceBlockFromBlueprint(e.Blueprint); ObjectBlock removing = null; foreach (ObjectBlock block in manager.GetMoveables(bag)) { if (block.Equals(lost)) { removing = block; break; } } if (removing != null) { manager.RemoveMoveable(bag, removing); } } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } if (loadBlueprints) { Action action = new Action ( delegate() { string bag = String.Format(BlueprintBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock lost = blocks.CreateBlueprintBlock(e.Blueprint); ObjectBlock removing = null; foreach (ObjectBlock block in manager.GetMoveables(bag)) { if (block.Equals(lost)) { removing = block; break; } } if (removing != null) { manager.RemoveMoveable(bag, removing); } } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } }; reporter.AreaOpened += delegate(object sender, AreaEventArgs e) { if (manager == null) { return; } Thread thread = new Thread(new ParameterizedThreadStart(CreateBlocksWhenAreaIsReady)); thread.IsBackground = true; thread.Start(e.Area); }; reporter.ResourceViewerClosed += delegate(object sender, ResourceViewerClosedEventArgs e) { if (manager == null) { return; } foreach (Moveable moveable in manager.GetMoveables(AreasBagName)) { ObjectBlock block = moveable as ObjectBlock; if (block == null) { continue; } AreaBehaviour area = block.Behaviour as AreaBehaviour; if (area == null) { continue; } // Assumes that there are no conversations or scripts with the same name as an // area, but there's no immediately apparent way around this: // (TODO: Could check that module doesn't have a script or conversation of the same name.) if (area.Identifier == e.ResourceName) { manager.RemoveMoveable(AreasBagName, moveable); break; } } if (NWN2ToolsetMainForm.App.Module != null && NWN2ToolsetMainForm.App.Module.Areas.ContainsCaseInsensitive(e.ResourceName)) { // At this point we think it's an area that's been closed, so remove // any instances associated with that area: foreach (NWN2ObjectType type in Enum.GetValues(typeof(NWN2ObjectType))) { string bag = String.Format(InstanceBagNamingFormat, type); if (manager.HasBag(bag)) { List <Moveable> removing = new List <Moveable>(); foreach (Moveable moveable in manager.GetMoveables(bag)) { ObjectBlock block = moveable as ObjectBlock; if (block == null) { continue; } InstanceBehaviour instance = block.Behaviour as InstanceBehaviour; if (instance == null) { continue; } if (instance.AreaTag.ToLower() == e.ResourceName.ToLower()) { removing.Add(moveable); } } foreach (Moveable moveable in removing) { manager.RemoveMoveable(bag, moveable); } } } } }; // Ensure that an area always has the same resource name and tag: reporter.AreaNameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { NWN2GameArea area = eArgs.Item as NWN2GameArea; if (area == null) { return; } string blockHasTag = area.Tag; if (area.Tag != area.Name) { area.Tag = area.Name; } OEIShared.Utils.OEIExoLocString oeiStr = Nwn2Strings.GetOEIStringFromString(area.Name); if (area.DisplayName != oeiStr) { area.DisplayName = oeiStr; } // Note that this will only work for areas that are currently open... // we'll deal with changing the name of closed areas when they open. // Update the area block, if the area is open: bool open = false; foreach (NWN2AreaViewer av in NWN2ToolsetMainForm.App.GetAllAreaViewers()) { if (av.Area == area) { open = true; break; } } if (!open) { return; } AreaBehaviour behaviour = blocks.CreateAreaBehaviour(area); if (manager.HasBag(AreasBagName)) { UIElementCollection existingBlocks = manager.GetMoveables(AreasBagName); bool updated = false; foreach (UIElement u in existingBlocks) { ObjectBlock existing = u as ObjectBlock; if (existing == null) { continue; } AreaBehaviour existingBehaviour = existing.Behaviour as AreaBehaviour; if (existingBehaviour == null) { continue; } // If you find an area with the same tag, replace its behaviour to update it: if (existingBehaviour.Tag == blockHasTag) { existing.Behaviour = behaviour; updated = true; break; } } if (!updated) { ObjectBlock block = blocks.CreateAreaBlock(behaviour); manager.AddMoveable(AreasBagName, block, false); } } }; // If a script has its name changed, change it back: reporter.ScriptNameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { Thread thread = new Thread(new ParameterizedThreadStart(ReverseScriptNameChange)); thread.IsBackground = false; thread.Start(eArgs); }; }
protected void WatchModule(NWN2GameModule mod) { /* Only tracking blueprints which are added to and removed from the module... * this is correct for our purposes! Narrative Threads only uses the module blueprint collections. */ if (mod != null) { /* There seems to be a bug where the following events events fire at a later stage... they do * fire when they should, but when the paused test is allowed to complete, they fire again. */ foreach (NWN2BlueprintCollection bc in mod.BlueprintCollections) { bc.Inserted += delegate(OEICollectionWithEvents cList, int index, object value) { OnBlueprintAdded(bc, new BlueprintEventArgs((INWN2Blueprint)value)); }; bc.Removed += delegate(OEICollectionWithEvents cList, int index, object value) { OnBlueprintRemoved(bc, new BlueprintEventArgs((INWN2Blueprint)value)); }; } List <OEIDictionaryWithEvents> dictionaries; dictionaries = new List <OEIDictionaryWithEvents> { mod.Areas, mod.Conversations, mod.Scripts }; OEIDictionaryWithEvents.ChangeHandler dAdded = new OEIDictionaryWithEvents.ChangeHandler(ResourceInsertedIntoCollection); OEIDictionaryWithEvents.ChangeHandler dRemoved = new OEIDictionaryWithEvents.ChangeHandler(ResourceRemovedFromCollection); foreach (OEIDictionaryWithEvents dictionary in dictionaries) { dictionary.Inserted += dAdded; dictionary.Removed += dRemoved; } // Watch for changes to the names of areas, conversations and scripts: foreach (NWN2GameArea area in mod.Areas) { Watch(area); } foreach (NWN2GameConversation conversation in mod.Conversations) { Watch(conversation); } foreach (NWN2GameScript script in mod.Scripts) { Watch(script); } mod.Areas.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameArea area = value as NWN2GameArea; if (area != null) { Watch(area); } }; mod.Conversations.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameConversation conversation = value as NWN2GameConversation; if (conversation != null) { Watch(conversation); } }; mod.Scripts.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameScript script = value as NWN2GameScript; if (script != null) { Watch(script); } }; } }
/// <summary> /// Constructs a new <see cref="Sussex.Flip.Games.NeverwinterNightsTwo.Utils.InstanceEventArgs"/> instance. /// </summary> /// <param name="instance">The instance relating to this event.</param> /// <param name="area">The area that owns (or owned) the instance.</param> public InstanceEventArgs(INWN2Instance instance, NWN2GameArea area) { this.instance = instance; this.area = area; }
/// <summary> /// Translates Flip source into NWScript, compiles it, /// and attaches the results to a Neverwinter Nights 2 module. /// </summary> /// <param name="source">The Flip source to be compiled.</param> /// <param name="address">An address representing the location /// to attach this script to.</param> /// <returns>The name the script was saved under.</returns> public override string Attach(FlipScript source, string address) { if (source == null) { throw new ArgumentNullException("source"); } if (address == null) { throw new ArgumentNullException("address"); } if (address == String.Empty) { throw new ArgumentException("Must provide a valid address for attaching script.", "address"); } if (!Nwn2ToolsetFunctions.ToolsetIsOpen()) { throw new InvalidOperationException("Toolset must be open to attach scripts."); } NWN2GameModule module = session.GetModule(); if (module == null) { throw new InvalidOperationException("No module is currently open in the toolset."); } string name = GetUnusedName(); try { if (name.Length > 32) { throw new ApplicationException("Cannot attach script under the generated name ('" + name + "') " + "because it is of length " + name.Length + ", and the maximum " + "valid length of a resource name for NWN2 is 32."); } NWN2GameScript script = session.AddScript(name, source.Code); session.CompileScript(script); if (address.StartsWith("Conversation")) { Nwn2ConversationAddress convAddress = new Nwn2ConversationAddress(address); NWN2GameConversation conversation = session.GetConversation(convAddress.Conversation); if (conversation == null) { throw new ArgumentException("Conversation '" + convAddress.Conversation + "' was not found in current module.", "address"); } // foreach (NWN2Toolset.NWN2.Views.INWN2Viewer v in NWN2Toolset.NWN2ToolsetMainForm.App.GetAllViewers()) { // NWN2Toolset.NWN2.Views.NWN2ConversationViewer cv = v as NWN2Toolset.NWN2.Views.NWN2ConversationViewer; // if (cv != null) { // System.Windows.MessageBox.Show("From viewer...\n" + cv.Conversation.Name + // "\nConnectors: " + cv.Conversation.AllConnectors.Count + "\n" + // "Entries: " + cv.Conversation.Entries.Count + "\n" + // "Replies: " + cv.Conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); // } // } // // // System.Windows.MessageBox.Show("From module, before insisting on load...\n" + conversation.Name + // "\nConnectors: " + conversation.AllConnectors.Count + "\n" + // "Entries: " + conversation.Entries.Count + "\n" + // "Replies: " + conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); // // // // if (!conversation.Loaded) conversation.Demand(); // // // System.Windows.MessageBox.Show("From module, after insisting on load...\n" + conversation.Name + // "\nConnectors: " + conversation.AllConnectors.Count + "\n" + // "Entries: " + conversation.Entries.Count + "\n" + // "Replies: " + conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); NWN2ConversationLine line = session.GetConversationLine(conversation, convAddress.LineID); if (line == null) { throw new ArgumentException("Line with ID " + convAddress.LineID + " was not found in current module.", "address"); } if (convAddress.AttachedAs == ScriptType.Conditional) { session.AttachScriptToConversationAsCondition(script, line, conversation); } else { session.AttachScriptToConversation(script, line, conversation); } } else { Nwn2Address nwn2Address = new Nwn2Address(address); if (!Scripts.IsEventRaiser(nwn2Address.TargetType)) { throw new ArgumentException("Cannot attach scripts to a " + nwn2Address.TargetType + "."); } if (nwn2Address.TargetType == Nwn2Type.Module) { session.AttachScriptToModule(script, nwn2Address.TargetSlot); } else if (nwn2Address.TargetType == Nwn2Type.Area) { NWN2GameArea area = session.GetArea(nwn2Address.AreaTag); if (area == null) { throw new ArgumentException("Area '" + nwn2Address.AreaTag + "' was not found in current module.", "address"); } session.AttachScriptToArea(script, area, nwn2Address.TargetSlot); } else { /* * We want to attach to ALL instances matching the address in ALL OPEN areas, ignoring AreaTag and UseIndex. */ NWN2ObjectType nwn2ObjectType = Nwn2ScriptSlot.GetObjectType(nwn2Address.TargetType).Value; bool attached = false; foreach (NWN2GameArea a in module.Areas.Values) { if (!session.AreaIsOpen(a)) { continue; } NWN2InstanceCollection instances = session.GetObjectsByTag(a, nwn2ObjectType, nwn2Address.InstanceTag); foreach (INWN2Instance instance in instances) { session.AttachScriptToObject(script, instance, nwn2Address.TargetSlot); attached = true; } } /* * We also want to attach to any blueprints which use this tag as their resref. */ // First check that if a blueprint which uses this tag as resref exists, it was created by Narrative Threads: if (nt.CreatedByNarrativeThreads(Nwn2ScriptSlot.GetNwn2Type(nwn2ObjectType), nwn2Address.InstanceTag)) { INWN2Blueprint blueprint = session.GetBlueprint(nwn2Address.InstanceTag.ToLower(), nwn2ObjectType); if (blueprint != null) { session.AttachScriptToBlueprint(script, blueprint, nwn2Address.TargetSlot); attached = true; } } if (!attached) { string error; if (nt.IsLoaded) { error = String.Format("There isn't a {0} with tag '{1}' in any of the areas that are open, or " + "in the blueprints collection.", nwn2Address.TargetType, nwn2Address.InstanceTag); } else { error = String.Format("There isn't a {0} with tag '{1}' in any of the areas that are open.", nwn2Address.TargetType, nwn2Address.InstanceTag); } throw new MatchingInstanceNotFoundException(error, nwn2Address); } } } } catch (MatchingInstanceNotFoundException x) { throw x; } catch (Exception x) { throw new ApplicationException("Something went wrong while saving and attaching script.", x); } if (backups != null) { if (!Directory.Exists(backups)) { try { Directory.CreateDirectory(backups); } catch (Exception) { return(name); } } string saveTo; if (createFoldersForUsers) { try { saveTo = Path.Combine(backups, Environment.UserName); if (!Directory.Exists(saveTo)) { Directory.CreateDirectory(saveTo); } saveTo = Path.Combine(saveTo, module.Name); if (!Directory.Exists(saveTo)) { Directory.CreateDirectory(saveTo); } } catch (Exception) { saveTo = backups; } } else { saveTo = backups; } try { WriteBackup(name, saveTo, source.Code); } catch (Exception) { } } return(name); }
/// <summary> /// This method finds the coordinates that have been clicked on the area (not the coordinates that have been clicked on in the toolset). /// </summary> /// <param name="X">The X coordinates from the toolset panel</param> /// <param name="Y">The Y coordinates from the toolset panel</param> /// <param name="area">The area we are working on</param> /// <returns></returns> private SFX.YATT.Tools.Vector<float> findAreaCoor(int X, int Y, NWN2GameArea area) { try { NWN2NetDisplayManager manager = NWN2NetDisplayManager.Instance; byte[] cMessage = null; bool flag = false; Random ran = new Random(); manager.BeginSynchronizedOperation(); int iMessageID = manager.PlanePick(areaViewer.AreaNetDisplayWindow, X, Y, NWN2ToolsetMainForm.App.TerrainEditor.TerrainValue); manager.WaitForMessageSynchronous(NetDisplayMessageType.TerrainPickResults, out cMessage, iMessageID); manager.EndSynchronizedOperation(); if (!flag) { BinaryReader reader = new BinaryReader(new MemoryStream(cMessage)); if (reader.ReadInt32() != areaViewer.AreaNetDisplayWindow.Scene.ID) { throw new Exception("Reader Error"); } int num = reader.ReadInt32(); // The coordinates from the mouse float valueX = reader.ReadSingle(); float valueY = reader.ReadSingle(); float valueZ = reader.ReadSingle(); SFX.YATT.Tools.Vector<float> vec = new SFX.YATT.Tools.Vector<float>(valueX, valueY, valueZ); return vec; } else { return null; } } catch (Exception e) { debugOut("Problem with finding the coordinates: " + e.Message); throw new Exception("Problem with finding the coordinates: " + e.Message); } }
/// <summary> /// /// </summary> /// <param name="script"></param> /// <param name="attachment">Only return a script if it is attached /// in the manner indicated by this parameter.</param> /// <returns></returns> /// <remarks>This method expects that the NWN2GameScript is already Loaded /// (that is, the responsibility for calling Demand() falls to the client.)</remarks> public FlipScript GetFlipScript(NWN2GameScript script, Attachment attachment) { if (script == null) { throw new ArgumentNullException("script"); } string code, address, naturalLanguage; ScriptWriter.ParseNWScript(script.Data, out code, out address, out naturalLanguage); ScriptType scriptType = GetScriptType(script); if (attachment == Attachment.Ignore) { return(new FlipScript(code, scriptType, script.Name)); } NWN2GameModule mod = session.GetModule(); if (mod == null) { throw new InvalidOperationException("No module is open."); } Nwn2Address nwn2Address; Nwn2ConversationAddress nwn2ConversationAddress; switch (attachment) { case Attachment.Attached: nwn2Address = Nwn2Address.TryCreate(address); nwn2ConversationAddress = Nwn2ConversationAddress.TryCreate(address); break; case Attachment.AttachedToConversation: nwn2Address = null; nwn2ConversationAddress = Nwn2ConversationAddress.TryCreate(address); break; case Attachment.AttachedToScriptSlot: nwn2Address = Nwn2Address.TryCreate(address); nwn2ConversationAddress = null; break; default: nwn2Address = null; nwn2ConversationAddress = null; break; } if (nwn2Address != null) { try { if (nwn2Address.TargetType == Nwn2Type.Module) { IResourceEntry resource = typeof(NWN2ModuleInformation).GetProperty(nwn2Address.TargetSlot).GetValue(mod.ModuleInfo, null) as IResourceEntry; if (resource != null && resource.ResRef.Value == script.Name) { return(new FlipScript(code, scriptType, script.Name)); } } else if (nwn2Address.TargetType == Nwn2Type.Area) { NWN2GameArea area = session.GetArea(nwn2Address.AreaTag); if (area != null) { IResourceEntry resource = typeof(NWN2GameArea).GetProperty(nwn2Address.TargetSlot).GetValue(area, null) as IResourceEntry; if (resource != null && resource.ResRef.Value == script.Name) { return(new FlipScript(code, scriptType, script.Name)); } } } else { /* * The script might be attached to a Narrative Threads blueprint: */ // First check that if a blueprint which uses this tag as resref exists, it was created by Narrative Threads: if (nt.CreatedByNarrativeThreads(nwn2Address.TargetType, nwn2Address.InstanceTag)) { NWN2ObjectType objectType = Nwn2ScriptSlot.GetObjectType(nwn2Address.TargetType).Value; INWN2Blueprint blueprint = session.GetBlueprint(nwn2Address.InstanceTag.ToLower(), objectType); if (blueprint != null) { IResourceEntry resource = blueprint.GetType().GetProperty(nwn2Address.TargetSlot).GetValue(blueprint, null) as IResourceEntry; if (resource != null && resource.ResRef.Value == script.Name) { return(new FlipScript(code, scriptType, script.Name)); } } } // Check through all OPEN areas. foreach (NWN2GameArea area in mod.Areas.Values) { if (!session.AreaIsOpen(area)) { continue; } NWN2InstanceCollection instances = session.GetObjectsByAddressInArea(nwn2Address, area.Tag); if (instances != null) { // Check the script is still attached to the target object in the slot it claims to be, // in at least one instance, and if so add it to the set of scripts to be opened: foreach (INWN2Instance instance in instances) { IResourceEntry resource = instance.GetType().GetProperty(nwn2Address.TargetSlot).GetValue(instance, null) as IResourceEntry; if (resource != null && resource.ResRef.Value == script.Name) { return(new FlipScript(code, scriptType, script.Name)); } } } } } } catch (Exception x) { throw new ApplicationException(String.Format("Failed to handle script + '{0}' properly.", script.Name), x); } } else if (nwn2ConversationAddress != null) // Check through all conversations, regardless of whether they're open. { NWN2GameConversation conversation = session.GetConversation(nwn2ConversationAddress.Conversation); if (conversation == null) { return(null); } if (NWN2Toolset.NWN2ToolsetMainForm.App.GetViewerForResource(conversation) == null) { conversation.Demand(); } NWN2ConversationLine line = conversation.GetLineFromGUID(nwn2ConversationAddress.LineID); if (line == null) { return(null); } if (line.Actions.Count == 0) { return(null); } IResourceEntry resource = line.Actions[0].Script; if (resource != null && resource.ResRef.Value == script.Name) { return(new FlipScript(code, scriptType, script.Name)); } } return(null); }