-
Notifications
You must be signed in to change notification settings - Fork 0
/
dfstock.rb
96 lines (85 loc) · 2.92 KB
/
dfstock.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# A programmatic way to query and set stockpiles
=begin
dfstock
===
Use the DFStock module and stockpile objects to query/set stockpile items to create the perfect stockflow.
Note::
Currently, DFStock is not integrated into DFHack, meaning each command must be prefixed with 'ruby', or 'rb'
Usage::
rb DFStock.pile_at_cursor.status
[ prints pile status summary ...]
Examples::
rb p DFStock::Tree.instances.map {|t| d = t.material.solid_density ; [t.name, d] }.sort_by {|n,d| d }.first(5)
[["feather trees", 100], ["papaya trees", 130], ["candlenuts", 140], ["kapoks", 260], ["custard-apple trees", 360]]
rb pile_at_cursor.food.disable
=end
$LOAD_PATH << File.dirname(__FILE__)
require 'thing/thing'
require 'scaffold'
require 'stockpile/settings'
require 'stockpile/buildings'
require 'linkages'
module DFStock
def self.clear_error_before_loading
return if $!.nil?
puts "Clearing lingering error message"
begin
load '~/foo'
rescue LoadError => e
puts "Rescuing"
end
end
def self.loadfile fn
# puts "Loading #{fn}"
load fn
end
def self.libs
Dir.glob("#{File.dirname __FILE__}/**/*rb")
end
def self.reload
return :already_reloading if caller.any? {|c| c =~ /:in `reload'/ }
clear_error_before_loading
libs.each {|f| loadfile f }
puts "Finished reload"
end
end
DFStock.reload
module DFStock
def self.pathname_separator ; '|' end
def self.buildings ; df.world.buildings.all.select {|x| x.class <= DFHack::Building } end
def self.stockpiles
buildings.select {|x| x.class == DFHack::BuildingStockpilest }
end
def self.linkable_workshops
buildings.select {|x| x.class == DFHack::BuildingWorkshopst && x.respond_to?(:getStockpileLinks) && x.getStockpileLinks }
end
def self.hauling_stops # HaulingStops - there often are multiple at the same location for manually-guided routes.
df.ui.hauling.routes.map {|r| r.stops.to_a }.flatten
end
end
# debug methods
def wrap ; r = nil ; begin ; r = yield ; rescue Exception => e ; $e = e ; end ; r || e end
def try &b ; r = wrap &b ; puts(r.backtrace[0..12],'...',r.backtrace[-12..-1]) if r.is_a?(Exception) ; r end
def time ; s = Time.now ; r = yield ; puts "Took #{Time.now - s}s" ; r end
# UX Convenience methods at top level
def pile_at_cursor
c = df.cursor
(DFStock.stockpiles + DFStock.hauling_stops + DFStock.linkable_workshops).find {|b|
if b.respond_to? :pos # Hauling Stops - Warning: Will only find the first stop at a location
b.pos.z == c.z &&
b.pos.x == c.x &&
b.pos.y == c.y
elsif b.respond_to?(:room) && b.room.extents
next unless c.z == b.z
ox = c.x - b.room.x
oy = c.y - b.room.y
next if ox < 0 || ox > b.room.width || oy < 0 || oy > b.room.height
offset = ox + oy * b.room.width
b.room.extents[offset] == :Stockpile
else
b.z == c.z &&
b.x1 <= c.x && b.x2 >= c.x &&
b.y1 <= c.y && b.y2 >= c.y
end
}
end