Commit 16d6499d authored by Adam Leyshon's avatar Adam Leyshon
Browse files

Added debug menu option to dump all thingdef to JSON.

Fixed: HasUplink check now looks at the map of the pawn that initiated dialog
rather than the visible map.
parent 5fba5773
......@@ -9,11 +9,10 @@ namespace Glitterworld_Prime
{
class Building_PrimeUplink : Building
{
public static bool HasUplink()
public static bool HasUplink(Map map)
{
Map m = Find.CurrentMap;
List<Thing> poweredList = new List<Thing>();
var alllist = m.listerThings.ThingsOfDef(DefDatabase<ThingDef>.GetNamed("PrimeUplink"));
var poweredList = new List<Thing>();
var alllist = map.listerThings.ThingsOfDef(DefDatabase<ThingDef>.GetNamed("PrimeUplink"));
foreach (var uplinkThing in alllist)
{
var trader = uplinkThing.TryGetComp<CompPowerTrader>();
......
......@@ -3,7 +3,7 @@
// This file was created by TwistedSoul @ TheCodeCache.net
// You are free to inspect the mod but may not modify or redistribute without my express permission.
// However! If you would like to contribute to GWP please feel free to drop me a message.
// Glitterworld Prime, Building_TradeWithPrime.cs, Created 2018-07-22
// Glitterworld Prime, Building_TradeWithPrime.cs, Created 2017-11-18
#endregion
......@@ -61,45 +61,48 @@ namespace Glitterworld_Prime
};
return floatMenuOptions;
}
// At this point, There's no order, We can reach the console and it's not reserved.
floatMenuOptions = new List<FloatMenuOption>();
var tradeship = mapComponent.GetTradeShip();
var communicable = (ICommunicable) tradeship; // Cast trader as ICommunicable;
if (communicable != null)
Action action = delegate
{
Action action = delegate
if (!Building_PrimeUplink.HasUplink(myPawn.Map))
{
if (!Building_PrimeUplink.HasUplink())
{
Messages.Message("GWPNeedUplink".Translate(), this,
MessageTypeDefOf.RejectInput);
return;
}
if (!Building_OrbitalTradeBeacon.AllPowered(Map).Any())
{
Messages.Message("MessageNeedBeaconToTradeWithShip".Translate(), this,
MessageTypeDefOf.RejectInput);
return;
}
var job = new Job(JobDefOf.UseCommsConsole, this);
job.commTarget = communicable;
myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.OpeningComms, KnowledgeAmount.Total);
};
floatMenuOptions.Add(FloatMenuUtility.DecoratePrioritizedTask(
new FloatMenuOption(tradeship.TraderName, action, MenuOptionPriority.InitiateSocial, null, null, 0f,
null, null), myPawn, this, "ReservedBy"));
}
Messages.Message("GWPNeedUplink".Translate(), this,
MessageTypeDefOf.RejectInput);
return;
}
if (!Building_OrbitalTradeBeacon.AllPowered(Map).Any())
{
Messages.Message("MessageNeedBeaconToTradeWithShip".Translate(), this,
MessageTypeDefOf.RejectInput);
return;
}
var job = new Job(JobDefOf.UseCommsConsole, this) {commTarget = communicable};
myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.OpeningComms, KnowledgeAmount.Total);
};
#if DEBUG
floatMenuOptions.Add(FloatMenuUtility.DecoratePrioritizedTask(
new FloatMenuOption("Dump Thing data", Tools.DumpThingData.DumpData, MenuOptionPriority.InitiateSocial, null, null, 0f,
null, null), myPawn, this, "ReservedBy"));
#endif
floatMenuOptions.Add(FloatMenuUtility.DecoratePrioritizedTask(
new FloatMenuOption(tradeship.TraderName, action, MenuOptionPriority.InitiateSocial, null, null, 0f,
null, null), myPawn, this, "ReservedBy"));
return floatMenuOptions;
}
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
......
......@@ -162,42 +162,47 @@ namespace Glitterworld_Prime
AcceptButtonSize.y);
if (Widgets.ButtonText(rect9, "AcceptButton".Translate(), true, false, true))
{
Action action = delegate
{
bool flag;
var tracker = Utilities.GetMapComponent(TradeSession.playerNegotiator.Map).OrderTracker;
if (TradeSession.deal.TryExecute(out flag))
{
if (flag)
{
var orderSuccess = tracker.TryPlaceOrder((TraderPrime) TradeSession.trader);
// Were we able to place the order?
if (orderSuccess)
{
// Yes, Plav a sound and record the trade deal for the pawn.
SoundDefOf.ExecuteTrade.PlayOneShotOnCamera(null);
var pawn = TradeSession.trader as Pawn;
if (pawn != null)
TaleRecorder.RecordTale(TaleDefOf.TradedWith, TradeSession.playerNegotiator, pawn);
}
// If not then the refund was already issued and the error displayed.
// Close the dialog.
Close(false);
}
else
{
LogWriter.WriteErrorMessage(
"Error processing order, RimWorld couldn't complete the trade.");
}
Event.current.Use();
Close();
}
};
Action action = () =>
{
Log.Message("Button clicked", true);
bool flag;
var tracker = Utilities.GetMapComponent(TradeSession.playerNegotiator.Map).OrderTracker;
if (!TradeSession.deal.TryExecute(out flag))
{
Log.Message("Error @ TradeSession.deal.TryExecute()", true);
return;
}
if (flag)
{
var orderSuccess = tracker.TryPlaceOrder((TraderPrime)TradeSession.trader);
// Were we able to place the order?
if (orderSuccess)
{
// Yes, Plav a sound and record the trade deal for the pawn.
SoundDefOf.ExecuteTrade.PlayOneShotOnCamera(null);
var pawn = TradeSession.trader as Pawn;
if (pawn != null)
TaleRecorder.RecordTale(TaleDefOf.TradedWith, TradeSession.playerNegotiator, pawn);
}
// If not then the refund was already issued and the error displayed.
// Close the dialog.
Close(false);
}
else
{
LogWriter.WriteErrorMessage(
"Error processing order, RimWorld couldn't complete the trade.");
}
Event.current.Use();
Close();
};
if (TradeSession.deal.DoesTraderHaveEnoughSilver())
{
action();
......@@ -252,13 +257,12 @@ namespace Glitterworld_Prime
where x.IsCurrency
select x).FirstOrDefault();
#if DEBUG
foreach (var tr in TradeSession.deal.AllTradeables)
LogWriter.WriteMessage(
$"Item {tr.AnyThing.GetInnerIfMinified().def} is minified: {tr.AnyThing.def.Minifiable}, " +
$"Belongs in Categories {string.Join(", ", tr.AnyThing.GetInnerIfMinified().def.thingCategories.Select(t => t.ToString()).ToArray())} ");
#endif
//#if DEBUG
// foreach (var tr in TradeSession.deal.AllTradeables)
// LogWriter.WriteMessage(
// $"Item {tr.AnyThing.GetInnerIfMinified().def} is minified: {tr.AnyThing.def.Minifiable}, " +
// $"Belongs in Categories {string.Join(", ", tr.AnyThing.GetInnerIfMinified().def.thingCategories.Select(t => t.ToString()).ToArray())} ");
//#endif
_cachedTradeables = (from tr in TradeSession.deal.AllTradeables
where !tr.IsCurrency
......@@ -423,4 +427,4 @@ namespace Glitterworld_Prime
#endregion
}
}
\ No newline at end of file
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Glitterworld_Prime.ApiStructs;
using RimWorld;
using Verse;
namespace Glitterworld_Prime.Tools
{
internal static class DumpThingData
{
private static void setQuality(Thing thing, QualityCategory quality)
{
if (!thing.def.HasComp(typeof(CompQuality))) return;
// Fix some strange errors with the games tale generation by forcing these items not to have any art assigned.
var art = thing.TryGetComp<CompArt>();
if (art != null) ((ThingWithComps) thing).AllComps.Remove(art);
thing.TryGetComp<CompQuality>().SetQuality(quality, ArtGenerationContext.Outsider);
}
private static IEnumerable<GlitterWorldItem> ComputeItemsMadeFromStuff(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
foreach (var category in thing.stuffCategories)
{
var stuffThings = stuffData[category];
foreach (var stuff in stuffThings)
{
// Create the Thing
Thing t = Utilities.CreateThing(thing.defName, 1, stuff.defName);
yield return new GlitterWorldItem()
{
Name = thing.defName,
StuffType = stuff.defName,
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
}
private static IEnumerable<GlitterWorldItem> ComputeItemsMadeFromStuffWithQuality(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
for (var quality = 2; quality < 7; quality++)
foreach (var category in thing.stuffCategories)
{
var stuffThings = stuffData[category];
foreach (var stuff in stuffThings)
{
Thing t = Utilities.CreateThing(thing.defName, 1, stuff.defName);
setQuality(t, (QualityCategory)quality);
yield return new GlitterWorldItem()
{
Name = thing.defName,
Quality = Enum.GetName(typeof(QualityCategory), quality),
StuffType = stuff.defName,
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
}
private static IEnumerable<GlitterWorldItem> ComputeItemsWithQuality(ThingDef thing)
{
for (var quality = 2; quality < 7; quality++)
{
Thing t = Utilities.CreateThing(thing.defName, 1);
setQuality(t, (QualityCategory)quality);
yield return new GlitterWorldItem()
{
Name = thing.defName,
Quality = Enum.GetName(typeof(QualityCategory), quality),
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
private static IEnumerable<GlitterWorldItem> ComputeThingDef(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
var result = new List<GlitterWorldItem>();
// Add support for things made of stuff.
if (thing.MadeFromStuff)
{
// Add support for things with Quality.
result.AddRange(thing.HasComp(typeof(CompQuality))
? ComputeItemsMadeFromStuffWithQuality(thing, stuffData)
: ComputeItemsMadeFromStuff(thing, stuffData));
}
else
{
// Add support for things with Quality.
if (thing.HasComp(typeof(CompQuality)))
result.AddRange(ComputeItemsWithQuality(thing));
else
result.Add(new GlitterWorldItem()
{
Name = thing.defName,
BaseMarketValue = thing.BaseMarketValue,
MinifiedContainer = thing.Minifiable
});
}
return result;
}
private static IEnumerable<GlitterWorldItem> GetThingData()
{
var stuffCategories = new Dictionary<StuffCategoryDef, List<ThingDef>>();
var thingData = new List<GlitterWorldItem>();
var stuffCategoryDefs = DefDatabase<StuffCategoryDef>.AllDefsListForReading;
var things = DefDatabase<ThingDef>.AllDefsListForReading;
foreach (var stuffCategory in stuffCategoryDefs) stuffCategories.Add(stuffCategory, new List<ThingDef>());
// Scan Defs for Things that can be used as stuff.
foreach (var thing in things)
// If this can be used as Stuff and it has StuffCategories assigned
if (thing.IsStuff && thing.stuffProps.categories.Count > 0)
foreach (var category in thing.stuffProps.categories)
stuffCategories[category].Add(thing);
// Then scan for Defs that can be traded.
foreach (var thing in things)
try
{
if (thing.category == ThingCategory.Item && thing.thingClass.Name != "MinifiedThing" &&
TradeUtility.EverTradeable(thing))
thingData.AddRange(ComputeThingDef(thing, stuffCategories));
// Add support for Minifiable buildings
else if (thing.category == ThingCategory.Building && thing.Minifiable &&
thing.tradeability != Tradeability.Never)
thingData.AddRange(ComputeThingDef(thing, stuffCategories));
}
catch (Exception ex)
{
LogWriter.WriteErrorMessage(
$"GlitterWorldPrime failed to dump ThingDef {thing.defName}.");
LogWriter.WriteErrorMessage(ex.Message);
}
return thingData;
}
internal static void DumpData()
{
var data = new List<GlitterWorldItem>(GetThingData());
var path = Path.Combine(GenFilePaths.SaveDataFolderPath, "GWP-MarketDataDump.json");
var jsonString = RestSharp.SimpleJson.SerializeObject(data);
File.WriteAllText(path, jsonString);
Messages.Message($"{data.Count()} objects dumped to {path}", MessageTypeDefOf.TaskCompletion);
}
}
}
......@@ -75,40 +75,9 @@ namespace Glitterworld_Prime
return _currentTradeShip ?? (_currentTradeShip = new TraderPrime(map));
}
public void InitialiseStuffDefs()
private void InitialiseStuffDefs()
{
var stuffCategories = new Dictionary<StuffCategoryDef, List<ThingDef>>();
ThingsToRequestFromMarket = new List<GlitterWorldRequestItem>();
var stuffCategoryDefs = DefDatabase<StuffCategoryDef>.AllDefsListForReading;
var things = DefDatabase<ThingDef>.AllDefsListForReading;
foreach (var stuffCategory in stuffCategoryDefs) stuffCategories.Add(stuffCategory, new List<ThingDef>());
// Scan Defs for Things that can be used as stuff.
foreach (var thing in things)
// If this can be used as Stuff and it has StuffCategories assigned
if (thing.IsStuff && thing.stuffProps.categories.Count > 0)
foreach (var category in thing.stuffProps.categories)
stuffCategories[category].Add(thing);
// Then scan for Defs that can be traded.
foreach (var thing in things)
try
{
if (thing.category == ThingCategory.Item && thing.thingClass.Name != "MinifiedThing" &&
TradeUtility.EverPlayerSellable(thing))
ThingsToRequestFromMarket.AddRange(Utilities.ComputeThingDef(thing, stuffCategories));
// Add support for Minifiable buildings
else if (thing.category == ThingCategory.Building && thing.Minifiable &&
thing.tradeability != Tradeability.None)
ThingsToRequestFromMarket.AddRange(Utilities.ComputeThingDef(thing, stuffCategories));
}
catch (Exception ex)
{
LogWriter.WriteErrorMessage(
$"GlitterWorldPrime failed to process ThingDef {thing.defName} for trading, it won't be tradeable.");
LogWriter.WriteErrorMessage(ex.Message);
}
ThingsToRequestFromMarket = new List<GlitterWorldRequestItem>(Utilities.GetAllItems());
}
public override void MapComponentTick()
......
......@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Assemblies\</OutputPath>
<DefineConstants>TRACE;DEBUG;LOCALSERVER,DISABLESTEAM</DefineConstants>
<DefineConstants>TRACE;DEBUG;LOCALSERVER</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
......@@ -35,11 +35,11 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\RimWorldWin_Data\Managed\Assembly-CSharp.dll</HintPath>
<HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp-firstpass">
<HintPath>..\..\..\RimWorldWin_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
<HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
......@@ -52,9 +52,8 @@
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\RimWorldWin_Data\Managed\UnityEngine.dll</HintPath>
<Reference Include="UnityEngine">
<HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
......@@ -73,6 +72,7 @@
<Compile Include="GlitterWorldOrderTracker.cs" />
<Compile Include="LogWriter.cs" />
<Compile Include="ObjectDumper.cs" />
<Compile Include="Tools\DumpThingData.cs" />
<Compile Include="TraderPrime.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TraderKindDef_PrimeTrader.cs" />
......
#region License
// This file was created by TwistedSoul @ TheCodeCache.net
// You are free to inspect the mod but may not modify or redistribute without my express permission.
// However! If you would like to contribute to GWP please feel free to drop me a message.
// Glitterworld Prime, MessageSoundShim.cs, Updated 2018-01-17
#endregion
using Verse;
namespace Glitterworld_Prime
{
#if !B18
public static class MessageTypeDefOf
{
#region Fields
public static MessageSound RejectInput = MessageSound.Negative;
public static MessageSound NegativeEvent = MessageSound.Negative;
public static MessageSound PositiveEvent = MessageSound.Benefit;
public static MessageSound NeutralEvent = MessageSound.Standard;
#endregion
}
#endif
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Glitterworld_Prime.ApiStructs;
using RimWorld;
using Verse;
namespace Glitterworld_Prime.Tools
{
internal static class DumpThingData
{
private static void setQuality(Thing thing, QualityCategory quality)
{
if (!thing.def.HasComp(typeof(CompQuality))) return;
// Fix some strange errors with the games tale generation by forcing these items not to have any art assigned.
var art = thing.TryGetComp<CompArt>();
if (art != null) ((ThingWithComps) thing).AllComps.Remove(art);
thing.TryGetComp<CompQuality>().SetQuality(quality, ArtGenerationContext.Outsider);
}
private static IEnumerable<GlitterWorldItem> ComputeItemsMadeFromStuff(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
foreach (var category in thing.stuffCategories)
{
var stuffThings = stuffData[category];
foreach (var stuff in stuffThings)
{
// Create the Thing
Thing t = Utilities.CreateThing(thing.defName, 1, stuff.defName);
yield return new GlitterWorldItem()
{
Name = thing.defName,
StuffType = stuff.defName,
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
}
private static IEnumerable<GlitterWorldItem> ComputeItemsMadeFromStuffWithQuality(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
for (var quality = 2; quality < 7; quality++)
foreach (var category in thing.stuffCategories)
{
var stuffThings = stuffData[category];
foreach (var stuff in stuffThings)
{
Thing t = Utilities.CreateThing(thing.defName, 1, stuff.defName);
setQuality(t, (QualityCategory)quality);
yield return new GlitterWorldItem()
{
Name = thing.defName,
Quality = Enum.GetName(typeof(QualityCategory), quality),
StuffType = stuff.defName,
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
}
private static IEnumerable<GlitterWorldItem> ComputeItemsWithQuality(ThingDef thing)
{
for (var quality = 2; quality < 7; quality++)
{
Thing t = Utilities.CreateThing(thing.defName, 1);
setQuality(t, (QualityCategory)quality);
yield return new GlitterWorldItem()
{
Name = thing.defName,
Quality = Enum.GetName(typeof(QualityCategory), quality),
BaseMarketValue = t.MarketValue,
MinifiedContainer = thing.Minifiable
};
}
}
private static IEnumerable<GlitterWorldItem> ComputeThingDef(ThingDef thing,
Dictionary<StuffCategoryDef, List<ThingDef>> stuffData)
{
var result = new List<GlitterWorldItem>();
// Add support for things made of stuff.
if (thing.MadeFromStuff)
{
// Add support for things with Quality.
result.AddRange(thing.HasComp(typeof(CompQuality))
? ComputeItemsMadeFromStuffWithQuality(thing, stuffData)
: ComputeItemsMadeFromStuff(thing, stuffData));
}
else