#region ================== Copyright (c) 2007 Pascal vd Heiden /* * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com * This program is released under GNU General Public License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #endregion #region ================== Namespaces using System; using System.Collections.Generic; using System.Windows.Forms; using CodeImp.DoomBuilder.GZBuilder; using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Rendering; using System.Drawing; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Types; #endregion namespace CodeImp.DoomBuilder.BuilderModes { [FindReplace("Thing Action and Arguments", BrowseButton = true)] internal class FindThingAction : BaseFindThing { #region ================== Constants #endregion #region ================== Variables #endregion #region ================== Properties public override Presentation RenderPresentation { get { return Presentation.Things; } } public override Image BrowseImage { get { return Properties.Resources.List; } } #endregion #region ================== Constructor / Destructor #endregion #region ================== Methods // This is called to test if the item should be displayed public override bool DetermineVisiblity() { return General.Map.FormatInterface.HasThingAction; } // This is called when the browse button is pressed public override string Browse(string initialvalue) { int action; int.TryParse(initialvalue, out action); action = General.Interface.BrowseLinedefActions(BuilderPlug.Me.FindReplaceForm, action); return action.ToString(); } // This is called to perform a search (and replace) // Returns a list of items to show in the results list // replacewith is null when not replacing public override FindReplaceObject[] Find(string value, bool withinselection, bool replace, string replacewith, bool keepselection) { List objs = new List(); // Interpret the replacement int replaceaction = 0; string replacearg0str = string.Empty; //mxd int[] replaceargs = null; //mxd if(replace) { string[] replaceparts = replacewith.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // If it cannot be interpreted, set replacewith to null (not replacing at all) if(replaceparts.Length == 0) replacewith = null; //mxd if(!int.TryParse(replaceparts[0], out replaceaction)) replacewith = null; if(replaceaction < 0) replacewith = null; if(replaceaction > Int16.MaxValue) replacewith = null; if(replacewith == null) { MessageBox.Show("Invalid replace value for this search type!", "Find and Replace", MessageBoxButtons.OK, MessageBoxIcon.Error); return objs.ToArray(); } //mxd. Now try parsing the args if(replaceparts.Length > 1) { replaceargs = new[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; int i = 1; //mxd. Named script search support... if(General.Map.UDMF && Array.IndexOf(GZGeneral.ACS_SPECIALS, replaceaction) != -1) { string possiblescriptname = replaceparts[1].Trim().Replace("\"", "").ToLowerInvariant(); int tmp; if(!string.IsNullOrEmpty(possiblescriptname) && possiblescriptname != "*" && !int.TryParse(possiblescriptname, out tmp)) { replacearg0str = possiblescriptname; i = 2; } } for(; i < replaceparts.Length && i < replaceargs.Length + 1; i++) { int argout; if(replaceparts[i].Trim() == "*") continue; //mxd. Any arg value support if(int.TryParse(replaceparts[i].Trim(), out argout)) replaceargs[i - 1] = argout; } } } // Interpret the number given int action; string[] parts = value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); //For the search, the user may make the following queries: // action arg0 arg1 arg2 arg3 arg4 // action arg0str arg1 arg2 arg3 arg4 // //this allows users to search for lines that contain actions with specific arguments. //useful for locating script lines if(int.TryParse(parts[0], out action)) { int[] args = null; string arg0str = string.Empty; //mxd //parse the arg values out if(parts.Length > 1) { args = new[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; int i = 1; //mxd. Named script search support... if(General.Map.UDMF && Array.IndexOf(GZGeneral.ACS_SPECIALS, action) != -1) { string possiblescriptname = parts[1].Trim().Replace("\"", "").ToLowerInvariant(); int tmp; if(!string.IsNullOrEmpty(possiblescriptname) && possiblescriptname != "*" && !int.TryParse(possiblescriptname, out tmp)) { arg0str = possiblescriptname; i = 2; } } for(; i < parts.Length && i < args.Length + 1; i++) { int argout; if(parts[i].Trim() == "*") continue; //mxd. Any arg value support if(int.TryParse(parts[i].Trim(), out argout)) args[i - 1] = argout; } } // Where to search? ICollection list = withinselection ? General.Map.Map.GetSelectedThings(true) : General.Map.Map.Things; // Go for all things foreach(Thing t in list) { // Action matches? if(t.Action != action) continue; bool match = true; string argtext = ""; //if args were specified, then process them if(args != null) { int x = 0; argtext = " args: ("; //mxd. Check script name... if(!string.IsNullOrEmpty(arg0str)) { string s = t.Fields.GetValue("arg0str", string.Empty); if(s.ToLowerInvariant() != arg0str) match = false; else argtext += "\"" + s + "\""; x = 1; } for(; x < args.Length; x++) { if(args[x] != int.MinValue && args[x] != t.Args[x]) { match = false; break; } argtext += (x == 0 ? "" : ",") + t.Args[x]; } argtext += ")"; } if(match) { // Replace if(replace) { t.Action = replaceaction; //mxd. Replace args as well? if(replaceargs != null) { int i = 0; if(!string.IsNullOrEmpty(replacearg0str)) { t.Fields["arg0str"] = new UniValue(UniversalType.String, replacearg0str); i = 1; } for(; i < replaceargs.Length; i++) { if(replaceargs[i] != int.MinValue) t.Args[i] = replaceargs[i]; } } } // Add to list ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type); objs.Add(new FindReplaceObject(t, "Thing " + t.Index + " (" + ti.Title + ")" + argtext)); } } } return objs.ToArray(); } #endregion } }