Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Template for new versions:
## New Features
- `sort`: search and sort for squad assignment screen
- `zone`: advanced unit assignment screens for cages, restraints, and pits/ponds
- `buildingplan`: one-click magma/fire safety filter for planned buildings

## Fixes
- Core: reload scripts in mods when a world is unloaded and immediately loaded again
Expand Down
4 changes: 2 additions & 2 deletions library/include/modules/Job.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ namespace DFHack
df::job_item_ref::T_role role,
int filter_idx = -1, int insert_idx = -1);

DFHACK_EXPORT bool isSuitableItem(df::job_item *item, df::item_type itype, int isubtype);
DFHACK_EXPORT bool isSuitableMaterial(df::job_item *item, int mat_type,
DFHACK_EXPORT bool isSuitableItem(const df::job_item *item, df::item_type itype, int isubtype);
DFHACK_EXPORT bool isSuitableMaterial(const df::job_item *item, int mat_type,
int mat_index,
df::item_type itype);
DFHACK_EXPORT std::string getName(df::job *job);
Expand Down
4 changes: 2 additions & 2 deletions library/modules/Job.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ bool DFHack::Job::attachJobItem(df::job *job, df::item *item,
return true;
}

bool Job::isSuitableItem(df::job_item *item, df::item_type itype, int isubtype)
bool Job::isSuitableItem(const df::job_item *item, df::item_type itype, int isubtype)
{
CHECK_NULL_POINTER(item);

Expand All @@ -581,7 +581,7 @@ bool Job::isSuitableItem(df::job_item *item, df::item_type itype, int isubtype)
}

bool Job::isSuitableMaterial(
df::job_item *item, int mat_type, int mat_index, df::item_type itype)
const df::job_item *item, int mat_type, int mat_index, df::item_type itype)
{
CHECK_NULL_POINTER(item);

Expand Down
6 changes: 4 additions & 2 deletions library/modules/Materials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,13 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma
TEST(fire_safe, material->heat.melting_point > 11000
&& material->heat.boiling_point > 11000
&& material->heat.ignite_point > 11000
&& material->heat.heatdam_point > 11000);
&& material->heat.heatdam_point > 11000
&& (material->heat.colddam_point == 60001 || material->heat.colddam_point < 11000));
TEST(magma_safe, material->heat.melting_point > 12000
&& material->heat.boiling_point > 12000
&& material->heat.ignite_point > 12000
&& material->heat.heatdam_point > 12000);
&& material->heat.heatdam_point > 12000
&& (material->heat.colddam_point == 60001 || material->heat.colddam_point < 12000));
TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL));
TEST(non_economic, !inorganic || !(plotinfo && vector_get(plotinfo->economic_stone, index)));

Expand Down
20 changes: 8 additions & 12 deletions plugins/buildingplan/buildingplan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,8 @@ static void load_material_cache() {
}

static HeatSafety get_heat_safety_filter(const BuildingTypeKey &key) {
// comment out until we can get heat safety working as intended
// if (cur_heat_safety.count(key))
// return cur_heat_safety.at(key);
if (cur_heat_safety.count(key))
return cur_heat_safety.at(key);
return HEAT_SAFETY_ANY;
}

