Split play into body, items, interactions, autofeed and camera, with events, commands and literal strings
This commit is contained in:
1 parent
167f1a5ddd
commit
3e9a0cbd34
21 files changed
+2504
-2431
No files matched your search
+81
-71
@@ -6,6 +6,11 @@ constexpr float FONT_SIZE = 20;
|
||||
constexpr const char* EFFECT_NAMES[] = {"animation", "big", "color", "delay", "oscillation", "scene",
|
||||
"screenshake", "shake", "silent", "small", "sound"};
|
||||
constexpr const char* USE_NAMES[] = {"", "edible", "tool"};
|
||||
constexpr const char* HOOK_NAMES[] = {
|
||||
#define X(id, name) name,
|
||||
HOOKS(X)
|
||||
#undef X
|
||||
};
|
||||
|
||||
struct SoundSource
|
||||
{
|
||||
@@ -42,13 +47,23 @@ Entry* Dialogue::pool_get(const std::string& pool)
|
||||
return entry_get(found->second[SDL_rand((Sint32)found->second.size())]);
|
||||
}
|
||||
|
||||
Entry* Dialogue::hook_get(const std::string& hook)
|
||||
Entry* Dialogue::hook_get(Hook hook)
|
||||
{
|
||||
auto found = hooks.find(hook);
|
||||
if (found == hooks.end())
|
||||
return nullptr;
|
||||
Entry* entry = pool_get(found->second);
|
||||
return entry ? entry : entry_get(found->second);
|
||||
Entry* entry = pool_get(hooks[hook]);
|
||||
return entry ? entry : entry_get(hooks[hook]);
|
||||
}
|
||||
|
||||
bool Dialogue::is_hook(Hook hook)
|
||||
{
|
||||
return pools.contains(hooks[hook]) || entries.contains(hooks[hook]);
|
||||
}
|
||||
|
||||
int Catalog::item_get(const std::string& name)
|
||||
{
|
||||
for (int i = 0; i < (int)items.size(); i++)
|
||||
if (items[i].name == name)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Character::preview_load(const std::string& path, Renderer& renderer)
|
||||
@@ -65,7 +80,7 @@ void Character::preview_load(const std::string& path, Renderer& renderer)
|
||||
description = json_string(root, "description");
|
||||
credits = json_string(root, "credits");
|
||||
color = json_color(root, "color", color);
|
||||
weight = json_float(root, "weight");
|
||||
traits.weight = json_float(root, "weight");
|
||||
anm2Path = json_string(root, "anm2");
|
||||
portrait = root["portrait"].error() ? nullptr : renderer.texture_get(folder + json_string(root, "portrait"));
|
||||
render = root["render"].error() ? nullptr : renderer.texture_get(folder + json_string(root, "render"));
|
||||
@@ -120,35 +135,34 @@ static void interact_parse(object source, InteractArea& area, Character& charact
|
||||
static void character_parse(object root, Character& character, Renderer& renderer, Audio& audio)
|
||||
{
|
||||
character.anm2 = character.anm2_get(character.anm2Path, renderer, audio);
|
||||
character.weightMax = json_float(root, "weightMax", character.weight);
|
||||
character.capacity = json_float(root, "capacity");
|
||||
character.capacityMin = json_float(root, "capacityMin");
|
||||
character.capacityMax = json_float(root, "capacityMax", character.capacity);
|
||||
character.overstuffedMultiplier = json_float(root, "overstuffedMultiplier", 1);
|
||||
character.overstuffedDigestBonus = json_float(root, "overstuffedDigestBonus");
|
||||
character.caloriesToKilogram = json_float(root, "caloriesToKilogram");
|
||||
character.digestionRate = json_float(root, "digestionRate") / TICK_RATE;
|
||||
character.digestionRateMin = json_float(root, "digestionRateMin") / TICK_RATE;
|
||||
character.digestionRateMax = json_float(root, "digestionRateMax", character.digestionRate * TICK_RATE) / TICK_RATE;
|
||||
character.digestionTime = json_int(root, "digestionTime");
|
||||
character.blinkChance = json_float(root, "blinkChance");
|
||||
character.gurgleChance = json_float(root, "gurgleChance");
|
||||
character.gurgleCapacityMultiplier = json_float(root, "gurgleCapacityMultiplier");
|
||||
Traits& traits = character.traits;
|
||||
traits.weightMax = json_float(root, "weightMax", traits.weight);
|
||||
traits.capacity = json_float(root, "capacity");
|
||||
traits.capacityMin = json_float(root, "capacityMin");
|
||||
traits.capacityMax = json_float(root, "capacityMax", traits.capacity);
|
||||
traits.overstuffedMultiplier = json_float(root, "overstuffedMultiplier", 1);
|
||||
traits.overstuffedDigestBonus = json_float(root, "overstuffedDigestBonus");
|
||||
traits.caloriesToKilogram = json_float(root, "caloriesToKilogram");
|
||||
traits.digestionRate = json_float(root, "digestionRate") / TICK_RATE;
|
||||
traits.digestionRateMin = json_float(root, "digestionRateMin") / TICK_RATE;
|
||||
traits.digestionRateMax = json_float(root, "digestionRateMax", traits.digestionRate * TICK_RATE) / TICK_RATE;
|
||||
traits.digestionTime = json_int(root, "digestionTime");
|
||||
traits.blinkChance = json_float(root, "blinkChance");
|
||||
traits.gurgleChance = json_float(root, "gurgleChance");
|
||||
traits.gurgleCapacityMultiplier = json_float(root, "gurgleCapacityMultiplier");
|
||||
character.dialoguePool = json_string(root, "dialoguePool");
|
||||
|
||||
object alternate = json_object(root, "alternate");
|
||||
if (!alternate["texture"].error())
|
||||
character.alternateTexture = renderer.texture_get(character.folder + json_string(alternate, "texture"));
|
||||
character.alternate.texture = renderer.texture_get(character.folder + json_string(alternate, "texture"));
|
||||
if (!alternate["sound"].error())
|
||||
character.alternateSound = audio.sound_get(character.folder + json_string(alternate, "sound"));
|
||||
character.alternateChance = json_float(alternate, "chance");
|
||||
character.alternateSheet = json_int(alternate, "spritesheet");
|
||||
character.alternate.sound = audio.sound_get(character.folder + json_string(alternate, "sound"));
|
||||
character.alternate.chance = json_float(alternate, "chance");
|
||||
character.alternate.sheet = json_int(alternate, "spritesheet");
|
||||
|
||||
object animations = json_object(root, "animations");
|
||||
character.animationStart = json_string(animations, "start");
|
||||
character.animationIdle = json_string(animations, "idle");
|
||||
character.animationIdleFull = json_string(animations, "idleFull");
|
||||
character.animationStageUp = json_string(animations, "stageUp");
|
||||
character.animations = {json_string(animations, "idle"), json_string(animations, "idleFull"),
|
||||
json_string(animations, "stageUp"), json_string(animations, "start")};
|
||||
|
||||
Anm2* anm2 = character.anm2;
|
||||
auto layer_get = [&](object source, const char* key) {
|
||||
@@ -157,10 +171,9 @@ static void character_parse(object root, Character& character, Renderer& rendere
|
||||
auto null_get = [&](object source, const char* key) {
|
||||
return anm2 ? anm2->null_get(json_string(source, key)) : -1;
|
||||
};
|
||||
character.talkSource = layer_get(json_object(root, "talk"), "source");
|
||||
character.talkDestination = layer_get(json_object(root, "talk"), "destination");
|
||||
character.blinkSource = layer_get(json_object(root, "blink"), "source");
|
||||
character.blinkDestination = layer_get(json_object(root, "blink"), "destination");
|
||||
character.talk = {layer_get(json_object(root, "talk"), "destination"), layer_get(json_object(root, "talk"), "source")};
|
||||
character.blink = {layer_get(json_object(root, "blink"), "destination"),
|
||||
layer_get(json_object(root, "blink"), "source")};
|
||||
|
||||
for (element entry : json_array(root, "eatAreas"))
|
||||
{
|
||||
@@ -225,26 +238,28 @@ static void character_parse(object root, Character& character, Renderer& rendere
|
||||
}
|
||||
|
||||
object cursor = json_object(root, "cursor");
|
||||
character.cursor = character.anm2_get(json_string(cursor, "anm2"), renderer, audio);
|
||||
object cursorAnimations = json_object(cursor, "animations");
|
||||
character.cursorIdle = json_string(cursorAnimations, "idle");
|
||||
character.cursorClick = json_string(cursorAnimations, "click");
|
||||
character.cursorHover = json_string(cursorAnimations, "hover");
|
||||
character.cursorGrab = json_string(cursorAnimations, "grab");
|
||||
character.cursorPan = json_string(cursorAnimations, "pan");
|
||||
character.cursorZoom = json_string(cursorAnimations, "zoom");
|
||||
character.cursorDispose = json_string(cursorAnimations, "dispose");
|
||||
character.grabParticles = json_strings(json_object(cursor, "particles"), "grab");
|
||||
auto cursor_get = [&](const char* key) {
|
||||
return json_string(cursorAnimations, key);
|
||||
};
|
||||
character.cursor = {cursor_get("click"),
|
||||
cursor_get("dispose"),
|
||||
cursor_get("grab"),
|
||||
cursor_get("hover"),
|
||||
cursor_get("idle"),
|
||||
cursor_get("pan"),
|
||||
cursor_get("zoom"),
|
||||
json_strings(json_object(cursor, "particles"), "grab"),
|
||||
character.anm2_get(json_string(cursor, "anm2"), renderer, audio)};
|
||||
|
||||
object menu = json_object(root, "menu");
|
||||
ImFontAtlas* fonts = ImGui::GetIO().Fonts;
|
||||
if (!menu["font"].error())
|
||||
character.font = fonts->AddFontFromFileTTF((character.folder + json_string(menu, "font")).c_str(), FONT_SIZE);
|
||||
if (!menu["iconsFont"].error())
|
||||
character.iconsFont =
|
||||
fonts->AddFontFromFileTTF((character.folder + json_string(menu, "iconsFont")).c_str(), FONT_SIZE);
|
||||
character.rounding = json_float(menu, "rounding");
|
||||
character.homeGlyph = json_string(menu, "homeGlyph");
|
||||
auto font_get = [&](const char* key) {
|
||||
std::string path = json_string(menu, key);
|
||||
return path.empty() ? nullptr
|
||||
: ImGui::GetIO().Fonts->AddFontFromFileTTF((character.folder + path).c_str(), FONT_SIZE);
|
||||
};
|
||||
character.menu = {json_string(menu, "homeGlyph"), font_get("font"), font_get("iconsFont"),
|
||||
json_float(menu, "rounding")};
|
||||
|
||||
for (auto [name, value] : json_object(root, "particles"))
|
||||
{
|
||||
@@ -253,22 +268,19 @@ static void character_parse(object root, Character& character, Renderer& rendere
|
||||
character.particles[std::string(name)] = {
|
||||
json_string(fields, "animation"), character.anm2_get(json_string(fields, "anm2"), renderer, audio)};
|
||||
}
|
||||
|
||||
object strings = json_object(root, "strings");
|
||||
for (int i = 0; i < STRING_COUNT; i++)
|
||||
character.strings[i] = json_string(strings, STRING_NAMES[i], STRING_DEFAULTS[i]);
|
||||
}
|
||||
|
||||
static void items_parse(object root, Character& character, Renderer& renderer, Audio& audio)
|
||||
{
|
||||
Catalog& catalog = character.catalog;
|
||||
Anm2* baseAnm2 = character.anm2_get(json_string(root, "anm2"), renderer, audio);
|
||||
character.itemSheet = json_int(root, "spritesheet");
|
||||
character.spawnDelay = json_int(root, "spawnDelay", character.spawnDelay);
|
||||
character.spawnDelayMultiplier = json_float(root, "spawnDelayMultiplier", character.spawnDelayMultiplier);
|
||||
character.spawnLimit = json_int(root, "spawnLimit", character.spawnLimit);
|
||||
catalog.sheet = json_int(root, "spritesheet");
|
||||
catalog.spawnDelay = json_int(root, "spawnDelay", catalog.spawnDelay);
|
||||
catalog.spawnDelayMultiplier = json_float(root, "spawnDelayMultiplier", catalog.spawnDelayMultiplier);
|
||||
catalog.spawnLimit = json_int(root, "spawnLimit", catalog.spawnLimit);
|
||||
object particles = json_object(root, "particles");
|
||||
character.disposeParticles = json_strings(particles, "dispose");
|
||||
character.summonParticles = json_strings(particles, "summon");
|
||||
catalog.disposeParticles = json_strings(particles, "dispose");
|
||||
catalog.summonParticles = json_strings(particles, "summon");
|
||||
|
||||
object categories = json_object(root, "categories");
|
||||
std::vector<std::string> rarityNames;
|
||||
@@ -278,7 +290,7 @@ static void items_parse(object root, Character& character, Renderer& renderer, A
|
||||
if (value.get(fields))
|
||||
continue;
|
||||
std::string sound = json_string(fields, "sound");
|
||||
character.rarities.push_back({std::string(name), sound.empty() ? nullptr : audio.sound_get(character.folder + sound),
|
||||
catalog.rarities.push_back({std::string(name), sound.empty() ? nullptr : audio.sound_get(character.folder + sound),
|
||||
json_float(fields, "weight")});
|
||||
rarityNames.emplace_back(name);
|
||||
}
|
||||
@@ -288,7 +300,7 @@ static void items_parse(object root, Character& character, Renderer& renderer, A
|
||||
object fields;
|
||||
if (entry.get(fields))
|
||||
continue;
|
||||
Item& item = character.items.emplace_back();
|
||||
Item& item = catalog.items.emplace_back();
|
||||
item.name = json_string(fields, "name", "???");
|
||||
item.description = json_string(fields, "description", "???");
|
||||
item.category = json_string(fields, "category");
|
||||
@@ -323,12 +335,9 @@ static void dialogue_parse(object root, Character& character, Audio& audio)
|
||||
if (!value.get(fields))
|
||||
dialogue.pauses[std::string(letter)] = {json_int(fields, "delay"), json_is(fields, "isSilent")};
|
||||
}
|
||||
for (auto [hook, value] : json_object(root, "hooks"))
|
||||
{
|
||||
std::string_view target;
|
||||
if (!value.get(target))
|
||||
dialogue.hooks[std::string(hook)] = target;
|
||||
}
|
||||
object hooks = json_object(root, "hooks");
|
||||
for (int i = 0; i < HOOK_COUNT; i++)
|
||||
dialogue.hooks[i] = json_string(hooks, HOOK_NAMES[i]);
|
||||
for (auto [pool, value] : json_object(root, "pools"))
|
||||
{
|
||||
array list;
|
||||
@@ -418,10 +427,11 @@ void Character::load(Renderer& renderer, Audio& audio)
|
||||
// An actor for an item, showing its texture in place of its anm2's item spritesheet.
|
||||
Actor Character::item_actor_get(int item)
|
||||
{
|
||||
Actor actor(items[item].anm2);
|
||||
Item& entry = catalog.items[item];
|
||||
Actor actor(entry.anm2);
|
||||
actor.isStatic = true;
|
||||
if (items[item].texture && itemSheet >= 0 && itemSheet < (int)actor.sheets.size())
|
||||
actor.sheets[itemSheet] = items[item].texture;
|
||||
if (entry.texture && catalog.sheet >= 0 && catalog.sheet < (int)actor.sheets.size())
|
||||
actor.sheets[catalog.sheet] = entry.texture;
|
||||
return actor;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user