Skip to content

Commit b684fd1

Browse files
authored
Adria refill mana as mod
1 parent 844cca4 commit b684fd1

12 files changed

Lines changed: 125 additions & 26 deletions

File tree

CMake/Assets.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ set(devilutionx_assets
158158
lua_internal/get_lua_function_signature.lua
159159
lua/devilutionx/events.lua
160160
lua/inspect.lua
161+
lua/mods/adria_refills_mana/init.lua
161162
lua/mods/clock/init.lua
162163
"lua/mods/Floating Numbers - Damage/init.lua"
163164
"lua/mods/Floating Numbers - XP/init.lua"

Source/engine/demomode.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ struct {
127127
bool autoElixirPickup = false;
128128
bool autoOilPickup = false;
129129
bool autoPickupInTown = false;
130-
bool adriaRefillsMana = false;
131130
bool autoEquipWeapons = false;
132131
bool autoEquipArmor = false;
133132
bool autoEquipHelms = false;
@@ -166,7 +165,7 @@ void ReadSettings(FILE *in, uint8_t version) // NOLINT(readability-identifier-le
166165
DemoSettings.autoElixirPickup = ReadByte(in) != 0;
167166
DemoSettings.autoOilPickup = ReadByte(in) != 0;
168167
DemoSettings.autoPickupInTown = ReadByte(in) != 0;
169-
DemoSettings.adriaRefillsMana = ReadByte(in) != 0;
168+
(void)ReadByte(in); // adriaRefillsMana (removed feature, kept for backward compatibility)
170169
DemoSettings.autoEquipWeapons = ReadByte(in) != 0;
171170
DemoSettings.autoEquipArmor = ReadByte(in) != 0;
172171
DemoSettings.autoEquipHelms = ReadByte(in) != 0;
@@ -195,7 +194,6 @@ void ReadSettings(FILE *in, uint8_t version) // NOLINT(readability-identifier-le
195194
{ _("Auto Elixir Pickup"), DemoSettings.autoGoldPickup },
196195
{ _("Auto Oil Pickup"), DemoSettings.autoOilPickup },
197196
{ _("Auto Pickup in Town"), DemoSettings.autoPickupInTown },
198-
{ _("Adria Refills Mana"), DemoSettings.adriaRefillsMana },
199197
{ _("Auto Equip Weapons"), DemoSettings.autoEquipWeapons },
200198
{ _("Auto Equip Armor"), DemoSettings.autoEquipArmor },
201199
{ _("Auto Equip Helms"), DemoSettings.autoEquipHelms },
@@ -231,7 +229,7 @@ void WriteSettings(FILE *out)
231229
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoElixirPickup));
232230
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoOilPickup));
233231
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoPickupInTown));
234-
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.adriaRefillsMana));
232+
WriteByte(out, 0); // adriaRefillsMana (removed feature, kept for backward compatibility)
235233
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipWeapons));
236234
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipArmor));
237235
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipHelms));
@@ -650,7 +648,6 @@ void OverrideOptions()
650648
options.Gameplay.autoElixirPickup.SetValue(DemoSettings.autoElixirPickup);
651649
options.Gameplay.autoOilPickup.SetValue(DemoSettings.autoOilPickup);
652650
options.Gameplay.autoPickupInTown.SetValue(DemoSettings.autoPickupInTown);
653-
options.Gameplay.adriaRefillsMana.SetValue(DemoSettings.adriaRefillsMana);
654651
options.Gameplay.autoEquipWeapons.SetValue(DemoSettings.autoEquipWeapons);
655652
options.Gameplay.autoEquipArmor.SetValue(DemoSettings.autoEquipArmor);
656653
options.Gameplay.autoEquipHelms.SetValue(DemoSettings.autoEquipHelms);

Source/lua/lua_event.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <string_view>
4+
5+
namespace devilution {
6+
7+
/**
8+
* @brief Triggers a Lua event by name.
9+
* This is a minimal header for code that only needs to trigger events.
10+
*/
11+
void LuaEvent(std::string_view name);
12+
void LuaEvent(std::string_view name, std::string_view arg);
13+
14+
} // namespace devilution

Source/lua/lua_global.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ sol::environment CreateLuaSandbox()
205205

206206
sandbox["require"] = lua["requireGen"](sandbox, CurrentLuaState->commonPackages, LuaLoadScriptFromAssets);
207207

208+
// Expose commonly used enums globally for mods
209+
sandbox["SfxID"] = lua["SfxID"];
210+
208211
return sandbox;
209212
}
210213

@@ -347,6 +350,21 @@ void LuaEvent(std::string_view name, const Player *player, uint32_t arg1)
347350
CallLuaEvent(name, player, arg1);
348351
}
349352

