outfitLevel moved, character ID safeguard
This commit is contained in:
@@ -26,9 +26,6 @@ struct SlotSelection {
|
||||
struct CharacterSlotsComponent {
|
||||
Ogre::String sex = "male";
|
||||
|
||||
/* Global outfit level: 0=nude, 1=lingerie, 2=clothed */
|
||||
int outfitLevel = 2;
|
||||
|
||||
/* Backward-compat: old mesh-name map. Deserialized into slotSelections on load. */
|
||||
std::unordered_map<Ogre::String, Ogre::String> slots;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ ecs.subscribe_event("game_start", function(event, params)
|
||||
-- ecs.debug_crash("new_game triggered")
|
||||
local tsub = ecs.subscribe_event("scene_ready", function(event, params)
|
||||
-- ecs.unsubscribe_event(tsub)
|
||||
ecs.debug_crash("scene_ready triggered")
|
||||
-- ecs.debug_crash("scene_ready triggered")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -522,9 +522,19 @@ static void registerAllComponents()
|
||||
lua_setfield(L, -2, "explicitMesh");
|
||||
lua_setfield(L, -2, kv.first.c_str());
|
||||
} lua_setfield(L, -2, "slotSelections");
|
||||
lua_pushinteger(L, c.outfitLevel);
|
||||
lua_setfield(L, -2, "outfitLevel"); pushVector3(L, c.frontAxis);
|
||||
lua_setfield(L, -2, "frontAxis");
|
||||
{ // Push: outfitLevel from registry
|
||||
int outfitLevel = 2;
|
||||
if (e.has<CharacterIdentityComponent>()) {
|
||||
auto &id = e.get<CharacterIdentityComponent>();
|
||||
const CharacterRegistry::CharacterRecord *rec =
|
||||
CharacterRegistry::getSingleton()
|
||||
.findCharacter(id.registryId);
|
||||
if (rec)
|
||||
outfitLevel = rec->inlineOutfitLevel;
|
||||
}
|
||||
lua_pushinteger(L, outfitLevel);
|
||||
} lua_setfield(L, -2, "outfitLevel");
|
||||
pushVector3(L, c.frontAxis); lua_setfield(L, -2, "frontAxis");
|
||||
,
|
||||
{ // Read: age into registry
|
||||
if (lua_getfield(L, idx, "age"), lua_isstring(L, -1)) {
|
||||
@@ -540,16 +550,38 @@ static void registerAllComponents()
|
||||
rec->age = age;
|
||||
CharacterRegistry::getSingleton()
|
||||
.autoSave();
|
||||
CharacterRegistry::getSingleton()
|
||||
.markCharacterDirty(
|
||||
id.registryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
} lua_pop(L, 1);
|
||||
if (lua_getfield(L, idx, "sex"), lua_isstring(L, -1))
|
||||
c.sex = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (lua_getfield(L, idx, "outfitLevel"), lua_isnumber(L, -1))
|
||||
c.outfitLevel = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pop(L, 1); { // Read: outfitLevel into registry
|
||||
if (lua_getfield(L, idx, "outfitLevel"),
|
||||
lua_isnumber(L, -1)) {
|
||||
int outfitLevel = (int)lua_tointeger(L, -1);
|
||||
if (e.has<CharacterIdentityComponent>()) {
|
||||
auto &id = e.get<
|
||||
CharacterIdentityComponent>();
|
||||
CharacterRegistry::CharacterRecord *rec =
|
||||
CharacterRegistry::getSingleton()
|
||||
.findCharacter(
|
||||
id.registryId);
|
||||
if (rec) {
|
||||
rec->inlineOutfitLevel =
|
||||
outfitLevel;
|
||||
CharacterRegistry::getSingleton()
|
||||
.autoSave();
|
||||
CharacterRegistry::getSingleton()
|
||||
.markCharacterDirty(
|
||||
id.registryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
} lua_pop(L, 1);
|
||||
if (lua_getfield(L, idx, "slots"), lua_istable(L, -1)) {
|
||||
c.slots.clear();
|
||||
lua_pushnil(L);
|
||||
|
||||
@@ -297,7 +297,6 @@ readPrefabAppearance(const std::string &path, CharacterSlotsComponent &cs,
|
||||
if (j.contains("characterSlots")) {
|
||||
auto &s = j["characterSlots"];
|
||||
cs.sex = s.value("sex", "male");
|
||||
cs.outfitLevel = s.value("outfitLevel", 2);
|
||||
if (s.contains("slotSelections")) {
|
||||
for (auto &[slot, selJson] :
|
||||
s["slotSelections"].items()) {
|
||||
@@ -429,7 +428,7 @@ uint64_t CharacterRegistry::createChild(uint64_t parentA, uint64_t parentB)
|
||||
child->inlineShapeKeyWeights, prefabAge);
|
||||
child->age = prefabAge;
|
||||
child->inlineSex = tmpCs.sex;
|
||||
child->inlineOutfitLevel = tmpCs.outfitLevel;
|
||||
child->inlineOutfitLevel = sameSexParent->inlineOutfitLevel;
|
||||
child->inlineSlotSelections = tmpCs.slotSelections;
|
||||
} else {
|
||||
child->age = sameSexParent->age;
|
||||
@@ -540,7 +539,6 @@ flecs::entity CharacterRegistry::spawnInlineCharacter(const CharacterRecord &c,
|
||||
/* CharacterSlots */
|
||||
CharacterSlotsComponent cs;
|
||||
cs.sex = c.inlineSex;
|
||||
cs.outfitLevel = c.inlineOutfitLevel;
|
||||
cs.slotSelections = c.inlineSlotSelections;
|
||||
cs.dirty = true;
|
||||
inst.set<CharacterSlotsComponent>(cs);
|
||||
@@ -695,6 +693,15 @@ flecs::entity CharacterRegistry::findSpawnedEntity(uint64_t id) const
|
||||
return result;
|
||||
}
|
||||
|
||||
void CharacterRegistry::markCharacterDirty(uint64_t id)
|
||||
{
|
||||
flecs::entity e = findSpawnedEntity(id);
|
||||
if (!e.is_alive())
|
||||
return;
|
||||
if (e.has<CharacterSlotsComponent>())
|
||||
e.get_mut<CharacterSlotsComponent>().dirty = true;
|
||||
}
|
||||
|
||||
bool CharacterRegistry::despawnCharacter(uint64_t id)
|
||||
{
|
||||
if (!m_world)
|
||||
@@ -829,6 +836,14 @@ uint64_t CharacterRegistry::createCharacter(const std::string &firstName,
|
||||
bool persistent)
|
||||
{
|
||||
uint64_t id = persistent ? m_nextId++ : m_nextRuntimeId++;
|
||||
/* Safety: id must never be 0 */
|
||||
if (id == 0) {
|
||||
id = persistent ? m_nextId++ : m_nextRuntimeId++;
|
||||
Ogre::LogManager::getSingleton().logMessage(
|
||||
"CharacterRegistry: id wrapped to 0, "
|
||||
"incremented to " +
|
||||
std::to_string(id));
|
||||
}
|
||||
CharacterRecord rec;
|
||||
rec.id = id;
|
||||
rec.firstName = firstName;
|
||||
@@ -1169,7 +1184,11 @@ nlohmann::json CharacterRegistry::serialize() const
|
||||
const CharacterRecord &c = pair.second;
|
||||
if (!c.persistent)
|
||||
continue;
|
||||
/* Belt-and-suspenders: never serialize id == 0 */
|
||||
if (c.id == 0)
|
||||
continue;
|
||||
nlohmann::json rec;
|
||||
|
||||
rec["id"] = c.id;
|
||||
rec["persistent"] = c.persistent;
|
||||
rec["firstName"] = c.firstName;
|
||||
@@ -1423,6 +1442,17 @@ void CharacterRegistry::deserialize(const nlohmann::json &j)
|
||||
c.stringColumns[k] =
|
||||
v.get<std::string>();
|
||||
}
|
||||
|
||||
/* ---- Safeguard: reject id == 0 ---- */
|
||||
if (c.id == 0) {
|
||||
Ogre::LogManager::getSingleton().logMessage(
|
||||
"CharacterRegistry: skipping corrupt "
|
||||
"record with id=0 (firstName=" +
|
||||
c.firstName +
|
||||
" lastName=" + c.lastName + ")");
|
||||
continue;
|
||||
}
|
||||
|
||||
m_characters[c.id] = c;
|
||||
}
|
||||
}
|
||||
@@ -1777,15 +1807,24 @@ void CharacterRegistry::drawEditor(bool *p_open)
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(
|
||||
"Promote to Roster")) {
|
||||
c->persistent = true;
|
||||
c->prefabPath =
|
||||
/* Assign a proper persistent
|
||||
* ID */
|
||||
uint64_t newId = m_nextId++;
|
||||
CharacterRecord promoted = *c;
|
||||
promoted.id = newId;
|
||||
promoted.persistent = true;
|
||||
promoted.prefabPath =
|
||||
generatePrefabPath(
|
||||
c->id,
|
||||
newId,
|
||||
c->firstName,
|
||||
c->lastName);
|
||||
m_characters.erase(c->id);
|
||||
m_characters[newId] = promoted;
|
||||
m_selectedCharacterId = newId;
|
||||
autoSave();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::InputText("First Name", fnBuf,
|
||||
sizeof(fnBuf))) {
|
||||
c->firstName = fnBuf;
|
||||
@@ -1848,13 +1887,20 @@ void CharacterRegistry::drawEditor(bool *p_open)
|
||||
/* Age category from catalog */
|
||||
CharacterSlotSystem::loadCatalog();
|
||||
std::string currentAgeCat = c->age;
|
||||
std::vector<Ogre::String> ageCats = CharacterSlotSystem::getAges();
|
||||
if (ImGui::BeginCombo("Age Category", currentAgeCat.c_str())) {
|
||||
std::vector<Ogre::String> ageCats =
|
||||
CharacterSlotSystem::getAges();
|
||||
if (ImGui::BeginCombo("Age Category",
|
||||
currentAgeCat.c_str())) {
|
||||
for (const auto &ac : ageCats) {
|
||||
bool isSelected = (currentAgeCat == ac);
|
||||
if (ImGui::Selectable(ac.c_str(), isSelected)) {
|
||||
bool isSelected =
|
||||
(currentAgeCat == ac);
|
||||
if (ImGui::Selectable(
|
||||
ac.c_str(),
|
||||
isSelected)) {
|
||||
c->age = ac;
|
||||
autoSave();
|
||||
markCharacterDirty(
|
||||
c->id);
|
||||
}
|
||||
if (isSelected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
@@ -1862,6 +1908,25 @@ void CharacterRegistry::drawEditor(bool *p_open)
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
/* Outfit level */
|
||||
{
|
||||
const char *outfitLabels[] = {
|
||||
"Nude", "Lingerie", "Clothed"
|
||||
};
|
||||
int outfit = c->inlineOutfitLevel;
|
||||
if (outfit < 0)
|
||||
outfit = 0;
|
||||
if (outfit > 2)
|
||||
outfit = 2;
|
||||
if (ImGui::Combo("Outfit Level",
|
||||
&outfit, outfitLabels,
|
||||
3)) {
|
||||
c->inlineOutfitLevel = outfit;
|
||||
autoSave();
|
||||
markCharacterDirty(c->id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Family */
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Family");
|
||||
|
||||
@@ -319,6 +319,13 @@ public:
|
||||
/* Spawn / Save */
|
||||
/* ------------------------------------------------------------------ */
|
||||
flecs::entity findSpawnedEntity(uint64_t id) const;
|
||||
/**
|
||||
* Mark the spawned entity for a character as dirty so its visual
|
||||
* appearance (CharacterSlotsComponent) is rebuilt on the next
|
||||
* update. Call this after changing outfitLevel, age, or any other
|
||||
* registry field that affects the character's look.
|
||||
*/
|
||||
void markCharacterDirty(uint64_t id);
|
||||
bool despawnCharacter(uint64_t id);
|
||||
flecs::entity spawnCharacter(uint64_t id);
|
||||
flecs::entity spawnInlineCharacter(const CharacterRecord &c,
|
||||
|
||||
@@ -441,6 +441,23 @@ static Ogre::String getCharacterAge(flecs::entity e)
|
||||
return "adult";
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: retrieve the character's outfit level from the registry.
|
||||
* Falls back to 2 (clothed) if no registry entry is found.
|
||||
*/
|
||||
static int getCharacterOutfitLevel(flecs::entity e)
|
||||
{
|
||||
if (e.has<CharacterIdentityComponent>()) {
|
||||
auto &id = e.get<CharacterIdentityComponent>();
|
||||
const CharacterRegistry::CharacterRecord *rec =
|
||||
CharacterRegistry::getSingleton().findCharacter(
|
||||
id.registryId);
|
||||
if (rec)
|
||||
return rec->inlineOutfitLevel;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
void CharacterSlotSystem::buildCharacter(flecs::entity e,
|
||||
CharacterSlotsComponent &cs)
|
||||
{
|
||||
@@ -473,12 +490,14 @@ void CharacterSlotSystem::buildCharacter(flecs::entity e,
|
||||
if (!transform.node)
|
||||
return;
|
||||
|
||||
int outfitLevel = getCharacterOutfitLevel(e);
|
||||
|
||||
/* Determine master slot (face preferred, else first non-empty) */
|
||||
Ogre::String masterSlot;
|
||||
if (cs.slotSelections.find("face") != cs.slotSelections.end()) {
|
||||
Ogre::String mesh = resolveMesh(age, cs.sex, "face",
|
||||
cs.slotSelections["face"],
|
||||
cs.outfitLevel);
|
||||
outfitLevel);
|
||||
if (!mesh.empty())
|
||||
masterSlot = "face";
|
||||
}
|
||||
@@ -486,7 +505,7 @@ void CharacterSlotSystem::buildCharacter(flecs::entity e,
|
||||
for (const auto &pair : cs.slotSelections) {
|
||||
Ogre::String mesh = resolveMesh(age, cs.sex, pair.first,
|
||||
pair.second,
|
||||
cs.outfitLevel);
|
||||
outfitLevel);
|
||||
if (!mesh.empty()) {
|
||||
masterSlot = pair.first;
|
||||
break;
|
||||
@@ -499,7 +518,7 @@ void CharacterSlotSystem::buildCharacter(flecs::entity e,
|
||||
|
||||
Ogre::String masterMesh = resolveMesh(age, cs.sex, masterSlot,
|
||||
cs.slotSelections[masterSlot],
|
||||
cs.outfitLevel);
|
||||
outfitLevel);
|
||||
|
||||
if (masterMesh.empty())
|
||||
return;
|
||||
@@ -539,7 +558,7 @@ void CharacterSlotSystem::buildCharacter(flecs::entity e,
|
||||
continue;
|
||||
|
||||
Ogre::String mesh =
|
||||
resolveMesh(age, cs.sex, slot, sel, cs.outfitLevel);
|
||||
resolveMesh(age, cs.sex, slot, sel, outfitLevel);
|
||||
if (mesh.empty())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -344,8 +344,8 @@ nlohmann::json SceneSerializer::serializeEntity(flecs::entity entity)
|
||||
}
|
||||
|
||||
if (entity.has<GoapBlackboard>()) {
|
||||
json["goapBlackboard"] = serializeGoapBlackboard(
|
||||
entity.get<GoapBlackboard>());
|
||||
json["goapBlackboard"] =
|
||||
serializeGoapBlackboard(entity.get<GoapBlackboard>());
|
||||
}
|
||||
|
||||
if (entity.has<ItemComponent>()) {
|
||||
@@ -2201,7 +2201,6 @@ nlohmann::json SceneSerializer::serializeCharacterSlots(flecs::entity entity)
|
||||
nlohmann::json json;
|
||||
|
||||
json["sex"] = cs.sex;
|
||||
json["outfitLevel"] = cs.outfitLevel;
|
||||
json["slots"] = nlohmann::json::object();
|
||||
for (const auto &pair : cs.slots)
|
||||
json["slots"][pair.first] = pair.second;
|
||||
@@ -2224,26 +2223,28 @@ nlohmann::json SceneSerializer::serializeCharacterSlots(flecs::entity entity)
|
||||
}
|
||||
|
||||
void SceneSerializer::deserializeCharacterSlots(flecs::entity entity,
|
||||
const nlohmann::json &json)
|
||||
const nlohmann::json &json)
|
||||
{
|
||||
CharacterSlotsComponent cs;
|
||||
cs.sex = json.value("sex", "male");
|
||||
cs.outfitLevel = json.value("outfitLevel", 2);
|
||||
if (json.contains("slots") && json["slots"].is_object()) {
|
||||
for (auto &[slot, mesh] : json["slots"].items())
|
||||
cs.slots[slot] = mesh.get<std::string>();
|
||||
}
|
||||
// Deserialize per-layer slot selections
|
||||
if (json.contains("slotSelections") && json["slotSelections"].is_object()) {
|
||||
if (json.contains("slotSelections") &&
|
||||
json["slotSelections"].is_object()) {
|
||||
for (auto &[slot, selJson] : json["slotSelections"].items()) {
|
||||
SlotSelection sel;
|
||||
if (selJson.contains("layer1Mesh"))
|
||||
sel.layer1Mesh = selJson.value("layer1Mesh", "");
|
||||
sel.layer1Mesh =
|
||||
selJson.value("layer1Mesh", "");
|
||||
if (selJson.contains("layer2Mesh"))
|
||||
sel.layer2Mesh = selJson.value("layer2Mesh", "");
|
||||
sel.layer2Mesh =
|
||||
selJson.value("layer2Mesh", "");
|
||||
// Backward compat: old format had layer/requiredTags/excludedTags
|
||||
if (selJson.contains("layer") && sel.layer1Mesh.empty() &&
|
||||
sel.layer2Mesh.empty()) {
|
||||
if (selJson.contains("layer") &&
|
||||
sel.layer1Mesh.empty() && sel.layer2Mesh.empty()) {
|
||||
int oldLayer = selJson.value("layer", 2);
|
||||
if (oldLayer == 1)
|
||||
sel.layer1Mesh = "auto";
|
||||
@@ -3684,9 +3685,11 @@ void SceneSerializer::deserializePathFollowing(flecs::entity entity,
|
||||
pf.walkSpeed = json.value("walkSpeed", 2.5f);
|
||||
pf.runSpeed = json.value("runSpeed", 5.0f);
|
||||
pf.useRootMotion = json.value("useRootMotion", true);
|
||||
pf.currentLocomotionState = json.value("currentLocomotionState", "idle");
|
||||
pf.currentLocomotionState =
|
||||
json.value("currentLocomotionState", "idle");
|
||||
pf.hasTarget = json.value("hasTarget", false);
|
||||
if (json.contains("targetPosition") && json["targetPosition"].is_object()) {
|
||||
if (json.contains("targetPosition") &&
|
||||
json["targetPosition"].is_object()) {
|
||||
auto &tp = json["targetPosition"];
|
||||
pf.targetPosition = Ogre::Vector3(tp.value("x", 0.0f),
|
||||
tp.value("y", 0.0f),
|
||||
@@ -3696,8 +3699,8 @@ void SceneSerializer::deserializePathFollowing(flecs::entity entity,
|
||||
pf.path.clear();
|
||||
for (const auto &pt : json["path"]) {
|
||||
pf.path.push_back(Ogre::Vector3(pt.value("x", 0.0f),
|
||||
pt.value("y", 0.0f),
|
||||
pt.value("z", 0.0f)));
|
||||
pt.value("y", 0.0f),
|
||||
pt.value("z", 0.0f)));
|
||||
}
|
||||
}
|
||||
pf.pathIndex = json.value("pathIndex", 0);
|
||||
@@ -3793,8 +3796,8 @@ void SceneSerializer::deserializeGoapRunner(flecs::entity entity,
|
||||
const nlohmann::json &json)
|
||||
{
|
||||
GoapRunnerComponent runner;
|
||||
runner.state = static_cast<GoapRunnerComponent::State>(
|
||||
json.value("state", 0));
|
||||
runner.state =
|
||||
static_cast<GoapRunnerComponent::State>(json.value("state", 0));
|
||||
runner.currentActionIndex = json.value("currentActionIndex", 0);
|
||||
runner.currentActionName = json.value("currentActionName", "");
|
||||
runner.actionTimer = json.value("actionTimer", 0.0f);
|
||||
@@ -4038,7 +4041,8 @@ void SceneSerializer::deserializeInventory(flecs::entity entity,
|
||||
slot.stackSize = slotJson.value("stackSize", 0);
|
||||
|
||||
// Backward compatibility: old slots had inline data
|
||||
if (slot.itemId.empty() && slotJson.contains("itemName")) {
|
||||
if (slot.itemId.empty() &&
|
||||
slotJson.contains("itemName")) {
|
||||
slot.itemId = slotJson.value("itemName", "");
|
||||
}
|
||||
ensureItemInRegistry(slot.itemId, slotJson);
|
||||
|
||||
@@ -10,7 +10,6 @@ CharacterSlotsEditor::CharacterSlotsEditor(Ogre::SceneManager *sceneMgr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
CharacterSlotsComponent &cs)
|
||||
{
|
||||
@@ -22,7 +21,6 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
|
||||
CharacterSlotSystem::loadCatalog();
|
||||
|
||||
|
||||
/* Get current age from registry */
|
||||
Ogre::String currentAge = "adult";
|
||||
if (entity.has<CharacterIdentityComponent>()) {
|
||||
@@ -55,21 +53,6 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
/* Global outfit level */
|
||||
const char *outfitLabels[] = { "Nude", "Lingerie", "Clothed" };
|
||||
int outfit = cs.outfitLevel;
|
||||
if (outfit < 0)
|
||||
outfit = 0;
|
||||
if (outfit > 2)
|
||||
outfit = 2;
|
||||
if (ImGui::Combo("Outfit", &outfit, outfitLabels, 3)) {
|
||||
cs.outfitLevel = outfit;
|
||||
modified = true;
|
||||
cs.dirty = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("(global layer switch)");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
/* Front-facing axis */
|
||||
@@ -136,6 +119,17 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
/* Get outfit level from registry for resolveMesh calls */
|
||||
int outfitLevel = 2;
|
||||
if (entity.has<CharacterIdentityComponent>()) {
|
||||
auto &id = entity.get<CharacterIdentityComponent>();
|
||||
auto *rec =
|
||||
CharacterRegistry::getSingleton().findCharacter(
|
||||
id.registryId);
|
||||
if (rec)
|
||||
outfitLevel = rec->inlineOutfitLevel;
|
||||
}
|
||||
|
||||
/* Slot selections */
|
||||
std::vector<Ogre::String> availableSlots =
|
||||
CharacterSlotSystem::getSlots(currentAge, cs.sex);
|
||||
@@ -166,7 +160,7 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
Ogre::String resolved =
|
||||
CharacterSlotSystem::resolveMesh(
|
||||
currentAge, cs.sex, slot, sel,
|
||||
cs.outfitLevel);
|
||||
outfitLevel);
|
||||
ImGui::TextDisabled("Resolved: %s",
|
||||
resolved.empty() ?
|
||||
"(none)" :
|
||||
@@ -185,7 +179,7 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
currentAge,
|
||||
cs.sex, slot,
|
||||
sel,
|
||||
cs.outfitLevel);
|
||||
outfitLevel);
|
||||
}
|
||||
modified = true;
|
||||
cs.dirty = true;
|
||||
@@ -194,7 +188,8 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
if (useExplicit) {
|
||||
std::vector<Ogre::String> meshes =
|
||||
CharacterSlotSystem::getMeshes(
|
||||
currentAge, cs.sex, slot);
|
||||
currentAge, cs.sex,
|
||||
slot);
|
||||
Ogre::String preview =
|
||||
sel.explicitMesh.empty() ?
|
||||
"(none)" :
|
||||
@@ -229,14 +224,15 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
std::vector<Ogre::String> layer1Meshes =
|
||||
CharacterSlotSystem::
|
||||
getMeshesForLayer(
|
||||
currentAge, cs.sex,
|
||||
slot, 1);
|
||||
currentAge,
|
||||
cs.sex, slot,
|
||||
1);
|
||||
Ogre::String l1Preview = "none";
|
||||
if (!sel.layer1Mesh.empty())
|
||||
l1Preview = CharacterSlotSystem::
|
||||
getMeshLabel(
|
||||
currentAge, cs.sex,
|
||||
slot,
|
||||
currentAge,
|
||||
cs.sex, slot,
|
||||
sel.layer1Mesh);
|
||||
if (ImGui::BeginCombo(
|
||||
"Lingerie (Layer 1)",
|
||||
@@ -277,14 +273,15 @@ bool CharacterSlotsEditor::renderComponent(flecs::entity entity,
|
||||
std::vector<Ogre::String> layer2Meshes =
|
||||
CharacterSlotSystem::
|
||||
getMeshesForLayer(
|
||||
currentAge, cs.sex,
|
||||
slot, 2);
|
||||
currentAge,
|
||||
cs.sex, slot,
|
||||
2);
|
||||
Ogre::String l2Preview = "none";
|
||||
if (!sel.layer2Mesh.empty())
|
||||
l2Preview = CharacterSlotSystem::
|
||||
getMeshLabel(
|
||||
currentAge, cs.sex,
|
||||
slot,
|
||||
currentAge,
|
||||
cs.sex, slot,
|
||||
sel.layer2Mesh);
|
||||
if (ImGui::BeginCombo(
|
||||
"Clothing (Layer 2)",
|
||||
|
||||
Reference in New Issue
Block a user