2020-09-08 01:17:56 -06:00
|
|
|
#pragma once
|
|
|
|
|
2020-10-16 15:08:52 -06:00
|
|
|
#include <queue>
|
2020-10-16 14:52:23 -06:00
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
#include "df/building.h"
|
2020-09-08 01:17:56 -06:00
|
|
|
#include "df/dfhack_material_category.h"
|
2020-10-16 14:52:23 -06:00
|
|
|
#include "df/item_quality.h"
|
|
|
|
#include "df/job_item.h"
|
|
|
|
|
2020-09-08 01:17:56 -06:00
|
|
|
#include "modules/Materials.h"
|
|
|
|
#include "modules/Persistence.h"
|
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
class ItemFilter
|
2020-09-08 01:17:56 -06:00
|
|
|
{
|
2020-10-16 14:52:23 -06:00
|
|
|
public:
|
|
|
|
ItemFilter();
|
|
|
|
|
|
|
|
void clear();
|
2020-10-16 15:08:52 -06:00
|
|
|
bool deserialize(std::string ser);
|
|
|
|
std::string serialize() const;
|
2020-10-16 14:52:23 -06:00
|
|
|
|
|
|
|
void addMaterialMask(uint32_t mask);
|
|
|
|
void clearMaterialMask();
|
|
|
|
void setMaterials(std::vector<DFHack::MaterialInfo> materials);
|
|
|
|
|
|
|
|
void incMinQuality();
|
|
|
|
void decMinQuality();
|
|
|
|
void incMaxQuality();
|
|
|
|
void decMaxQuality();
|
|
|
|
void toggleDecoratedOnly();
|
|
|
|
|
|
|
|
uint32_t getMaterialMask() const;
|
|
|
|
std::vector<std::string> getMaterials() const;
|
|
|
|
std::string getMinQuality() const;
|
|
|
|
std::string getMaxQuality() const;
|
|
|
|
bool getDecoratedOnly() const;
|
|
|
|
|
|
|
|
bool matches(df::dfhack_material_category mask) const;
|
|
|
|
bool matches(DFHack::MaterialInfo &material) const;
|
|
|
|
bool matches(df::item *item) const;
|
|
|
|
|
|
|
|
private:
|
2020-10-16 15:08:52 -06:00
|
|
|
// remove friend declaration when we no longer need v1 deserialization
|
|
|
|
friend void migrateV1ToV2();
|
|
|
|
|
2020-09-08 01:17:56 -06:00
|
|
|
df::dfhack_material_category mat_mask;
|
|
|
|
std::vector<DFHack::MaterialInfo> materials;
|
|
|
|
df::item_quality min_quality;
|
|
|
|
df::item_quality max_quality;
|
|
|
|
bool decorated_only;
|
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
bool deserializeMaterialMask(std::string ser);
|
|
|
|
bool deserializeMaterials(std::string ser);
|
|
|
|
void setMinQuality(int quality);
|
|
|
|
void setMaxQuality(int quality);
|
|
|
|
bool matchesMask(DFHack::MaterialInfo &mat) const;
|
2020-09-08 01:17:56 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
class PlannedBuilding
|
|
|
|
{
|
|
|
|
public:
|
2020-10-16 14:52:23 -06:00
|
|
|
PlannedBuilding(df::building *building, const std::vector<ItemFilter> &filters);
|
|
|
|
PlannedBuilding(DFHack::PersistentDataItem &config);
|
2020-09-08 01:17:56 -06:00
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
bool isValid() const;
|
2020-09-08 01:17:56 -06:00
|
|
|
void remove();
|
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
df::building * getBuilding();
|
|
|
|
const std::vector<ItemFilter> & getFilters() const;
|
2020-09-08 01:17:56 -06:00
|
|
|
|
|
|
|
private:
|
|
|
|
DFHack::PersistentDataItem config;
|
2020-10-16 14:52:23 -06:00
|
|
|
df::building *building;
|
2020-10-16 15:08:52 -06:00
|
|
|
const df::building::key_field_type building_id;
|
|
|
|
const std::vector<ItemFilter> filters;
|
2020-10-16 14:52:23 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
// building type, subtype, custom
|
|
|
|
typedef std::tuple<df::building_type, int16_t, int32_t> BuildingTypeKey;
|
|
|
|
|
|
|
|
BuildingTypeKey toBuildingTypeKey(
|
|
|
|
df::building_type btype, int16_t subtype, int32_t custom);
|
|
|
|
BuildingTypeKey toBuildingTypeKey(df::building *bld);
|
|
|
|
BuildingTypeKey toBuildingTypeKey(df::ui_build_selector *uibs);
|
|
|
|
|
|
|
|
struct BuildingTypeKeyHash
|
|
|
|
{
|
|
|
|
std::size_t operator() (const BuildingTypeKey & key) const;
|
2020-09-08 01:17:56 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
class Planner
|
|
|
|
{
|
|
|
|
public:
|
2020-10-16 14:52:23 -06:00
|
|
|
class ItemFiltersWrapper
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ItemFiltersWrapper(std::vector<ItemFilter> & item_filters)
|
|
|
|
: item_filters(item_filters) { }
|
|
|
|
std::vector<ItemFilter>::reverse_iterator rbegin() const { return item_filters.rbegin(); }
|
|
|
|
std::vector<ItemFilter>::reverse_iterator rend() const { return item_filters.rend(); }
|
|
|
|
const std::vector<ItemFilter> & get() const { return item_filters; }
|
|
|
|
private:
|
|
|
|
std::vector<ItemFilter> &item_filters;
|
|
|
|
};
|
2020-09-08 01:17:56 -06:00
|
|
|
|
2020-10-22 22:37:49 -06:00
|
|
|
const std::map<std::string, bool> & getGlobalSettings() const;
|
|
|
|
bool setGlobalSetting(std::string name, bool value);
|
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
void reset();
|
2020-09-08 01:17:56 -06:00
|
|
|
|
|
|
|
void addPlannedBuilding(df::building *bld);
|
2020-10-16 14:52:23 -06:00
|
|
|
PlannedBuilding *getPlannedBuilding(df::building *bld);
|
2020-09-08 01:17:56 -06:00
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
bool isPlannableBuilding(BuildingTypeKey key);
|
2020-09-08 01:17:56 -06:00
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
// returns an empty vector if the type is not supported
|
|
|
|
ItemFiltersWrapper getItemFilters(BuildingTypeKey key);
|
2020-09-08 01:17:56 -06:00
|
|
|
|
2020-10-16 14:52:23 -06:00
|
|
|
void doCycle();
|
2020-09-08 01:17:56 -06:00
|
|
|
|
|
|
|
private:
|
2020-10-22 22:37:49 -06:00
|
|
|
std::map<std::string, bool> global_settings;
|
2020-10-16 14:52:23 -06:00
|
|
|
std::unordered_map<BuildingTypeKey,
|
|
|
|
std::vector<ItemFilter>,
|
|
|
|
BuildingTypeKeyHash> default_item_filters;
|
2020-10-16 15:08:52 -06:00
|
|
|
// building id -> PlannedBuilding
|
|
|
|
std::unordered_map<int32_t, PlannedBuilding> planned_buildings;
|
|
|
|
// vector id -> filter bucket -> queue of (building id, job_item index)
|
|
|
|
std::map<df::job_item_vector_id, std::map<std::string, std::queue<std::pair<int32_t, int>>>> tasks;
|
|
|
|
|
|
|
|
bool registerTasks(PlannedBuilding &plannedBuilding);
|
|
|
|
void unregisterBuilding(int32_t id);
|
|
|
|
void popInvalidTasks(std::queue<std::pair<int32_t, int>> &task_queue);
|
2020-10-22 22:37:49 -06:00
|
|
|
void doVector(df::job_item_vector_id vector_id,
|
|
|
|
std::map<std::string, std::queue<std::pair<int32_t, int>>> & buckets);
|
2020-09-08 01:17:56 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
extern Planner planner;
|