snivy
This commit is contained in:
+3
-1
@@ -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.
|
||||
### Summon
|
||||
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
|
||||
The sound that will play when an item is returned.
|
||||
### Sound
|
||||
@@ -464,7 +466,7 @@ Outside of resources, Shweet's Sim also has a few files it writes outside of the
|
||||
## settings.xml
|
||||
Stores general game settings and configuration; beyond invididual characters.
|
||||
### MeasurementSystem ("Imperial", "Metric")
|
||||
Determines measurement system (kg/lb).
|
||||
Determines measurement system (kg/g or lb/oz).
|
||||
### Volume (int, percent)
|
||||
Master volume.
|
||||
### 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.
+11494
-11448
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.
@@ -63,6 +63,10 @@
|
||||
<Sound Path="kiss5.ogg" />
|
||||
<Particle Type="Circle" />
|
||||
</InteractArea>
|
||||
<InteractArea Type="Turn Around" GlyphFromIconFont="5">
|
||||
<Particle Type="Circle" />
|
||||
<Sound Path="turn.ogg" />
|
||||
</InteractArea>
|
||||
</InteractAreaTypes>
|
||||
<InteractAreas>
|
||||
<InteractArea Type="Rub" Null="Head" DialoguePool="HeadRub" DialoguePoolFull="HeadRubFull" />
|
||||
@@ -73,5 +77,7 @@
|
||||
<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="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>
|
||||
</Character>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</RootAnimation>
|
||||
<LayerAnimations>
|
||||
<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>
|
||||
</LayerAnimations>
|
||||
<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"/>
|
||||
</NullAnimation>
|
||||
<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>
|
||||
</NullAnimations>
|
||||
<Triggers/>
|
||||
@@ -39,7 +39,7 @@
|
||||
<Content>
|
||||
<Spritesheets>
|
||||
<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>
|
||||
</Spritesheets>
|
||||
<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"/>
|
||||
</NullAnimation>
|
||||
<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>
|
||||
</NullAnimations>
|
||||
<Triggers/>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 6.9 KiB |
+183607
-177427
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 |
@@ -13,6 +13,9 @@
|
||||
<Sound Path="summon.ogg" />
|
||||
<Particle Type="Puff" />
|
||||
</Summon>
|
||||
<NewItem>
|
||||
<Sound Path="newItem.ogg" />
|
||||
</NewItem>
|
||||
<Return>
|
||||
<Sound Path="return.ogg" />
|
||||
<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 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. It also is the biggest calorie nuke ever. Can Snivy eat it!? 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. You've earned it...if Snivy can eat it!" Category="Food" Flavor="Mocha" Rarity="Special" Calories="2500.0" DigestionBonus="0.0125" />
|
||||
<Item Name="Cheri Berry" Texture="item_027_cheri_berry.png" Description="A spherical red berry that cures paralysis ...oh, and it also excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Uncommon" Calories="25.0" DigestionBonus="0.000833" />
|
||||
<Item Name="Tamato Berry" Texture="item_028_tamato_berry.png" Description="A spiny crimson berry that lowers speed and raises friendship. ...oh, and it also greatly excites one's stomach." Category="Food" Flavor="Spicy" Rarity="Rare" Calories="50.0" DigestionBonus="0.0041665" />
|
||||
<Item Name="Touga Berry" Texture="item_029_touga_berry.png" Description="An obscure, searing-red berry from faraway lands. 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="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="Poké Puff (Supreme Honor)" Texture="item_026_poke_puff_supreme_honor.png" Description="A supreme Poké Puff that tastes like a monumental victory. 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 ...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. ...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. 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.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" />
|
||||
</Items>
|
||||
</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.
@@ -730,6 +730,7 @@ namespace game::resource::xml
|
||||
X(KILL, soundKill) \
|
||||
X(LEVEL_UP, soundLevelUp) \
|
||||
X(LEVEL_UP_READY, soundLevelUpReady) \
|
||||
X(NEW_ITEM, soundNewItem) \
|
||||
X(OPEN, soundOpen) \
|
||||
X(RELEASE, soundRelease) \
|
||||
X(SELECT, soundSelect) \
|
||||
@@ -804,6 +805,7 @@ namespace game::resource::xml
|
||||
root->soundKill = {};
|
||||
root->soundLevelUp = {};
|
||||
root->soundLevelUpReady = {};
|
||||
root->soundNewItem = {};
|
||||
root->soundOpen = {};
|
||||
root->soundRelease = {};
|
||||
root->soundSelect = {};
|
||||
@@ -873,6 +875,8 @@ namespace game::resource::xml
|
||||
sound_entry_add(*element, root->soundLevelUp);
|
||||
for (auto* element : schema.children_get(*sounds, Schema::Element::LEVEL_UP_READY))
|
||||
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))
|
||||
sound_entry_add(*element, root->soundOpen);
|
||||
for (auto* element : schema.children_get(*sounds, Schema::Element::RELEASE))
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
X(LowCapacity, LOW_CAPACITY) \
|
||||
X(Menu, MENU) \
|
||||
X(New, NEW) \
|
||||
X(NewItem, NEW_ITEM) \
|
||||
X(Null, NULL_) \
|
||||
X(NullAnimation, NULL_ANIMATION) \
|
||||
X(NullAnimations, NULL_ANIMATIONS) \
|
||||
@@ -468,6 +469,7 @@
|
||||
X(DATA, MEMBER, soundLevelUp, SoundEntryCollection, "Sound Level Up", NONE, \
|
||||
"", "", "", soundLevelUp) \
|
||||
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, "", "", "", \
|
||||
soundOpen) \
|
||||
X(DATA, MEMBER, soundRelease, SoundEntryCollection, "Sound Release", NONE, \
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace game::resource::xml
|
||||
X(InteractSpawnItemCooldownFormat, "TextInteractSpawnItemCooldownFormat", "Next item in %0.2fs") \
|
||||
X(InteractStats, "TextInteractStats", "Stats") \
|
||||
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(InteractTotalCaloriesFormat, "TextInteractTotalCaloriesFormat", "Total Calories Consumed: %0.0f kcal") \
|
||||
X(InteractTotalItemsSpawnedFormat, "TextInteractTotalItemsSpawnedFormat", "Total Items Spawned: %i") \
|
||||
@@ -35,9 +35,9 @@ namespace game::resource::xml
|
||||
X(SettingsFullscreen, "TextSettingsFullscreen", "Fullscreen") \
|
||||
X(SettingsMeasurementSystem, "TextSettingsMeasurementSystem", "Measurement System") \
|
||||
X(SettingsMetric, "TextSettingsMetric", "Metric") \
|
||||
X(SettingsMetricTooltip, "TextSettingsMetricTooltip", "Use kilograms (kg).") \
|
||||
X(SettingsMetricTooltip, "TextSettingsMetricTooltip", "Use kilograms/grams (kg/g).") \
|
||||
X(SettingsImperial, "TextSettingsImperial", "Imperial") \
|
||||
X(SettingsImperialTooltip, "TextSettingsImperialTooltip", "Use pounds (lbs).") \
|
||||
X(SettingsImperialTooltip, "TextSettingsImperialTooltip", "Use pounds/ounces (lbs/oz).") \
|
||||
X(SettingsSound, "TextSettingsSound", "Sound") \
|
||||
X(SettingsVolume, "TextSettingsVolume", "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.") \
|
||||
X(ToastCheatsUnlocked, "TextToastCheatsUnlocked", "Cheats unlocked!") \
|
||||
X(ToastSaving, "TextToastSaving", "Saving...") \
|
||||
X(ToastNewItemFound, "TextToastNewItemFound", "New item found!") \
|
||||
X(ToolsHomeButton, "TextToolsHomeButton", "Home") \
|
||||
X(ToolsHomeTooltip, "TextToolsHomeTooltip", "Reset camera view.\n(Shortcut: Home)") \
|
||||
X(ToolsOpenTooltip, "TextToolsOpenTooltip", "Open Tools") \
|
||||
|
||||
@@ -311,6 +311,12 @@ namespace game::state
|
||||
auto& interactionCursor = autofeed.active_get() ? autofeedCursor : cursor;
|
||||
itemManager.isAutomation = autofeed.active_get();
|
||||
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);
|
||||
for (auto& particle : itemManager.particles)
|
||||
particleManager.spawn(character.data, particle.label, particle.position);
|
||||
|
||||
+55
-18
@@ -15,10 +15,14 @@ namespace game::state::play
|
||||
{
|
||||
constexpr float CURSOR_SPEED = 9.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_SCALE_MIN = 0.5f;
|
||||
constexpr float CURSOR_SPEED_SCALE_MAX = 2.0f;
|
||||
constexpr float CURSOR_BRAKING_ACCELERATION_MULTIPLIER = 2.0f;
|
||||
constexpr float CALORIE_EPSILON = 0.001f;
|
||||
constexpr float CURSOR_TARGET_EPSILON = 0.001f;
|
||||
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}; }
|
||||
@@ -31,21 +35,51 @@ namespace game::state::play
|
||||
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;
|
||||
|
||||
auto delta = target - cursor.position;
|
||||
auto distance = glm::length(delta);
|
||||
if (!std::isfinite(distance)) return false;
|
||||
if (distance <= speed || distance <= 0.001f)
|
||||
if (distance <= CURSOR_TARGET_EPSILON)
|
||||
{
|
||||
cursor.position = target;
|
||||
velocity = {};
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -224,13 +258,14 @@ namespace game::state::play
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void state_reset(Entity& cursor, bool& isItemMouseHeld, bool& isDigestMouseHeld, int& targetItemIndex,
|
||||
int& digestClickCooldown)
|
||||
void state_reset(Entity& cursor, glm::vec2& cursorVelocity, bool& isItemMouseHeld, bool& isDigestMouseHeld,
|
||||
int& targetItemIndex, int& digestClickCooldown)
|
||||
{
|
||||
isItemMouseHeld = false;
|
||||
isDigestMouseHeld = false;
|
||||
targetItemIndex = -1;
|
||||
digestClickCooldown = 0;
|
||||
cursorVelocity = {};
|
||||
if (!is_finite(cursor.position)) cursor.position = {};
|
||||
}
|
||||
}
|
||||
@@ -243,13 +278,13 @@ namespace game::state::play
|
||||
|
||||
if (!isEnabled)
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
if (character.isStageUp || character.isJustStageUp || character.isJustStageFinal)
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -257,7 +292,7 @@ namespace game::state::play
|
||||
|
||||
if (!is_food(character, itemManager))
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -271,6 +306,8 @@ namespace game::state::play
|
||||
auto speedScale = cursor_speed_scale_get(character);
|
||||
auto cursorSpeed = 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 isEatTarget = eat_rect_get(character, eatRect);
|
||||
|
||||
@@ -281,7 +318,7 @@ namespace game::state::play
|
||||
{
|
||||
isActive = false;
|
||||
cursor.isVisible = false;
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
auto& schemaItem = schema.items[heldItem.schemaID];
|
||||
@@ -290,7 +327,7 @@ namespace game::state::play
|
||||
{
|
||||
isActive = true;
|
||||
cursor.isVisible = true;
|
||||
move_toward(cursor, rect_center(eatRect), cursorSpeed);
|
||||
move_toward(cursor, cursorVelocity, rect_center(eatRect), cursorSpeed, cursorAcceleration);
|
||||
|
||||
itemInput.isMouseLeftDown = true;
|
||||
itemManager.inputOverride = itemInput;
|
||||
@@ -319,13 +356,13 @@ namespace game::state::play
|
||||
auto rect = item.rect();
|
||||
if (!is_finite(rect))
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
isActive = 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);
|
||||
|
||||
@@ -341,7 +378,7 @@ namespace game::state::play
|
||||
auto isWorldFood = is_world_food(character, itemManager);
|
||||
if (character.calories <= CALORIE_EPSILON && !isWorldFood)
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -350,20 +387,20 @@ namespace game::state::play
|
||||
auto* interactArea = digestion_area_get(character);
|
||||
if (!interactArea)
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
|
||||
auto rect = character.null_frame_rect(character.data.null_id_get(interactArea->null));
|
||||
if (!is_finite(rect))
|
||||
{
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
return;
|
||||
}
|
||||
auto radius = glm::max(1.0f, glm::min(rect.z, rect.w) * 0.25f);
|
||||
digestAngle += 0.08f;
|
||||
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;
|
||||
cursor.isVisible = true;
|
||||
|
||||
@@ -394,7 +431,7 @@ namespace game::state::play
|
||||
return;
|
||||
}
|
||||
|
||||
state_reset(cursor, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
state_reset(cursor, cursorVelocity, isItemMouseHeld, isDigestMouseHeld, targetItemIndex, digestClickCooldown);
|
||||
}
|
||||
|
||||
void Autofeed::toggle() { isEnabled = !isEnabled; }
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace game::state::play
|
||||
int targetItemIndex{-1};
|
||||
int digestClickCooldown{};
|
||||
float digestAngle{};
|
||||
glm::vec2 cursorVelocity{};
|
||||
bool isEnabled{};
|
||||
bool isActive{};
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@ namespace game::state::play
|
||||
if (isItemHovered != isItemHoveredPrevious && !isItemHovered) isJustItemHoveredStopped = true;
|
||||
if (spawnDelayTicks > 0) spawnDelayTicks--;
|
||||
if (discoveredItemIDs.size() != schema.items.size()) discoveredItemIDs.resize(schema.items.size());
|
||||
newItemFoundCount = 0;
|
||||
|
||||
for (auto& id : queuedItemIDs)
|
||||
{
|
||||
@@ -237,7 +238,11 @@ namespace game::state::play
|
||||
auto& anm2 = itemSchema.anm2s.at(id);
|
||||
items.emplace_back(anm2, position, id);
|
||||
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);
|
||||
}
|
||||
queuedItemIDs.clear();
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace game::state::play
|
||||
|
||||
std::vector<int> queuedItemIDs{};
|
||||
std::vector<bool> discoveredItemIDs{};
|
||||
int newItemFoundCount{};
|
||||
int spawnDelayTicks{};
|
||||
struct Particle
|
||||
{
|
||||
|
||||
@@ -54,15 +54,15 @@ namespace game::state::play::menu
|
||||
{
|
||||
auto* settings = resources.settings.root();
|
||||
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 stageMax = character.stage_max_get();
|
||||
auto stageCount = character.stage_count_get();
|
||||
auto stageWeight = character.stage_threshold_get(stage, system);
|
||||
auto stageNextWeight = character.stage_threshold_next_get(system);
|
||||
auto unitString = (system == measurement::IMPERIAL ? "lbs" : "kg");
|
||||
auto stageWeight = measurement::weight_display_get(character.stage_threshold_get(stage), system);
|
||||
auto stageNextWeight = measurement::weight_display_get(character.stage_threshold_next_get(), system);
|
||||
|
||||
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),
|
||||
Font::HEADER_2);
|
||||
ImGui::SetItemTooltip("%s", weightString.c_str());
|
||||
@@ -81,9 +81,9 @@ namespace game::state::play::menu
|
||||
ImGui::TextUnformatted(strings.get(Strings::InfoMaxedOut).c_str());
|
||||
else
|
||||
{
|
||||
ImGui::Text(strings.get(Strings::InfoStageStartFormat).c_str(), stageWeight, unitString);
|
||||
ImGui::Text(strings.get(Strings::InfoStageCurrentFormat).c_str(), weight, unitString);
|
||||
ImGui::Text(strings.get(Strings::InfoStageNextFormat).c_str(), stageNextWeight, unitString);
|
||||
ImGui::Text(strings.get(Strings::InfoStageStartFormat).c_str(), stageWeight.value, stageWeight.unit);
|
||||
ImGui::Text(strings.get(Strings::InfoStageCurrentFormat).c_str(), weight.value, weight.unit);
|
||||
ImGui::Text(strings.get(Strings::InfoStageNextFormat).c_str(), stageNextWeight.value, stageNextWeight.unit);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndTooltip();
|
||||
@@ -100,14 +100,26 @@ namespace game::state::play::menu
|
||||
|
||||
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 capacityMax = character.max_capacity();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, caloriesColor);
|
||||
auto caloriesString = std::format("{:.0f} kcal / {:.0f} kcal", calories,
|
||||
character.is_over_capacity() ? character.max_capacity() : character.capacity);
|
||||
auto caloriesString = std::format("{:.0f} / {:.0f} kcal", calories, capacity);
|
||||
auto caloriesTooltipStart = std::format("{:.0f} / {:.0f} ", calories, capacity);
|
||||
auto caloriesTooltipEffective = std::format("({:.0f})", capacityMax);
|
||||
imgui::text_unformatted_fit_draw(caloriesString.c_str(),
|
||||
ImVec2(ImGui::GetContentRegionAvail().x, Font::HEADER_2), Font::HEADER_2);
|
||||
ImGui::SetItemTooltip("%s", caloriesString.c_str());
|
||||
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
|
||||
? (float)character.digestionTimer / character.data.root()->digestionTimerMax
|
||||
@@ -171,7 +183,7 @@ namespace game::state::play::menu
|
||||
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::PopFont();
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../../util/imgui/style.hpp"
|
||||
#include "../../util/imgui/widget.hpp"
|
||||
#include "../../util/measurement.hpp"
|
||||
#include "../../util/string.hpp"
|
||||
#include "../../util/vector.hpp"
|
||||
|
||||
using namespace game::util;
|
||||
@@ -41,7 +42,7 @@ namespace game::state::select
|
||||
auto* saveRoot = save.root();
|
||||
auto isSaveValid = saveRoot && saveRoot->type == resource::xml::Schema::Element::SAVE;
|
||||
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);
|
||||
|
||||
@@ -74,8 +75,10 @@ namespace game::state::select
|
||||
|
||||
ImGui::PushFont(ImGui::GetFont(), Font::HEADER_2);
|
||||
|
||||
ImGui::Text("Weight: %0.2f %s", system == IMPERIAL ? weight * KG_TO_LB : weight,
|
||||
system == IMPERIAL ? "lbs" : "kg");
|
||||
auto weightDisplay = weight_display_get(weight, system);
|
||||
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);
|
||||
ImGui::Text("Stages: %i", (int)stages.size() + 1);
|
||||
|
||||
|
||||
@@ -9,4 +9,27 @@ namespace game::util::measurement
|
||||
};
|
||||
|
||||
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"};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user