Quietust 2012-11-20 09:42:21 -06:00
commit 284f02d4dd
7 changed files with 264 additions and 3 deletions

@ -27,7 +27,7 @@ distribution.
#include "Pragma.h" #include "Pragma.h"
#include "Export.h" #include "Export.h"
#include "Types.h" /* #include "Types.h" */
#include <map> #include <map>
#include <sys/types.h> #include <sys/types.h>
#include <vector> #include <vector>

@ -110,7 +110,7 @@ namespace DFHack
Pen chtile(char ch, int tile) { Pen cp(*this); cp.ch = ch; cp.tile = tile; return cp; } Pen chtile(char ch, int tile) { Pen cp(*this); cp.ch = ch; cp.tile = tile; return cp; }
}; };
struct ViewRect { struct DFHACK_EXPORT ViewRect {
rect2d view, clip; rect2d view, clip;
ViewRect(rect2d area) : view(area), clip(area) {} ViewRect(rect2d area) : view(area), clip(area) {}

@ -1 +1 @@
Subproject commit 111ba2297edb13a60f17e0b8ebc786c56df9c45f Subproject commit 42e26b368f48a148aba07fea295c6d19bca3fcbc

@ -0,0 +1,152 @@
class AutoFarm
def initialize
@thresholds = Hash.new(50)
@lastcounts = Hash.new(0)
end
def setthreshold (id, v)
if df.world.raws.plants.all.find { |r| r.id == id }
@thresholds[id] = v.to_i
else
puts "No plant with id #{id}"
end
end
def setdefault (v)
@thresholds.default = v.to_i
end
def is_plantable (plant)
season = df.cur_season
harvest = df.cur_season_tick + plant.growdur * 10
will_finish = harvest < 10080
can_plant = plant.flags[season]
can_plant = can_plant && (will_finish || plant.flags[(season+1)%4])
can_plant
end
def find_plantable_plants
plantable = {}
for i in 0..df.ui.tasks.known_plants.length-1
if df.ui.tasks.known_plants[i]
plant = df.world.raws.plants.all[i]
if is_plantable(plant)
plantable[i] = :Surface if (plant.underground_depth_min == 0 || plant.underground_depth_max == 0)
plantable[i] = :Underground if (plant.underground_depth_min > 0 || plant.underground_depth_max > 0)
end
end
end
return plantable
end
def set_farms ( plants, farms)
return if farms.length == 0
if plants.length == 0
plants = [-1]
end
season = df.cur_season
idx = 0
farms.each { |f|
f.plant_id[season] = plants[idx]
idx = (idx + 1) % plants.length
}
end
def process
return false unless @running
plantable = find_plantable_plants
counts = Hash.new(0)
df.world.items.other[:PLANT].each { |i|
if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect &&
!i.flags.hostile && !i.flags.on_fire && !i.flags.rotten &&
!i.flags.trader && !i.flags.in_building && !i.flags.construction &&
!i.flags.artifact1 && plantable.has_key? (i.mat_index))
counts[i.mat_index] = counts[i.mat_index] + i.stack_size
end
}
plants_s = []
plants_u = []
@lastcounts.clear
plantable.each_key { |k|
plant = df.world.raws.plants.all[k]
if (counts[k] < @thresholds[plant.id])
plants_s.push(k) if plantable[k] == :Surface
plants_u.push(k) if plantable[k] == :Underground
end
@lastcounts[plant.id] = counts[k]
}
farms_s = []
farms_u = []
df.world.buildings.other[:FARM_PLOT].each { |f|
if (f.flags.exists)
outside = df.map_designation_at(f.centerx,f.centery,f.z).outside
farms_s.push(f) if outside
farms_u.push(f) unless outside
end
}
set_farms (plants_s, farms_s)
set_farms (plants_u, farms_u)
end
def start
@onupdate = df.onupdate_register (100) { process }
@running = true
end
def stop
df.onupdate_unregister(@onupdate)
@running = false
end
def status
stat = @running ? "Running." : "Stopped."
@thresholds.each { |k,v|
stat += "\n#{k} limit #{v} current #{@lastcounts[k]}"
}
stat += "\nDefault: #{@thresholds.default}"
stat
end
end
$AutoFarm = AutoFarm.new unless $AutoFarm
case $script_args[0]
when 'start'
$AutoFarm.start
when 'end', 'stop'
$AutoFarm.stop
when 'default'
$AutoFarm.setdefault($script_args[1])
when 'threshold'
t = $script_args[1]
$script_args[2..-1].each {|i|
$AutoFarm.setthreshold(i, t)
}
when 'delete'
$AutoFarm.stop
$AutoFarm = nil
else
if $AutoFarm
puts $AutoFarm.status
else
puts "AI not started"
end
end

@ -0,0 +1,58 @@
class AutoUnsuspend
def initialize
end
def process
return false unless @running
joblist = df.world.job_list.next
count = 0
while joblist
job = joblist.item
joblist = joblist.next
if job.job_type == :ConstructBuilding
if (job.flags.suspend)
item = job.items[0].item
job.flags.suspend = false
count += 1
end
end
end
puts "Unsuspended #{count} job(s)." unless count == 0
end
def start
@onupdate = df.onupdate_register (5) { process }
@running = true
end
def stop
df.onupdate_unregister(@onupdate)
@running = false
end
def status
stat = @running ? "Running." : "Loaded."
end
end
case $script_args[0]
when 'start'
$AutoUnsuspend = AutoUnsuspend.new unless $AutoUnsuspend
$AutoUnsuspend.start
when 'end', 'stop'
$AutoUnsuspend.stop
else
if $AutoUnsuspend
puts $AutoUnsuspend.status
else
puts "AI not started"
end
end

@ -99,6 +99,16 @@ function boost_population(entry, factor, boost_count)
return boost_count return boost_count
end end
function incr_population(entry, factor, boost_count)
for _,v in ipairs(entry.records) do
if v.quantity < 10000001 then
boost_count = boost_count + 1
v.quantity = math.max(0, v.quantity + factor)
end
end
return boost_count
end
local args = {...} local args = {...}
local pops = enum_populations() local pops = enum_populations()
@ -123,6 +133,26 @@ elseif args[1] == 'boost' or args[1] == 'boost-all' then
end end
end end
print('Updated '..count..' populations.')
elseif args[1] == 'incr' or args[1] == 'incr-all' then
local factor = tonumber(args[3])
if not factor then
qerror('Invalid increment factor.')
end
local count = 0
if args[1] == 'incr' then
local entry = pops.any[args[2]] or qerror('Unknown population token.')
count = incr_population(entry, factor, count)
else
for k,entry in pairs(pops.any) do
if string.match(k, args[2]) then
count = incr_population(entry, factor, count)
end
end
end
print('Updated '..count..' populations.') print('Updated '..count..' populations.')
else else
print([[ print([[
@ -137,5 +167,9 @@ Usage:
population, otherwise decreases it. population, otherwise decreases it.
region-pops boost-all <pattern> <factor> region-pops boost-all <pattern> <factor>
Same as above, but match using a pattern acceptable to list. Same as above, but match using a pattern acceptable to list.
region-pops incr <TOKEN> <factor>
Augment (or diminish) all populations of TOKEN by factor (additive).
region-pops incr-all <pattern> <factor>
Same as above, but match using a pattern acceptable to list.
]]) ]])
end end

@ -0,0 +1,17 @@
joblist = df.world.job_list.next
count = 0
while joblist
job = joblist.item
joblist = joblist.next
if job.job_type == :ConstructBuilding
if (job.flags.suspend && job.items && job.items[0])
item = job.items[0].item
job.flags.suspend = false
count += 1
end
end
end
puts "Unsuspended #{count} job(s)."