lfs, current build
This commit is contained in:
+100
-142
@@ -19,23 +19,24 @@ using namespace glm;
|
||||
|
||||
namespace game::state
|
||||
{
|
||||
namespace
|
||||
void entity_debug_flags_apply(Entity& entity, bool isShowLayers, bool isShowNulls)
|
||||
{
|
||||
int durability_animation_index_get(const resource::xml::Schema& schema, const resource::xml::Anm2& anm2,
|
||||
int durability, int durabilityMax)
|
||||
{
|
||||
if (durability >= durabilityMax) return -1;
|
||||
entity.isShowLayers = isShowLayers;
|
||||
entity.isShowNulls = isShowNulls;
|
||||
}
|
||||
|
||||
auto animationName = schema.root()->animationChew + std::to_string(std::max(0, durability));
|
||||
return anm2.animationMap.contains(animationName) ? anm2.animationMap.at(animationName) : -1;
|
||||
}
|
||||
int saved_item_id_get(const Schema& itemSchema, const Schema::Element& item)
|
||||
{
|
||||
if (item.id >= 0 && item.id < (int)itemSchema.items.size() && item.id < (int)itemSchema.anm2s.size())
|
||||
return item.id;
|
||||
return -1;
|
||||
}
|
||||
|
||||
World::Focus Play::focus_get()
|
||||
{
|
||||
if (!isWindows) return World::CENTER;
|
||||
if (text.is_scene_active()) return World::CENTER;
|
||||
|
||||
auto isToolsOpen = tools.isOpen && !menu.is_fullscreen_visible_get();
|
||||
auto isToolsOpen = tools.isOpen;
|
||||
return menu.isOpen && isToolsOpen ? World::MENU_TOOLS
|
||||
: menu.isOpen ? World::MENU
|
||||
: isToolsOpen ? World::TOOLS
|
||||
@@ -48,34 +49,16 @@ namespace game::state
|
||||
return root && root->type == Schema::Element::CURSOR;
|
||||
}
|
||||
|
||||
void Play::start_sequence_begin()
|
||||
void Play::debug_flags_apply()
|
||||
{
|
||||
auto& dialogue = character.data.dialogue;
|
||||
auto* start = dialogue.get(Schema::Element::START);
|
||||
if (!start) return;
|
||||
|
||||
character.play({.animation = start->animation,
|
||||
.appendID = character.animation_append_id_get(),
|
||||
.interrupt = Entity::Interrupt::NEVER});
|
||||
character.update();
|
||||
text.entry = nullptr;
|
||||
text.isEnabled = false;
|
||||
isWindows = false;
|
||||
isStart = true;
|
||||
isStartBegin = false;
|
||||
isStartEnd = false;
|
||||
}
|
||||
|
||||
void Play::end_sequence_begin()
|
||||
{
|
||||
auto& dialogue = character.data.dialogue;
|
||||
if (!dialogue.get(Schema::Element::END)) return;
|
||||
|
||||
text.entry = nullptr;
|
||||
text.isEnabled = false;
|
||||
isEnd = true;
|
||||
isEndBegin = false;
|
||||
isEndEnd = false;
|
||||
entity_debug_flags_apply(character, isShowLayers, isShowNulls);
|
||||
entity_debug_flags_apply(cursor, isShowLayers, isShowNulls);
|
||||
entity_debug_flags_apply(autofeedCursor, isShowLayers, isShowNulls);
|
||||
areaManager.debug_flags_set(isShowLayers, isShowNulls);
|
||||
for (auto& item : itemManager.items)
|
||||
entity_debug_flags_apply(item, isShowLayers, isShowNulls);
|
||||
for (auto& particle : particleManager.particles)
|
||||
entity_debug_flags_apply(particle, isShowLayers, isShowNulls);
|
||||
}
|
||||
|
||||
void Play::set(Resources& resources, int selectedCharacterIndex, enum Game game)
|
||||
@@ -84,8 +67,8 @@ namespace game::state
|
||||
auto* saveRoot = data.save.root();
|
||||
auto isSaveValid = saveRoot && saveRoot->type == Schema::Element::SAVE;
|
||||
auto* saveCharacter = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::CHARACTER) : nullptr;
|
||||
auto* saveInventory = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::INVENTORY) : nullptr;
|
||||
auto* saveItems = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::ITEMS) : nullptr;
|
||||
auto* saveDiscovered = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::DISCOVERED) : nullptr;
|
||||
auto* savePan = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::PAN) : nullptr;
|
||||
auto* saveZoom = isSaveValid ? data.save.child_get(*saveRoot, Schema::Element::ZOOM) : nullptr;
|
||||
auto& itemSchema = data.itemSchema;
|
||||
@@ -96,12 +79,11 @@ namespace game::state
|
||||
resources.last_character_save(selectedCharacterIndex);
|
||||
cheatCodeIndex = 0;
|
||||
cheatCodeStartTime = 0.0;
|
||||
world = play::World{};
|
||||
|
||||
character = Entity(data, vec2(World::BOUNDS.x + World::BOUNDS.z * 0.5f, World::BOUNDS.w - World::BOUNDS.y));
|
||||
character = Entity(data, vec2{});
|
||||
character.digestionRate =
|
||||
glm::clamp(character.digestionRate, characterRoot->digestionRateMin, characterRoot->digestionRateMax);
|
||||
character.eatSpeed =
|
||||
glm::clamp(character.eatSpeed, characterRoot->eatSpeedMinMultiplier, characterRoot->eatSpeedMaxMultiplier);
|
||||
character.capacity =
|
||||
glm::clamp(character.capacity, characterRoot->capacityMinCalories, characterRoot->capacityMaxCalories);
|
||||
|
||||
@@ -116,11 +98,16 @@ namespace game::state
|
||||
}
|
||||
|
||||
character.totalCaloriesConsumed = saveCharacter ? saveCharacter->totalCaloriesConsumed : 0;
|
||||
character.totalFoodItemsEaten = saveCharacter ? saveCharacter->totalFoodItemsEaten : 0;
|
||||
character.totalItemsSpawned = saveCharacter ? saveCharacter->totalItemsSpawned : 0;
|
||||
character.totalItemsConsumed = saveCharacter ? saveCharacter->totalItemsConsumed : 0;
|
||||
character.totalPlaytimeSeconds = saveCharacter ? saveCharacter->totalPlaytimeSeconds : 0;
|
||||
autofeed = play::Autofeed{};
|
||||
characterManager = CharacterManager{};
|
||||
particleManager = ParticleManager{};
|
||||
areaManager = AreaManager{};
|
||||
areaManager.set(character);
|
||||
world.bounds_set(areaManager.bounds_get(character, World::BOUNDS));
|
||||
character.position = {};
|
||||
|
||||
cursor = Entity{};
|
||||
cursor.entityType = CURSOR;
|
||||
@@ -143,24 +130,24 @@ namespace game::state
|
||||
}
|
||||
|
||||
menu.inventory = play::menu::Inventory{};
|
||||
for (auto* item : saveInventory ? data.save.children_get(*saveInventory, Schema::Element::ITEM)
|
||||
: std::vector<Schema::Element*>{})
|
||||
{
|
||||
if (item->quantity == 0) continue;
|
||||
menu.inventory.values[item->id] = item->quantity;
|
||||
}
|
||||
|
||||
itemManager = ItemManager{};
|
||||
itemManager.spawnDelayTicks = saveRoot ? saveRoot->spawnDelayTicks : 0;
|
||||
itemManager.discoveredItemIDs.resize(itemSchema.items.size());
|
||||
for (auto* item :
|
||||
saveDiscovered ? data.save.children_get(*saveDiscovered, Schema::Element::ITEM) : std::vector<Schema::Element*>{})
|
||||
{
|
||||
auto itemID = saved_item_id_get(itemSchema, *item);
|
||||
if (itemID != -1) itemManager.discoveredItemIDs[itemID] = true;
|
||||
}
|
||||
for (auto* item :
|
||||
saveItems ? data.save.children_get(*saveItems, Schema::Element::ITEM) : std::vector<Schema::Element*>{})
|
||||
{
|
||||
auto& anm2 = itemSchema.anm2s.at(item->id);
|
||||
auto& schemaItem = itemSchema.items.at(item->id);
|
||||
auto durabilityMax = schemaItem.isDurability ? schemaItem.durability : itemSchema.durability;
|
||||
auto animationIndex = durability_animation_index_get(itemSchema, anm2, item->durability, durabilityMax);
|
||||
auto& saveItem = itemSchema.anm2s.at(item->id);
|
||||
itemManager.items.emplace_back(saveItem, item->position, item->id, item->durability, animationIndex,
|
||||
item->velocity, item->rotation);
|
||||
auto itemID = saved_item_id_get(itemSchema, *item);
|
||||
if (itemID == -1) continue;
|
||||
auto& saveItem = itemSchema.anm2s[itemID];
|
||||
itemManager.items.emplace_back(saveItem, item->position, itemID, item->velocity, item->rotation);
|
||||
itemManager.discoveredItemIDs[itemID] = true;
|
||||
}
|
||||
|
||||
imgui::style::widget_set(menuSchema.rounding);
|
||||
@@ -169,6 +156,7 @@ namespace game::state
|
||||
|
||||
text.entry = nullptr;
|
||||
text.isEnabled = false;
|
||||
isPostgamePending = false;
|
||||
|
||||
#if DEBUG
|
||||
menu.isCheats = true;
|
||||
@@ -180,32 +168,29 @@ namespace game::state
|
||||
if (character.stage_get() >= character.stage_max_get()) isPostgame = true;
|
||||
if (isPostgame) menu.isCheats = true;
|
||||
|
||||
if (game == NEW_GAME) isWindows = false;
|
||||
|
||||
if (auto font = character.data.menuSchema.font.get()) ImGui::GetIO().FontDefault = font;
|
||||
|
||||
character.play({.animation = character.idle_animation_get(), .appendID = character.animation_append_id_get()});
|
||||
character.update();
|
||||
areaManager.set(character);
|
||||
worldCanvas.size_set(imgui::to_vec2(ImGui::GetMainViewport()->Size));
|
||||
world.set(character, worldCanvas, focus_get());
|
||||
if (savePan) worldCanvas.pan = savePan->position;
|
||||
if (saveZoom && saveZoom->zoom >= World::ZOOM_MIN)
|
||||
{
|
||||
worldCanvas.zoom = glm::clamp(World::ZOOM_MIN, saveZoom->zoom, World::ZOOM_MAX);
|
||||
world.zoom_index_set(worldCanvas);
|
||||
}
|
||||
|
||||
if (game == NEW_GAME && dialogue.get(Schema::Element::START)) start_sequence_begin();
|
||||
if (game == NEW_GAME)
|
||||
text.set(dialogue.dialogue_hook_entry_get(Schema::Element::START), character, false);
|
||||
|
||||
if (isPostgame)
|
||||
{
|
||||
isEnd = true;
|
||||
isEndBegin = true;
|
||||
isEndEnd = true;
|
||||
isPostgamePending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isEnd = false;
|
||||
isEndBegin = false;
|
||||
isEndEnd = false;
|
||||
isPostgamePending = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +216,7 @@ namespace game::state
|
||||
auto focus = focus_get();
|
||||
auto& dialogue = character.data.dialogue;
|
||||
auto isCursorEnabled = cursor_enabled_get();
|
||||
character.totalPlaytimeSeconds += ImGui::GetIO().DeltaTime;
|
||||
if (isCursorEnabled)
|
||||
{
|
||||
cursor.isVisible = true;
|
||||
@@ -276,87 +262,55 @@ namespace game::state
|
||||
}
|
||||
}
|
||||
|
||||
if (isWindows)
|
||||
auto isSceneActive = text.is_scene_active();
|
||||
|
||||
if (!isSceneActive)
|
||||
{
|
||||
auto isToolsDisabled = menu.is_fullscreen_visible_get();
|
||||
auto uiAlpha = UI_ALPHA_MAX - menu.fullscreen_alpha_get();
|
||||
tools.update(character, cursor, world, focus, worldCanvas, isToolsDisabled, uiAlpha);
|
||||
info.update(resources, character, uiAlpha);
|
||||
tools.update(character, cursor, world, focus, worldCanvas, false, UI_ALPHA_MAX);
|
||||
menu.update(resources, itemManager, character, text, autofeed);
|
||||
toasts.update();
|
||||
}
|
||||
|
||||
auto isEndSequenceActive = isEndBegin && !isEndEnd;
|
||||
itemManager.isDisabled = isEndSequenceActive;
|
||||
characterManager.isDisabled = isEndSequenceActive;
|
||||
itemManager.isDisabled = isSceneActive;
|
||||
characterManager.isDisabled = isSceneActive;
|
||||
|
||||
if (text.isEnabled) text.update(character, worldCanvas);
|
||||
|
||||
if (isStart)
|
||||
if (character.isJustStageFinal && !isPostgame && !isPostgamePending)
|
||||
{
|
||||
if (!isStartBegin)
|
||||
auto* end = dialogue.dialogue_hook_entry_get(Schema::Element::END);
|
||||
if (end)
|
||||
{
|
||||
if (auto animation = character.animation_get())
|
||||
{
|
||||
if (animation->isLoop || character.state == Entity::STOPPED)
|
||||
{
|
||||
auto* start = dialogue.get(Schema::Element::START);
|
||||
text.set(start ? dialogue.dialogue_entry_get(*start) : nullptr, character);
|
||||
isStartBegin = true;
|
||||
}
|
||||
}
|
||||
text.set(end, character, false);
|
||||
tools.isOpen = false;
|
||||
menu.isOpen = false;
|
||||
character.calories = 0;
|
||||
character.digestionProgress = 0;
|
||||
itemManager.heldItemIndex = -1;
|
||||
isPostgamePending = true;
|
||||
world.character_focus(character, worldCanvas, focus_get());
|
||||
}
|
||||
else if (!isStartEnd)
|
||||
else
|
||||
{
|
||||
if (text.entry && text.is_terminal() && text.is_finished())
|
||||
{
|
||||
isWindows = true;
|
||||
isStartEnd = true;
|
||||
isStart = false;
|
||||
world.character_focus(character, worldCanvas, focus_get());
|
||||
}
|
||||
isPostgame = true;
|
||||
menu.isCheats = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (character.isJustStageFinal && !isEnd && !isPostgame) isEnd = true;
|
||||
|
||||
if (isEnd)
|
||||
if (isPostgamePending && text.is_terminal() && text.is_finished() && !text.is_scene_active())
|
||||
{
|
||||
if (!isEndBegin)
|
||||
{
|
||||
if (character.is_animation_finished())
|
||||
{
|
||||
auto* end = dialogue.get(Schema::Element::END);
|
||||
text.set(end ? dialogue.dialogue_entry_get(*end) : nullptr, character);
|
||||
isEndBegin = true;
|
||||
isWindows = false;
|
||||
tools.isOpen = false;
|
||||
menu.isOpen = false;
|
||||
character.calories = 0;
|
||||
character.digestionProgress = 0;
|
||||
itemManager.heldItemIndex = -1;
|
||||
world.character_focus(character, worldCanvas, focus_get());
|
||||
}
|
||||
}
|
||||
else if (!isEndEnd)
|
||||
{
|
||||
if (text.entry && text.is_terminal() && text.is_finished())
|
||||
{
|
||||
menu.isOpen = true;
|
||||
isWindows = true;
|
||||
isEndEnd = true;
|
||||
isEnd = false;
|
||||
isPostgame = true;
|
||||
menu.isCheats = true;
|
||||
world.character_focus(character, worldCanvas, focus_get());
|
||||
}
|
||||
}
|
||||
menu.isOpen = true;
|
||||
isPostgamePending = false;
|
||||
isPostgame = true;
|
||||
menu.isCheats = true;
|
||||
world.character_focus(character, worldCanvas, focus_get());
|
||||
}
|
||||
|
||||
autofeed.update(resources, character, autofeedCursor, menu.inventory, itemManager, characterManager, worldCanvas);
|
||||
if (!text.is_scene_active())
|
||||
autofeed.update(resources, character, autofeedCursor, menu.inventory, itemManager, characterManager, worldCanvas);
|
||||
auto& interactionCursor = autofeed.active_get() ? autofeedCursor : cursor;
|
||||
itemManager.isAutomation = autofeed.active_get();
|
||||
itemManager.update(character, interactionCursor, areaManager, text, World::BOUNDS, worldCanvas);
|
||||
itemManager.update(character, interactionCursor, areaManager, text, world.bounds, worldCanvas);
|
||||
characterManager.update(character, interactionCursor, text, worldCanvas);
|
||||
for (auto& particle : itemManager.particles)
|
||||
particleManager.spawn(character.data, particle.label, particle.position);
|
||||
@@ -371,6 +325,7 @@ namespace game::state
|
||||
|
||||
character.update();
|
||||
areaManager.update(character);
|
||||
world.bounds_set(areaManager.bounds_get(character, world.bounds));
|
||||
particleManager.update();
|
||||
cursor.update();
|
||||
if (autofeed.active_get()) autofeedCursor.update();
|
||||
@@ -396,13 +351,15 @@ namespace game::state
|
||||
worldCanvas.bind();
|
||||
worldCanvas.size_set(size);
|
||||
worldCanvas.clear();
|
||||
debug_flags_apply();
|
||||
|
||||
areaManager.render(character, textureShader, rectShader, worldCanvas);
|
||||
|
||||
character.render(textureShader, rectShader, worldCanvas);
|
||||
|
||||
for (auto& item : itemManager.items)
|
||||
item.render(textureShader, rectShader, worldCanvas);
|
||||
if (!text.is_scene_active())
|
||||
for (auto& item : itemManager.items)
|
||||
item.render(textureShader, rectShader, worldCanvas);
|
||||
|
||||
auto isCursorEnabled = cursor_enabled_get();
|
||||
if (isCursorEnabled && autofeed.active_get()) autofeedCursor.render(textureShader, rectShader, worldCanvas);
|
||||
@@ -423,9 +380,11 @@ namespace game::state
|
||||
void Play::save(Resources& resources)
|
||||
{
|
||||
resource::xml::Schema save;
|
||||
auto& itemSchema = character.data.itemSchema;
|
||||
auto& root = save.element_add(resource::xml::Schema::Element::SAVE);
|
||||
root.isPostgame = isPostgame;
|
||||
root.isAlternateSpritesheet = character.spritesheetType == Entity::ALTERNATE;
|
||||
root.spawnDelayTicks = itemManager.spawnDelayTicks;
|
||||
|
||||
auto& panElement = save.element_add(resource::xml::Schema::Element::PAN, 0);
|
||||
panElement.position = worldCanvas.pan;
|
||||
@@ -438,36 +397,35 @@ namespace game::state
|
||||
characterElement.calories = character.calories;
|
||||
characterElement.capacityCalories = character.capacity;
|
||||
characterElement.digestionRate = character.digestionRate;
|
||||
characterElement.eatSpeedMultiplier = character.eatSpeed;
|
||||
characterElement.digestionProgress = character.digestionProgress;
|
||||
characterElement.isDigesting = character.isDigesting;
|
||||
characterElement.digestionTimer = character.digestionTimer;
|
||||
characterElement.totalCaloriesConsumed = character.totalCaloriesConsumed;
|
||||
characterElement.totalFoodItemsEaten = character.totalFoodItemsEaten;
|
||||
|
||||
auto inventoryIndex = (int)save.elements.size();
|
||||
save.element_add(resource::xml::Schema::Element::INVENTORY, 0);
|
||||
|
||||
for (auto& [id, quantity] : menu.inventory.values)
|
||||
{
|
||||
if (quantity == 0) continue;
|
||||
auto& item = save.element_add(resource::xml::Schema::Element::ITEM, inventoryIndex);
|
||||
item.id = id;
|
||||
item.quantity = quantity;
|
||||
}
|
||||
characterElement.totalItemsSpawned = character.totalItemsSpawned;
|
||||
characterElement.totalItemsConsumed = character.totalItemsConsumed;
|
||||
characterElement.totalPlaytimeSeconds = character.totalPlaytimeSeconds;
|
||||
|
||||
auto itemsIndex = (int)save.elements.size();
|
||||
save.element_add(resource::xml::Schema::Element::ITEMS, 0);
|
||||
for (auto& item : itemManager.items)
|
||||
{
|
||||
if (item.schemaID < 0 || item.schemaID >= (int)itemSchema.items.size()) continue;
|
||||
auto& itemElement = save.element_add(resource::xml::Schema::Element::ITEM, itemsIndex);
|
||||
itemElement.id = item.schemaID;
|
||||
itemElement.durability = item.durability;
|
||||
itemElement.position = item.position;
|
||||
itemElement.velocity = item.velocity;
|
||||
itemElement.rotation = *item.overrides[item.rotationOverrideID].frame.rotation;
|
||||
}
|
||||
|
||||
auto discoveredIndex = (int)save.elements.size();
|
||||
save.element_add(resource::xml::Schema::Element::DISCOVERED, 0);
|
||||
for (int i = 0; i < (int)itemManager.discoveredItemIDs.size(); i++)
|
||||
{
|
||||
if (!itemManager.discoveredItemIDs[i]) continue;
|
||||
auto& itemElement = save.element_add(resource::xml::Schema::Element::ITEM, discoveredIndex);
|
||||
itemElement.id = i;
|
||||
}
|
||||
|
||||
resources.character_save_set(characterIndex, save);
|
||||
save.serialize(character.data.save_path_get());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user