353+
void LuaEvent(std::string_view name, std::string_view arg)
354+
{
355+
if (!CurrentLuaState.has_value()) {
356+
return;
357+
}
358+
359+
const auto trigger = CurrentLuaState->events.traverse_get<std::optional<sol::object>>(name, "trigger");
360+
if (!trigger.has_value() || !trigger->is<sol::protected_function>()) {
361+
LogError("events.{}.trigger is not a function", name);
362+
return;
363+
}
364+
const sol::protected_function fn = trigger->as<sol::protected_function>();
365+
SafeCallResult(fn(arg), /*optional=*/true);
366+
}
367+
350368
sol::state &GetLuaState()
351369
{
352370
return CurrentLuaState->sol;

Source/lua/lua_global.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void LuaInitialize();
1515
void LuaReloadActiveMods();
1616
void LuaShutdown();
1717
void LuaEvent(std::string_view name);
18+
void LuaEvent(std::string_view name, std::string_view arg);
1819
void LuaEvent(std::string_view name, const Player *player, int arg1, int arg2);
1920
void LuaEvent(std::string_view name, const Monster *monster, int arg1, int arg2);
2021
void LuaEvent(std::string_view name, const Player *player, uint32_t arg1);

Source/lua/modules/audio.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "lua/modules/audio.hpp"
22

3+
#include <magic_enum/magic_enum.hpp>
34
#include <sol/sol.hpp>
45

56
#include "effects.h"
67
#include "lua/metadoc.hpp"
8+
#include "sound_effect_enums.h"
79

810
namespace devilution {
911

@@ -14,17 +16,36 @@ bool IsValidSfx(int16_t psfx)
1416
return psfx >= 0 && psfx <= static_cast<int16_t>(SfxID::LAST);
1517
}
1618

19+
void RegisterSfxIDEnum(sol::state_view &lua)
20+
{
21+
constexpr auto enumValues = magic_enum::enum_values<SfxID>();
22+
sol::table enumTable = lua.create_table();
23+
for (const auto enumValue : enumValues) {
24+
const std::string_view name = magic_enum::enum_name(enumValue);
25+
if (!name.empty() && name != "LAST" && name != "None") {
26+
enumTable[name] = static_cast<int16_t>(enumValue);
27+
}
28+
}
29+
// Add LAST and None explicitly
30+
enumTable["LAST"] = static_cast<int16_t>(SfxID::LAST);
31+
enumTable["None"] = static_cast<int16_t>(SfxID::None);
32+
lua["SfxID"] = enumTable;
33+
}
34+
1735
} // namespace
1836

1937
sol::table LuaAudioModule(sol::state_view &lua)
2038
{
39+
RegisterSfxIDEnum(lua);
2140
sol::table table = lua.create_table();
2241
LuaSetDocFn(table,
2342
"playSfx", "(id: number)",
2443
[](int16_t psfx) { if (IsValidSfx(psfx)) PlaySFX(static_cast<SfxID>(psfx)); });
2544
LuaSetDocFn(table,
2645
"playSfxLoc", "(id: number, x: number, y: number)",
2746
[](int16_t psfx, int x, int y) { if (IsValidSfx(psfx)) PlaySfxLoc(static_cast<SfxID>(psfx), { x, y }); });
47+
// Expose SfxID enum through the module table
48+
table["SfxID"] = lua["SfxID"];
2849
return table;
2950
}
3051

Source/lua/modules/player.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <sol/sol.hpp>
66

7+
#include "effects.h"
8+
#include "engine/backbuffer_state.hpp"
79
#include "engine/point.hpp"
810
#include "engine/random.hpp"
911
#include "inv.h"
@@ -103,6 +105,12 @@ void InitPlayerUserType(sol::state_view &lua)
103105
player._pMana = player._pMaxMana;
104106
player._pManaBase = player._pMaxManaBase;
105107
});
108+
LuaSetDocReadonlyProperty(playerType, "mana", "number",
109+
"Current mana (readonly)",
110+
[](Player &player) { return player._pMana >> 6; });
111+
LuaSetDocReadonlyProperty(playerType, "maxMana", "number",
112+
"Maximum mana (readonly)",
113+
[](Player &player) { return player._pMaxMana >> 6; });
106114
}
107115
} // namespace
108116

