Skip to content

Commit

Permalink
Merge pull request #768 from zymex22/issue594
Browse files Browse the repository at this point in the history
Added finer selection options to the Smart Hopper
  • Loading branch information
Sn1p3rr3c0n authored Feb 25, 2024
2 parents 12765e6 + 3b543d1 commit ce4334d
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 31 deletions.
1 change: 1 addition & 0 deletions Defs/ThingDefs_Buildings/Buildings_Logistics.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<inspectorTabs>
<li>ITab_Storage</li>
<li>ProjectRimFactory.Common.ITab_PowerSupply</li> <!-- Power boost -->
<li>ProjectRimFactory.SAL3.Things.ITab_SmartHopper</li>
</inspectorTabs>
<castEdgeShadows>true</castEdgeShadows>
<statBases>
Expand Down
8 changes: 7 additions & 1 deletion Languages/English/Keyed/AllKeyed_SAL3.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@
<SmartHopper_Maximum>Current item max limit: {0}</SmartHopper_Maximum>
<SmartHopper_Minimum_UseTooltip>When this is enabled, the smart hopper will unforbid its items if the stored item has less than X stack size. It will also only take items if there are enough items around to exceed the minimum.</SmartHopper_Minimum_UseTooltip>
<SmartHopper_Maximum_UseTooltip>When this is enabled, the smart hopper will stop taking items if either the stack is full, or the stack size exceeds or is equal to X.</SmartHopper_Maximum_UseTooltip>
<SmartHopper_PickupFromGround>Pickup from ground</SmartHopper_PickupFromGround>
<PRF_CantCreateStockpile>Can't create Stockpile (No free Cells).</PRF_CantCreateStockpile>
<PRF.SmartHopper.ITab.Name>Pickup</PRF.SmartHopper.ITab.Name>
<PRF.SmartHopper.ITab.Description>Pickup Settings:</PRF.SmartHopper.ITab.Description>
<PRF.SmartHopper.ITab.AllowGround>Ground</PRF.SmartHopper.ITab.AllowGround>
<PRF.SmartHopper.ITab.AllowStockpile>Stockpile</PRF.SmartHopper.ITab.AllowStockpile>
<PRF.SmartHopper.ITab.AllowStorage>Storage Building</PRF.SmartHopper.ITab.AllowStorage>
<PRF.SmartHopper.ITab.AllowForbidden>Allow forbidden</PRF.SmartHopper.ITab.AllowForbidden>
<PRF.SmartHopper.ITab.AllowBelt>Allow Belt</PRF.SmartHopper.ITab.AllowBelt>

<!--Mod settings-->
<ProjectRimFactoryModName>Project RimFactory</ProjectRimFactoryModName>
Expand Down
20 changes: 20 additions & 0 deletions Source/ProjectRimFactory/Common/IPickupSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectRimFactory.Common
{
internal interface IPickupSettings
{

bool AllowGroundPickup { get; set; }
bool AllowStockpilePickup { get; set; }
bool AllowStoragePickup { get; set; }
bool AllowForbiddenPickup { get; set; }
bool AllowBeltPickup { get; set; }


}
}
138 changes: 108 additions & 30 deletions Source/ProjectRimFactory/SAL3/Things/Building_SmartHopper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ProjectRimFactory.Common;
using ProjectRimFactory.Common.HarmonyPatches;
using ProjectRimFactory.AutoMachineTool;
using ProjectRimFactory.Common;
using ProjectRimFactory.SAL3.Tools;
using ProjectRimFactory.Storage;
using ProjectRimFactory.Storage.UI;
Expand All @@ -8,42 +8,75 @@
using System.Linq;
using UnityEngine;
using Verse;
using Verse.Noise;

