This commit is contained in:
2026-08-09 00:20:29 -04:00
parent a5904b917b
commit 019a2f73fb
78 changed files with 197829 additions and 191493 deletions
+3 -1
View File
@@ -365,6 +365,8 @@ The sound that will play when an item is bounced (hitting a floor/wall/ceiling w
The sound that will play when an item is disposed of. The sound that will play when an item is disposed of.
### Summon ### Summon
The sound that will play when an item is spawned. The sound that will play when an item is spawned.
### NewItem
The sound that will play when an item is discovered in the Catalog for the first time.
### Return ### Return
The sound that will play when an item is returned. The sound that will play when an item is returned.
### Sound ### Sound
@@ -464,7 +466,7 @@ Outside of resources, Shweet's Sim also has a few files it writes outside of the
## settings.xml ## settings.xml
Stores general game settings and configuration; beyond invididual characters. Stores general game settings and configuration; beyond invididual characters.
### MeasurementSystem ("Imperial", "Metric") ### MeasurementSystem ("Imperial", "Metric")
Determines measurement system (kg/lb). Determines measurement system (kg/g or lb/oz).
### Volume (int, percent) ### Volume (int, percent)
Master volume. Master volume.
### IsAudioMuted (bool) ### IsAudioMuted (bool)
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6
View File
@@ -63,6 +63,10 @@
<Sound Path="kiss5.ogg" /> <Sound Path="kiss5.ogg" />
<Particle Type="Circle" /> <Particle Type="Circle" />
</InteractArea> </InteractArea>
<InteractArea Type="Turn Around" GlyphFromIconFont="5">
<Particle Type="Circle" />
<Sound Path="turn.ogg" />
</InteractArea>
</InteractAreaTypes> </InteractAreaTypes>
<InteractAreas> <InteractAreas>
<InteractArea Type="Rub" Null="Head" DialoguePool="HeadRub" DialoguePoolFull="HeadRubFull" /> <InteractArea Type="Rub" Null="Head" DialoguePool="HeadRub" DialoguePoolFull="HeadRubFull" />
@@ -73,5 +77,7 @@
<InteractArea Type="Kiss" Null="Tail" DialoguePool="TailKiss" DialoguePoolFull="TailKiss" /> <InteractArea Type="Kiss" Null="Tail" DialoguePool="TailKiss" DialoguePoolFull="TailKiss" />
<InteractArea Type="Smack" Null="Belly" DialoguePool="BellySmack" Layer="Torso" DigestionBonusOnClick="0.25" DialoguePoolFull="BellySmack" /> <InteractArea Type="Smack" Null="Belly" DialoguePool="BellySmack" Layer="Torso" DigestionBonusOnClick="0.25" DialoguePoolFull="BellySmack" />
<InteractArea Type="Smack" Null="Tail" DialoguePool="TailSmack" Layer="Tail" DialoguePoolFull="TailSmack" /> <InteractArea Type="Smack" Null="Tail" DialoguePool="TailSmack" Layer="Tail" DialoguePoolFull="TailSmack" />
<InteractArea Type="Turn Around" Null="FullBody" AnimationCursorHover="TurnAround" Animation="NeutralBack" />
<InteractArea Type="Turn Around" Null="FullBodyBack" AnimationCursorHover="TurnAroundBack" Animation="Neutral" />
</InteractAreas> </InteractAreas>
</Character> </Character>
@@ -20,7 +20,7 @@
</RootAnimation> </RootAnimation>
<LayerAnimations> <LayerAnimations>
<LayerAnimation LayerId="0" Visible="true"> <LayerAnimation LayerId="0" Visible="true">
<Frame XPivot="400" YPivot="500" XCrop="0" YCrop="0" Width="800" Height="600" XPosition="0" YPosition="0" Delay="1" Visible="true" XScale="100" YScale="100" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/> <Frame XPivot="350" YPivot="400" XCrop="0" YCrop="0" Width="700" Height="500" XPosition="0" YPosition="0" Delay="1" Visible="true" XScale="100" YScale="100" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/>
</LayerAnimation> </LayerAnimation>
</LayerAnimations> </LayerAnimations>
<NullAnimations> <NullAnimations>
@@ -28,7 +28,7 @@
<Frame XPosition="1" YPosition="-172" Delay="1" Visible="true" XScale="640" YScale="400" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/> <Frame XPosition="1" YPosition="-172" Delay="1" Visible="true" XScale="640" YScale="400" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/>
</NullAnimation> </NullAnimation>
<NullAnimation NullId="1" Visible="true"> <NullAnimation NullId="1" Visible="true">
<Frame XPosition="0" YPosition="-299" Delay="1" Visible="true" XScale="440" YScale="145" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/> <Frame XPosition="0" YPosition="-245" Delay="1" Visible="true" XScale="440" YScale="145" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/>
</NullAnimation> </NullAnimation>
</NullAnimations> </NullAnimations>
<Triggers/> <Triggers/>
@@ -39,7 +39,7 @@
<Content> <Content>
<Spritesheets> <Spritesheets>
<Spritesheet Id="0" Path="area.png"> <Spritesheet Id="0" Path="area.png">
<Region Id="0" Name="Main" XCrop="0" YCrop="0" Width="800" Height="600" XPivot="400" YPivot="500"/> <Region Id="0" Name="Main" XCrop="0" YCrop="0" Width="700" Height="500" XPivot="350" YPivot="400"/>
</Spritesheet> </Spritesheet>
</Spritesheets> </Spritesheets>
<Layers> <Layers>
@@ -66,7 +66,7 @@
<Frame XPosition="1" YPosition="-172" Delay="1" Visible="true" XScale="640" YScale="400" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/> <Frame XPosition="1" YPosition="-172" Delay="1" Visible="true" XScale="640" YScale="400" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/>
</NullAnimation> </NullAnimation>
<NullAnimation NullId="1" Visible="true"> <NullAnimation NullId="1" Visible="true">
<Frame XPosition="0" YPosition="-299" Delay="1" Visible="true" XScale="440" YScale="145" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/> <Frame XPosition="0" YPosition="-245" Delay="1" Visible="true" XScale="440" YScale="145" RedTint="255" GreenTint="255" BlueTint="255" AlphaTint="255" RedOffset="0" GreenOffset="0" BlueOffset="0" Rotation="0" Interpolated="false"/>
</NullAnimation> </NullAnimation>
</NullAnimations> </NullAnimations>
<Triggers/> <Triggers/>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 162 KiB

+8 -5
View File
@@ -13,6 +13,9 @@
<Sound Path="summon.ogg" /> <Sound Path="summon.ogg" />
<Particle Type="Puff" /> <Particle Type="Puff" />
</Summon> </Summon>
<NewItem>
<Sound Path="newItem.ogg" />
</NewItem>
<Return> <Return>
<Sound Path="return.ogg" /> <Sound Path="return.ogg" />
<Particle Type="Puff" /> <Particle Type="Puff" />
@@ -68,11 +71,11 @@
<Item Name="Poké Puff (Supreme Autumn)" Texture="item_023_poke_puff_supreme_autumn.png" Description="A supreme Poké Puff that tastes like a bountiful autumn harvest." Category="Food" Flavor="Citrus" Rarity="Legendary" Calories="2500.0" /> <Item Name="Poké Puff (Supreme Autumn)" Texture="item_023_poke_puff_supreme_autumn.png" Description="A supreme Poké Puff that tastes like a bountiful autumn harvest." Category="Food" Flavor="Citrus" Rarity="Legendary" Calories="2500.0" />
<Item Name="Poké Puff (Supreme Winter)" Texture="item_024_poke_puff_supreme_winter.png" Description="A supreme Poké Puff that tastes like a frosty winter wonderland." Category="Food" Flavor="Spice" Rarity="Legendary" Calories="2500.0" /> <Item Name="Poké Puff (Supreme Winter)" Texture="item_024_poke_puff_supreme_winter.png" Description="A supreme Poké Puff that tastes like a frosty winter wonderland." Category="Food" Flavor="Spice" Rarity="Legendary" Calories="2500.0" />
<Item Name="Poké Puff (Supreme Wish)" Texture="item_025_poke_puff_supreme_wish.png" Description="A supreme Poké Puff that tastes like a cherished birthday celebration.&#10;It also is the biggest calorie nuke ever.&#10;Can Snivy eat it!?&#10;Also, statistically, it might be your birthday today, right?" Category="Food" Flavor="Spice" Rarity="???" Calories="10000.0" /> <Item Name="Poké Puff (Supreme Wish)" Texture="item_025_poke_puff_supreme_wish.png" Description="A supreme Poké Puff that tastes like a cherished birthday celebration.&#10;It also is the biggest calorie nuke ever.&#10;Can Snivy eat it!?&#10;Also, statistically, it might be your birthday today, right?" Category="Food" Flavor="Spice" Rarity="???" Calories="10000.0" />
<Item Name="Poké Puff (Supreme Honor)" Texture="item_026_poke_puff_supreme_honor.png" Description="A supreme Poké Puff that tastes like a monumental victory.&#10;You've earned it...if Snivy can eat it!" Category="Food" Flavor="Mocha" Rarity="Special" Calories="2500.0" DigestionBonus="0.0125" /> <Item Name="Poké Puff (Supreme Honor)" Texture="item_026_poke_puff_supreme_honor.png" Description="A supreme Poké Puff that tastes like a monumental victory.&#10;With your luck, you've earned it...if Snivy can eat it!" Category="Food" Flavor="Mocha" Rarity="???" Calories="2500.0" DigestionBonus="0.01" />
<Item Name="Cheri Berry" Texture="item_027_cheri_berry.png" Description="A spherical red berry that cures paralysis&#10;...oh, and it also excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Uncommon" Calories="25.0" DigestionBonus="0.000833" /> <Item Name="Cheri Berry" Texture="item_027_cheri_berry.png" Description="A spherical red berry that cures paralysis&#10;...oh, and it also excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Uncommon" Calories="25.0" DigestionBonus="0.00015" />
<Item Name="Tamato Berry" Texture="item_028_tamato_berry.png" Description="A spiny crimson berry that lowers speed and raises friendship.&#10;...oh, and it also greatly excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Rare" Calories="50.0" DigestionBonus="0.0041665" /> <Item Name="Tamato Berry" Texture="item_028_tamato_berry.png" Description="A spiny crimson berry that lowers speed and raises friendship.&#10;...oh, and it also greatly excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Rare" Calories="50.0" DigestionBonus="0.0003" />
<Item Name="Touga Berry" Texture="item_029_touga_berry.png" Description="An obscure, searing-red berry from faraway lands.&#10;It cures confusion...and it'll make one's stomach a burning inferno." Category="Food" Flavor="Spicy" Rarity="Epic" Calories="100.0" DigestionBonus="0.00833" /> <Item Name="Touga Berry" Texture="item_029_touga_berry.png" Description="An obscure, searing-red berry from faraway lands.&#10;It cures confusion...and it'll make one's stomach a burning inferno." Category="Food" Flavor="Spicy" Rarity="Epic" Calories="100.0" DigestionBonus="0.00066" />
<Item Name="Pomeg Berry" Texture="item_030_pomeg_berry.png" Description="cG9tZWcgYmVycnkgcG9tZWcgYmVycnkgcG9tZWcgYmVycnk=" Category="Food" Flavor="None" Rarity="???" Calories="-2500.0" DigestionBonus="0.1" Gravity="0.05" /> <Item Name="Pomeg Berry" Texture="item_030_pomeg_berry.png" Description="cG9tZWcgYmVycnkgcG9tZWcgYmVycnkgcG9tZWcgYmVycnk=" Category="Food" Flavor="None" Rarity="???" Calories="-2500.0" DigestionBonus="0.01" Gravity="0.05" />
<Item Name="Shiny Charm" Texture="item_031_shiny_charm.png" Description="Can change a Pokémon's color scheme..." Category="Tool" Rarity="???" IsToggleSpritesheet="true" /> <Item Name="Shiny Charm" Texture="item_031_shiny_charm.png" Description="Can change a Pokémon's color scheme..." Category="Tool" Rarity="???" IsToggleSpritesheet="true" />
</Items> </Items>
</ItemSchema> </ItemSchema>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -730,6 +730,7 @@ namespace game::resource::xml
X(KILL, soundKill) \ X(KILL, soundKill) \
X(LEVEL_UP, soundLevelUp) \ X(LEVEL_UP, soundLevelUp) \
X(LEVEL_UP_READY, soundLevelUpReady) \ X(LEVEL_UP_READY, soundLevelUpReady) \
X(NEW_ITEM, soundNewItem) \
X(OPEN, soundOpen) \ X(OPEN, soundOpen) \
X(RELEASE, soundRelease) \ X(RELEASE, soundRelease) \
X(SELECT, soundSelect) \ X(SELECT, soundSelect) \
@@ -804,6 +805,7 @@ namespace game::resource::xml
root->soundKill = {}; root->soundKill = {};
root->soundLevelUp = {}; root->soundLevelUp = {};
root->soundLevelUpReady = {}; root->soundLevelUpReady = {};
root->soundNewItem = {};
root->soundOpen = {}; root->soundOpen = {};
root->soundRelease = {}; root->soundRelease = {};
root->soundSelect = {}; root->soundSelect = {};
@@ -873,6 +875,8 @@ namespace game::resource::xml
sound_entry_add(*element, root->soundLevelUp); sound_entry_add(*element, root->soundLevelUp);
for (auto* element : schema.children_get(*sounds, Schema::Element::LEVEL_UP_READY)) for (auto* element : schema.children_get(*sounds, Schema::Element::LEVEL_UP_READY))
sound_entry_add(*element, root->soundLevelUpReady); sound_entry_add(*element, root->soundLevelUpReady);
for (auto* element : schema.children_get(*sounds, Schema::Element::NEW_ITEM))
sound_entry_add(*element, root->soundNewItem);
for (auto* element : schema.children_get(*sounds, Schema::Element::OPEN)) for (auto* element : schema.children_get(*sounds, Schema::Element::OPEN))
sound_entry_add(*element, root->soundOpen); sound_entry_add(*element, root->soundOpen);
for (auto* element : schema.children_get(*sounds, Schema::Element::RELEASE)) for (auto* element : schema.children_get(*sounds, Schema::Element::RELEASE))
+2
View File
@@ -97,6 +97,7 @@
X(LowCapacity, LOW_CAPACITY) \ X(LowCapacity, LOW_CAPACITY) \
X(Menu, MENU) \ X(Menu, MENU) \
X(New, NEW) \ X(New, NEW) \
X(NewItem, NEW_ITEM) \
X(Null, NULL_) \ X(Null, NULL_) \
X(NullAnimation, NULL_ANIMATION) \ X(NullAnimation, NULL_ANIMATION) \
X(NullAnimations, NULL_ANIMATIONS) \ X(NullAnimations, NULL_ANIMATIONS) \
@@ -468,6 +469,7 @@
X(DATA, MEMBER, soundLevelUp, SoundEntryCollection, "Sound Level Up", NONE, \ X(DATA, MEMBER, soundLevelUp, SoundEntryCollection, "Sound Level Up", NONE, \
"", "", "", soundLevelUp) \ "", "", "", soundLevelUp) \
X(DATA, MEMBER, soundLevelUpReady, SoundEntryCollection, "Sound Level Up Ready", NONE, "", "", "", soundLevelUpReady) \ X(DATA, MEMBER, soundLevelUpReady, SoundEntryCollection, "Sound Level Up Ready", NONE, "", "", "", soundLevelUpReady) \
X(DATA, MEMBER, soundNewItem, SoundEntryCollection, "Sound New Item", NONE, "", "", "", soundNewItem) \
X(DATA, MEMBER, soundOpen, SoundEntryCollection, "Sound Open", NONE, "", "", "", \ X(DATA, MEMBER, soundOpen, SoundEntryCollection, "Sound Open", NONE, "", "", "", \
soundOpen) \ soundOpen) \
X(DATA, MEMBER, soundRelease, SoundEntryCollection, "Sound Release", NONE, \ X(DATA, MEMBER, soundRelease, SoundEntryCollection, "Sound Release", NONE, \
+4 -3
View File
@@ -21,7 +21,7 @@ namespace game::resource::xml
X(InteractSpawnItemCooldownFormat, "TextInteractSpawnItemCooldownFormat", "Next item in %0.2fs") \ X(InteractSpawnItemCooldownFormat, "TextInteractSpawnItemCooldownFormat", "Next item in %0.2fs") \
X(InteractStats, "TextInteractStats", "Stats") \ X(InteractStats, "TextInteractStats", "Stats") \
X(InteractWeightFormat, "TextInteractWeightFormat", "Weight: %0.2f %s (Stage: %i)") \ X(InteractWeightFormat, "TextInteractWeightFormat", "Weight: %0.2f %s (Stage: %i)") \
X(InteractCapacityFormat, "TextInteractCapacityFormat", "Capacity: %0.0f kcal (Max: %0.0f kcal)") \ X(InteractCapacityFormat, "TextInteractCapacityFormat", "Capacity: %0.0f / %0.0f kcal") \
X(InteractDigestionRateFormat, "TextInteractDigestionRateFormat", "Digestion Rate: %0.2f%%/sec") \ X(InteractDigestionRateFormat, "TextInteractDigestionRateFormat", "Digestion Rate: %0.2f%%/sec") \
X(InteractTotalCaloriesFormat, "TextInteractTotalCaloriesFormat", "Total Calories Consumed: %0.0f kcal") \ X(InteractTotalCaloriesFormat, "TextInteractTotalCaloriesFormat", "Total Calories Consumed: %0.0f kcal") \
X(InteractTotalItemsSpawnedFormat, "TextInteractTotalItemsSpawnedFormat", "Total Items Spawned: %i") \ X(InteractTotalItemsSpawnedFormat, "TextInteractTotalItemsSpawnedFormat", "Total Items Spawned: %i") \
@@ -35,9 +35,9 @@ namespace game::resource::xml
X(SettingsFullscreen, "TextSettingsFullscreen", "Fullscreen") \ X(SettingsFullscreen, "TextSettingsFullscreen", "Fullscreen") \
X(SettingsMeasurementSystem, "TextSettingsMeasurementSystem", "Measurement System") \ X(SettingsMeasurementSystem, "TextSettingsMeasurementSystem", "Measurement System") \
X(SettingsMetric, "TextSettingsMetric", "Metric") \ X(SettingsMetric, "TextSettingsMetric", "Metric") \
X(SettingsMetricTooltip, "TextSettingsMetricTooltip", "Use kilograms (kg).") \ X(SettingsMetricTooltip, "TextSettingsMetricTooltip", "Use kilograms/grams (kg/g).") \
X(SettingsImperial, "TextSettingsImperial", "Imperial") \ X(SettingsImperial, "TextSettingsImperial", "Imperial") \
X(SettingsImperialTooltip, "TextSettingsImperialTooltip", "Use pounds (lbs).") \ X(SettingsImperialTooltip, "TextSettingsImperialTooltip", "Use pounds/ounces (lbs/oz).") \
X(SettingsSound, "TextSettingsSound", "Sound") \ X(SettingsSound, "TextSettingsSound", "Sound") \
X(SettingsVolume, "TextSettingsVolume", "Volume") \ X(SettingsVolume, "TextSettingsVolume", "Volume") \
X(SettingsVolumeTooltip, "TextSettingsVolumeTooltip", "Adjust master volume.") \ X(SettingsVolumeTooltip, "TextSettingsVolumeTooltip", "Adjust master volume.") \
@@ -57,6 +57,7 @@ namespace game::resource::xml
"Go back to the character selection screen.\nProgress will be saved.") \ "Go back to the character selection screen.\nProgress will be saved.") \
X(ToastCheatsUnlocked, "TextToastCheatsUnlocked", "Cheats unlocked!") \ X(ToastCheatsUnlocked, "TextToastCheatsUnlocked", "Cheats unlocked!") \
X(ToastSaving, "TextToastSaving", "Saving...") \ X(ToastSaving, "TextToastSaving", "Saving...") \
X(ToastNewItemFound, "TextToastNewItemFound", "New item found!") \
X(ToolsHomeButton, "TextToolsHomeButton", "Home") \ X(ToolsHomeButton, "TextToolsHomeButton", "Home") \
X(ToolsHomeTooltip, "TextToolsHomeTooltip", "Reset camera view.\n(Shortcut: Home)") \ X(ToolsHomeTooltip, "TextToolsHomeTooltip", "Reset camera view.\n(Shortcut: Home)") \
X(ToolsOpenTooltip, "TextToolsOpenTooltip", "Open Tools") \ X(ToolsOpenTooltip, "TextToolsOpenTooltip", "Open Tools") \
+6
View File
@@ -311,6 +311,12 @@ namespace game::state
auto& interactionCursor = autofeed.active_get() ? autofeedCursor : cursor; auto& interactionCursor = autofeed.active_get() ? autofeedCursor : cursor;
itemManager.isAutomation = autofeed.active_get(); itemManager.isAutomation = autofeed.active_get();
itemManager.update(character, interactionCursor, areaManager, text, world.bounds, worldCanvas); itemManager.update(character, interactionCursor, areaManager, text, world.bounds, worldCanvas);
auto* itemRoot = character.data.itemSchema.root();
for (int i = 0; i < itemManager.newItemFoundCount; i++)
{
toasts.push(character.data.strings.get(Strings::ToastNewItemFound));
if (itemRoot) itemRoot->soundNewItem.play();
}
characterManager.update(character, interactionCursor, text, worldCanvas); characterManager.update(character, interactionCursor, text, worldCanvas);
for (auto& particle : itemManager.particles) for (auto& particle : itemManager.particles)
particleManager.spawn(character.data, particle.label, particle.position); particleManager.spawn(character.data, particle.label, particle.position);
+55 -18
View File
@@ -15,10 +15,14 @@ namespace game::state::play
{ {
constexpr float CURSOR_SPEED = 9.0f; constexpr float CURSOR_SPEED = 9.0f;
constexpr float DIGEST_CURSOR_SPEED = 3.0f; constexpr float DIGEST_CURSOR_SPEED = 3.0f;
constexpr float CURSOR_ACCELERATION = 0.45f;
constexpr float DIGEST_CURSOR_ACCELERATION = 0.15f;
constexpr float CURSOR_SPEED_REFERENCE_AREA = 512.0f * 512.0f; constexpr float CURSOR_SPEED_REFERENCE_AREA = 512.0f * 512.0f;
constexpr float CURSOR_SPEED_SCALE_MIN = 0.5f; constexpr float CURSOR_SPEED_SCALE_MIN = 0.5f;
constexpr float CURSOR_SPEED_SCALE_MAX = 2.0f; constexpr float CURSOR_SPEED_SCALE_MAX = 2.0f;
constexpr float CURSOR_BRAKING_ACCELERATION_MULTIPLIER = 2.0f;
constexpr float CALORIE_EPSILON = 0.001f; constexpr float CALORIE_EPSILON = 0.001f;
constexpr float CURSOR_TARGET_EPSILON = 0.001f;
constexpr float FOOD_TIE_PICK_WEIGHT = 1.0f; constexpr float FOOD_TIE_PICK_WEIGHT = 1.0f;
glm::vec2 rect_center(glm::vec4 rect) { return {rect.x + rect.z * 0.5f, rect.y + rect.w * 0.5f}; } glm::vec2 rect_center(glm::vec4 rect) { return {rect.x + rect.z * 0.5f, rect.y + rect.w * 0.5f}; }
@@ -31,21 +35,51 @@ namespace game::state::play
value.z > 0.0f && value.w > 0.0f; value.z > 0.0f && value.w > 0.0f;
} }
bool move_toward(Entity& cursor, glm::vec2 target, float speed) bool move_toward(Entity& cursor, glm::vec2& velocity, glm::vec2 target, float speed, float acceleration)
{ {
if (!is_finite(cursor.position)) cursor.position = {}; if (!is_finite(cursor.position))
{
cursor.position = {};
velocity = {};
}
if (!is_finite(target)) return false; if (!is_finite(target)) return false;
auto delta = target - cursor.position; auto delta = target - cursor.position;
auto distance = glm::length(delta); auto distance = glm::length(delta);
if (!std::isfinite(distance)) return false; if (!std::isfinite(distance)) return false;
if (distance <= speed || distance <= 0.001f) if (distance <= CURSOR_TARGET_EPSILON)
{ {
cursor.position = target; cursor.position = target;
velocity = {};
return true; return true;
} }
cursor.position += delta / distance * speed; auto targetSpeed = glm::min(speed, std::sqrt(CURSOR_BRAKING_ACCELERATION_MULTIPLIER * acceleration * distance));
auto desiredVelocity = delta / distance * targetSpeed;
auto velocityDelta = desiredVelocity - velocity;
auto velocityDeltaDistance = glm::length(velocityDelta);
if (!std::isfinite(velocityDeltaDistance))
velocity = {};
else if (velocityDeltaDistance > acceleration)
velocity += velocityDelta / velocityDeltaDistance * acceleration;
else
velocity = desiredVelocity;
auto speedCurrent = glm::length(velocity);
if (!std::isfinite(speedCurrent))
{
velocity = {};
return false;
}
if (speedCurrent >= distance)
{
cursor.position = target;
velocity = {};
return true;
}
cursor.position += velocity;
return false; return false;
} }
@@ -224,13 +258,14 @@ namespace game::state::play
return nullptr; return nullptr;
} }
void state_reset(Entity& cursor, bool& isItemMouseHeld, bool& isDigestMouseHeld, int& targetItemIndex, void state_reset(Entity& cursor, glm::vec2& cursorVelocity, bool& isItemMouseHeld, bool& isDigestMouseHeld,
int& digestClickCooldown) int& targetItemIndex, int& digestClickCooldown)
{ {
isItemMouseHeld = false; isItemMouseHeld = false;
isDigestMouseHeld = false; isDigestMouseHeld = false;
targetItemIndex = -1; targetItemIndex = -1;
digestClickCooldown = 0; digestClickCooldown = 0;
cursorVelocity = {};
if (!is_finite(cursor.position)) cursor.position = {}; if (!is_finite(cursor.position)) cursor.position = {};
} }
} }
@@ -243,13 +278,13 @@ namespace game::state::play
if (!isEnabled) if (!isEnabled)
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
if (character.isStageUp || character.isJustStageUp || character.isJustStageFinal) if (character.isStageUp || character.isJustStageUp || character.isJustStageFinal)
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
@@ -257,7 +292,7 @@ namespace game::state::play
if (!is_food(character, itemManager)) if (!is_food(character, itemManager))
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
@@ -271,6 +306,8 @@ namespace game::state::play
auto speedScale = cursor_speed_scale_get(character); auto speedScale = cursor_speed_scale_get(character);
auto cursorSpeed = CURSOR_SPEED * speedScale; auto cursorSpeed = CURSOR_SPEED * speedScale;
auto digestCursorSpeed = DIGEST_CURSOR_SPEED * speedScale; auto digestCursorSpeed = DIGEST_CURSOR_SPEED * speedScale;
auto cursorAcceleration = CURSOR_ACCELERATION * speedScale;
auto digestCursorAcceleration = DIGEST_CURSOR_ACCELERATION * speedScale;
auto eatRect = glm::vec4{}; auto eatRect = glm::vec4{};
auto isEatTarget = eat_rect_get(character, eatRect); auto isEatTarget = eat_rect_get(character, eatRect);
@@ -281,7 +318,7 @@ namespace game::state::play
{ {
isActive = false; isActive = false;
cursor.isVisible = false; cursor.isVisible = false;
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
auto& schemaItem = schema.items[heldItem.schemaID]; auto& schemaItem = schema.items[heldItem.schemaID];
@@ -290,7 +327,7 @@ namespace game::state::play
{ {
isActive = true; isActive = true;
cursor.isVisible = true; cursor.isVisible = true;
move_toward(cursor, rect_center(eatRect), cursorSpeed); move_toward(cursor, cursorVelocity, rect_center(eatRect), cursorSpeed, cursorAcceleration);
itemInput.isMouseLeftDown = true; itemInput.isMouseLeftDown = true;
itemManager.inputOverride = itemInput; itemManager.inputOverride = itemInput;
@@ -319,13 +356,13 @@ namespace game::state::play
auto rect = item.rect(); auto rect = item.rect();
if (!is_finite(rect)) if (!is_finite(rect))
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
isActive = true; isActive = true;
cursor.isVisible = true; cursor.isVisible = true;
move_toward(cursor, rect_center(rect), cursorSpeed); move_toward(cursor, cursorVelocity, rect_center(rect), cursorSpeed, cursorAcceleration);
auto isInItemRect = math::is_point_in_rectf(rect, cursor.position); auto isInItemRect = math::is_point_in_rectf(rect, cursor.position);
@@ -341,7 +378,7 @@ namespace game::state::play
auto isWorldFood = is_world_food(character, itemManager); auto isWorldFood = is_world_food(character, itemManager);
if (character.calories <= CALORIE_EPSILON && !isWorldFood) if (character.calories <= CALORIE_EPSILON && !isWorldFood)
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
@@ -350,20 +387,20 @@ namespace game::state::play
auto* interactArea = digestion_area_get(character); auto* interactArea = digestion_area_get(character);
if (!interactArea) if (!interactArea)
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
auto rect = character.null_frame_rect(character.data.null_id_get(interactArea->null)); auto rect = character.null_frame_rect(character.data.null_id_get(interactArea->null));
if (!is_finite(rect)) if (!is_finite(rect))
{ {
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
return; return;
} }
auto radius = glm::max(1.0f, glm::min(rect.z, rect.w) * 0.25f); auto radius = glm::max(1.0f, glm::min(rect.z, rect.w) * 0.25f);
digestAngle += 0.08f; digestAngle += 0.08f;
auto targetWorld = rect_center(rect) + glm::vec2(std::cos(digestAngle), std::sin(digestAngle)) * radius; auto targetWorld = rect_center(rect) + glm::vec2(std::cos(digestAngle), std::sin(digestAngle)) * radius;
auto isAtTarget = move_toward(cursor, targetWorld, digestCursorSpeed); auto isAtTarget = move_toward(cursor, cursorVelocity, targetWorld, digestCursorSpeed, digestCursorAcceleration);
isActive = true; isActive = true;
cursor.isVisible = true; cursor.isVisible = true;
@@ -394,7 +431,7 @@ namespace game::state::play
return; return;
} }
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown); state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
} }
void Autofeed::toggle() { isEnabled = !isEnabled; } void Autofeed::toggle() { isEnabled = !isEnabled; }
+1
View File
@@ -14,6 +14,7 @@ namespace game::state::play
int targetItemIndex{-1}; int targetItemIndex{-1};
int digestClickCooldown{}; int digestClickCooldown{};
float digestAngle{}; float digestAngle{};
glm::vec2 cursorVelocity{};
bool isEnabled{}; bool isEnabled{};
bool isActive{}; bool isActive{};
+6 -1
View File
@@ -226,6 +226,7 @@ namespace game::state::play
if (isItemHovered != isItemHoveredPrevious && !isItemHovered) isJustItemHoveredStopped = true; if (isItemHovered != isItemHoveredPrevious && !isItemHovered) isJustItemHoveredStopped = true;
if (spawnDelayTicks > 0) spawnDelayTicks--; if (spawnDelayTicks > 0) spawnDelayTicks--;
if (discoveredItemIDs.size() != schema.items.size()) discoveredItemIDs.resize(schema.items.size()); if (discoveredItemIDs.size() != schema.items.size()) discoveredItemIDs.resize(schema.items.size());
newItemFoundCount = 0;
for (auto& id : queuedItemIDs) for (auto& id : queuedItemIDs)
{ {
@@ -237,7 +238,11 @@ namespace game::state::play
auto& anm2 = itemSchema.anm2s.at(id); auto& anm2 = itemSchema.anm2s.at(id);
items.emplace_back(anm2, position, id); items.emplace_back(anm2, position, id);
character.totalItemsSpawned++; character.totalItemsSpawned++;
if (id >= 0 && id < (int)discoveredItemIDs.size()) discoveredItemIDs[id] = true; if (id >= 0 && id < (int)discoveredItemIDs.size())
{
if (!discoveredItemIDs[id]) newItemFoundCount++;
discoveredItemIDs[id] = true;
}
particles_queue(itemSchema, resource::xml::Schema::Element::SUMMON, position); particles_queue(itemSchema, resource::xml::Schema::Element::SUMMON, position);
} }
queuedItemIDs.clear(); queuedItemIDs.clear();
+1
View File
@@ -44,6 +44,7 @@ namespace game::state::play
std::vector<int> queuedItemIDs{}; std::vector<int> queuedItemIDs{};
std::vector<bool> discoveredItemIDs{}; std::vector<bool> discoveredItemIDs{};
int newItemFoundCount{};
int spawnDelayTicks{}; int spawnDelayTicks{};
struct Particle struct Particle
{ {
+24 -12
View File
@@ -54,15 +54,15 @@ namespace game::state::play::menu
{ {
auto* settings = resources.settings.root(); auto* settings = resources.settings.root();
auto system = settings->measurementSystem == "Imperial" ? measurement::IMPERIAL : measurement::METRIC; auto system = settings->measurementSystem == "Imperial" ? measurement::IMPERIAL : measurement::METRIC;
auto weight = character.weight_get(system); auto weight = measurement::weight_display_get(character.weight, system);
auto stage = character.stage_get(); auto stage = character.stage_get();
auto stageMax = character.stage_max_get(); auto stageMax = character.stage_max_get();
auto stageCount = character.stage_count_get(); auto stageCount = character.stage_count_get();
auto stageWeight = character.stage_threshold_get(stage, system); auto stageWeight = measurement::weight_display_get(character.stage_threshold_get(stage), system);
auto stageNextWeight = character.stage_threshold_next_get(system); auto stageNextWeight = measurement::weight_display_get(character.stage_threshold_next_get(), system);
auto unitString = (system == measurement::IMPERIAL ? "lbs" : "kg");
auto weightString = util::string::format_commas(weight, 2) + " " + unitString; auto weightString = util::string::format_commas(weight.value, measurement::WEIGHT_DISPLAY_DECIMAL_DIGITS) + " " +
weight.unit;
imgui::text_unformatted_fit_draw(weightString.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, Font::HEADER_2), imgui::text_unformatted_fit_draw(weightString.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, Font::HEADER_2),
Font::HEADER_2); Font::HEADER_2);
ImGui::SetItemTooltip("%s", weightString.c_str()); ImGui::SetItemTooltip("%s", weightString.c_str());
@@ -81,9 +81,9 @@ namespace game::state::play::menu
ImGui::TextUnformatted(strings.get(Strings::InfoMaxedOut).c_str()); ImGui::TextUnformatted(strings.get(Strings::InfoMaxedOut).c_str());
else else
{ {
ImGui::Text(strings.get(Strings::InfoStageStartFormat).c_str(), stageWeight, unitString); ImGui::Text(strings.get(Strings::InfoStageStartFormat).c_str(), stageWeight.value, stageWeight.unit);
ImGui::Text(strings.get(Strings::InfoStageCurrentFormat).c_str(), weight, unitString); ImGui::Text(strings.get(Strings::InfoStageCurrentFormat).c_str(), weight.value, weight.unit);
ImGui::Text(strings.get(Strings::InfoStageNextFormat).c_str(), stageNextWeight, unitString); ImGui::Text(strings.get(Strings::InfoStageNextFormat).c_str(), stageNextWeight.value, stageNextWeight.unit);
} }
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::EndTooltip(); ImGui::EndTooltip();
@@ -100,14 +100,26 @@ namespace game::state::play::menu
auto overstuffedPercent = std::max(ZERO_FLOAT, (calories - capacity) / (character.max_capacity() - capacity)); auto overstuffedPercent = std::max(ZERO_FLOAT, (calories - capacity) / (character.max_capacity() - capacity));
auto caloriesColor = ImVec4(1.0f, 1.0f - overstuffedPercent, 1.0f - overstuffedPercent, 1.0f); auto caloriesColor = ImVec4(1.0f, 1.0f - overstuffedPercent, 1.0f - overstuffedPercent, 1.0f);
auto capacityMax = character.max_capacity();
ImGui::PushStyleColor(ImGuiCol_Text, caloriesColor); ImGui::PushStyleColor(ImGuiCol_Text, caloriesColor);
auto caloriesString = std::format("{:.0f} kcal / {:.0f} kcal", calories, auto caloriesString = std::format("{:.0f} / {:.0f} kcal", calories, capacity);
character.is_over_capacity() ? character.max_capacity() : character.capacity); auto caloriesTooltipStart = std::format("{:.0f} / {:.0f} ", calories, capacity);
auto caloriesTooltipEffective = std::format("({:.0f})", capacityMax);
imgui::text_unformatted_fit_draw(caloriesString.c_str(), imgui::text_unformatted_fit_draw(caloriesString.c_str(),
ImVec2(ImGui::GetContentRegionAvail().x, Font::HEADER_2), Font::HEADER_2); ImVec2(ImGui::GetContentRegionAvail().x, Font::HEADER_2), Font::HEADER_2);
ImGui::SetItemTooltip("%s", caloriesString.c_str());
ImGui::PopStyleColor(); ImGui::PopStyleColor();
if (ImGui::BeginItemTooltip())
{
ImGui::TextUnformatted(caloriesTooltipStart.c_str());
ImGui::SameLine(ZERO_FLOAT, ZERO_FLOAT);
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(imgui::to_imvec4(color::GRAY)));
ImGui::TextUnformatted(caloriesTooltipEffective.c_str());
ImGui::PopStyleColor();
ImGui::SameLine(ZERO_FLOAT, ZERO_FLOAT);
ImGui::TextUnformatted(" kcal");
ImGui::EndTooltip();
}
auto digestionProgress = character.isDigesting auto digestionProgress = character.isDigesting
? (float)character.digestionTimer / character.data.root()->digestionTimerMax ? (float)character.digestionTimer / character.data.root()->digestionTimerMax
@@ -171,7 +183,7 @@ namespace game::state::play::menu
ImGui::PopFont(); ImGui::PopFont();
}; };
ImGui::PushFont(ImGui::GetFont(), resource::Font::HEADER_1); ImGui::PushFont(ImGui::GetFont(), resource::Font::HUGE);
ImGui::SeparatorText(character.data.root()->name.c_str()); ImGui::SeparatorText(character.data.root()->name.c_str());
ImGui::PopFont(); ImGui::PopFont();
+6 -3
View File
@@ -5,6 +5,7 @@
#include "../../util/imgui/style.hpp" #include "../../util/imgui/style.hpp"
#include "../../util/imgui/widget.hpp" #include "../../util/imgui/widget.hpp"
#include "../../util/measurement.hpp" #include "../../util/measurement.hpp"
#include "../../util/string.hpp"
#include "../../util/vector.hpp" #include "../../util/vector.hpp"
using namespace game::util; using namespace game::util;
@@ -41,7 +42,7 @@ namespace game::state::select
auto* saveRoot = save.root(); auto* saveRoot = save.root();
auto isSaveValid = saveRoot && saveRoot->type == resource::xml::Schema::Element::SAVE; auto isSaveValid = saveRoot && saveRoot->type == resource::xml::Schema::Element::SAVE;
auto* savedCharacter = isSaveValid ? save.child_get(*saveRoot, resource::xml::Schema::Element::CHARACTER) : nullptr; auto* savedCharacter = isSaveValid ? save.child_get(*saveRoot, resource::xml::Schema::Element::CHARACTER) : nullptr;
auto weight = savedCharacter ? (double)savedCharacter->weightKilograms : (double)character->weight; auto weight = savedCharacter ? (double)savedCharacter->weightKilograms : (double)character->weightKilograms;
ImGui::PushFont(ImGui::GetFont(), Font::HEADER_3); ImGui::PushFont(ImGui::GetFont(), Font::HEADER_3);
@@ -74,8 +75,10 @@ namespace game::state::select
ImGui::PushFont(ImGui::GetFont(), Font::HEADER_2); ImGui::PushFont(ImGui::GetFont(), Font::HEADER_2);
ImGui::Text("Weight: %0.2f %s", system == IMPERIAL ? weight * KG_TO_LB : weight, auto weightDisplay = weight_display_get(weight, system);
system == IMPERIAL ? "lbs" : "kg"); auto weightString =
string::format_commas(weightDisplay.value, WEIGHT_DISPLAY_DECIMAL_DIGITS) + " " + weightDisplay.unit;
ImGui::Text("Weight: %s", weightString.c_str());
auto stages = resources.characterPreviews[characterIndex].get_all(resource::xml::Schema::Element::STAGE); auto stages = resources.characterPreviews[characterIndex].get_all(resource::xml::Schema::Element::STAGE);
ImGui::Text("Stages: %i", (int)stages.size() + 1); ImGui::Text("Stages: %i", (int)stages.size() + 1);
+23
View File
@@ -9,4 +9,27 @@ namespace game::util::measurement
}; };
constexpr auto KG_TO_LB = 2.20462; constexpr auto KG_TO_LB = 2.20462;
constexpr auto KG_TO_G = 1000.0;
constexpr auto LB_TO_OZ = 16.0;
constexpr auto SMALL_WEIGHT_UNIT_THRESHOLD = 1.0;
constexpr auto WEIGHT_DISPLAY_DECIMAL_DIGITS = 2;
struct WeightDisplay
{
double value{};
const char* unit{};
};
inline WeightDisplay weight_display_get(double kilograms, System system)
{
if (system == IMPERIAL)
{
auto pounds = kilograms * KG_TO_LB;
if (pounds < SMALL_WEIGHT_UNIT_THRESHOLD) return {pounds * LB_TO_OZ, "oz"};
return {pounds, "lbs"};
}
if (kilograms < SMALL_WEIGHT_UNIT_THRESHOLD) return {kilograms * KG_TO_G, "g"};
return {kilograms, "kg"};
}
} }