Source/options.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ namespace {
7272
void DiscoverMods()
7373
{
7474
// Add mods available by default:
75-
std::unordered_set<std::string> modNames = { "clock", "Floating Numbers - Damage", "Floating Numbers - XP" };
75+
std::unordered_set<std::string> modNames = { "clock", "adria_refills_mana", "Floating Numbers - Damage", "Floating Numbers - XP" };
7676

7777
if (HaveHellfire()) {
7878
modNames.insert("Hellfire");
@@ -852,7 +852,6 @@ GameplayOptions::GameplayOptions()
852852
, autoElixirPickup("Auto Elixir Pickup", OptionEntryFlags::None, N_("Auto Elixir Pickup"), N_("Elixirs are automatically collected when in close proximity to the player."), false)
853853
, autoOilPickup("Auto Oil Pickup", OptionEntryFlags::OnlyHellfire, N_("Auto Oil Pickup"), N_("Oils are automatically collected when in close proximity to the player."), false)
854854
, autoPickupInTown("Auto Pickup in Town", OptionEntryFlags::None, N_("Auto Pickup in Town"), N_("Automatically pickup items in town."), false)
855-
, adriaRefillsMana("Adria Refills Mana", OptionEntryFlags::None, N_("Adria Refills Mana"), N_("Adria will refill your mana when you visit her shop."), false)
856855
, autoEquipWeapons("Auto Equip Weapons", OptionEntryFlags::None, N_("Auto Equip Weapons"), N_("Weapons will be automatically equipped on pickup or purchase if enabled."), true)
857856
, autoEquipArmor("Auto Equip Armor", OptionEntryFlags::None, N_("Auto Equip Armor"), N_("Armor will be automatically equipped on pickup or purchase if enabled."), false)
858857
, autoEquipHelms("Auto Equip Helms", OptionEntryFlags::None, N_("Auto Equip Helms"), N_("Helms will be automatically equipped on pickup or purchase if enabled."), false)
@@ -913,7 +912,6 @@ std::vector<OptionEntryBase *> GameplayOptions::GetEntries()
913912
&numFullRejuPotionPickup,
914913
&autoPickupInTown,
915914
&disableCripplingShrines,
916-
&adriaRefillsMana,
917915
&grabInput,
918916
&pauseOnFocusLoss,
919917
&skipLoadingScreenThresholdMs,

Source/options.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,6 @@ struct GameplayOptions : OptionCategoryBase {
599599
OptionEntryBoolean autoOilPickup;
600600
/** @brief Enable or Disable auto-pickup in town */
601601
OptionEntryBoolean autoPickupInTown;
602-
/** @brief Recover mana when talking to Adria. */
603-
OptionEntryBoolean adriaRefillsMana;
604602
/** @brief Automatically attempt to equip weapon-type items when picking them up. */
605603
OptionEntryBoolean autoEquipWeapons;
606604
/** @brief Automatically attempt to equip armor-type items when picking them up. */

Source/stores.cpp

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "engine/render/text_render.hpp"
2222
#include "engine/trn.hpp"
2323
#include "game_mode.hpp"
24+
#include "lua/lua_event.hpp"
2425
#include "minitext.h"
2526
#include "multi.h"
2627
#include "options.h"
@@ -653,24 +654,8 @@ void StartSmithRepair()
653654
AddItemListBackButton();
654655
}
655656

656-
void FillManaPlayer()
657-
{
658-
if (!*GetOptions().Gameplay.adriaRefillsMana)
659-
return;
660-
661-
Player &myPlayer = *MyPlayer;
662-
663-
if (myPlayer._pMana != myPlayer._pMaxMana) {
664-
PlaySFX(SfxID::CastHealing);
665-
}
666-
myPlayer._pMana = myPlayer._pMaxMana;
667-
myPlayer._pManaBase = myPlayer._pMaxManaBase;
668-
RedrawComponent(PanelDrawComponent::Mana);
669-
}
670-
671657
void StartWitch()
672658
{
673-
FillManaPlayer();
674659
IsTextFullSize = false;
675660
HasScrollbar = false;
676661
AddSText(0, 2, _("Witch's shack"), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false);
@@ -2215,6 +2200,37 @@ void StartStore(TalkID s)
22152200
CloseGoldDrop();
22162201
ClearSText(0, NumStoreLines);
22172202
ReleaseStoreBtn();
2203+
2204+
// Fire StoreOpened Lua event for main store entries
2205+
switch (s) {
2206+
case TalkID::Smith:
2207+
LuaEvent("StoreOpened", "griswold");
2208+
break;
2209+
case TalkID::Witch:
2210+
LuaEvent("StoreOpened", "adria");
2211+
break;
2212+
case TalkID::Boy:
2213+
LuaEvent("StoreOpened", "wirt");
2214+
break;
2215+
case TalkID::Healer:
2216+
LuaEvent("StoreOpened", "pepin");
2217+
break;
2218+
case TalkID::Storyteller:
2219+
LuaEvent("StoreOpened", "cain");
2220+
break;
2221+
case TalkID::Tavern:
2222+
LuaEvent("StoreOpened", "ogden");
2223+
break;
2224+
case TalkID::Drunk:
2225+
LuaEvent("StoreOpened", "farnham");
2226+
break;
2227+
case TalkID::Barmaid:
2228+
LuaEvent("StoreOpened", "gillian");
2229+
break;
2230+
default:
2231+
break;
2232+
}
2233+
22182234
switch (s) {
22192235
case TalkID::Smith:
22202236
StartSmith();

0 commit comments

Comments
 (0)