mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-17 01:22:18 +00:00
Fixed, game configurations: Boom game configurations used incorrect "thingflagscompare" block.
Fixed, Thing edit form: implemented overcomplicated required flags check (which should work as expected this time. probably.).
This commit is contained in:
parent
06163d4611
commit
f986f5c98d
9 changed files with 242 additions and 110 deletions
|
@ -97,7 +97,7 @@ mapformat_doom
|
|||
// How to compare thing flags (for the stuck things error checker)
|
||||
thingflagscompare
|
||||
{
|
||||
include("Doom_misc.cfg", "thingflagscompare");
|
||||
include("Boom_misc.cfg", "thingflagscompare");
|
||||
}
|
||||
|
||||
// Things flags masks
|
||||
|
|
|
@ -35,25 +35,30 @@ thingflagstranslation
|
|||
// How thing flags should be compared (for the stuck thing error check)
|
||||
thingflagscompare
|
||||
{
|
||||
skills {
|
||||
1;
|
||||
2;
|
||||
4;
|
||||
}
|
||||
skills {
|
||||
1;
|
||||
2;
|
||||
4;
|
||||
}
|
||||
|
||||
gamemodes {
|
||||
16 {
|
||||
invert = true;
|
||||
}
|
||||
gamemodes {
|
||||
16 {
|
||||
//invert = true;
|
||||
ignoredgroup = "skills";
|
||||
ingnorethisgroupwhenunset = true;
|
||||
}
|
||||
|
||||
32 {
|
||||
invert = true;
|
||||
}
|
||||
32 {
|
||||
invert = true;
|
||||
requiredflag = "16";
|
||||
}
|
||||
|
||||
64 {
|
||||
invert = true;
|
||||
}
|
||||
}
|
||||
64 {
|
||||
invert = true;
|
||||
requiredflag = "16";
|
||||
requiredgroup = "skills";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ thingflagscompare
|
|||
gamemodes {
|
||||
16 {
|
||||
comparemethod = "equal";
|
||||
ignoredgroup = "skills";
|
||||
ingnorethisgroupwhenunset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,9 +59,15 @@ thingflagscompare
|
|||
}
|
||||
|
||||
gamemodes {
|
||||
256;
|
||||
512;
|
||||
1024;
|
||||
256 {
|
||||
requiredgroup = "skills";
|
||||
}
|
||||
512 {
|
||||
requiredgroup = "skills";
|
||||
}
|
||||
1024 {
|
||||
ignoredgroup = "skills";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,9 +48,15 @@ thingflagscompare
|
|||
}
|
||||
|
||||
gamemodes {
|
||||
single;
|
||||
dm;
|
||||
coop;
|
||||
single {
|
||||
requiredgroup = "skills";
|
||||
}
|
||||
coop {
|
||||
requiredgroup = "skills";
|
||||
}
|
||||
dm {
|
||||
ignoredgroup = "skills";
|
||||
}
|
||||
}
|
||||
|
||||
classes {
|
||||
|
|
|
@ -733,6 +733,34 @@ namespace CodeImp.DoomBuilder.Config
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Integrity check
|
||||
foreach (KeyValuePair<string, Dictionary<string, ThingFlagsCompare>> group in thingflagscompare)
|
||||
{
|
||||
foreach (KeyValuePair<string, ThingFlagsCompare> flaggrp in group.Value)
|
||||
{
|
||||
// Required group is missing?
|
||||
if (!string.IsNullOrEmpty(flaggrp.Value.RequiredGroup) && !thingflagscompare.ContainsKey(flaggrp.Value.RequiredGroup))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "thingflagscompare group '" + flaggrp.Value.RequiredGroup + "', required by flag '" + flaggrp.Key + "' does not exist!");
|
||||
flaggrp.Value.RequiredGroup = string.Empty;
|
||||
}
|
||||
|
||||
// Ignored group is missing?
|
||||
if(!string.IsNullOrEmpty(flaggrp.Value.IgnoredGroup) && !thingflagscompare.ContainsKey(flaggrp.Value.IgnoredGroup))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "thingflagscompare group '" + flaggrp.Value.IgnoredGroup + "', ignored by flag '" + flaggrp.Key + "' does not exist!");
|
||||
flaggrp.Value.IgnoredGroup = string.Empty;
|
||||
}
|
||||
|
||||
// Required flag is missing?
|
||||
if(!string.IsNullOrEmpty(flaggrp.Value.RequiredFlag) && !group.Value.ContainsKey(flaggrp.Value.RequiredFlag))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "thingflagscompare flag '" + flaggrp.Value.RequiredFlag + "', required by flag '" + flaggrp.Key + "' does not exist!");
|
||||
flaggrp.Value.RequiredFlag = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the translation flags, because they must be compared highest first!
|
||||
thingflagstranslation.Sort();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
|
@ -39,6 +41,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
#region ================== Variables
|
||||
|
||||
private readonly string flag;
|
||||
private string requiredgroup; //mxd. This flag only works if at least one flag is set in the "requiredgroup"
|
||||
private string ignoredgroup; //mxd. If this flag is set, flags from ignoredgroup can be... well... ignored!
|
||||
private string requiredflag; //mxd. This flag only works if requiredflag is set.
|
||||
private readonly bool ingnorethisgroupwhenunset; //mxd
|
||||
private readonly CompareMethod comparemethod;
|
||||
private readonly bool invert;
|
||||
private readonly string group;
|
||||
|
@ -49,6 +55,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
|
||||
public string Flag { get { return flag; } }
|
||||
public string Group { get { return group; } }
|
||||
public string RequiredGroup { get { return requiredgroup; } internal set { requiredgroup = value; } } //mxd
|
||||
public string IgnoredGroup { get { return ignoredgroup; } internal set { ignoredgroup = value; } } //mxd
|
||||
public string RequiredFlag { get { return requiredflag; } internal set { requiredflag = value; } } //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -77,6 +86,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
}
|
||||
|
||||
invert = cfg.ReadSetting(cfgpath + ".invert", false);
|
||||
requiredgroup = cfg.ReadSetting(cfgpath + ".requiredgroup", string.Empty); //mxd
|
||||
ignoredgroup = cfg.ReadSetting(cfgpath + ".ignoredgroup", string.Empty); //mxd
|
||||
requiredflag = cfg.ReadSetting(cfgpath + ".requiredflag", string.Empty); //mxd
|
||||
ingnorethisgroupwhenunset = cfg.ReadSetting(cfgpath + ".ingnorethisgroupwhenunset", false); //mxd
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -97,25 +110,155 @@ namespace CodeImp.DoomBuilder.Config
|
|||
bool t2flag;
|
||||
|
||||
// Check if the flags exist
|
||||
if(!t1.Flags.ContainsKey(flag) || !t2.Flags.ContainsKey(flag)) {
|
||||
//mxd. If a map is in UDMF format - check Fields
|
||||
if(!General.Map.UDMF || !t1.Fields.ContainsKey(flag) || !t2.Fields.ContainsKey(flag))
|
||||
return 0;
|
||||
if (!t1.Flags.ContainsKey(flag) || !t2.Flags.ContainsKey(flag)) return 0;
|
||||
|
||||
// tag flag inversion into account
|
||||
t1flag = invert ? !(bool)t1.Fields[flag].Value : (bool)t1.Fields[flag].Value;
|
||||
t2flag = invert ? !(bool)t2.Fields[flag].Value : (bool)t2.Fields[flag].Value;
|
||||
} else {
|
||||
// tag flag inversion into account
|
||||
t1flag = invert ? !t1.Flags[flag] : t1.Flags[flag];
|
||||
t2flag = invert ? !t2.Flags[flag] : t2.Flags[flag];
|
||||
//mxd. We should ignore the flag if requiredgroup doesn't have any flags set
|
||||
if(!string.IsNullOrEmpty(requiredgroup))
|
||||
{
|
||||
bool t1hasrequiredflags = false;
|
||||
bool t2hasrequiredflags = false;
|
||||
foreach(string key in General.Map.Config.ThingFlagsCompare[requiredgroup].Keys)
|
||||
{
|
||||
if(t1.Flags.ContainsKey(key) && (General.Map.Config.ThingFlagsCompare[requiredgroup][key].invert ? !t1.Flags[key] : t1.Flags[key]))
|
||||
t1hasrequiredflags = true;
|
||||
if(t2.Flags.ContainsKey(key) && (General.Map.Config.ThingFlagsCompare[requiredgroup][key].invert ? !t2.Flags[key] : t2.Flags[key]))
|
||||
t2hasrequiredflags = true;
|
||||
}
|
||||
|
||||
// Can't compare...
|
||||
if (!t1hasrequiredflags || !t2hasrequiredflags) return 0;
|
||||
}
|
||||
|
||||
//mxd. We should ignore the flag if requiredflag is not set
|
||||
if (string.IsNullOrEmpty(requiredflag))
|
||||
{
|
||||
bool inverted = General.Map.Config.ThingFlagsCompare[group].ContainsKey(requiredflag) && General.Map.Config.ThingFlagsCompare[group][requiredflag].invert;
|
||||
|
||||
bool t1hasrequiredflag = inverted ? !t1.Flags[requiredflag] : t1.Flags[requiredflag];
|
||||
bool t2hasrequiredflag = inverted ? !t2.Flags[requiredflag] : t2.Flags[requiredflag];
|
||||
|
||||
// Can't compare...
|
||||
if(!t1hasrequiredflag || !t2hasrequiredflag) return 0;
|
||||
}
|
||||
|
||||
//mxd. We should also ignore the flag if it's in ingoredgroup
|
||||
foreach(KeyValuePair<string, Dictionary<string, ThingFlagsCompare>> pair in General.Map.Config.ThingFlagsCompare)
|
||||
{
|
||||
foreach(KeyValuePair<string, ThingFlagsCompare> flaggrp in pair.Value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(flaggrp.Value.ignoredgroup) && group == flaggrp.Value.ignoredgroup)
|
||||
{
|
||||
bool t1ignoreflagset = flaggrp.Value.invert ? !t1.Flags[flaggrp.Key] : t1.Flags[flaggrp.Key];
|
||||
bool t2ignoreflagset = flaggrp.Value.invert ? !t2.Flags[flaggrp.Key] : t2.Flags[flaggrp.Key];
|
||||
|
||||
// Can't compare...
|
||||
if(!t1ignoreflagset || !t2ignoreflagset) return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Take flag inversion into account
|
||||
t1flag = invert ? !t1.Flags[flag] : t1.Flags[flag];
|
||||
t2flag = invert ? !t2.Flags[flag] : t2.Flags[flag];
|
||||
|
||||
if (comparemethod == CompareMethod.And && (t1flag && t2flag)) return 1;
|
||||
if (comparemethod == CompareMethod.Equal && (t1flag == t2flag)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//mxd
|
||||
public static string CheckThingEditFormFlags(List<CheckBox> checkboxes)
|
||||
{
|
||||
Dictionary<string, bool> flags = new Dictionary<string, bool>(checkboxes.Count);
|
||||
Dictionary<string, Dictionary<string, bool>> flagspergroup = new Dictionary<string, Dictionary<string, bool>>(General.Map.Config.ThingFlagsCompare.Count);
|
||||
Dictionary<string, bool> requiredgroups = new Dictionary<string, bool>();
|
||||
Dictionary<string, bool> ignoredgroups = new Dictionary<string, bool>();
|
||||
|
||||
// Gather flags
|
||||
foreach (CheckBox cb in checkboxes)
|
||||
{
|
||||
flags.Add(cb.Tag.ToString(), cb.CheckState == CheckState.Checked);
|
||||
}
|
||||
|
||||
// Gather flags per group
|
||||
foreach (KeyValuePair<string, Dictionary<string, ThingFlagsCompare>> group in General.Map.Config.ThingFlagsCompare)
|
||||
{
|
||||
flagspergroup.Add(group.Key, new Dictionary<string, bool>());
|
||||
|
||||
foreach (KeyValuePair<string, ThingFlagsCompare> flaggrp in group.Value)
|
||||
{
|
||||
bool flagset = IsFlagSet(flags, flaggrp.Key, flaggrp.Value.invert) && (string.IsNullOrEmpty(flaggrp.Value.requiredflag) || IsFlagSet(flags, flaggrp.Value.requiredflag, group.Value[flaggrp.Value.requiredflag].invert));
|
||||
|
||||
if(flagset)
|
||||
{
|
||||
flagspergroup[group.Key].Add(flaggrp.Key, true);
|
||||
|
||||
if(!string.IsNullOrEmpty(flaggrp.Value.requiredgroup) && !requiredgroups.ContainsKey(flaggrp.Value.requiredgroup))
|
||||
requiredgroups.Add(flaggrp.Value.requiredgroup, false);
|
||||
}
|
||||
else if(flaggrp.Value.ingnorethisgroupwhenunset)
|
||||
{
|
||||
ignoredgroups.Add(group.Key, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check dependancies
|
||||
foreach (KeyValuePair<string, Dictionary<string, bool>> group in flagspergroup)
|
||||
{
|
||||
foreach(KeyValuePair<string, bool> flaggrp in group.Value)
|
||||
{
|
||||
if(!flaggrp.Value) continue;
|
||||
|
||||
string ignoredgrp = General.Map.Config.ThingFlagsCompare[group.Key][flaggrp.Key].ignoredgroup;
|
||||
if (!string.IsNullOrEmpty(ignoredgrp) && !requiredgroups.ContainsKey(ignoredgrp))
|
||||
{
|
||||
ignoredgroups.Add(ignoredgrp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of ignoredgroups
|
||||
foreach (KeyValuePair<string, bool> group in ignoredgroups)
|
||||
{
|
||||
flagspergroup.Remove(group.Key);
|
||||
}
|
||||
|
||||
// Return message
|
||||
string result = string.Empty;
|
||||
|
||||
foreach (KeyValuePair<string, Dictionary<string, bool>> group in flagspergroup)
|
||||
{
|
||||
if (group.Value.Count == 0)
|
||||
{
|
||||
switch(group.Key)
|
||||
{
|
||||
case "skills":
|
||||
result += "Thing is not used in any skill level.";
|
||||
break;
|
||||
case "gamemodes":
|
||||
result += "Thing is not used in any game mode.";
|
||||
break;
|
||||
case "classes":
|
||||
result += "Thing is not used by any class.";
|
||||
break;
|
||||
default:
|
||||
result += "At least one '" + group.Key + "' flag should be set.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//mxd
|
||||
private static bool IsFlagSet(Dictionary<string, bool> flags, string flag, bool invert)
|
||||
{
|
||||
bool result = flags.ContainsKey(flag) && flags[flag];
|
||||
return (invert ? !result : result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -633,47 +633,17 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
{
|
||||
if(preventchanges) return;
|
||||
|
||||
foreach(KeyValuePair<string, Dictionary<string, ThingFlagsCompare>> group in General.Map.Config.ThingFlagsCompare)
|
||||
string warn = ThingFlagsCompare.CheckThingEditFormFlags(flags.Checkboxes);
|
||||
if(!string.IsNullOrEmpty(warn))
|
||||
{
|
||||
if(group.Value.Count < 2) continue;
|
||||
bool haveflags = false;
|
||||
|
||||
foreach(CheckBox cb in flags.Checkboxes)
|
||||
{
|
||||
if (group.Value.ContainsKey(cb.Tag.ToString()) && cb.CheckState != CheckState.Unchecked)
|
||||
{
|
||||
haveflags = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!haveflags)
|
||||
{
|
||||
switch(group.Key)
|
||||
{
|
||||
case "skills":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used in any skill level.");
|
||||
break;
|
||||
|
||||
case "gamemodes":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used in any game mode.");
|
||||
break;
|
||||
|
||||
case "classes":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used by any class.");
|
||||
break;
|
||||
|
||||
default:
|
||||
tooltip.SetToolTip(missingflags, "At least one '" + group.Key + "' flag should be set.");
|
||||
break;
|
||||
}
|
||||
|
||||
missingflags.Visible = true;
|
||||
settingsgroup.ForeColor = Color.DarkRed;
|
||||
return;
|
||||
}
|
||||
//got missing flags
|
||||
tooltip.SetToolTip(missingflags, warn);
|
||||
missingflags.Visible = true;
|
||||
settingsgroup.ForeColor = Color.DarkRed;
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is OK
|
||||
missingflags.Visible = false;
|
||||
settingsgroup.ForeColor = SystemColors.ControlText;
|
||||
}
|
||||
|
|
|
@ -335,10 +335,11 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
|
||||
preventchanges = false;
|
||||
|
||||
//mxd. Trigger angle/pitch/roll update manually...
|
||||
//mxd. Trigger updates manually...
|
||||
angle_WhenTextChanged(angle, EventArgs.Empty);
|
||||
pitch_WhenTextChanged(pitch, EventArgs.Empty);
|
||||
roll_WhenTextChanged(roll, EventArgs.Empty);
|
||||
flags_OnValueChanged(flags, EventArgs.Empty);
|
||||
|
||||
updateScriptControls(); //mxd
|
||||
|
||||
|
@ -862,46 +863,17 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
{
|
||||
if(preventchanges) return;
|
||||
|
||||
foreach(KeyValuePair<string, Dictionary<string, ThingFlagsCompare>> group in General.Map.Config.ThingFlagsCompare)
|
||||
string warn = ThingFlagsCompare.CheckThingEditFormFlags(flags.Checkboxes);
|
||||
if(!string.IsNullOrEmpty(warn))
|
||||
{
|
||||
if(group.Value.Count < 2) continue;
|
||||
bool haveflags = false;
|
||||
|
||||
foreach(CheckBox cb in flags.Checkboxes)
|
||||
{
|
||||
if(group.Value.ContainsKey(cb.Tag.ToString()) && cb.CheckState != CheckState.Unchecked) {
|
||||
haveflags = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!haveflags)
|
||||
{
|
||||
switch(group.Key)
|
||||
{
|
||||
case "skills":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used in any skill level.");
|
||||
break;
|
||||
|
||||
case "gamemodes":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used in any game mode.");
|
||||
break;
|
||||
|
||||
case "classes":
|
||||
tooltip.SetToolTip(missingflags, "Thing is not used by any class.");
|
||||
break;
|
||||
|
||||
default:
|
||||
tooltip.SetToolTip(missingflags, "At least one '" + group.Key + "' flag should be set.");
|
||||
break;
|
||||
}
|
||||
|
||||
missingflags.Visible = true;
|
||||
settingsgroup.ForeColor = Color.DarkRed;
|
||||
return;
|
||||
}
|
||||
//got missing flags
|
||||
tooltip.SetToolTip(missingflags, warn);
|
||||
missingflags.Visible = true;
|
||||
settingsgroup.ForeColor = Color.DarkRed;
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is OK
|
||||
missingflags.Visible = false;
|
||||
settingsgroup.ForeColor = SystemColors.ControlText;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue