ZoneBuilder/Source/Plugins/BuilderModes/FindReplace/FindThingAction.cs

247 lines
6.9 KiB
C#

#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<FindReplaceObject> objs = new List<FindReplaceObject>();
// 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<Thing> 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.SRB2Type);
objs.Add(new FindReplaceObject(t, "Thing " + t.Index + " (" + ti.Title + ")" + argtext));
}
}
}
return objs.ToArray();
}
#endregion
}
}