Expand Down Expand Up @@ -948,22 +947,19 @@ static int getMaterialFilter(lua_State *L) {
map<MaterialInfo, int32_t> counts;
scanAvailableItems(*out, type, subtype, custom, index, false, NULL, &counts);
HeatSafety heat = get_heat_safety_filter(key);
df::job_item jitem_cur_heat = getJobItemWithHeatSafety(
get_job_items(*out, key)[index], heat);
df::job_item jitem_fire = getJobItemWithHeatSafety(
get_job_items(*out, key)[index], HEAT_SAFETY_FIRE);
df::job_item jitem_magma = getJobItemWithHeatSafety(
get_job_items(*out, key)[index], HEAT_SAFETY_MAGMA);
const df::job_item *jitem = get_job_items(*out, key)[index];
// name -> {count=int, enabled=bool, category=string, heat=string}
map<string, map<string, string>> ret;
for (auto & entry : mat_cache) {
auto &mat = entry.second.first;
if (!mat.matches(jitem_cur_heat))
if (!mat.matches(jitem))
continue;
if (!matchesHeatSafety(mat.type, mat.index, heat))
continue;
string heat_safety = "";
if (mat.matches(jitem_magma))
if (matchesHeatSafety(mat.type, mat.index, HEAT_SAFETY_MAGMA))
heat_safety = "magma-safe";
else if (mat.matches(jitem_fire))
else if (matchesHeatSafety(mat.type, mat.index, HEAT_SAFETY_FIRE))
heat_safety = "fire-safe";
auto &name = entry.first;
auto &cat = entry.second.second;
Expand Down
2 changes: 1 addition & 1 deletion plugins/buildingplan/buildingplan.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void set_config_bool(DFHack::PersistentDataItem &c, int index, bool value);

std::vector<df::job_item_vector_id> getVectorIds(DFHack::color_ostream &out, const df::job_item *job_item, bool ignore_filters);
bool itemPassesScreen(DFHack::color_ostream& out, df::item* item);
df::job_item getJobItemWithHeatSafety(const df::job_item *job_item, HeatSafety heat);
bool matchesHeatSafety(int16_t mat_type, int32_t mat_index, HeatSafety heat);
bool matchesFilters(df::item * item, const df::job_item * job_item, HeatSafety heat, const ItemFilter &item_filter, const std::set<std::string> &special);
bool isJobReady(DFHack::color_ostream &out, const std::vector<df::job_item *> &jitems);
void finalizeBuilding(DFHack::color_ostream &out, df::building *bld, bool unsuspend_on_finalize);
49 changes: 28 additions & 21 deletions plugins/buildingplan/buildingplan_cycle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,38 @@ bool itemPassesScreen(color_ostream& out, df::item* item) {
&& isAccessible(out, item);
}

df::job_item getJobItemWithHeatSafety(const df::job_item *job_item, HeatSafety heat) {
df::job_item jitem = *job_item;
if (heat >= HEAT_SAFETY_MAGMA) {
jitem.flags2.bits.magma_safe = true;
jitem.flags2.bits.fire_safe = false;
} else if (heat == HEAT_SAFETY_FIRE && !jitem.flags2.bits.magma_safe)
jitem.flags2.bits.fire_safe = true;
return jitem;
bool matchesHeatSafety(int16_t mat_type, int32_t mat_index, HeatSafety heat) {
if (heat == HEAT_SAFETY_ANY)
return true;

MaterialInfo minfo(mat_type, mat_index);
df::job_item_flags2 ok;
df::job_item_flags2 mask;
minfo.getMatchBits(ok, mask);

if (heat >= HEAT_SAFETY_MAGMA)
return ok.bits.magma_safe;
if (heat == HEAT_SAFETY_FIRE)
return ok.bits.fire_safe || ok.bits.magma_safe;
return false;
}

bool matchesFilters(df::item * item, const df::job_item * job_item, HeatSafety heat, const ItemFilter &item_filter, const std::set<string> &specials) {
bool matchesFilters(df::item * item, const df::job_item * jitem, HeatSafety heat, const ItemFilter &item_filter, const std::set<string> &specials) {
// check the properties that are not checked by Job::isSuitableItem()
if (job_item->item_type > -1 && job_item->item_type != item->getType())
if (jitem->item_type > -1 && jitem->item_type != item->getType())
return false;

if (job_item->item_subtype > -1 &&
job_item->item_subtype != item->getSubtype())
if (jitem->item_subtype > -1 &&
jitem->item_subtype != item->getSubtype())
return false;

if (job_item->flags2.bits.building_material && !item->isBuildMat())
if (jitem->flags2.bits.building_material && !item->isBuildMat())
return false;

if ((job_item->flags1.bits.empty || job_item->flags2.bits.lye_milk_free)) {
if ((jitem->flags1.bits.empty || jitem->flags2.bits.lye_milk_free)) {
auto gref = Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM);
if (gref) {
if (job_item->flags1.bits.empty)
if (jitem->flags1.bits.empty)
return false;
if (auto contained_item = gref->getItem(); contained_item) {
MaterialInfo mi;
Expand All @@ -102,23 +108,24 @@ bool matchesFilters(df::item * item, const df::job_item * job_item, HeatSafety h
}
}

if (job_item->metal_ore > -1 && !item->isMetalOre(job_item->metal_ore))
if (jitem->metal_ore > -1 && !item->isMetalOre(jitem->metal_ore))
return false;

if (job_item->has_tool_use > df::tool_uses::NONE
&& !item->hasToolUse(job_item->has_tool_use))
if (jitem->has_tool_use > df::tool_uses::NONE
&& !item->hasToolUse(jitem->has_tool_use))
return false;

if (item->getType() == df::item_type::SLAB && specials.count("engraved")
&& static_cast<df::item_slabst *>(item)->engraving_type != df::slab_engraving_type::Memorial)
return false;

df::job_item jitem = getJobItemWithHeatSafety(job_item, heat);
if (!matchesHeatSafety(item->getMaterial(), item->getMaterialIndex(), heat))
return false;

return Job::isSuitableItem(
&jitem, item->getType(), item->getSubtype())
jitem, item->getType(), item->getSubtype())
&& Job::isSuitableMaterial(
&jitem, item->getMaterial(), item->getMaterialIndex(),
jitem, item->getMaterial(), item->getMaterialIndex(),
item->getType())
&& item_filter.matches(item);
}
Expand Down
3 changes: 1 addition & 2 deletions plugins/buildingplan/plannedbuilding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ PlannedBuilding::PlannedBuilding(color_ostream &out, df::building *bld, HeatSafe
PlannedBuilding::PlannedBuilding(color_ostream &out, PersistentDataItem &bld_config)
: id(get_config_val(bld_config, BLD_CONFIG_ID)),
vector_ids(deserialize_vector_ids(out, bld_config)),
//heat_safety((HeatSafety)get_config_val(bld_config, BLD_CONFIG_HEAT)), // until this works
heat_safety(HEAT_SAFETY_ANY),
heat_safety((HeatSafety)get_config_val(bld_config, BLD_CONFIG_HEAT)),
item_filters(get_item_filters(out, bld_config)),
specials(get_specials(out, bld_config)),
bld_config(bld_config) { }
Expand Down
1 change: 0 additions & 1 deletion plugins/lua/buildingplan/planneroverlay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,6 @@ function PlannerOverlay:init()
on_change=function(heat)
buildingplan.setHeatSafetyFilter(uibs.building_type, uibs.building_subtype, uibs.custom_type, heat)
end,
visible=false, -- until we can make this work the way it's intended
},
},
},
Expand Down