namespace ProjectRimFactory.SAL3.Things
{
public class Building_SmartHopper : Building, IStoreSettingsParent, IPowerSupplyMachineHolder
public class Building_SmartHopper : Building, IStoreSettingsParent, IPowerSupplyMachineHolder, IPickupSettings
{
private OutputSettings outputSettings;

public IEnumerable<IntVec3> cachedDetectorCells;
public List<IntVec3> cachedDetectorCells = new List<IntVec3>();
private bool cachedDetectorCellsDirty = true;

protected virtual bool ShouldRespectStackLimit => true;

public StorageSettings settings;

public Thing StoredThing => Position.GetFirstItem(Map);

private bool pickupFromGround;
private CompPowerWorkSetting compPowerWorkSetting;

public IPowerSupplyMachine RangePowerSupplyMachine => this.GetComp<CompPowerWorkSetting>();
public IPowerSupplyMachine RangePowerSupplyMachine => compPowerWorkSetting ?? this.GetComp<CompPowerWorkSetting>();

private IEnumerable<IntVec3> CellsToTarget => (this.GetComp<CompPowerWorkSetting>()?.GetRangeCells() ?? GenRadial.RadialCellsAround(Position, this.def.specialDisplayRadius, false)).Where(c => c.GetFirst<Building_SmartHopper>(this.Map) == null);
private IEnumerable<IntVec3> CellsToTarget
{
get
{
IEnumerable<IntVec3> cells = compPowerWorkSetting?.GetRangeCells() ?? GenRadial.RadialCellsAround(Position, this.def.specialDisplayRadius, false);
return cells.Where(c => c.GetFirst<Building_SmartHopper>(this.Map) == null); //Exclude other Smart Hoppers
}
}


private bool cellIsZone_Stockpile(IntVec3 cell)
{
return cell.GetZone(Map) is Zone_Stockpile;
}
private bool cellIsBuilding_Storage(IntVec3 cell)
{
return cell.GetThingList(Map).FirstOrDefault(t => t is ISlotGroupParent) is Building_Storage;
}
private bool cellIsBuilding_BeltConveyor(IntVec3 cell)
{
return cell.GetThingList(Map).Any(t => t is Building_BeltConveyor);
}

public IEnumerable<IntVec3> CellsToSelect
public List<IntVec3> CellsToSelect
{
get
{
if (Find.TickManager.TicksGame % 50 != 0 && cachedDetectorCells != null)
if (Find.TickManager.TicksGame % 50 != 0 && !cachedDetectorCellsDirty)
{
return cachedDetectorCells;
}

var resultCache = from IntVec3 c
in this.CellsToTarget
where this.pickupFromGround || c.HasSlotGroupParent(Map)
select c;
cachedDetectorCells = resultCache;
return resultCache;
cachedDetectorCellsDirty = false;
cachedDetectorCells.Clear();
foreach (IntVec3 c in CellsToTarget)
{
if (!c.InBounds(this.Map)) continue;
if ((allowStockpilePickup && cellIsZone_Stockpile(c)) ||
(allowStoragePickup && cellIsBuilding_Storage(c)) ||
(allowBeltPickup && cellIsBuilding_BeltConveyor(c)) ||
(this.allowGroundPickup && !cellIsZone_Stockpile(c) && !cellIsBuilding_Storage(c) && !cellIsBuilding_BeltConveyor(c))
)
{
cachedDetectorCells.Add(c);
}
}

return cachedDetectorCells;
}
}

Expand All @@ -53,10 +86,13 @@ public IEnumerable<Thing> ThingsToSelect
{
foreach (var c in CellsToSelect)
{
if (!c.InBounds(this.Map)) continue;
foreach (Thing t in GatherThingsUtility.AllThingsInCellForUse(c, Map,false))
foreach (Thing t in GatherThingsUtility.AllThingsInCellForUse(c, Map,AllowStockpilePickup))
{
yield return t;
var SlotGroupParrent = t.GetSlotGroup()?.parent;
if (allowForbiddenPickup || !t.IsForbidden(Faction.OfPlayer))
{
yield return t;
}
}
}
}
Expand All @@ -80,19 +116,65 @@ public OutputSettings OutputSettings
}
}

public Thing NPDI_Item => StoredThing;


private bool allowGroundPickup = false;
private bool allowStockpilePickup = false;
private bool allowStoragePickup = false;
private bool allowForbiddenPickup = false;
private bool allowBeltPickup = false;

public bool AllowGroundPickup
{
get => allowGroundPickup;

set
{
if (value != allowGroundPickup) cachedDetectorCellsDirty = true;
allowGroundPickup = value;
}
}
public bool AllowStockpilePickup
{
get => allowStockpilePickup;
set
{
if (value != allowStockpilePickup) cachedDetectorCellsDirty = true;
allowStockpilePickup = value;
}
}
public bool AllowStoragePickup
{
get => allowStoragePickup;
set
{
if (value != allowStoragePickup) cachedDetectorCellsDirty = true;
allowStoragePickup = value;
}
}
public bool AllowForbiddenPickup { get => allowForbiddenPickup; set => allowForbiddenPickup = value; }
public bool AllowBeltPickup
{
get => allowBeltPickup;
set
{
if (value != allowBeltPickup) cachedDetectorCellsDirty = true;
allowBeltPickup = value;
}
}

public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
compPowerWorkSetting = this.GetComp<CompPowerWorkSetting>();
if (settings == null)
{
settings = new StorageSettings();
settings.CopyFrom(GetParentStoreSettings());
}
if (!respawningAfterLoad)
{
this.pickupFromGround = true;
this.allowGroundPickup = true;
}
}

