local _ENV = mkmodule('plugins.plant') local argparse = require('argparse') local utils = require('utils') local function search_str(s) return dfhack.upperCp437(dfhack.toSearchNormalized(s)) end local function find_plant_idx(s) --find plant raw index by id string local id_str = search_str(s) for k, v in ipairs(df.global.world.raws.plants.all) do if search_str(v.id) == id_str then return k end end qerror('Plant raw not found: "'..s..'"') end local function find_plant(s) --accept index string or match id string if tonumber(s) then return argparse.nonnegativeInt(s, 'plant_id') else return find_plant_idx(s) end end local function build_filter(vec, s) if #vec > 0 then qerror('Filter already defined!') end local set = {} for _,id in ipairs(argparse.stringList(s, 'list')) do if id ~= '' then set[find_plant(id)] = true end end for idx,_ in pairs(set) do vec:insert('#', idx) --add plant raw indices to vector end end local year_table = { tree = 3, --sapling_to_tree_threshold ["1x1"] = 3, ["2x2"] = 201, --kapok, ginkgo, highwood ["3x3"] = 401, --highwood (tower-cap is bugged) } local function plant_age(s) --tree stage or numerical value local n if tonumber(s) then n = argparse.nonnegativeInt(s, 'age') else n = year_table[s:lower()] end if n then n = math.min(n, 1250) --grow_counter stops at 1250 years return math.max(0, 40320*n-1) --years to tens of ticks - 1; correct for n = 0 end qerror('Invalid age: "'..s..'"') end function parse_commandline(opts, pos_1, pos_2, filter_vec, args) local positionals = argparse.processArgsGetopt(args, { {'c', 'force', handler=function() opts.force = true end}, {'s', 'shrubs', handler=function() opts.shrubs = true end}, {'p', 'saplings', handler=function() opts.saplings = true end}, {'t', 'trees', handler=function() opts.trees = true end}, {'d', 'dead', handler=function() opts.dead = true end}, {'a', 'age', hasArg=true, handler=function(optarg) opts.age = plant_age(optarg) end}, {'f', 'filter', hasArg=true, handler=function(optarg) build_filter(filter_vec, optarg) end}, {'e', 'exclude', hasArg=true, handler=function(optarg) opts.filter_ex = true build_filter(filter_vec, optarg) end}, {'z', 'zlevel', handler=function() opts.zlevel = true end}, {'n', 'dry-run', handler=function() opts.dry_run = true end}, }) if #positionals > 3 then qerror('Too many positionals!') end local p1 = positionals[1] if not p1 then qerror('Specify mode: list, create, grow, or remove!') elseif p1 == 'list' then opts.plant_idx = -2 --will print all non-grass IDs elseif p1 == 'create' then opts.create = true if positionals[2] then opts.plant_idx = find_plant(positionals[2]) else qerror('Must specify plant_id for create!') end elseif p1 == 'grow' then opts.grow = true elseif p1 == 'remove' then opts.del = true else qerror('Invalid mode: "'..p1..'"! Must be list, create, grow, or remove!') end local n = opts.create and 3 or 2 if positionals[n] then utils.assign(pos_1, argparse.coords(positionals[n], 'pos_1', true)) end if not opts.create and positionals[3] then utils.assign(pos_2, argparse.coords(positionals[3], 'pos_2', true)) end end return _ENV