Clothing::Clothing(int32_t equipid, const BodyDrawinfo& drawinfo) : ItemData(equipid) { static const CharacterLayer layers[15] = { CL_HAT, CL_FACEACC, CL_EYEACC, CL_EARRINGS, CL_TOP, CL_MAIL, CL_PANTS, CL_SHOES, CL_GLOVE, CL_SHIELD, CL_CAPE, CL_RING, CL_PENDANT, CL_BELT, CL_MEDAL }; static const Equipslot equipslots[15] = { EQL_CAP, EQL_FACEACC, EQL_EYEACC, EQL_EARRINGS, EQL_TOP, EQL_TOP, EQL_PANTS, EQL_SHOES, EQL_GLOVES, EQL_SHIELD, EQL_CAPE, EQL_RING, EQL_PENDANT, EQL_BELT, EQL_MEDAL }; static const string equiptypes[15] = { "HAT", "FACE ACCESSORY", "EYE ACCESSORY", "EARRINGS", "TOP", "OVERALL", "BOTTOM", "SHOES", "GLOVES", "SHIELD", "CAPE", "RING", "PENDANT", "BELT", "MEDAL" }; CharacterLayer chlayer; int32_t index = (equipid / 10000) - 100; if (index >= 0 && index < 15) { chlayer = layers[index]; eqslot = equipslots[index]; type = equiptypes[index]; } else if (index >= 30 && index <= 49) { chlayer = CL_WEAPON; eqslot = EQL_WEAPON; static const string weapontypes[20] = { "ONE-HANDED SWORD", "ONE-HANDED AXE", "ONE-HANDED MACE", "DAGGER", "", "", "", "WAND", "STAFF", "", "TWO-HANDED SWORD", "TWO-HANDED AXE", "TWO-HANDED MACE", "SPEAR", "POLEARM", "BOW", "CROSSBOW", "CLAW", "KNUCKLE", "GUN" }; int32_t weaponindex = index - 30; if (weaponindex >= 0 && weaponindex < 20) type = weapontypes[weaponindex]; else type = "CASH"; } else { chlayer = CL_BASE; eqslot = EQL_NONE; type = ""; } using nl::node; node equipnode = nl::nx::character[getcategory()]["0" + std::to_string(equipid) + ".img"]; for (node stancenode : equipnode) { string stance = stancenode.name(); if (stance == "info") { cash = stancenode["cash"].get_bool(); tradeblock = stancenode["tradeBlock"].get_bool(); price = stancenode["price"]; slots = stancenode["tuc"]; reqstats[MS_LEVEL] = stancenode["reqLevel"]; reqstats[MS_JOB] = stancenode["reqJob"]; reqstats[MS_STR] = stancenode["reqSTR"]; reqstats[MS_DEX] = stancenode["reqDEX"]; reqstats[MS_INT] = stancenode["reqINT"]; reqstats[MS_LUK] = stancenode["reqLUK"]; defstats[ES_STR] = stancenode["incSTR"]; defstats[ES_DEX] = stancenode["incDEX"]; defstats[ES_INT] = stancenode["incINT"]; defstats[ES_LUK] = stancenode["incLUK"]; defstats[ES_WATK] = stancenode["incPAD"]; defstats[ES_WDEF] = stancenode["incPDD"]; defstats[ES_MAGIC] = stancenode["incMAD"]; defstats[ES_MDEF] = stancenode["incMDD"]; defstats[ES_HP] = stancenode["incMHP"]; defstats[ES_MP] = stancenode["incMMP"]; defstats[ES_ACC] = stancenode["incACC"]; defstats[ES_AVOID] = stancenode["incEVA"]; defstats[ES_HANDS] = stancenode["incHANDS"]; defstats[ES_SPEED] = stancenode["incSPEED"]; defstats[ES_JUMP] = stancenode["incJUMP"]; } else if (stance != "default" && stance != "backDefault") { uint8_t frame = 0; node framenode = stancenode[std::to_string(frame)]; while (framenode.size() > 0) { for (node partnode : framenode) { string part = partnode.name(); if (partnode.data_type() == node::type::bitmap) { CharacterLayer z = chlayer; string zs = partnode["z"]; if (z == CL_WEAPON) { if (zs == "weaponOverHand") z = CL_WEAPONOHAND; else if (zs == "weaponOverGlove") z = CL_WEAPONOGLOVE; else if (zs == "backWeaponOverShield") z = CL_BACKWEAPON; } else if (z == CL_SHIELD) { if (zs == "shieldOverHair") z = CL_SHIELDOHAIR; else if (zs == "shieldBelowBody") z = CL_SHIELDBBODY; else if (zs == "backShield") z = CL_BACKSHIELD; } else if (part == "mailArm") { z = CL_MAILARM; } stances[stance][z][frame] = Texture(partnode); string parent; vector2d<int16_t> parentpos; for (node mapnode : partnode["map"]) { if (mapnode.data_type() == node::type::vector) { parent = mapnode.name(); parentpos = vector2d<int16_t>(mapnode); } } vector2d<int16_t> shift; switch (z) { case CL_FACEACC: shift -= parentpos; break; case CL_TOP: case CL_PANTS: case CL_CAPE: case CL_SHOES: case CL_MAIL: case CL_MAILARM: case CL_GLOVE: case CL_BACKWEAPON: case CL_BACKSHIELD: shift = drawinfo.getbodypos(stance, frame) - parentpos; break; case CL_HAT: case CL_EARRINGS: case CL_EYEACC: shift = drawinfo.getfacepos(stance, frame) - parentpos; break; case CL_SHIELD: case CL_SHIELDOHAIR: case CL_WEAPON: case CL_WEAPONOHAND: case CL_WEAPONOGLOVE: if (parent == "hand") { shift += drawinfo.getarmpos(stance, frame); } else if (parent == "handMove") { shift += drawinfo.gethandpos(stance, frame); } shift += drawinfo.getbodypos(stance, frame) - parentpos; break; default: shift = vector2d<int16_t>(); } stances[stance][z][frame].setshift(shift); } } frame++; framenode = stancenode[std::to_string(frame)]; } } } static const int32_t transparentequips[1] = { 1002186 }; transparent = false; for (size_t i = 0; i < 1; i++) { if (equipid == transparentequips[i]) transparent = true; } }
Clothing::Clothing(int32_t id, const BodyDrawinfo& drawinfo) : itemid(id) { const EquipData& equipdata = EquipData::get(itemid); eqslot = equipdata.get_eqslot(); if (eqslot == Equipslot::WEAPON) { twohanded = WeaponData::get(itemid) .is_twohanded(); } else { twohanded = false; } constexpr size_t NON_WEAPON_TYPES = 15; constexpr size_t WEAPON_OFFSET = NON_WEAPON_TYPES + 15; constexpr size_t WEAPON_TYPES = 20; constexpr Layer layers[NON_WEAPON_TYPES] = { Layer::CAP, Layer::FACEACC, Layer::EYEACC, Layer::EARRINGS, Layer::TOP, Layer::MAIL, Layer::PANTS, Layer::SHOES, Layer::GLOVE, Layer::SHIELD, Layer::CAPE, Layer::RING, Layer::PENDANT, Layer::BELT, Layer::MEDAL }; Layer chlayer; size_t index = (itemid / 10000) - 100; if (index < NON_WEAPON_TYPES) { chlayer = layers[index]; } else if (index >= WEAPON_OFFSET && index < WEAPON_OFFSET + WEAPON_TYPES) { chlayer = Layer::WEAPON; } else { chlayer = Layer::CAPE; } std::string strid = "0" + std::to_string(itemid); std::string category = equipdata.get_itemdata().get_category(); nl::node src = nl::nx::character[category][strid + ".img"]; nl::node info = src["info"]; vslot = info["vslot"]; switch (int32_t standno = info["stand"]) { case 1: stand = Stance::STAND1; break; case 2: stand = Stance::STAND2; break; default: stand = twohanded ? Stance::STAND2 : Stance::STAND1; } switch (int32_t walkno = info["walk"]) { case 1: walk = Stance::WALK1; break; case 2: walk = Stance::WALK2; break; default: walk = twohanded ? Stance::WALK2 : Stance::WALK1; } for (auto iter : Stance::names) { Stance::Id stance = iter.first; const std::string& stancename = iter.second; nl::node stancenode = src[stancename]; if (!stancenode) continue; for (uint8_t frame = 0; nl::node framenode = stancenode[frame]; ++frame) { for (nl::node partnode : framenode) { std::string part = partnode.name(); if (!partnode || partnode.data_type() != nl::node::type::bitmap) continue; Layer z = chlayer; std::string zs = partnode["z"]; if (part == "mailArm") { z = Layer::MAILARM; } else { auto sublayer_iter = sublayernames.find(zs); if (sublayer_iter != sublayernames.end()) z = sublayer_iter->second; } std::string parent; Point<int16_t> parentpos; for (auto mapnode : partnode["map"]) { if (mapnode.data_type() == nl::node::type::vector) { parent = mapnode.name(); parentpos = mapnode; } } nl::node mapnode = partnode["map"]; Point<int16_t> shift; switch (eqslot) { case Equipslot::FACEACC: shift -= parentpos; break; case Equipslot::SHOES: case Equipslot::GLOVES: case Equipslot::TOP: case Equipslot::PANTS: case Equipslot::CAPE: shift = drawinfo.get_body_position(stance, frame) - parentpos; break; case Equipslot::CAP: case Equipslot::EARRINGS: case Equipslot::EYEACC: shift = drawinfo.getfacepos(stance, frame) - parentpos; break; case Equipslot::SHIELD: case Equipslot::WEAPON: if (parent == "handMove") { shift += drawinfo.get_hand_position(stance, frame); } else if (parent == "hand") { shift += drawinfo.get_arm_position(stance, frame); } else if (parent == "navel") { shift += drawinfo.get_body_position(stance, frame); } shift -= parentpos; break; } stances[stance][z] .emplace(frame, partnode) ->second.shift(shift); } } } static const std::unordered_set<int32_t> transparents = { 1002186 }; transparent = transparents.count(itemid) > 0; }