Expand All @@ -101,7 +183,11 @@ public override void ExposeData()
base.ExposeData();
Scribe_Deep.Look(ref outputSettings, "outputSettings", "SmartHopper_Minimum_UseTooltip", "SmartHopper_Maximum_UseTooltip");
Scribe_Deep.Look(ref settings, "settings", this);
Scribe_Values.Look(ref this.pickupFromGround, "pickupFromGround");
Scribe_Values.Look(ref this.allowGroundPickup, "allowGroundPickup", false);
Scribe_Values.Look(ref this.allowStockpilePickup, "allowStockpilePickup", false);
Scribe_Values.Look(ref this.allowStoragePickup, "allowStoragePickup", false);
Scribe_Values.Look(ref this.allowForbiddenPickup, "allowForbiddenPickup", false);
Scribe_Values.Look(ref this.allowBeltPickup, "allowBeltPickup", false);
}

public override string GetInspectString()
Expand Down Expand Up @@ -185,8 +271,7 @@ public virtual void TryStoreThing(Thing element)
public override void DrawExtraSelectionOverlays()
{
base.DrawExtraSelectionOverlays();
if (!this.pickupFromGround)
GenDraw.DrawFieldEdges(CellsToSelect.ToList(), Color.green);
GenDraw.DrawFieldEdges(CellsToSelect, Color.green);
}

public override IEnumerable<Gizmo> GetGizmos()
Expand All @@ -201,13 +286,6 @@ public override IEnumerable<Gizmo> GetGizmos()
defaultLabel = "SmartHopper_SetTargetAmount".Translate(),
action = () => Find.WindowStack.Add(new Dialog_OutputMinMax(OutputSettings)),
};
yield return new Command_Toggle
{
icon = ContentFinder<Texture2D>.Get("PRFUi/PickupFromGround"),
defaultLabel = "SmartHopper_PickupFromGround".Translate(),
toggleAction = () => this.pickupFromGround = !this.pickupFromGround,
isActive = () => this.pickupFromGround
};
}

public StorageSettings GetStoreSettings()
Expand Down
68 changes: 68 additions & 0 deletions Source/ProjectRimFactory/SAL3/Things/ITab_SmartHopper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using ProjectRimFactory.Common;
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;

namespace ProjectRimFactory.SAL3.Things
{
public class ITab_SmartHopper : ITab
{

private static readonly Vector2 WinSize = new Vector2(200f, 200f);

private IPickupSettings hopper => this.SelThing as IPickupSettings;


private bool GroundPickup = false;
private bool Stockpile = false;
private bool BuildingStorage = false;
private bool Allowforbidden = false;
private bool AllowBelt = false;

public ITab_SmartHopper()
{
this.size = WinSize;
this.labelKey = "PRF.SmartHopper.ITab.Name";
}

protected override void FillTab()
{
Listing_Standard list = new Listing_Standard();
Rect rect = new Rect(0f, 0f, WinSize.x-20f, WinSize.y).ContractedBy(10f);
list.Begin(rect);

GroundPickup = hopper.AllowGroundPickup;
Stockpile = hopper.AllowStockpilePickup;
BuildingStorage = hopper.AllowStoragePickup;
Allowforbidden = hopper.AllowForbiddenPickup;
AllowBelt = hopper.AllowBeltPickup;


list.Label("PRF.SmartHopper.ITab.Description".Translate());
rect = list.GetRect(30);
Widgets.CheckboxLabeled(rect, "PRF.SmartHopper.ITab.AllowGround".Translate(), ref GroundPickup);
rect = list.GetRect(30);
Widgets.CheckboxLabeled(rect, "PRF.SmartHopper.ITab.AllowStockpile".Translate(), ref Stockpile);
rect = list.GetRect(30);
Widgets.CheckboxLabeled(rect, "PRF.SmartHopper.ITab.AllowStorage".Translate(), ref BuildingStorage);
rect = list.GetRect(30);
Widgets.CheckboxLabeled(rect, "PRF.SmartHopper.ITab.AllowForbidden".Translate(), ref Allowforbidden);
rect = list.GetRect(30);
Widgets.CheckboxLabeled(rect, "PRF.SmartHopper.ITab.AllowBelt".Translate(), ref AllowBelt);

hopper.AllowGroundPickup = GroundPickup;
hopper.AllowStockpilePickup = Stockpile;
hopper.AllowStoragePickup = BuildingStorage;
hopper.AllowForbiddenPickup = Allowforbidden;
hopper.AllowBeltPickup = AllowBelt;

list.End();

}
}
}

0 comments on commit ce4334d

Please sign in to comment.