diff --git a/NEWS b/NEWS index ada60cb1b..f2b79867b 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,10 @@ DFHack Future hack-wish: Made items stack properly. modtools/skill-change: made level granularity work properly. show-unit-syndromes should work + stockflow: Fixed error message in Arena mode + stockflow: No longer checks the DF version + stockflow: Fixed ballistic arrow head orders + stockflow: Now convinces the bookkeeper to update records more often zone: Stopped crash when scrolling cage owner list Removed Misc Improvements diff --git a/plugins/lua/stockflow.lua b/plugins/lua/stockflow.lua index 44a9e054c..745427656 100644 --- a/plugins/lua/stockflow.lua +++ b/plugins/lua/stockflow.lua @@ -31,9 +31,10 @@ CenterCol = 38 -- Populate the reaction and stockpile order lists. -- To be called whenever a world is loaded. function initialize_world() + -- Clear old reactions, just in case. + clear_caches() reaction_list = collect_reactions() saved_orders = collect_orders() - jobs_to_create = {} end -- Clear all caches. @@ -148,7 +149,13 @@ function select_order(stockpile) screen:show() end -function reaction_entry(job_type, values, name) +function reaction_entry(reactions, job_type, values, name) + if not job_type then + -- Perhaps df.job_type.something returned nil for an unknown job type. + -- We could warn about it; in any case, don't add it to the list. + return + end + local order = df.manager_order:new() -- These defaults differ from the newly created order's. order:assign{ @@ -164,10 +171,10 @@ function reaction_entry(job_type, values, name) order:assign(values) end - return { + table.insert(reactions, { name = name or df.job_type.attrs[job_type].caption, order = order, - } + }) end function resource_reactions(reactions, job_type, mat_info, keys, items, options) @@ -190,7 +197,7 @@ function resource_reactions(reactions, job_type, mat_info, keys, items, options) end values.item_subtype = itemid - table.insert(reactions, reaction_entry(job_type, values, start.." "..mat_info.adjective..item_name)) + reaction_entry(reactions, job_type, values, start.." "..mat_info.adjective..item_name) end end end @@ -203,7 +210,7 @@ function material_reactions(reactions, itemtypes, mat_info) line = line.." "..row[3] end - table.insert(reactions, reaction_entry(row[1], mat_info.management, line)) + reaction_entry(reactions, row[1], mat_info.management, line) end end @@ -226,9 +233,6 @@ function collect_reactions() -- Even that list doesn't seem to include their names. local result = {} - -- A few task types are obsolete in newer DF versions. - local v34 = string.match(dfhack.getDFVersion(), "v0.34") - -- Caching the enumeration might not be important, but saves lookups. local job_types = df.job_type @@ -251,11 +255,11 @@ function collect_reactions() materials.leather.clothing_flag = "LEATHER" -- Collection and Entrapment - table.insert(result, reaction_entry(job_types.CollectWebs)) - table.insert(result, reaction_entry(job_types.CollectSand)) - table.insert(result, reaction_entry(job_types.CollectClay)) - table.insert(result, reaction_entry(job_types.CatchLiveLandAnimal)) - table.insert(result, reaction_entry(job_types.CatchLiveFish)) + reaction_entry(result, job_types.CollectWebs) + reaction_entry(result, job_types.CollectSand) + reaction_entry(result, job_types.CollectClay) + reaction_entry(result, job_types.CatchLiveLandAnimal) + reaction_entry(result, job_types.CatchLiveFish) -- Cutting, encrusting, and metal extraction. local rock_types = df.global.world.raws.inorganics @@ -263,36 +267,36 @@ function collect_reactions() local material = rock_types[rock_id].material local rock_name = material.state_adj.Solid if material.flags.IS_STONE or material.flags.IS_GEM then - table.insert(result, reaction_entry(job_types.CutGems, { + reaction_entry(result, job_types.CutGems, { mat_type = 0, mat_index = rock_id, - }, "Cut "..rock_name)) + }, "Cut "..rock_name) - table.insert(result, reaction_entry(job_types.EncrustWithGems, { + reaction_entry(result, job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {finished_goods = true}, - }, "Encrust Finished Goods With "..rock_name)) + }, "Encrust Finished Goods With "..rock_name) - table.insert(result, reaction_entry(job_types.EncrustWithGems, { + reaction_entry(result, job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {furniture = true}, - }, "Encrust Furniture With "..rock_name)) + }, "Encrust Furniture With "..rock_name) - table.insert(result, reaction_entry(job_types.EncrustWithGems, { + reaction_entry(result, job_types.EncrustWithGems, { mat_type = 0, mat_index = rock_id, item_category = {ammo = true}, - }, "Encrust Ammo With "..rock_name)) + }, "Encrust Ammo With "..rock_name) end if #rock_types[rock_id].metal_ore.mat_index > 0 then - table.insert(result, reaction_entry(job_types.SmeltOre, {mat_type = 0, mat_index = rock_id}, "Smelt "..rock_name.." Ore")) + reaction_entry(result, job_types.SmeltOre, {mat_type = 0, mat_index = rock_id}, "Smelt "..rock_name.." Ore") end if #rock_types[rock_id].thread_metal.mat_index > 0 then - table.insert(result, reaction_entry(job_types.ExtractMetalStrands, {mat_type = 0, mat_index = rock_id})) + reaction_entry(result, job_types.ExtractMetalStrands, {mat_type = 0, mat_index = rock_id}) end end @@ -310,28 +314,28 @@ function collect_reactions() management = {mat_type = glass_id}, }) - table.insert(result, reaction_entry(job_types.CutGlass, {mat_type = glass_id}, "Cut "..glass_name)) + reaction_entry(result, job_types.CutGlass, {mat_type = glass_id}, "Cut "..glass_name) - table.insert(result, reaction_entry(job_types.EncrustWithGlass, { + reaction_entry(result, job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {finished_goods = true}, - }, "Encrust Finished Goods With "..glass_name)) + }, "Encrust Finished Goods With "..glass_name) - table.insert(result, reaction_entry(job_types.EncrustWithGlass, { + reaction_entry(result, job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {furniture = true}, - }, "Encrust Furniture With "..glass_name)) + }, "Encrust Furniture With "..glass_name) - table.insert(result, reaction_entry(job_types.EncrustWithGlass, { + reaction_entry(result, job_types.EncrustWithGlass, { mat_type = glass_id, item_category = {ammo = true}, - }, "Encrust Ammo With "..glass_name)) + }, "Encrust Ammo With "..glass_name) end end -- Dyeing - table.insert(result, reaction_entry(job_types.DyeThread)) - table.insert(result, reaction_entry(job_types.DyeCloth)) + reaction_entry(result, job_types.DyeThread) + reaction_entry(result, job_types.DyeCloth) -- Sew Image local cloth_mats = {materials.cloth, materials.silk, materials.yarn, materials.leather} @@ -343,54 +347,56 @@ function collect_reactions() material_reactions(result, {{job_types.DecorateWith, "Decorate With"}}, spec) end - table.insert(result, reaction_entry(job_types.MakeTotem)) - table.insert(result, reaction_entry(job_types.ButcherAnimal)) - table.insert(result, reaction_entry(job_types.MillPlants)) - table.insert(result, reaction_entry(job_types.MakePotashFromLye)) - table.insert(result, reaction_entry(job_types.MakePotashFromAsh)) + reaction_entry(result, job_types.MakeTotem) + reaction_entry(result, job_types.ButcherAnimal) + reaction_entry(result, job_types.MillPlants) + reaction_entry(result, job_types.MakePotashFromLye) + reaction_entry(result, job_types.MakePotashFromAsh) -- Kitchen - table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 2}, "Prepare Easy Meal")) - table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 3}, "Prepare Fine Meal")) - table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 4}, "Prepare Lavish Meal")) + reaction_entry(result, job_types.PrepareMeal, {mat_type = 2}, "Prepare Easy Meal") + reaction_entry(result, job_types.PrepareMeal, {mat_type = 3}, "Prepare Fine Meal") + reaction_entry(result, job_types.PrepareMeal, {mat_type = 4}, "Prepare Lavish Meal") - if v34 then - -- Brew Drink - table.insert(result, reaction_entry(job_types.BrewDrink)) - end + -- Brew Drink + reaction_entry(result, job_types.BrewDrink) -- Weaving - table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {plant = true}}, "Weave Thread into Cloth")) - table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {silk = true}}, "Weave Thread into Silk")) - table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {yarn = true}}, "Weave Yarn into Cloth")) + reaction_entry(result, job_types.WeaveCloth, {material_category = {plant = true}}, "Weave Thread into Cloth") + reaction_entry(result, job_types.WeaveCloth, {material_category = {silk = true}}, "Weave Thread into Silk") + reaction_entry(result, job_types.WeaveCloth, {material_category = {yarn = true}}, "Weave Yarn into Cloth") -- Extracts, farmer's workshop, and wood burning - table.insert(result, reaction_entry(job_types.ExtractFromPlants)) - table.insert(result, reaction_entry(job_types.ExtractFromRawFish)) - table.insert(result, reaction_entry(job_types.ExtractFromLandAnimal)) - table.insert(result, reaction_entry(job_types.PrepareRawFish)) - table.insert(result, reaction_entry(job_types.MakeCheese)) - table.insert(result, reaction_entry(job_types.MilkCreature)) - table.insert(result, reaction_entry(job_types.ShearCreature)) - table.insert(result, reaction_entry(job_types.SpinThread)) - table.insert(result, reaction_entry(job_types.MakeLye)) - table.insert(result, reaction_entry(job_types.ProcessPlants)) - if v34 then - table.insert(result, reaction_entry(job_types.ProcessPlantsBag)) - end - table.insert(result, reaction_entry(job_types.ProcessPlantsVial)) - table.insert(result, reaction_entry(job_types.ProcessPlantsBarrel)) - table.insert(result, reaction_entry(job_types.MakeCharcoal)) - table.insert(result, reaction_entry(job_types.MakeAsh)) + reaction_entry(result, job_types.ExtractFromPlants) + reaction_entry(result, job_types.ExtractFromRawFish) + reaction_entry(result, job_types.ExtractFromLandAnimal) + reaction_entry(result, job_types.PrepareRawFish) + reaction_entry(result, job_types.MakeCheese) + reaction_entry(result, job_types.MilkCreature) + reaction_entry(result, job_types.ShearCreature) + reaction_entry(result, job_types.SpinThread) + reaction_entry(result, job_types.MakeLye) + reaction_entry(result, job_types.ProcessPlants) + reaction_entry(result, job_types.ProcessPlantsBag) + reaction_entry(result, job_types.ProcessPlantsVial) + reaction_entry(result, job_types.ProcessPlantsBarrel) + reaction_entry(result, job_types.MakeCharcoal) + reaction_entry(result, job_types.MakeAsh) -- Reactions defined in the raws. -- Not all reactions are allowed to the civilization. -- That includes "Make sharp rock" by default. local entity = df.historical_entity.find(df.global.ui.civ_id) + if not entity then + -- No global civilization; arena mode? + -- Anyway, skip remaining reactions, since many depend on the civ. + return result + end + for _, reaction_id in ipairs(entity.entity_raw.workshops.permitted_reaction_id) do local reaction = df.global.world.raws.reactions[reaction_id] local name = string.gsub(reaction.name, "^.", string.upper) - table.insert(result, reaction_entry(job_types.CustomReaction, {reaction_name = reaction.code}, name)) + reaction_entry(result, job_types.CustomReaction, {reaction_name = reaction.code}, name) end -- Metal forging @@ -405,7 +411,7 @@ function collect_reactions() } if material.flags.IS_METAL then - table.insert(result, reaction_entry(job_types.StudWith, mat_flags.management, "Stud With "..rock_name)) + reaction_entry(result, job_types.StudWith, mat_flags.management, "Stud With "..rock_name) if material.flags.ITEMS_WEAPON then -- Todo: Are these really the right flags to check? @@ -414,7 +420,7 @@ function collect_reactions() }) -- Is this entirely disconnected from the entity? - material_reactions(result, {{MakeBallistaArrowHead, "Forge", "Ballista Arrow Head"}}, mat_flags) + material_reactions(result, {{job_types.MakeBallistaArrowHead, "Forge", "Ballista Arrow Head"}}, mat_flags) resource_reactions(result, job_types.MakeTrapComponent, mat_flags, entity.resources.trapcomp_type, itemdefs.trapcomps, { adjective = true, @@ -518,7 +524,7 @@ function collect_reactions() end -- Traction Bench - table.insert(result, reaction_entry(job_types.ConstructTractionBench)) + reaction_entry(result, job_types.ConstructTractionBench) -- Non-metal weapons resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.weapon_type, itemdefs.weapons, { @@ -642,7 +648,7 @@ function collect_reactions() end -- Bed, specified as wooden. - table.insert(result, reaction_entry(job_types.ConstructBed, materials.wood.management)) + reaction_entry(result, job_types.ConstructBed, materials.wood.management) -- Windows for _, mat_info in ipairs(glasses) do @@ -652,7 +658,7 @@ function collect_reactions() end -- Rock Mechanisms - table.insert(result, reaction_entry(job_types.ConstructMechanisms, materials.rock.management)) + reaction_entry(result, job_types.ConstructMechanisms, materials.rock.management) resource_reactions(result, job_types.AssembleSiegeAmmo, materials.wood, entity.resources.siegeammo_type, itemdefs.siege_ammo, { verb = "Assemble", @@ -711,8 +717,8 @@ function collect_reactions() end -- Siege engine parts - table.insert(result, reaction_entry(job_types.ConstructCatapultParts, materials.wood.management)) - table.insert(result, reaction_entry(job_types.ConstructBallistaParts, materials.wood.management)) + reaction_entry(result, job_types.ConstructCatapultParts, materials.wood.management) + reaction_entry(result, job_types.ConstructBallistaParts, materials.wood.management) for _, mat in ipairs{materials.wood, materials.bone} do resource_reactions(result, job_types.MakeAmmo, mat, entity.resources.ammo_type, itemdefs.ammo, { @@ -729,7 +735,7 @@ function collect_reactions() end -- Melt a Metal Object - table.insert(result, reaction_entry(job_types.MeltMetalObject)) + reaction_entry(result, job_types.MeltMetalObject) return result end diff --git a/plugins/stockflow.cpp b/plugins/stockflow.cpp index abbda87af..34dfc1bd7 100644 --- a/plugins/stockflow.cpp +++ b/plugins/stockflow.cpp @@ -81,12 +81,21 @@ public: } } - if (found && !bookkeeping) { - command_method("start_bookkeeping", out); - bookkeeping = true; - } else if (bookkeeping && !found) { - command_method("finish_bookkeeping", out); - bookkeeping = false; + if (found) { + // Entice the bookkeeper to spend less time update records. + ui->bookkeeper_precision += ui->bookkeeper_precision >> 3; + if (!bookkeeping) { + command_method("start_bookkeeping", out); + bookkeeping = true; + } + } else { + // Entice the bookkeeper to update records more often. + ui->bookkeeper_precision -= ui->bookkeeper_precision >> 5; + ui->bookkeeper_cooldown -= ui->bookkeeper_cooldown >> 2; + if (bookkeeping) { + command_method("finish_bookkeeping", out); + bookkeeping = false; + } } } diff --git a/travis/lint.py b/travis/lint.py index 5d16eca70..23c30449e 100644 --- a/travis/lint.py +++ b/travis/lint.py @@ -74,7 +74,7 @@ class TrailingWhitespaceLinter(Linter): msg = 'Contains trailing whitespace' def check_line(self, line): line = line.replace('\r', '') - return not line.endswith(' ') and not line.endswith('\t') + return not line.strip() or not line.endswith(' ') and not line.endswith('\t') def fix_line(self, line): return line.rstrip('\t ')