mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 20:02:48 +00:00
Merge remote-tracking branch 'udb/master'
This commit is contained in:
commit
3726bb5a3b
18 changed files with 473 additions and 146 deletions
2
.editorconfig
Normal file
2
.editorconfig
Normal file
|
@ -0,0 +1,2 @@
|
|||
[*.cs]
|
||||
indent_style = tab
|
|
@ -7,7 +7,7 @@ compilers
|
|||
// All others are the required files (the setting names do not matter)
|
||||
bcc
|
||||
{
|
||||
interface = "AccCompiler";
|
||||
interface = "BccCompiler";
|
||||
program = "bcc.exe";
|
||||
zcommon = "zcommon.bcs";
|
||||
std = "std.acs";
|
||||
|
|
|
@ -648,6 +648,138 @@ universalfields
|
|||
default = 0.0;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
nogradient_top
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
flipgradient_top
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
clampgradient_top
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
useowncolors_top
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
uppercolor_top
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
lowercolor_top
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
nogradient_mid
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
flipgradient_mid
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
clampgradient_mid
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
useowncolors_mid
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
uppercolor_mid
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
lowercolor_mid
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
nogradient_bottom
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
flipgradient_bottom
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
clampgradient_bottom
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
useowncolors_bottom
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
managed = false;
|
||||
|
||||
}
|
||||
|
||||
uppercolor_bottom
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
|
||||
lowercolor_bottom
|
||||
{
|
||||
type = 10;
|
||||
default = 16777215;
|
||||
managed = false;
|
||||
}
|
||||
}
|
||||
|
||||
thing
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="Compilers\AccCompiler.cs" />
|
||||
<Compile Include="Compilers\BccCompiler.cs" />
|
||||
<Compile Include="Compilers\NodesCompiler.cs" />
|
||||
<Compile Include="Config\ArgumentInfo.cs" />
|
||||
<Compile Include="Config\ExternalCommandSettings.cs" />
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="Compilers\AccCompiler.cs" />
|
||||
<Compile Include="Compilers\BccCompiler.cs" />
|
||||
<Compile Include="Compilers\NodesCompiler.cs" />
|
||||
<Compile Include="Config\ArgumentInfo.cs" />
|
||||
<Compile Include="Config\ExternalCommandSettings.cs" />
|
||||
|
|
|
@ -30,18 +30,24 @@ using CodeImp.DoomBuilder.ZDoom.Scripting;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Compilers
|
||||
{
|
||||
internal sealed class AccCompiler : Compiler
|
||||
internal class AccCompiler : Compiler
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const string ACS_ERROR_FILE = "acs.err";
|
||||
|
||||
#region ================== Internal classes
|
||||
|
||||
protected class CompileContext { }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Constants
|
||||
|
||||
private const string ACS_ERROR_FILE = "acs.err";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private AcsParserSE parser; //mxd
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -52,7 +58,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
|
||||
// Constructor
|
||||
public AccCompiler(CompilerInfo info) : base(info, false)
|
||||
{
|
||||
|
@ -62,7 +68,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
public override void Dispose()
|
||||
{
|
||||
// Not already disposed?
|
||||
if(!isdisposed)
|
||||
if (!isdisposed)
|
||||
{
|
||||
// Clean up
|
||||
|
||||
|
@ -70,26 +76,116 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
protected virtual CompileContext OnBeforeProcessStart(ProcessStartInfo info)
|
||||
{
|
||||
return new CompileContext();
|
||||
}
|
||||
|
||||
protected virtual void OnCheckError(HashSet<string> includes, ProcessStartInfo processinfo, Process process, CompileContext context)
|
||||
{
|
||||
int line = 0;
|
||||
|
||||
// Now find the error file
|
||||
string errfile = Path.Combine(this.workingdir, ACS_ERROR_FILE);
|
||||
if (File.Exists(errfile))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Regex to find error lines
|
||||
Regex errlinematcher = new Regex(":[0-9]+: ", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
// Read all lines
|
||||
bool erroradded = false; //mxd
|
||||
string[] errlines = File.ReadAllLines(errfile);
|
||||
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
||||
while (line < errlines.Length)
|
||||
{
|
||||
// Check line
|
||||
string linestr = errlines[line];
|
||||
Match match = errlinematcher.Match(linestr);
|
||||
if (match.Success && (match.Index > 0))
|
||||
{
|
||||
CompilerError err = new CompilerError();
|
||||
|
||||
// The match without spaces and semicolon is the line number
|
||||
string linenr = match.Value.Replace(":", "").Trim();
|
||||
if (!int.TryParse(linenr, out err.linenumber))
|
||||
err.linenumber = CompilerError.NO_LINE_NUMBER;
|
||||
else
|
||||
err.linenumber--;
|
||||
|
||||
// Everything before the match is the filename
|
||||
err.filename = linestr.Substring(0, match.Index).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
//mxd. Get rid of temp directory path
|
||||
if (err.filename.StartsWith(temppath)) err.filename = err.filename.Replace(temppath, string.Empty);
|
||||
|
||||
if (!Path.IsPathRooted(err.filename))
|
||||
{
|
||||
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||
if (includes.Contains(err.filename))
|
||||
{
|
||||
foreach (DataReader dr in General.Map.Data.Containers)
|
||||
{
|
||||
if (dr is DirectoryReader && dr.FileExists(err.filename))
|
||||
{
|
||||
err.filename = Path.Combine(dr.Location.location, err.filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Everything after the match is the description
|
||||
err.description = linestr.Substring(match.Index + match.Length).Trim();
|
||||
|
||||
// Report the error
|
||||
ReportError(err);
|
||||
erroradded = true; //mxd
|
||||
}
|
||||
|
||||
// Next line
|
||||
line++;
|
||||
}
|
||||
|
||||
//mxd. Some ACC errors are not properly formatted. If that's the case, threat the whole acs.err as an error...
|
||||
if (!erroradded && errlines.Length > 0)
|
||||
{
|
||||
ReportError(new CompilerError(string.Join(Environment.NewLine, errlines)));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error reading errors (ironic, isn't it)
|
||||
ReportError(new CompilerError("Failed to retrieve compiler error report. " + e.GetType().Name + ": " + e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This runs the compiler
|
||||
public override bool Run()
|
||||
{
|
||||
Process process;
|
||||
int line = 0;
|
||||
string sourcedir = Path.GetDirectoryName(sourcefile);
|
||||
|
||||
// Preprocess the file
|
||||
parser = new AcsParserSE
|
||||
{
|
||||
IsMapScriptsLump = SourceIsMapScriptsLump,
|
||||
OnInclude = delegate(AcsParserSE se, string includefile, AcsParserSE.IncludeType includetype)
|
||||
OnInclude = delegate (AcsParserSE se, string includefile, AcsParserSE.IncludeType includetype)
|
||||
{
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(includefile);
|
||||
if(data == null)
|
||||
if (data == null)
|
||||
{
|
||||
se.ReportError("Unable to find include file \"" + includefile + "\".");
|
||||
return false; // Fial
|
||||
|
@ -100,31 +196,31 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
};
|
||||
|
||||
string inputfilepath = Path.Combine(this.tempdir.FullName, inputfile);
|
||||
using(FileStream stream = File.OpenRead(inputfilepath))
|
||||
using (FileStream stream = File.OpenRead(inputfilepath))
|
||||
{
|
||||
// Map SCRIPTS lump is empty. Abort the process without generating any warnings or errors.
|
||||
if(SourceIsMapScriptsLump && stream.Length == 0) return false;
|
||||
if (SourceIsMapScriptsLump && stream.Length == 0) return false;
|
||||
|
||||
DataLocation dl = new DataLocation(DataLocation.RESOURCE_DIRECTORY, Path.GetDirectoryName(inputfilepath), false, false, false, null);
|
||||
//mxd. TextResourceData must point to temp path when compiling WAD lumps for lump to be recognized as map lump when reporting errors...
|
||||
TextResourceData data = new TextResourceData(stream, dl, (SourceIsMapScriptsLump ? inputfile : sourcefile));
|
||||
if(!parser.Parse(data, info.Files, true, AcsParserSE.IncludeType.NONE, false))
|
||||
if (!parser.Parse(data, info.Files, true, AcsParserSE.IncludeType.NONE, false))
|
||||
{
|
||||
// Check for errors
|
||||
if(parser.HasError) ReportError(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
if (parser.HasError) ReportError(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. External lumps should be libraries
|
||||
if(!SourceIsMapScriptsLump && !parser.IsLibrary)
|
||||
if (!SourceIsMapScriptsLump && !parser.IsLibrary)
|
||||
{
|
||||
ReportError(new CompilerError("External ACS files can only be compiled as libraries.", sourcefile));
|
||||
return true;
|
||||
}
|
||||
|
||||
//mxd. Update script names if we are compiling the map SCRIPTS lump
|
||||
if(SourceIsMapScriptsLump)
|
||||
if (SourceIsMapScriptsLump)
|
||||
{
|
||||
General.Map.UpdateScriptNames(parser);
|
||||
}
|
||||
|
@ -132,22 +228,22 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
//xabis
|
||||
// Copy includes from the resources into the compiler's folder, preserving relative pathing and naming
|
||||
HashSet<string> includes = parser.GetIncludes(); //mxd
|
||||
foreach(string include in includes)
|
||||
foreach (string include in includes)
|
||||
{
|
||||
// Grab the script text from the resources
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(include);
|
||||
if(data != null && data.Stream != null)
|
||||
if (data != null && data.Stream != null)
|
||||
{
|
||||
// Pull the pk3 or directory sub folder out if applicable
|
||||
FileInfo fi = new FileInfo(Path.Combine(this.tempdir.FullName, include));
|
||||
|
||||
// Do not allow files to be overwritten, either accidentally or maliciously
|
||||
if(!fi.Exists)
|
||||
if (!fi.Exists)
|
||||
{
|
||||
General.WriteLogLine("Copying script include: " + include);
|
||||
|
||||
// Create the directory path as needed
|
||||
if(!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
if (!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
|
||||
// Dump the script into the target file
|
||||
BinaryReader reader = new BinaryReader(data.Stream);
|
||||
|
@ -164,7 +260,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
args = args.Replace("%PT", this.tempdir.FullName);
|
||||
args = args.Replace("%PS", sourcedir);
|
||||
args = args.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); //mxd. This fixes include path when the map is in a root directory
|
||||
|
||||
|
||||
// Setup process info
|
||||
ProcessStartInfo processinfo = new ProcessStartInfo();
|
||||
processinfo.Arguments = args;
|
||||
|
@ -174,114 +270,37 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
processinfo.UseShellExecute = true;
|
||||
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
processinfo.WorkingDirectory = this.workingdir;
|
||||
|
||||
|
||||
CompileContext context = OnBeforeProcessStart(processinfo);
|
||||
|
||||
// Output info
|
||||
General.WriteLogLine("Running compiler...");
|
||||
General.WriteLogLine("Program: " + processinfo.FileName);
|
||||
General.WriteLogLine("Arguments: " + processinfo.Arguments);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Start the compiler
|
||||
process = Process.Start(processinfo);
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
// Unable to start the compiler
|
||||
General.ShowErrorMessage("Unable to start the compiler (" + info.Name + "). " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Wait for compiler to complete
|
||||
process.WaitForExit();
|
||||
TimeSpan deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks);
|
||||
General.WriteLogLine("Compiler process has finished.");
|
||||
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
|
||||
|
||||
// Now find the error file
|
||||
string errfile = Path.Combine(this.workingdir, ACS_ERROR_FILE);
|
||||
if(File.Exists(errfile))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Regex to find error lines
|
||||
Regex errlinematcher = new Regex(":[0-9]+: ", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
// Read all lines
|
||||
bool erroradded = false; //mxd
|
||||
string[] errlines = File.ReadAllLines(errfile);
|
||||
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
||||
while(line < errlines.Length)
|
||||
{
|
||||
// Check line
|
||||
string linestr = errlines[line];
|
||||
Match match = errlinematcher.Match(linestr);
|
||||
if(match.Success && (match.Index > 0))
|
||||
{
|
||||
CompilerError err = new CompilerError();
|
||||
|
||||
// The match without spaces and semicolon is the line number
|
||||
string linenr = match.Value.Replace(":", "").Trim();
|
||||
if(!int.TryParse(linenr, out err.linenumber))
|
||||
err.linenumber = CompilerError.NO_LINE_NUMBER;
|
||||
else
|
||||
err.linenumber--;
|
||||
|
||||
// Everything before the match is the filename
|
||||
err.filename = linestr.Substring(0, match.Index).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
//mxd. Get rid of temp directory path
|
||||
if(err.filename.StartsWith(temppath)) err.filename = err.filename.Replace(temppath, string.Empty);
|
||||
|
||||
if(!Path.IsPathRooted(err.filename))
|
||||
{
|
||||
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||
if(includes.Contains(err.filename))
|
||||
{
|
||||
foreach(DataReader dr in General.Map.Data.Containers)
|
||||
{
|
||||
if(dr is DirectoryReader && dr.FileExists(err.filename))
|
||||
{
|
||||
err.filename = Path.Combine(dr.Location.location, err.filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Everything after the match is the description
|
||||
err.description = linestr.Substring(match.Index + match.Length).Trim();
|
||||
|
||||
// Report the error
|
||||
ReportError(err);
|
||||
erroradded = true; //mxd
|
||||
}
|
||||
|
||||
// Next line
|
||||
line++;
|
||||
}
|
||||
OnCheckError(includes, processinfo, process, context);
|
||||
|
||||
//mxd. Some ACC errors are not properly formatted. If that's the case, threat the whole acs.err as an error...
|
||||
if(!erroradded && errlines.Length > 0)
|
||||
{
|
||||
ReportError(new CompilerError(string.Join(Environment.NewLine, errlines)));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Error reading errors (ironic, isn't it)
|
||||
ReportError(new CompilerError("Failed to retrieve compiler error report. " + e.GetType().Name + ": " + e.Message));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
83
Source/Core/Compilers/BccCompiler.cs
Normal file
83
Source/Core/Compilers/BccCompiler.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace CodeImp.DoomBuilder.Compilers
|
||||
{
|
||||
internal class BccCompiler : AccCompiler
|
||||
{
|
||||
public BccCompiler(CompilerInfo info) : base(info) { }
|
||||
|
||||
protected override CompileContext OnBeforeProcessStart(ProcessStartInfo info)
|
||||
{
|
||||
info.UseShellExecute = false;
|
||||
info.CreateNoWindow = true;
|
||||
info.RedirectStandardError = true;
|
||||
info.RedirectStandardOutput = true;
|
||||
return new CompileContext();
|
||||
}
|
||||
|
||||
protected override void OnCheckError(HashSet<string> includes, ProcessStartInfo processinfo, Process process, CompileContext context)
|
||||
{
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
bool foundAnyErrors = false;
|
||||
string[] errorLines = process.StandardOutput.ReadToEnd().Split('\n');
|
||||
|
||||
foreach (string rawErrorLine in errorLines)
|
||||
{
|
||||
string[] rawError = rawErrorLine.Split(new char[] { ':' }, 4);
|
||||
if (rawError.Length != 4)
|
||||
continue;
|
||||
string errorFile = rawError[0];
|
||||
int errorLine;
|
||||
if (!int.TryParse(rawError[1], out errorLine))
|
||||
continue;
|
||||
errorLine--;
|
||||
// rawError[2] is ignored. in BCC, this contains the column at which the error happened. not supported in error viewer.
|
||||
string errorContent = rawError[3].Trim();
|
||||
|
||||
// logic copied from AccCompiler
|
||||
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
||||
if (errorFile.StartsWith(temppath)) errorFile = errorFile.Replace(temppath, string.Empty);
|
||||
|
||||
if (!Path.IsPathRooted(errorFile))
|
||||
{
|
||||
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||
if (includes.Contains(errorFile))
|
||||
{
|
||||
foreach (DataReader dr in General.Map.Data.Containers)
|
||||
{
|
||||
if (dr is DirectoryReader && dr.FileExists(errorFile))
|
||||
{
|
||||
errorFile = Path.Combine(dr.Location.location, errorFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||
errorFile = Path.Combine(processinfo.WorkingDirectory, errorFile);
|
||||
}
|
||||
}
|
||||
// end logic copied from AccCompiler
|
||||
|
||||
CompilerError err = new CompilerError();
|
||||
err.linenumber = errorLine;
|
||||
err.filename = errorFile;
|
||||
err.description = errorContent;
|
||||
|
||||
ReportError(err);
|
||||
foundAnyErrors = true;
|
||||
}
|
||||
|
||||
if (!foundAnyErrors)
|
||||
ReportError(new CompilerError(string.Join(Environment.NewLine, errorLines)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -640,23 +640,30 @@ namespace CodeImp.DoomBuilder.Config
|
|||
if (renderradius == 0)
|
||||
renderradius = radius;
|
||||
|
||||
//mxd. DistanceCheck. The value is CVAR. Also we'll need squared value
|
||||
if(actor.HasPropertyWithValue("distancecheck"))
|
||||
// DistanceCheck. The value is CVAR. Also we'll need squared value
|
||||
if (actor.HasPropertyWithValue("distancecheck"))
|
||||
{
|
||||
string cvarname = actor.GetPropertyValueString("distancecheck", 0);
|
||||
if(!General.Map.Data.CVars.Integers.ContainsKey(cvarname))
|
||||
if (General.Map.Data.CVars.AllNames.Contains(cvarname))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". DistanceCheck property references undefined cvar \"" + cvarname + "\"");
|
||||
distancechecksq = double.MaxValue;
|
||||
if (!General.Map.Data.CVars.Integers.ContainsKey(cvarname))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". DistanceCheck property references cvar \"" + cvarname + "\" which has to be of type int, but is not");
|
||||
distancechecksq = double.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
distancechecksq = Math.Pow(General.Map.Data.CVars.Integers[cvarname], 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
distancechecksq = Math.Pow(General.Map.Data.CVars.Integers[cvarname], 2);
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". DistanceCheck property references undefined cvar \"" + cvarname + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. Renderstyle
|
||||
if(actor.HasPropertyWithValue("renderstyle") && !actor.HasProperty("$ignorerenderstyle"))
|
||||
if (actor.HasPropertyWithValue("renderstyle") && !actor.HasProperty("$ignorerenderstyle"))
|
||||
renderstyle = actor.GetPropertyValueString("renderstyle", 0, true).ToLower();
|
||||
|
||||
//mxd. Alpha
|
||||
|
|
|
@ -69,8 +69,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
if(AllowDecimal)
|
||||
{
|
||||
newValue1 = Math.Round(UniFields.GetFloat(fields, field1, defaultValue), 2).ToString();
|
||||
newValue2 = Math.Round(UniFields.GetFloat(fields, field2, defaultValue), 2).ToString();
|
||||
newValue1 = UniFields.GetFloat(fields, field1, defaultValue).ToString();
|
||||
newValue2 = UniFields.GetFloat(fields, field2, defaultValue).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
internal readonly Dictionary<string, PixelColor> Colors;
|
||||
internal readonly Dictionary<string, bool> Booleans;
|
||||
internal readonly Dictionary<string, string> Strings;
|
||||
private readonly HashSet<string> allnames;
|
||||
internal readonly HashSet<string> AllNames;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
Colors = new Dictionary<string, PixelColor>(StringComparer.OrdinalIgnoreCase);
|
||||
Booleans = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
Strings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
allnames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
AllNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -39,40 +39,40 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
public bool AddValue(string name, int value)
|
||||
{
|
||||
if(allnames.Contains(name)) return false;
|
||||
allnames.Add(name);
|
||||
if(AllNames.Contains(name)) return false;
|
||||
AllNames.Add(name);
|
||||
Integers.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddValue(string name, float value)
|
||||
{
|
||||
if(allnames.Contains(name)) return false;
|
||||
allnames.Add(name);
|
||||
if(AllNames.Contains(name)) return false;
|
||||
AllNames.Add(name);
|
||||
Floats.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddValue(string name, PixelColor value)
|
||||
{
|
||||
if(allnames.Contains(name)) return false;
|
||||
allnames.Add(name);
|
||||
if(AllNames.Contains(name)) return false;
|
||||
AllNames.Add(name);
|
||||
Colors.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddValue(string name, bool value)
|
||||
{
|
||||
if(allnames.Contains(name)) return false;
|
||||
allnames.Add(name);
|
||||
if(AllNames.Contains(name)) return false;
|
||||
AllNames.Add(name);
|
||||
Booleans.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddValue(string name, string value)
|
||||
{
|
||||
if(allnames.Contains(name)) return false;
|
||||
allnames.Add(name);
|
||||
if(AllNames.Contains(name)) return false;
|
||||
AllNames.Add(name);
|
||||
Strings.Add(name, value);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ using System.Diagnostics;
|
|||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
|
@ -293,6 +294,13 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
#region ================== Configurations
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a given game configuration file exists.
|
||||
/// </summary>
|
||||
/// <param name="filename">The file name of the game configuration file.</param>
|
||||
/// <returns>true if the game configuration exists, false if it doesn't</returns>
|
||||
internal static bool ConfigurationInfoExist(string filename) => configs.Any(ci => string.Compare(Path.GetFileNameWithoutExtension(ci.Filename), Path.GetFileNameWithoutExtension(filename), true) == 0);
|
||||
|
||||
// This returns the game configuration info by filename
|
||||
internal static ConfigurationInfo GetConfigurationInfo(string filename)
|
||||
{
|
||||
|
|
|
@ -421,7 +421,16 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
// Copy the map lumps to the temp file
|
||||
General.WriteLogLine("Copying map lumps to temporary file...");
|
||||
CopyLumpsByType(mapwad, options.CurrentName, tempwadreader.WadFile, TEMP_MAP_HEADER, true, true, true, true);
|
||||
if (!CopyLumpsByType(mapwad, options.CurrentName, tempwadreader.WadFile, TEMP_MAP_HEADER, true, true, true, true))
|
||||
{
|
||||
// Ooops, the map doesn't exit. This should only happend when run from the command line using the "-map" parameter
|
||||
General.ErrorLogger.Add(ErrorType.Error, $"Map \"{options.CurrentName}\" does not exist in file \"{filepathname}\".");
|
||||
|
||||
// Close the map file
|
||||
mapwad.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close the map file
|
||||
mapwad.Dispose();
|
||||
|
@ -1660,7 +1669,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This copies specific map lumps from one WAD to another
|
||||
private void CopyLumpsByType(WAD source, string sourcemapname,
|
||||
private bool CopyLumpsByType(WAD source, string sourcemapname,
|
||||
WAD target, string targetmapname,
|
||||
bool copyrequired, bool copyblindcopy,
|
||||
bool copynodebuild, bool copyscript,
|
||||
|
@ -1734,7 +1743,11 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
target.WriteHeaders(); //mxd
|
||||
target.Compress(); // [ZZ]
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This finds a lump within the range of known lump names
|
||||
|
|
|
@ -620,7 +620,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
if(args[0] > General.Map.FormatInterface.MaxArgument) // Split sector tag?
|
||||
{
|
||||
int hitag = args[0] / 256;
|
||||
int lotag = args[0] - hitag;
|
||||
int lotag = args[0] % 256;
|
||||
|
||||
args[0] = lotag;
|
||||
args[4] = hitag;
|
||||
|
@ -652,7 +652,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
break;
|
||||
|
||||
default: // Convert tag to Line_SetIdentification?
|
||||
if(tags[0] > General.Map.FormatInterface.MinArgument)
|
||||
if(tags[0] > General.Map.FormatInterface.MaxArgument)
|
||||
{
|
||||
if(action != 0)
|
||||
{
|
||||
|
@ -662,7 +662,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
else // Convert to Line_SetIdentification
|
||||
{
|
||||
int hiid = tags[0] / 256;
|
||||
int loid = tags[0] - hiid;
|
||||
int loid = tags[0] % 256;
|
||||
|
||||
action = 121;
|
||||
args[0] = loid;
|
||||
|
|
|
@ -617,7 +617,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
if(!resourcesunloaded)
|
||||
{
|
||||
ShaderName pass = Renderer.FullBrightness ? ShaderName.display2d_fullbright : ShaderName.display2d_normal; //mxd
|
||||
ShaderName pass = (Renderer.FullBrightness && General.Map.Renderer2D.ViewMode != ViewMode.Brightness) ? ShaderName.display2d_fullbright : ShaderName.display2d_normal; //mxd
|
||||
foreach(KeyValuePair<ImageData, List<SurfaceEntry>> imgsurfaces in surfaces)
|
||||
{
|
||||
graphics.SetShader(pass);
|
||||
|
|
|
@ -565,7 +565,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
configfile = General.AutoLoadConfig;
|
||||
|
||||
if (string.IsNullOrEmpty(configfile)) configfile = mapsettings.ReadSetting("gameconfig", "");
|
||||
if(configfile.Trim().Length == 0)
|
||||
if(configfile.Trim().Length == 0 || !General.ConfigurationInfoExist(configfile))
|
||||
{
|
||||
showdialog = true;
|
||||
}
|
||||
|
|
|
@ -14,11 +14,13 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
#region ================== DECORATE Actor Structure parsing
|
||||
|
||||
private DecorateParser parser;
|
||||
|
||||
internal DecorateActorStructure(ZDTextParser zdparser, DecorateCategoryInfo catinfo)
|
||||
{
|
||||
this.catinfo = catinfo; //mxd
|
||||
|
||||
DecorateParser parser = (DecorateParser)zdparser;
|
||||
parser = (DecorateParser)zdparser;
|
||||
bool done = false; //mxd
|
||||
|
||||
// First next token is the class name
|
||||
|
@ -170,6 +172,10 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
break;
|
||||
|
||||
case "states":
|
||||
// Skip cast type if there is one
|
||||
if (!SkipCastTypes())
|
||||
return;
|
||||
|
||||
if (!parser.NextTokenIs("{", true))
|
||||
return;
|
||||
|
||||
|
@ -456,6 +462,59 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// Skips state cast type, it one exists.
|
||||
/// </summary>
|
||||
/// <returns>true if there was nothing to skip or if skippen succeeded, false if it failed</returns>
|
||||
private bool SkipCastTypes()
|
||||
{
|
||||
// Alloed casts, see https://zdoom.org/wiki/Converting_DECORATE_code_to_ZScript#Cast_types
|
||||
string[] allowedcasts = { "actor", "overlay", "weapon", "item" };
|
||||
|
||||
// Skip cast types, which can be defined like this:
|
||||
// States(Actor, Item)
|
||||
// See https://github.com/UltimateDoomBuilder/UltimateDoomBuilder/issues/977
|
||||
if (parser.NextTokenIs("(", false))
|
||||
{
|
||||
while (parser.SkipWhitespace(true))
|
||||
{
|
||||
string token = parser.ReadToken().ToLowerInvariant();
|
||||
|
||||
if(!allowedcasts.Contains(token))
|
||||
{
|
||||
parser.ReportError($"Unexpected cast type \"{token}\", expected one of: " + string.Join(", ", allowedcasts));
|
||||
return false;
|
||||
}
|
||||
|
||||
parser.SkipWhitespace(true);
|
||||
|
||||
// Get next token
|
||||
token = parser.ReadToken();
|
||||
|
||||
// End of cast type?
|
||||
if(token == ")")
|
||||
return true;
|
||||
|
||||
// More cast types coming?
|
||||
if (token == ",")
|
||||
continue;
|
||||
|
||||
// No comma or brace after a cast type, so report an error and return
|
||||
parser.ReportError($"Expected \",\", or \")\", got {token}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We get here if there was no cast type
|
||||
return true;
|
||||
}
|
||||
|
||||
// We should never get here, since we'll return in the parsing loop,
|
||||
// but we need to make the compiler happy
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -549,6 +549,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return false;
|
||||
}
|
||||
|
||||
long prevstreamposition = DataStream.Position;
|
||||
|
||||
string token = ReadToken();
|
||||
|
||||
if(string.Compare(token, expectedtoken, true) != 0)
|
||||
|
@ -556,7 +558,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
if(reporterror) ReportError("Expected \"" + expectedtoken + "\", but got \"" + token + "\"");
|
||||
|
||||
// Rewind so this structure can be read again
|
||||
DataStream.Seek(-token.Length - 1, SeekOrigin.Current);
|
||||
DataStream.Seek(prevstreamposition, SeekOrigin.Begin);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -284,8 +284,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
offset.y %= texture.Height / s.Fields.GetValue((alignFloors ? "yscalefloor" : "yscaleceiling"), 1.0);
|
||||
}
|
||||
|
||||
UniFields.SetFloat(s.Fields, (alignFloors ? "xpanningfloor" : "xpanningceiling"), Math.Round(-offset.x), 0.0);
|
||||
UniFields.SetFloat(s.Fields, (alignFloors ? "ypanningfloor" : "ypanningceiling"), Math.Round(offset.y), 0.0);
|
||||
UniFields.SetFloat(s.Fields, (alignFloors ? "xpanningfloor" : "xpanningceiling"), Math.Round(-offset.x, 6), 0.0);
|
||||
UniFields.SetFloat(s.Fields, (alignFloors ? "ypanningfloor" : "ypanningceiling"), Math.Round(offset.y, 6), 0.0);
|
||||
|
||||
//update
|
||||
s.UpdateNeeded = true;
|
||||
|
|
Loading…
Reference in a new issue