feat: add PotionProfile and applyModifier

This commit is contained in:
dualfroz committed 2026-09-06 19:02:33 +02:00
1 parent 7ce131c342
commit d4d5d7b254
1 file changed
+154
+154
View File
@@ -0,0 +1,154 @@
#include "vf/Brewing.h"
#include <algorithm>
#include <cmath>
namespace vf {
namespace {
using Ingredient = BrewRecipe::Ingredient;
struct PotionProfile {
EffectKind kind = EffectKind::Count;
int baseTicks = 0;
int extendedTicks = 0; // zero: redstone does nothing
int upgradedTicks = 0; // zero: glowstone does nothing
int upgradedLevel = 1;
};
const PotionProfile& profileFor(PotionKind kind) {
static const PotionProfile profiles[] = {
{EffectKind::Count, 0, 0, 0, 1}, // Water
{EffectKind::Count, 0, 0, 0, 1}, // Mundane
{EffectKind::Count, 0, 0, 0, 1}, // Thick
{EffectKind::Count, 0, 0, 0, 1}, // Awkward
{EffectKind::InstantHealth, 1, 0, 1, 2}, // Healing
{EffectKind::InstantDamage, 1, 0, 1, 2}, // Harming
{EffectKind::Regeneration, 900, 1800, 440, 2}, // Regeneration
{EffectKind::Poison, 900, 1800, 432, 2}, // Poison
{EffectKind::Speed, 3600, 9600, 1800, 2}, // Swiftness
{EffectKind::Slowness, 1800, 4800, 400, 4}, // Slowness
{EffectKind::JumpBoost, 3600, 9600, 1800, 2}, // Leaping
{EffectKind::Strength, 3600, 9600, 1800, 2}, // Strength
{EffectKind::Weakness, 1800, 4800, 0, 1}, // Weakness
{EffectKind::FireResistance, 3600, 9600, 0, 1}, // FireResistance
{EffectKind::WaterBreathing, 3600, 9600, 0, 1}, // WaterBreathing
{EffectKind::NightVision, 3600, 9600, 0, 1}, // NightVision
{EffectKind::Invisibility, 3600, 9600, 0, 1}, // Invisibility
};
static_assert(sizeof(profiles) / sizeof(profiles[0]) ==
static_cast<std::size_t>(PotionKind::Count),
"potion profile table must cover every PotionKind");
return profiles[static_cast<std::size_t>(kind)];
}
bool applyModifier(PotionItem& potion, Ingredient ingredient) {
const PotionProfile& profile = profileFor(potion.kind);
switch (ingredient) {
case Ingredient::Glowstone:
if (profile.upgradedTicks == 0 || potion.upgraded) return false;
potion.upgraded = true;
potion.extended = false;
return true;
case Ingredient::Redstone:
if (profile.extendedTicks == 0 || potion.extended) return false;
potion.extended = true;
potion.upgraded = false;
return true;
case Ingredient::Gunpowder:
if (potion.form == PotionItem::Form::Splash) return false;
potion.form = PotionItem::Form::Splash;
return true;
default:
return false;
}
}
} // namespace
const std::vector<BrewRecipe>& brewRecipes() {
static const std::vector<BrewRecipe> recipes = {
{PotionKind::Water, Ingredient::NetherWart, PotionKind::Awkward},
{PotionKind::Water, Ingredient::Glowstone, PotionKind::Thick},
{PotionKind::Water, Ingredient::Redstone, PotionKind::Mundane},
{PotionKind::Water, Ingredient::FermentedSpiderEye, PotionKind::Weakness},
{PotionKind::Awkward, Ingredient::Sugar, PotionKind::Swiftness},
{PotionKind::Awkward, Ingredient::GlisteringMelon, PotionKind::Healing},
{PotionKind::Awkward, Ingredient::SpiderEye, PotionKind::Poison},
{PotionKind::Awkward, Ingredient::BlazePowder, PotionKind::Strength},
{PotionKind::Awkward, Ingredient::MagmaCream, PotionKind::FireResistance},
{PotionKind::Awkward, Ingredient::PufferFish, PotionKind::WaterBreathing},
{PotionKind::Awkward, Ingredient::GoldenCarrot, PotionKind::NightVision},
{PotionKind::Awkward, Ingredient::GhastTear, PotionKind::Regeneration},
{PotionKind::Awkward, Ingredient::RabbitFoot, PotionKind::Leaping},
{PotionKind::NightVision, Ingredient::FermentedSpiderEye, PotionKind::Invisibility},
{PotionKind::Healing, Ingredient::FermentedSpiderEye, PotionKind::Harming},
{PotionKind::Poison, Ingredient::FermentedSpiderEye, PotionKind::Harming},
{PotionKind::Swiftness, Ingredient::FermentedSpiderEye, PotionKind::Slowness},
{PotionKind::Leaping, Ingredient::FermentedSpiderEye, PotionKind::Slowness},
{PotionKind::Strength, Ingredient::FermentedSpiderEye, PotionKind::Weakness},
};
return recipes;
}
PotionItem brewResult(const PotionItem& base, Ingredient ingredient, bool& changed) {
PotionItem brewed = base;
changed = false;
if (ingredient == Ingredient::None) return brewed;
for (const BrewRecipe& recipe : brewRecipes()) {
if (recipe.input != base.kind || recipe.ingredient != ingredient) continue;
brewed.kind = recipe.output;
brewed.upgraded = false;
brewed.extended = false;
changed = true;
return brewed;
}
changed = applyModifier(brewed, ingredient);
return brewed;
}
bool setBottle(BrewingStandState& stand, int slot, const PotionItem& potion) {
if (slot < 0 || slot >= brewingBottleSlots) return false;
BrewingSlot& bottle = stand.bottles[static_cast<std::size_t>(slot)];
if (bottle.occupied) return false;
bottle.potion = potion;
bottle.occupied = true;
stand.progressTicks = 0;
return true;
}
PotionItem takeBottle(BrewingStandState& stand, int slot, bool& taken) {
taken = false;
if (slot < 0 || slot >= brewingBottleSlots) return {};
BrewingSlot& bottle = stand.bottles[static_cast<std::size_t>(slot)];
if (!bottle.occupied) return {};
PotionItem removed = bottle.potion;
bottle = BrewingSlot{};
taken = true;
stand.progressTicks = 0;
return removed;
}
bool setIngredient(BrewingStandState& stand, Ingredient ingredient, int count) {
if (ingredient == Ingredient::None || count <= 0) return false;
if (stand.ingredientCount > 0 && stand.ingredient != ingredient) return false;
if (stand.ingredient == ingredient) {
stand.ingredientCount += count;
return true;
}
stand.ingredient = ingredient;
stand.ingredientCount = count;
stand.progressTicks = 0;
return true;
}
bool addFuel(BrewingStandState& stand, int blazePowderCount) {
if (blazePowderCount <= 0) return false;
stand.fuel += blazePowderCount * brewsPerBlazePowder;
return true;
}