Commit f77e5aeb authored by Adam Leyshon's avatar Adam Leyshon
Browse files

Merge branch 'feature/batch-load-things-on-start' into develop

# Conflicts:
#	About/About.xml
#	About/PublishedFileId.txt
#	Glitterworld Prime/GlitterWorldApi.cs
#	Glitterworld Prime/Glitterworld Prime.csproj
#	Glitterworld Prime/Properties/AssemblyInfo.cs
#	nant.build
parents 9a9a9a7a d6e61136
......@@ -6,6 +6,7 @@
*.user
*.userosscache
*.sln.docstates
*.zip
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
......@@ -21,6 +22,7 @@
bld/
[Bb]in/
[Oo]bj/
[Mm]od_package
# Visual Studio 2015 cache/options directory
.vs/
......@@ -241,3 +243,4 @@ ModelManifest.xml
# FAKE - F# Make
.fake/
/Assemblies
/tools
<?xml version="1.0" encoding="utf-8"?>
<ModMetaData>
<name>GlitterWorld Prime [B19]</name>
<name>GlitterWorld Prime [1.0]</name>
<author>TwistedSoul / TheCodeCache.NET</author>
<targetVersion>0.19.0</targetVersion>
<supportedVersions>
<li>1.0</li>
<li>0.19</li>
</supportedVersions>
<url>https://www.thecodecache.net</url>
<description>
Build: @SHAHASH@ \n
......
1515842571
\ No newline at end of file
1515843333
\ No newline at end of file
<project outputDir="F:\Code\C#\GlitterWorld Prime\R1\Assemblies\Confused" baseDir="F:\Code\C#\GlitterWorld Prime\R1\Assemblies" xmlns="http://confuser.codeplex.com">
<module path="Glitterworld Prime.dll">
<rule pattern="true" preset="minimum" inherit="false">
<protection id="constants" />
<protection id="anti debug" />
<protection id="anti ildasm" />
<protection id="ref proxy" />
<protection id="ctrl flow" />
</rule>
</module>
<probePath>E:\Games\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed</probePath>
</project>
\ No newline at end of file
......@@ -9,12 +9,15 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Release-Local|Any CPU = Release-Local|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Release|Any CPU.Build.0 = Release|Any CPU
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Release-Local|Any CPU.ActiveCfg = Release-Local|Any CPU
{1976D016-8918-48C9-A54E-4D9EF7F200B7}.Release-Local|Any CPU.Build.0 = Release-Local|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
using System;
#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, Building_PrimeUplink.cs, Created 2018-08-17
#endregion
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
namespace Glitterworld_Prime
{
class Building_PrimeUplink : Building
internal class Building_PrimeUplink : Building
{
public static bool HasUplink(Map map)
#region Methods
internal static bool HasUplink(Map map)
{
var poweredList = new List<Thing>();
var alllist = map.listerThings.ThingsOfDef(DefDatabase<ThingDef>.GetNamed("PrimeUplink"));
foreach (var uplinkThing in alllist)
{
var trader = uplinkThing.TryGetComp<CompPowerTrader>();
if (trader != null && trader.PowerOn)
{
poweredList.Add(uplinkThing);
}
if (trader != null && trader.PowerOn) poweredList.Add(uplinkThing);
}
return poweredList.Count > 0;
}
#endregion
}
}
}
\ No newline at end of file
......@@ -3,13 +3,14 @@
// 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 2017-11-18
// Glitterworld Prime, Building_TradeWithPrime.cs, Created 2018-07-22
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using Glitterworld_Prime.Tools;
using RimWorld;
using Verse;
using Verse.AI;
......@@ -18,12 +19,6 @@ namespace Glitterworld_Prime
{
public class Building_TradeWithPrime : Building_CommsConsole
{
#region Fields
private const string TxtTradeWithTrader = "TradeWithTraderPawn";
#endregion
#region Methods
public override IEnumerable<FloatMenuOption> GetFloatMenuOptions(Pawn myPawn)
......@@ -61,7 +56,7 @@ namespace Glitterworld_Prime
};
return floatMenuOptions;
}
floatMenuOptions = new List<FloatMenuOption>();
var tradeship = mapComponent.GetTradeShip();
var communicable = (ICommunicable) tradeship; // Cast trader as ICommunicable;
......@@ -90,11 +85,12 @@ namespace Glitterworld_Prime
#if DEBUG
floatMenuOptions.Add(FloatMenuUtility.DecoratePrioritizedTask(
new FloatMenuOption("Dump Thing data", Tools.DumpThingData.DumpData, MenuOptionPriority.InitiateSocial, null, null, 0f,
new FloatMenuOption("Dump Thing data", 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"));
......@@ -110,4 +106,4 @@ namespace Glitterworld_Prime
#endregion
}
}
}
\ No newline at end of file
......@@ -28,6 +28,7 @@ namespace Glitterworld_Prime
private readonly ITrader _trader;
private int? _cacheSilver;
private DownloadStatus _isDownloadComplete = DownloadStatus.Incomplete;
private int? _reason;
private bool _resubscribePromptShown;
private GlitterWorldSubscriptionMetadata _subscriptionMeta;
......@@ -43,7 +44,7 @@ namespace Glitterworld_Prime
_trader = traderPrime;
_mapComponent = Utilities.GetMapComponent(_player.Map);
var t = new Thread(ApiAsync);
var t = new Thread(DoApiCallsAsync);
t.Start();
}
......@@ -95,7 +96,7 @@ namespace Glitterworld_Prime
Action actionConfirm = delegate
{
Find.WindowStack.Add(new DialogPrimeUpdateSubscription(_player, _trader,
_subscriptionMeta.SubscriptionCost));
_subscriptionMeta));
Close();
};
......@@ -124,7 +125,13 @@ namespace Glitterworld_Prime
break;
case DownloadStatus.Failed:
Messages.Message("GWPUnavailable".Translate(), MessageTypeDefOf.NegativeEvent);
string message;
if (_reason != null)
message = _reason == 403 ? "GWPBanned".Translate() : "GWPUnavailable".Translate();
else
message = "GWPUnavailable".Translate();
Messages.Message(message, MessageTypeDefOf.NegativeEvent);
Close();
break;
}
......@@ -137,7 +144,7 @@ namespace Glitterworld_Prime
select t).Sum(t => t.stackCount);
}
private void ApiAsync()
private void DoApiCallsAsync()
{
// Check API Version
if (!GlitterWorldApi.CheckApiVersion())
......@@ -175,14 +182,16 @@ namespace Glitterworld_Prime
else
{
#if DEBUG
LogWriter.WriteMessage($"Not creating new ID");
LogWriter.WriteMessage("Not creating new ID");
#endif
}
// Update Colony MetaData
if (!GlitterWorldApi.SendColonyMeta(_player.Map))
int reason;
if (!GlitterWorldApi.SendColonyMeta(_player.Map, out reason))
{
_isDownloadComplete = DownloadStatus.Failed;
if (reason != 0) _reason = reason;
return;
}
......@@ -196,7 +205,7 @@ namespace Glitterworld_Prime
}
LogWriter.WriteMessage(
$"GlitterWorld API: Subscripton server has expiry tick @ {_subscriptionMeta.TickSubscriptionExpires}");
$"GlitterWorld API: Subscription server has expiry tick @ {_subscriptionMeta.TickSubscriptionExpires}");
_mapComponent.SubscriptionExpiry = _subscriptionMeta.TickSubscriptionExpires;
_isDownloadComplete = DownloadStatus.Complete;
......@@ -204,7 +213,8 @@ namespace Glitterworld_Prime
private Dialog_MessageBox AskRenew(Action confirm, Action cancel)
{
var text1 = $"{"GWPDialogSubscribe1".Translate()} {_subscriptionMeta.SubscriptionCost} {"GWPCurrency".Translate()} {"GWPDialogSubscribe2".Translate()} {"GWPSubscriptionDuration".Translate()}";
var text1 =
$"{"GWPDialogSubscribe1".Translate()} {_subscriptionMeta.SubscriptionCost} {"GWPCurrency".Translate()} {"GWPDialogSubscribe2".Translate()} {"GWPSubscriptionDuration".Translate()}";
var text2 = "Confirm".Translate();
var text3 = "GoBack".Translate();
var text4 = "GWPDialogSubscribeTitle".Translate();
......@@ -215,10 +225,10 @@ namespace Glitterworld_Prime
private Dialog_MessageBox CannotAffordSub()
{
var s = new StringBuilder();
s.AppendLine("GWPDialgoCantAffordSubscription1".Translate());
s.AppendLine("GWPDialgoCantAffordSubscription2".Translate());
s.AppendLine("GWPDialogCantAffordSubscription1".Translate());
s.AppendLine("GWPDialogCantAffordSubscription2".Translate());
s.AppendLine($"{_subscriptionMeta.SubscriptionCost} {"GWPCurrency".Translate()}");
return new Dialog_MessageBox(s.ToString(), title: "GWPDialgoCantAffordSubscriptionTitle".Translate());
return new Dialog_MessageBox(s.ToString(), title: "GWPDialogCantAffordSubscriptionTitle".Translate());
}
#endregion
......
......@@ -7,6 +7,7 @@
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
......@@ -21,13 +22,15 @@ namespace Glitterworld_Prime
{
#region Fields
private static readonly string _downloadMessage = "Downloading market data...";
private readonly Stopwatch _apiStopwatch;
private readonly GlitterWorld_MapComponent _mapComponent;
private readonly Pawn _player;
private readonly bool _shouldClose = false;
private readonly ITrader _trader;
private DownloadStatus _isDownloadComplete;
private Stopwatch _apiStopwatch;
private string _downloadMessage = "GWPSendingThingList".Translate();
private DownloadStatus _previousStatus;
private DownloadStatus _status;
#endregion
......@@ -40,12 +43,19 @@ namespace Glitterworld_Prime
_player = playerNegotiator;
_trader = traderPrime;
_mapComponent = Utilities.GetMapComponent(_player.Map);
// Download Goods from Server
_apiStopwatch = new Stopwatch();
LogWriter.WriteMessage("Starting request to server");
_apiStopwatch.Start();
GlitterWorldApi.GetServerGoodsAsync(_mapComponent, DownloadThingsComplete_Callback);
if (_mapComponent.HasSentThingListYet)
{
_status = DownloadStatus.DoneSendingMods;
}
else
{
// Send supported things
LogWriter.WriteMessage("Starting request to server");
_apiStopwatch.Start();
GlitterWorldApi.PutItemListAsync(_mapComponent, PutThingsListComplete_Callback);
}
}
#endregion
......@@ -76,17 +86,53 @@ namespace Glitterworld_Prime
return;
}
switch (_isDownloadComplete)
Text.Font = GameFont.Small;
switch (_status)
{
case DownloadStatus.Incomplete:
Text.Font = GameFont.Small;
var textWidth = Text.CalcSize(_downloadMessage);
var label = new Rect((inRect.width - textWidth.x) / 2f, (inRect.height - textWidth.y) / 2f,
textWidth.x, textWidth.y);
Widgets.Label(label, _downloadMessage);
if (_previousStatus != DownloadStatus.Incomplete)
{
_previousStatus = DownloadStatus.Incomplete;
_downloadMessage = "GWPSendingThingList".Translate();
}
break;
case DownloadStatus.DoneSendingSupportedThings:
if (_previousStatus != DownloadStatus.DoneSendingSupportedThings)
{
// Now send the mods
_previousStatus = DownloadStatus.DoneSendingSupportedThings;
_downloadMessage = "GWPSendingModList".Translate();
_apiStopwatch = new Stopwatch();
LogWriter.WriteMessage("Starting request to server");
_apiStopwatch.Start();
GlitterWorldApi.PutModListAsync(_mapComponent, PutModListComplete_Callback);
}
break;
case DownloadStatus.DoneSendingMods:
if (_previousStatus != DownloadStatus.DoneSendingMods)
{
// Download Goods from Server
_previousStatus = DownloadStatus.DoneSendingMods;
_downloadMessage = "GWPGetMarketData".Translate();
_apiStopwatch = new Stopwatch();
LogWriter.WriteMessage("Starting request to server");
_apiStopwatch.Start();
GlitterWorldApi.GetServerGoodsAsync(_mapComponent, DownloadThingsComplete_Callback);
}
break;
case DownloadStatus.Complete:
// Mark that we've sent all the metadata, so not to do it again.
_mapComponent.HasSentThingListYet = true;
// We're done, close and go to the trade screen.
var dt = new DialogPrimeTrade(_player, _trader);
Find.WindowStack.Add(dt);
Close();
......@@ -96,32 +142,70 @@ namespace Glitterworld_Prime
Messages.Message("GWPCantGetMarketData".Translate(), MessageTypeDefOf.NegativeEvent);
Close();
break;
default:
throw new ArgumentOutOfRangeException();
}
var textWidth = Text.CalcSize(_downloadMessage);
var label = new Rect((inRect.width - textWidth.x) / 2f, (inRect.height - textWidth.y) / 2f,
textWidth.x, textWidth.y);
Widgets.Label(label, _downloadMessage);
}
public void DownloadThingsComplete_Callback(IRestResponse<List<GlitterWorldItem>> response,
RestRequestAsyncHandle handle)
private void PutThingsListComplete_Callback(IRestResponse response, RestRequestAsyncHandle handle)
{
LogWriter.WriteMessage(response.ResponseStatus.ToString());
_apiStopwatch.Stop();
LogWriter.WriteMessage($"Request completed, Request took {_apiStopwatch.Elapsed}");
GlitterWorldApi.CheckResponseForErrors(response);
if (response.StatusCode != HttpStatusCode.OK)
{
_status = DownloadStatus.Failed;
return;
}
_status = DownloadStatus.DoneSendingSupportedThings;
}
private void PutModListComplete_Callback(IRestResponse response, RestRequestAsyncHandle handle)
{
LogWriter.WriteMessage(response.ResponseStatus.ToString());
_apiStopwatch.Stop();
LogWriter.WriteMessage($"Request completed, Request took {_apiStopwatch.Elapsed}");
GlitterWorldApi.CheckResponseForErrors(response);
if (response.StatusCode != HttpStatusCode.OK)
{
_status = DownloadStatus.Failed;
return;
}
_status = DownloadStatus.DoneSendingMods;
}
private void DownloadThingsComplete_Callback(IRestResponse<List<GlitterWorldItem>> response,
RestRequestAsyncHandle handle)
{
LogWriter.WriteMessage(response.ResponseStatus.ToString());
_apiStopwatch.Stop();
LogWriter.WriteMessage($"Request completed, Request took {_apiStopwatch.Elapsed}");
GlitterWorldApi.CheckResponseForErrors(response);
// This was originally called back from a different thread, so we set the correct flag and hand control back to the UI thread.
if (response.StatusCode != HttpStatusCode.OK)
{
_isDownloadComplete = DownloadStatus.Failed;
_status = DownloadStatus.Failed;
}
else
{
if (_mapComponent != null)
{
_mapComponent.SetTraderShipGoods(response.Data);
_isDownloadComplete = DownloadStatus.Complete;
_status = DownloadStatus.Complete;
}
else
{
_isDownloadComplete = DownloadStatus.Failed;
_status = DownloadStatus.Failed;
}
}
}
......@@ -133,6 +217,8 @@ namespace Glitterworld_Prime
private enum DownloadStatus
{
Incomplete,
DoneSendingSupportedThings,
DoneSendingMods,
Complete,
Failed
}
......
......@@ -163,48 +163,56 @@ namespace Glitterworld_Prime
if (Widgets.ButtonText(rect9, "AcceptButton".Translate(), true, false, true))
{
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();
};
{
Log.Message("GWP Starting order build", true);
bool flag;
var tracker = Utilities.GetMapComponent(TradeSession.playerNegotiator.Map).OrderTracker;
if (!TradeSession.deal.TryExecute(out flag))
{
Log.Message("Error at TradeSession.deal.TryExecute() or Colony couldn't afford it", 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())
{
var amt = TradeSession.deal.SilverTradeable.CountToTransferToSource;
if (amt > 0 && amt < 1)
{
SoundDefOf.ClickReject.PlayOneShotOnCamera(null);
Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation("GWPGiveItAway".Translate(),
action, false, null));
}
action();
}
else
......@@ -301,7 +309,7 @@ namespace Glitterworld_Prime
if (Widgets.ButtonText(rect2, _sorter1.LabelCap, true, false, true))
OpenSorterChangeFloatMenu(sorter1Setter);
// Add secondadry sort drop down menu button
// Add secondary sort drop down menu button
var rect3 = new Rect(rect2.xMax + 10f, 0f, 130f, 27f);
if (Widgets.ButtonText(rect3, _sorter2.LabelCap, true, false, true))
OpenSorterChangeFloatMenu(sorter2Setter);
......@@ -396,10 +404,16 @@ namespace Glitterworld_Prime
{
var def = allDefsListForReading[i];
if (def.LabelCap.NullOrEmpty())
{
LogWriter.WriteMessage(
$"ThingCategoryDef {def.defName} has no label!, Not able to filter by this, skipping. Please report to Mod Author.");
continue;
}
// We'll never deal with corpses so don't show them.
if (!def.LabelCap.ToLower().Contains("corpse"))
list.Add(new FloatMenuOption(def.LabelCap, delegate { filterSetter(def); },
MenuOptionPriority.Default, null, null, 0f, null, null));
list.Add(new FloatMenuOption(def.LabelCap, delegate { filterSetter(def); }));
}
Find.WindowStack.Add(new FloatMenu(list));
......@@ -412,8 +426,7 @@ namespace Glitterworld_Prime
for (var i = 0; i < allDefsListForReading.Count; i++)
{
var def = allDefsListForReading[i];
list.Add(new FloatMenuOption(def.LabelCap, delegate { sorterSetter(def); }, MenuOptionPriority.Default,
null, null, 0f, null, null));
list.Add(new FloatMenuOption(def.LabelCap, delegate { sorterSetter(def); }));
}
Find.WindowStack.Add(new FloatMenu(list));
......