static int dfhack_matinfo_matches(lua_State *state) { MaterialInfo info; if (!decode_matinfo(state, &info)) luaL_argerror(state, 1, "material info object expected"); luaL_checkany(state, 2); if (lua_isuserdata(state, 2)) { if (auto mc = Lua::GetDFObject<df::job_material_category>(state, 2)) lua_pushboolean(state, info.matches(*mc)); else if (auto mc = Lua::GetDFObject<df::dfhack_material_category>(state, 2)) lua_pushboolean(state, info.matches(*mc)); else if (auto mc = Lua::GetDFObject<df::job_item>(state, 2)) lua_pushboolean(state, info.matches(*mc)); else luaL_argerror(state, 2, "material category object expected"); } else if (lua_istable(state, 2)) { df::dfhack_material_category tmp; Lua::CheckDFAssign(state, &tmp, 2, false); lua_pushboolean(state, info.matches(tmp)); } else luaL_argerror(state, 2, "material category object expected"); return 1; }
command_result df_changevein (color_ostream &out, vector <string> & parameters) { if (parameters.size() != 1) return CR_WRONG_USAGE; CoreSuspender suspend; if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } if (!cursor || cursor->x == -30000) { out.printerr("No cursor detected - please place the cursor over a mineral vein.\n"); return CR_FAILURE; } MaterialInfo mi; if (!mi.findInorganic(parameters[0])) { out.printerr("No such material!\n"); return CR_FAILURE; } if (mi.inorganic->material.flags.is_set(material_flags::IS_METAL) || mi.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE) || mi.inorganic->flags.is_set(inorganic_flags::SOIL_ANY)) { out.printerr("Invalid material - you must select a type of stone or gem\n"); return CR_FAILURE; } df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z); if (!block) { out.printerr("Invalid tile selected.\n"); return CR_FAILURE; } df::block_square_event_mineralst *mineral = NULL; int tx = cursor->x % 16, ty = cursor->y % 16; for (size_t j = 0; j < block->block_events.size(); j++) { df::block_square_event *evt = block->block_events[j]; if (evt->getType() != block_square_event_type::mineral) continue; mineral = (df::block_square_event_mineralst *)evt; if (mineral->getassignment(tx, ty)) break; mineral = NULL; } if (!mineral) { out.printerr("Selected tile does not contain a mineral vein.\n"); return CR_FAILURE; } mineral->inorganic_mat = mi.index; return CR_OK; }
static int dfhack_matinfo_getToken(lua_State *state) { MaterialInfo info; decode_matinfo(state, &info, true); auto str = info.getToken(); lua_pushstring(state, str.c_str()); return 1; }
static int dfhack_matinfo_getCraftClass(lua_State *state) { MaterialInfo info; if (decode_matinfo(state, &info, true)) lua_pushinteger(state, info.getCraftClass()); else lua_pushnil(state); return 1; }
static int dfhack_matinfo_toString(lua_State *state) { MaterialInfo info; decode_matinfo(state, &info); lua_settop(state, 3); auto str = info.toString(luaL_optint(state, 2, 10015), lua_toboolean(state, 3)); lua_pushstring(state, str.c_str()); return 1; }
static command_result job_material_in_build(Core *c, MaterialInfo &new_mat) { df::ui_build_selector *sel = ui_build_selector; df::ui_build_item_req *req = sel->requirements[ui_build_selector->req_index]; // Loop through matching choices bool matches = build_choice_matches(req, sel->choices[sel->sel_index], new_mat, true); size_t size = sel->choices.size(); int base = (matches ? sel->sel_index + 1 : 0); for (size_t i = 0; i < size; i++) { int idx = (base + i) % size; if (build_choice_matches(req, sel->choices[idx], new_mat, false)) { sel->sel_index = idx; return CR_OK; } } c->con.printerr("Could not find material in list: %s\n", new_mat.toString().c_str()); return CR_FAILURE; }
static int dfhack_matinfo_find(lua_State *state) { MaterialInfo info; int argc = lua_gettop(state); if (argc == 1) info.find(luaL_checkstring(state, 1)); else { std::vector<std::string> tokens; for (int i = 1; i < argc; i++) tokens.push_back(luaL_checkstring(state, i)); info.find(tokens); } push_matinfo(state, info); return 1; }
static std::string shortJobDescription(df::job *job) { std::string rv = stl_sprintf("job %d: ", job->id); if (job->job_type != job_type::CustomReaction) rv += ENUM_KEY_STR(job_type, job->job_type); else rv += job->reaction_name; MaterialInfo mat; df::dfhack_material_category mat_mask; guess_job_material(job, mat, mat_mask); if (mat.isValid()) rv += " [" + mat.toString() + "]"; else if (mat_mask.whole) rv += " [" + bitfield_to_string(mat_mask) + "]"; return rv; }
/** Binds the texture for the given mesh-key. - Returns false if not cached in */ bool D3D11GraphicsEngineTest::BindShaderForKey(const MeshKey& key) { zCTexture* tx = key.Texture; if(!tx) return false; // FIXME: Gregs hat has this! Returning here causes it to not render at all // Bind texture if(tx->CacheIn(0.6f) == zRES_CACHED_IN) // FIXME: Don't always use a texture in a z-pre-pass! { MyDirectDrawSurface7* surface = tx->GetSurface(); ID3D11ShaderResourceView* srv[2]; // Get diffuse and normalmap srv[0] = ((D3D11Texture *)surface->GetEngineTexture())->GetShaderResourceView(); srv[1] = surface->GetNormalmap() ? ((D3D11Texture *)surface->GetNormalmap())->GetShaderResourceView() : NULL; // Bind both Context->PSSetShaderResources(0,2, srv); if(RenderingStage == DES_Z_PRE_PASS) { // Force alphatest on vobs for now BindShaderForTexturePrePass(tx, true); }else { BindShaderForTextureDiffusePass(tx); } // Get and update info if neccessary MaterialInfo* info = key.Info; if(!info->Constantbuffer) info->UpdateConstantbuffer(); // Bind info to pixel shader info->Constantbuffer->BindToPixelShader(2); } }
//Method for setting the current material void OpenGLContainer::setMaterial(MaterialInfo m){ float *diffuse = m.getDiffuse(); glMaterialfv(GL_FRONT, GL_SPECULAR, m.getSpecular()); glMaterialf (GL_FRONT, GL_SHININESS, m.getShininess()); glMaterialfv(GL_FRONT, GL_AMBIENT, m.getAmbient()); glMaterialfv(GL_FRONT, GL_DIFFUSE, m.getDiffuse()); glMaterialfv(GL_FRONT, GL_EMISSION, m.getEmitted()); glColor4f(diffuse[0],diffuse[1],diffuse[2],1.0); }
static void push_matinfo(lua_State *state, MaterialInfo &info) { if (!info.isValid()) { lua_pushnil(state); return; } lua_newtable(state); lua_pushvalue(state, lua_upvalueindex(1)); lua_setmetatable(state, -2); lua_pushinteger(state, info.type); lua_setfield(state, -2, "type"); lua_pushinteger(state, info.index); lua_setfield(state, -2, "index"); #define SETOBJ(name) { \ Lua::PushDFObject(state, info.name); \ lua_setfield(state, -2, #name); \ } SETOBJ(material); if (info.plant) SETOBJ(plant); if (info.creature) SETOBJ(creature); if (info.inorganic) SETOBJ(inorganic); if (info.figure) SETOBJ(figure); #undef SETOBJ if (info.mode != MaterialInfo::Builtin) { lua_pushinteger(state, info.subtype); lua_setfield(state, -2, "subtype"); } const char *id = "builtin"; switch (info.mode) { case MaterialInfo::Plant: id = "plant"; break; case MaterialInfo::Creature: id = "creature"; break; case MaterialInfo::Inorganic: id = "inorganic"; break; default: break; } lua_pushstring(state, id); lua_setfield(state, -2, "mode"); }
void DFHack::describeMaterial(BasicMaterialInfo *info, const MaterialInfo &mat, const BasicMaterialInfoMask *mask) { assert(mat.isValid()); info->set_type(mat.type); info->set_index(mat.index); describeMaterial(info, mat.material, mask); switch (mat.mode) { case MaterialInfo::Inorganic: info->set_token(mat.inorganic->id); if (mask && mask->flags()) flagarray_to_ints(info->mutable_inorganic_flags(), mat.inorganic->flags); break; case MaterialInfo::Creature: info->set_subtype(mat.subtype); if (mat.figure) { info->set_histfig_id(mat.index); info->set_creature_id(mat.figure->race); } else info->set_creature_id(mat.index); break; case MaterialInfo::Plant: info->set_plant_id(mat.index); break; default: break; } }
static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_material_category &mat_mask) { using namespace df::enums::job_type; if (job->job_type == PrepareMeal) mat.decode(-1); else mat.decode(job); mat_mask.whole = job->material_category.whole; // Material from the job enum const char *job_material = ENUM_ATTR(job_type, material, job->job_type); if (job_material) { MaterialInfo info; if (info.findBuiltin(job_material)) mat = info; else parseJobMaterialCategory(&mat_mask, job_material); } // Material from the job reagent if (!mat.isValid() && !job->job_items.empty() && (job->job_items.size() == 1 || job->job_items[0]->item_type == item_type::PLANT)) { mat.decode(job->job_items[0]); switch (job->job_items[0]->item_type) { case item_type::WOOD: mat_mask.bits.wood = mat_mask.bits.wood2 = true; break; default: break; } } }
MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { Key key = pos.get_material_key(); int index = key & (size - 1); MaterialInfo *mi = entries + index; // If mi->key matches the position's material hash key, it means that we // have analysed this material configuration before, and we can simply // return the information we found the last time instead of recomputing it: if(mi->key == key) return mi; // Clear the MaterialInfo object, and set its key: mi->clear(); mi->key = key; // A special case before looking for a specialized evaluation function: // KNN vs K is a draw: if(key == KNNKMaterialKey || key == KKNNMaterialKey) { mi->factor[WHITE] = mi->factor[BLACK] = 0; return mi; } // Let's look if we have a specialized evaluation function for this // particular material configuration: if(key == KPKMaterialKey) { mi->evaluationFunction = &EvaluateKPK; return mi; } else if(key == KKPMaterialKey) { mi->evaluationFunction = &EvaluateKKP; return mi; } else if(key == KBNKMaterialKey) { mi->evaluationFunction = &EvaluateKBNK; return mi; } else if(key == KKBNMaterialKey) { mi->evaluationFunction = &EvaluateKKBN; return mi; } else if(key == KRKPMaterialKey) { mi->evaluationFunction = &EvaluateKRKP; return mi; } else if(key == KPKRMaterialKey) { mi->evaluationFunction = &EvaluateKPKR; return mi; } else if(key == KRKBMaterialKey) { mi->evaluationFunction = &EvaluateKRKB; return mi; } else if(key == KBKRMaterialKey) { mi->evaluationFunction = &EvaluateKBKR; return mi; } else if(key == KRKNMaterialKey) { mi->evaluationFunction = &EvaluateKRKN; return mi; } else if(key == KNKRMaterialKey) { mi->evaluationFunction = &EvaluateKNKR; return mi; } else if(key == KQKRMaterialKey) { mi->evaluationFunction = &EvaluateKQKR; return mi; } else if(key == KRKQMaterialKey) { mi->evaluationFunction = &EvaluateKRKQ; return mi; } else if(key == KBBKNMaterialKey) { mi->evaluationFunction = &EvaluateKBBKN; return mi; } else if(key == KNKBBMaterialKey) { mi->evaluationFunction = &EvaluateKNKBB; return mi; } else if(pos.non_pawn_material(BLACK) == Value(0) && pos.pawn_count(BLACK) == 0 && pos.non_pawn_material(WHITE) >= RookValueEndgame) { mi->evaluationFunction = &EvaluateKXK; return mi; } else if(pos.non_pawn_material(WHITE) == Value(0) && pos.pawn_count(WHITE) == 0 && pos.non_pawn_material(BLACK) >= RookValueEndgame) { mi->evaluationFunction = &EvaluateKKX; return mi; } else if(pos.pawns() == EmptyBoardBB && pos.rooks() == EmptyBoardBB && pos.queens() == EmptyBoardBB) { // Minor piece endgame with at least one minor piece per side, // and no pawns. assert(pos.knights(WHITE) | pos.bishops(WHITE)); assert(pos.knights(BLACK) | pos.bishops(BLACK)); if(pos.bishop_count(WHITE) + pos.knight_count(WHITE) <= 2 && pos.bishop_count(BLACK) + pos.knight_count(BLACK) <= 2) { mi->evaluationFunction = &EvaluateKmmKm; return mi; } } // OK, we didn't find any special evaluation function for the current // material configuration. Is there a suitable scaling function? // // The code below is rather messy, and it could easily get worse later, // if we decide to add more special cases. We face problems when there // are several conflicting applicable scaling functions and we need to // decide which one to use. if(key == KRPKRMaterialKey) { mi->scalingFunction[WHITE] = &ScaleKRPKR; return mi; } if(key == KRKRPMaterialKey) { mi->scalingFunction[BLACK] = &ScaleKRKRP; return mi; } if(key == KRPPKRPMaterialKey) { mi->scalingFunction[WHITE] = &ScaleKRPPKRP; return mi; } else if(key == KRPKRPPMaterialKey) { mi->scalingFunction[BLACK] = &ScaleKRPKRPP; return mi; } if(key == KBPKBMaterialKey) { mi->scalingFunction[WHITE] = &ScaleKBPKB; return mi; } if(key == KBKBPMaterialKey) { mi->scalingFunction[BLACK] = &ScaleKBKBP; return mi; } if(key == KBPKNMaterialKey) { mi->scalingFunction[WHITE] = &ScaleKBPKN; return mi; } if(key == KNKBPMaterialKey) { mi->scalingFunction[BLACK] = &ScaleKNKBP; return mi; } if(key == KNPKMaterialKey) { mi->scalingFunction[WHITE] = &ScaleKNPK; return mi; } if(key == KKNPMaterialKey) { mi->scalingFunction[BLACK] = &ScaleKKNP; return mi; } if(pos.non_pawn_material(WHITE) == BishopValueMidgame && pos.bishop_count(WHITE) == 1 && pos.pawn_count(WHITE) >= 1) mi->scalingFunction[WHITE] = &ScaleKBPK; if(pos.non_pawn_material(BLACK) == BishopValueMidgame && pos.bishop_count(BLACK) == 1 && pos.pawn_count(BLACK) >= 1) mi->scalingFunction[BLACK] = &ScaleKKBP; if(pos.pawn_count(WHITE) == 0 && pos.non_pawn_material(WHITE) == QueenValueMidgame && pos.queen_count(WHITE) == 1 && pos.rook_count(BLACK) == 1 && pos.pawn_count(BLACK) >= 1) mi->scalingFunction[WHITE] = &ScaleKQKRP; else if(pos.pawn_count(BLACK) == 0 && pos.non_pawn_material(BLACK) == QueenValueMidgame && pos.queen_count(BLACK) == 1 && pos.rook_count(WHITE) == 1 && pos.pawn_count(WHITE) >= 1) mi->scalingFunction[BLACK] = &ScaleKRPKQ; if(pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) == Value(0)) { if(pos.pawn_count(BLACK) == 0) { assert(pos.pawn_count(WHITE) >= 2); mi->scalingFunction[WHITE] = &ScaleKPsK; } else if(pos.pawn_count(WHITE) == 0) { assert(pos.pawn_count(BLACK) >= 2); mi->scalingFunction[BLACK] = &ScaleKKPs; } else if(pos.pawn_count(WHITE) == 1 && pos.pawn_count(BLACK) == 1) { mi->scalingFunction[WHITE] = &ScaleKPKPw; mi->scalingFunction[BLACK] = &ScaleKPKPb; } } // Compute the space weight if(pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 2*QueenValueMidgame + 4*RookValueMidgame + 2*KnightValueMidgame) { int minorPieceCount = pos.knight_count(WHITE) + pos.knight_count(BLACK) + pos.bishop_count(WHITE) + pos.bishop_count(BLACK); mi->spaceWeight = minorPieceCount * minorPieceCount; } // Evaluate the material balance. Color c; int sign; Value egValue = Value(0), mgValue = Value(0); for(c = WHITE, sign = 1; c <= BLACK; c++, sign = -sign) { // No pawns makes it difficult to win, even with a material advantage: if(pos.pawn_count(c) == 0 && pos.non_pawn_material(c) - pos.non_pawn_material(opposite_color(c)) <= BishopValueMidgame) { if(pos.non_pawn_material(c) == pos.non_pawn_material(opposite_color(c))) mi->factor[c] = 0; else if(pos.non_pawn_material(c) < RookValueMidgame) mi->factor[c] = 0; else { switch(pos.bishop_count(c)) { case 2: mi->factor[c] = 32; break; case 1: mi->factor[c] = 12; break; case 0: mi->factor[c] = 6; break; } } } // Bishop pair: if(pos.bishop_count(c) >= 2) { mgValue += sign * BishopPairMidgameBonus; egValue += sign * BishopPairEndgameBonus; } // Knights are stronger when there are many pawns on the board. The // formula is taken from Larry Kaufman's paper "The Evaluation of Material // Imbalances in Chess": // http://mywebpages.comcast.net/danheisman/Articles/evaluation_of_material_imbalance.htm mgValue += sign * Value(pos.knight_count(c)*(pos.pawn_count(c)-5)*16); egValue += sign * Value(pos.knight_count(c)*(pos.pawn_count(c)-5)*16); // Redundancy of major pieces, again based on Kaufman's paper: if(pos.rook_count(c) >= 1) { Value v = Value((pos.rook_count(c) - 1) * 32 + pos.queen_count(c) * 16); mgValue -= sign * v; egValue -= sign * v; } } mi->mgValue = int16_t(mgValue); mi->egValue = int16_t(egValue); return mi; }
static command_result job_material_in_job(Core *c, MaterialInfo &new_mat) { df::job *job = getSelectedWorkshopJob(c); if (!job) return CR_FAILURE; if (!new_mat.isValid() || new_mat.type != 0) { c->con.printerr("New job material isn't inorganic: %s\n", new_mat.toString().c_str()); return CR_FAILURE; } MaterialInfo cur_mat(job); if (!cur_mat.isValid() || cur_mat.type != 0) { c->con.printerr("Current job material isn't inorganic: %s\n", cur_mat.toString().c_str()); return CR_FAILURE; } df::craft_material_class old_class = cur_mat.getCraftClass(); if (old_class == craft_material_class::None) { c->con.printerr("Unexpected current material type: %s\n", cur_mat.toString().c_str()); return CR_FAILURE; } if (new_mat.getCraftClass() != old_class) { c->con.printerr("New material %s does not satisfy requirement: %s\n", new_mat.toString().c_str(), ENUM_KEY_STR(craft_material_class, old_class)); return CR_FAILURE; } for (size_t i = 0; i < job->job_items.size(); i++) { df::job_item *item = job->job_items[i]; MaterialInfo item_mat(item); if (item_mat != cur_mat) { c->con.printerr("Job item %d has different material: %s\n", i, item_mat.toString().c_str()); return CR_FAILURE; } if (!new_mat.matches(*item)) { c->con.printerr("Job item %d requirements not satisfied by %s.\n", i, new_mat.toString().c_str()); return CR_FAILURE; } } // Apply the substitution job->mat_type = new_mat.type; job->mat_index = new_mat.index; for (size_t i = 0; i < job->job_items.size(); i++) { df::job_item *item = job->job_items[i]; item->mat_type = new_mat.type; item->mat_index = new_mat.index; } c->con << "Applied material '" << new_mat.toString() << "' to job " << ENUM_KEY_STR(job_type,job->job_type) << endl; return CR_OK; }
static command_result job_cmd(Core * c, vector <string> & parameters) { CoreSuspender suspend(c); std::string cmd = (parameters.empty() ? "query" : parameters[0]); if (cmd == "query" || cmd == "list") { df::job *job = getSelectedJob(c); if (!job) return CR_WRONG_USAGE; if (cmd == "query") { printJobDetails(c, job); } else { if (!workshop_job_hotkey(c, c->getTopViewscreen())) return CR_WRONG_USAGE; df::building *selected = world->selected_building; for (size_t i = 0; i < selected->jobs.size(); i++) printJobDetails(c, selected->jobs[i]); } } else if (cmd == "item-material") { if (parameters.size() != 3) return CR_WRONG_USAGE; df::job *job = getSelectedJob(c); df::job_item *item = getJobItem(c, job, parameters[1]); if (!item) return CR_WRONG_USAGE; ItemTypeInfo iinfo(item); MaterialInfo minfo; if (!minfo.find(parameters[2])) { c->con.printerr("Could not find the specified material.\n"); return CR_FAILURE; } if (minfo.isValid() && !iinfo.matches(*item, &minfo)) { c->con.printerr("Material does not match the requirements.\n"); printJobDetails(c, job); return CR_FAILURE; } if (job->mat_type != -1 && job->mat_type == item->mat_type && job->mat_index == item->mat_index) { job->mat_type = minfo.type; job->mat_index = minfo.index; } item->mat_type = minfo.type; item->mat_index = minfo.index; c->con << "Job item updated." << endl; if (item->item_type < 0 && minfo.isValid()) c->con.printerr("WARNING: Due to a probable bug, creature & plant material subtype\n" " is ignored unless the item type is also specified.\n"); printJobDetails(c, job); return CR_OK; } else if (cmd == "item-type") { if (parameters.size() != 3) return CR_WRONG_USAGE; df::job *job = getSelectedJob(c); df::job_item *item = getJobItem(c, job, parameters[1]); if (!item) return CR_WRONG_USAGE; ItemTypeInfo iinfo; MaterialInfo minfo(item); if (!iinfo.find(parameters[2])) { c->con.printerr("Could not find the specified item type.\n"); return CR_FAILURE; } if (iinfo.isValid() && !iinfo.matches(*item, &minfo)) { c->con.printerr("Item type does not match the requirements.\n"); printJobDetails(c, job); return CR_FAILURE; } item->item_type = iinfo.type; item->item_subtype = iinfo.subtype; c->con << "Job item updated." << endl; printJobDetails(c, job); return CR_OK; } else return CR_WRONG_USAGE; return CR_OK; }
static ItemConstraint *get_constraint(Core *c, const std::string &str, PersistentDataItem *cfg) { std::vector<std::string> tokens; split_string(&tokens, str, "/"); if (tokens.size() > 3) return NULL; int weight = 0; ItemTypeInfo item; if (!item.find(tokens[0]) || !item.isValid()) { c->con.printerr("Cannot find item type: %s\n", tokens[0].c_str()); return NULL; } if (item.subtype >= 0) weight += 10000; df::dfhack_material_category mat_mask; std::string maskstr = vector_get(tokens,1); if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) { c->con.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); return NULL; } if (mat_mask.whole != 0) weight += 100; MaterialInfo material; std::string matstr = vector_get(tokens,2); if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) { c->con.printerr("Cannot find material: %s\n", matstr.c_str()); return NULL; } if (material.type >= 0) weight += (material.index >= 0 ? 5000 : 1000); if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) { c->con.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str()); return NULL; } for (size_t i = 0; i < constraints.size(); i++) { ItemConstraint *ct = constraints[i]; if (ct->item == item && ct->material == material && ct->mat_mask.whole == mat_mask.whole) return ct; } ItemConstraint *nct = new ItemConstraint; nct->item = item; nct->material = material; nct->mat_mask = mat_mask; nct->weight = weight; if (cfg) nct->config = *cfg; else { nct->config = c->getWorld()->AddPersistentData("workflow/constraints"); nct->init(str); } constraints.push_back(nct); return nct; }
int Items::getItemBaseValue(int16_t item_type, int16_t item_subtype, int16_t mat_type, int32_t mat_subtype) { int value = 0; switch (item_type) { case item_type::BAR: case item_type::SMALLGEM: case item_type::BLOCKS: case item_type::SKIN_TANNED: value = 5; break; case item_type::ROUGH: case item_type::BOULDER: case item_type::WOOD: value = 3; break; case item_type::DOOR: case item_type::FLOODGATE: case item_type::BED: case item_type::CHAIR: case item_type::CHAIN: case item_type::FLASK: case item_type::GOBLET: case item_type::INSTRUMENT: case item_type::TOY: case item_type::CAGE: case item_type::BARREL: case item_type::BUCKET: case item_type::ANIMALTRAP: case item_type::TABLE: case item_type::COFFIN: case item_type::BOX: case item_type::BIN: case item_type::ARMORSTAND: case item_type::WEAPONRACK: case item_type::CABINET: case item_type::FIGURINE: case item_type::AMULET: case item_type::SCEPTER: case item_type::CROWN: case item_type::RING: case item_type::EARRING: case item_type::BRACELET: case item_type::GEM: case item_type::ANVIL: case item_type::TOTEM: case item_type::BACKPACK: case item_type::QUIVER: case item_type::BALLISTAARROWHEAD: case item_type::PIPE_SECTION: case item_type::HATCH_COVER: case item_type::GRATE: case item_type::QUERN: case item_type::MILLSTONE: case item_type::SPLINT: case item_type::CRUTCH: case item_type::SLAB: case item_type::BOOK: value = 10; break; case item_type::WINDOW: case item_type::STATUE: value = 25; break; case item_type::CORPSE: case item_type::CORPSEPIECE: case item_type::REMAINS: return 0; case item_type::WEAPON: if (size_t(item_subtype) < world->raws.itemdefs.weapons.size()) value = world->raws.itemdefs.weapons[item_subtype]->value; else value = 10; break; case item_type::ARMOR: if (size_t(item_subtype) < world->raws.itemdefs.armor.size()) value = world->raws.itemdefs.armor[item_subtype]->value; else value = 10; break; case item_type::SHOES: if (size_t(item_subtype) < world->raws.itemdefs.shoes.size()) value = world->raws.itemdefs.shoes[item_subtype]->value; else value = 5; break; case item_type::SHIELD: if (size_t(item_subtype) < world->raws.itemdefs.shields.size()) value = world->raws.itemdefs.shields[item_subtype]->value; else value = 10; break; case item_type::HELM: if (size_t(item_subtype) < world->raws.itemdefs.helms.size()) value = world->raws.itemdefs.helms[item_subtype]->value; else value = 10; break; case item_type::GLOVES: if (size_t(item_subtype) < world->raws.itemdefs.gloves.size()) value = world->raws.itemdefs.gloves[item_subtype]->value; else value = 5; break; case item_type::AMMO: if (size_t(item_subtype) < world->raws.itemdefs.ammo.size()) value = world->raws.itemdefs.ammo[item_subtype]->value; else value = 1; break; case item_type::MEAT: case item_type::PLANT: case item_type::PLANT_GROWTH: case item_type::CHEESE: value = 2; break; case item_type::FISH: case item_type::FISH_RAW: case item_type::EGG: value = 2; if (size_t(mat_type) < world->raws.creatures.all.size()) { auto creature = world->raws.creatures.all[mat_type]; if (size_t(mat_subtype) < creature->caste.size()) { auto caste = creature->caste[mat_subtype]; mat_type = caste->misc.bone_mat; mat_subtype = caste->misc.bone_matidx; } } break; case item_type::VERMIN: value = 0; if (size_t(mat_type) < world->raws.creatures.all.size()) { auto creature = world->raws.creatures.all[mat_type]; if (size_t(mat_subtype) < creature->caste.size()) value = creature->caste[mat_subtype]->misc.petvalue; } value /= 2; if (!value) return 1; return value; case item_type::PET: if (size_t(mat_type) < world->raws.creatures.all.size()) { auto creature = world->raws.creatures.all[mat_type]; if (size_t(mat_subtype) < creature->caste.size()) return creature->caste[mat_subtype]->misc.petvalue; } return 0; case item_type::SEEDS: case item_type::DRINK: case item_type::POWDER_MISC: case item_type::LIQUID_MISC: case item_type::COIN: case item_type::GLOB: case item_type::ORTHOPEDIC_CAST: value = 1; break; case item_type::THREAD: value = 6; break; case item_type::CLOTH: value = 7; break; case item_type::PANTS: if (size_t(item_subtype) < world->raws.itemdefs.pants.size()) value = world->raws.itemdefs.pants[item_subtype]->value; else value = 10; break; case item_type::CATAPULTPARTS: case item_type::BALLISTAPARTS: case item_type::TRAPPARTS: value = 30; break; case item_type::SIEGEAMMO: case item_type::TRACTION_BENCH: value = 20; break; case item_type::TRAPCOMP: if (size_t(item_subtype) < world->raws.itemdefs.trapcomps.size()) value = world->raws.itemdefs.trapcomps[item_subtype]->value; else value = 10; break; case item_type::FOOD: return 10; // case item_type::ROCK: default: return 0; case item_type::TOOL: if (size_t(item_subtype) < world->raws.itemdefs.tools.size()) value = world->raws.itemdefs.tools[item_subtype]->value; else value = 10; break; } MaterialInfo mat; if (mat.decode(mat_type, mat_subtype)) value *= mat.material->material_value; return value; }
static ItemConstraint *get_constraint(color_ostream &out, const std::string &str, PersistentDataItem *cfg) { std::vector<std::string> tokens; split_string(&tokens, str, "/"); if (tokens.size() > 4) return NULL; int weight = 0; bool is_craft = false; ItemTypeInfo item; if (tokens[0] == "ANY_CRAFT" || tokens[0] == "CRAFTS") { is_craft = true; } else if (!item.find(tokens[0]) || !item.isValid()) { out.printerr("Cannot find item type: %s\n", tokens[0].c_str()); return NULL; } if (item.subtype >= 0) weight += 10000; df::dfhack_material_category mat_mask; std::string maskstr = vector_get(tokens,1); if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) { out.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); return NULL; } if (mat_mask.whole != 0) weight += 100; MaterialInfo material; std::string matstr = vector_get(tokens,2); if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) { out.printerr("Cannot find material: %s\n", matstr.c_str()); return NULL; } item_quality::item_quality minqual = item_quality::Ordinary; std::string qualstr = vector_get(tokens, 3); if(!qualstr.empty()) { if(qualstr == "ordinary") minqual = item_quality::Ordinary; else if(qualstr == "wellcrafted") minqual = item_quality::WellCrafted; else if(qualstr == "finelycrafted") minqual = item_quality::FinelyCrafted; else if(qualstr == "superior") minqual = item_quality::Superior; else if(qualstr == "exceptional") minqual = item_quality::Exceptional; else if(qualstr == "masterful") minqual = item_quality::Masterful; else { out.printerr("Cannot find quality: %s\nKnown qualities: ordinary, wellcrafted, finelycrafted, superior, exceptional, masterful\n", qualstr.c_str()); return NULL; } } if (material.type >= 0) weight += (material.index >= 0 ? 5000 : 1000); if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) { out.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str()); return NULL; } for (size_t i = 0; i < constraints.size(); i++) { ItemConstraint *ct = constraints[i]; if (ct->is_craft == is_craft && ct->item == item && ct->material == material && ct->mat_mask.whole == mat_mask.whole && ct->min_quality == minqual) return ct; } ItemConstraint *nct = new ItemConstraint; nct->is_craft = is_craft; nct->item = item; nct->material = material; nct->mat_mask = mat_mask; nct->min_quality = minqual; nct->weight = weight; if (cfg) nct->config = *cfg; else { nct->config = Core::getInstance().getWorld()->AddPersistentData("workflow/constraints"); nct->init(str); } constraints.push_back(nct); return nct; }
void MeshRenderSystem::fillInstanceData(InstanceData* p_data, Entity* p_entity, RenderInfo* p_renderInfo, int p_boneCount){ MaterialInfo matInfo; p_data->setNumberOfActiveBones(p_boneCount); // Try and get the gradient component auto gradient = static_cast<GradientComponent*>(p_entity->getComponent( ComponentType::Gradient)); if(gradient != NULL){ // Set all the values needed matInfo = m_gfxBackend->getGfxWrapper()->getMaterialInfoFromMeshID( p_renderInfo->m_meshId); matInfo.setGradientLayer(1,gradient->m_color.layerOne); matInfo.setGradientLayer(2,gradient->m_color.layerTwo); p_data->setNumberOfActiveGradientLayers( matInfo.numberOfLayers ); } // If none was found check why else{ // Assume its a valid Ship Module ShipModule* shipModule = static_cast<ShipModule*>(m_world-> getComponentManager()->getComponent(p_entity,ComponentType::ShipModule)); if(shipModule != NULL && shipModule->m_parentEntity > -1){ Entity* parentShip = m_world->getEntity(shipModule->m_parentEntity); ModuleHelper::FindParentShip(m_world,&parentShip, shipModule); if(parentShip != NULL){ RenderInfo* parentShipRenderInfo = getRenderInfo(parentShip); matInfo = m_gfxBackend->getGfxWrapper()->getMaterialInfoFromMeshID( parentShipRenderInfo->m_meshId); auto gradient = static_cast<GradientComponent*>(parentShip->getComponent( ComponentType::Gradient)); matInfo.setGradientLayer(1,gradient->m_color.layerOne); matInfo.setGradientLayer(2,gradient->m_color.layerTwo); p_data->setNumberOfActiveGradientLayers( matInfo.numberOfLayers ); } } // If not a Ship Module set values to default else{ matInfo.setGradientLayer(1, AglVector4(1,1,1,1)); matInfo.setGradientLayer(2, AglVector4(1,1,1,1)); p_data->setNumberOfActiveGradientLayers( 1 ); } } auto colorTone = static_cast<ColorTone*>(p_entity->getComponent(ComponentType::ColorTone)); if (colorTone && colorTone->toneEnabled) p_data->setColorTone(colorTone->color); auto glowAnimation = static_cast<GlowAnimation*>(p_entity->getComponent( ComponentType::GlowAnimation)); if(glowAnimation && glowAnimation->enabled) { p_data->setColorTone(glowAnimation->color); } //neg-x creates additive blending //neg-y replaces color entirely if (p_entity->getComponent(ComponentType::SelectionMarker)) p_data->setColorTone(AglVector4(-0.6f, 0.8f, 0.2f, 1)); ///< neg-sign on y for total color replacement else if (p_entity->getComponent(ComponentType::TAG_Highlight)) p_data->setColorTone(AglVector4(0.5f, 1, 1, 1)); ShipHighlight* highlight = static_cast<ShipHighlight*>(p_entity->getComponent(ComponentType::ShipHighlight)); if (highlight && highlight->active) p_data->setColorTone(highlight->color); ShineSpawn* shineSpawn = static_cast<ShineSpawn*>(p_entity->getComponent(ComponentType::ShineSpawn)); if (shineSpawn) { float age = m_world->getElapsedTime()-shineSpawn->m_createdAt; if (age < shineSpawn->m_lifetime) p_data->setColorTone(AglVector4(-1, 1, 1, 1) * ((shineSpawn->m_lifetime-age) / shineSpawn->m_lifetime)); } p_data->setGradientColor( matInfo.getGradientColors() ); }