From 15305d9680594041ba36d7e56477f035bc26af44 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Sat, 24 Aug 2024 15:35:28 +0200 Subject: [PATCH] feat: 2 new enemies and a few fixes --- Dockerfile | 9 ++- assets/scripts/definitions/api.lua | 8 +++ assets/scripts/enemies/clean_bot.lua | 2 +- assets/scripts/enemies/cyber_spider.lua | 6 +- assets/scripts/enemies/laser_drone.lua | 51 ++++++++++++++++ assets/scripts/enemies/plasma_golem.lua | 28 +++++++++ assets/scripts/enemies/rust_mite.lua | 2 +- assets/scripts/equipment/_debug.lua | 22 +++++++ assets/scripts/events/act_0/enemies.lua | 47 ++++++++++++++- assets/scripts/events/act_0/other.lua | 44 ++++++++++++-- assets/scripts/events/act_0/start.lua | 14 +++-- assets/scripts/story_teller/act_0.lua | 19 +++--- docs/GAME_CONTENT_DOCS.md | 23 ++++--- docs/LUA_API_DOCS.md | 24 ++++++++ game/enemy.go | 1 + game/lua.go | 17 +++++- game/saved_state.go | 1 + game/session.go | 79 +++++++++++++++---------- 18 files changed, 326 insertions(+), 71 deletions(-) create mode 100644 assets/scripts/enemies/laser_drone.lua create mode 100644 assets/scripts/enemies/plasma_golem.lua create mode 100644 assets/scripts/equipment/_debug.lua diff --git a/Dockerfile b/Dockerfile index 22f721a..2c066d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,11 +8,10 @@ COPY . . RUN apt-get update RUN apt-get install -y libasound2-dev -RUN go build -tags no_audio -o /app/end_of_eden ./cmd/game -RUN go build -tags no_audio -o /app/fuzzy_tester ./cmd/internal/fuzzy_tester - -# Disable SSH for now -# RUN go build -tags no_audio -o /app/end_of_eden_ssh ./cmd/game_ssh +RUN CGO_ENABLED=0 go build -tags no_audio -o /app/end_of_eden ./cmd/game +RUN CGO_ENABLED=0 go build -tags no_audio -o /app/end_of_eden_ssh ./cmd/game_ssh +RUN CGO_ENABLED=0 go build -tags no_audio -o /app/tester ./cmd/internal/tester +RUN CGO_ENABLED=0 go build -tags no_audio -o /app/fuzzy_tester ./cmd/internal/fuzzy_tester # Release image FROM debian:bullseye diff --git a/assets/scripts/definitions/api.lua b/assets/scripts/definitions/api.lua index ed96628..093ef35 100644 --- a/assets/scripts/definitions/api.lua +++ b/assets/scripts/definitions/api.lua @@ -111,6 +111,10 @@ function play_music(sound) end -- Game State -- ##################################### +--- get the number of action points per round. +---@return number +function get_action_points_per_round() end + --- Gets the ids of all the encountered events in the order of occurrence. ---@return string[] function get_event_history() end @@ -142,6 +146,10 @@ function had_events(event_ids) end ---@return boolean function had_events_any(eventIds) end +--- set the number of action points per round. +---@param points number +function set_action_points_per_round(points) end + --- Set event by id. ---@param event_id type_id function set_event(event_id) end diff --git a/assets/scripts/enemies/clean_bot.lua b/assets/scripts/enemies/clean_bot.lua index 7b0b61c..f2f6356 100644 --- a/assets/scripts/enemies/clean_bot.lua +++ b/assets/scripts/enemies/clean_bot.lua @@ -7,7 +7,7 @@ register_enemy("CLEAN_BOT", { color = "#32a891", initial_hp = 13, max_hp = 13, - gold = 15, + gold = 30, intend = function(ctx) local self = get_actor(ctx.guid) if self.hp <= 4 then diff --git a/assets/scripts/enemies/cyber_spider.lua b/assets/scripts/enemies/cyber_spider.lua index d478cb5..181536b 100644 --- a/assets/scripts/enemies/cyber_spider.lua +++ b/assets/scripts/enemies/cyber_spider.lua @@ -1,14 +1,14 @@ register_enemy("CYBER_SPIDER", { name = "CYBER Spider", description = "It waits for its prey to come closer", - look = [[/\o^o/\]], + look = [[/\o^o/\]], color = "#ff4d6d", initial_hp = 8, max_hp = 8, - gold = 15, + gold = 40, intend = function(ctx) if ctx.round > 0 and ctx.round % 3 == 0 then - return "Deal " .. highlight(5) .. " damage" + return "Deal " .. highlight(5) .. " damage" end return "Wait..." diff --git a/assets/scripts/enemies/laser_drone.lua b/assets/scripts/enemies/laser_drone.lua new file mode 100644 index 0000000..43ce606 --- /dev/null +++ b/assets/scripts/enemies/laser_drone.lua @@ -0,0 +1,51 @@ +register_enemy("LASER_DRONE", { + name = "Laser Drone", + description = "A drone equipped with a powerful laser cannon.", + look = [[|o|]], + color = "#ff0000", + initial_hp = 7, + max_hp = 7, + gold = 40, + intend = function(ctx) + if ctx.round % 3 == 0 then + return "Charge up for a powerful laser attack" + elseif ctx.round % 3 == 1 then + return "Deal " .. highlight(2) .. " damage" + else + return "Deal " .. highlight(5) .. " damage" + end + end, + callbacks = { + on_turn = function(ctx) + if ctx.round % 3 == 0 then + give_status_effect("CHARGING", ctx.guid) + elseif ctx.round % 3 == 1 then + deal_damage(ctx.guid, PLAYER_ID, 2) + else + deal_damage(ctx.guid, PLAYER_ID, 5) + end + return nil + end + } +}) + +register_status_effect("CHARGING", { + name = "Charging", + description = "The drone is charging up for a powerful attack.", + look = "CHRG", + foreground = "#ff0000", + state = function(ctx) + return "Charging up for a powerful attack." + end, + can_stack = false, + decay = DECAY_NONE, + rounds = 1, + callbacks = { + on_damage_calc = function(ctx) + if ctx.source == ctx.owner then + return ctx.damage + end + return nil + end + } +}) diff --git a/assets/scripts/enemies/plasma_golem.lua b/assets/scripts/enemies/plasma_golem.lua new file mode 100644 index 0000000..b889b85 --- /dev/null +++ b/assets/scripts/enemies/plasma_golem.lua @@ -0,0 +1,28 @@ +register_enemy("PLASMA_GOLEM", { + name = "Plasma Golem", + description = "A golem made of pure plasma energy.", + look = [[ + /\ + / \ +/_xx_\]], + color = "#ff69b4", + initial_hp = 12, + max_hp = 12, + gold = 80, + intend = function(ctx) + if ctx.round % 2 == 0 then + return "Charge up for a powerful plasma attack" + else + return "Deal " .. highlight(8) .. " damage" + end + end, + callbacks = { + on_turn = function(ctx) + if ctx.round % 2 == 0 then + else + deal_damage(ctx.guid, PLAYER_ID, 8) + end + return nil + end + } +}) diff --git a/assets/scripts/enemies/rust_mite.lua b/assets/scripts/enemies/rust_mite.lua index 0adc1ab..f205b05 100644 --- a/assets/scripts/enemies/rust_mite.lua +++ b/assets/scripts/enemies/rust_mite.lua @@ -5,7 +5,7 @@ register_enemy("RUST_MITE", { color = "#e6e65a", initial_hp = 12, max_hp = 12, - gold = 10, + gold = 35, intend = function(ctx) if ctx.round % 4 == 0 then return "Load battery" diff --git a/assets/scripts/equipment/_debug.lua b/assets/scripts/equipment/_debug.lua new file mode 100644 index 0000000..a7bfe4e --- /dev/null +++ b/assets/scripts/equipment/_debug.lua @@ -0,0 +1,22 @@ +register_card("DEBUG_INSTA_KILL", { + name = l("cards.DEBUG_INSTA_KILL.name", "DEBUG Insta Kill"), + description = l("cards.DEBUG_INSTA_KILL.description", "..."), + state = function(ctx) + return "Kill" + end, + tags = {}, + max_level = 1, + color = COLOR_GRAY, + need_target = true, + point_cost = 0, + price = -1, + callbacks = { + on_cast = function(ctx) + deal_damage_card(ctx.caster, ctx.guid, ctx.target, 10000) + return nil + end + }, + test = function() + return assert_cast_damage("DEBUG_INSTA_KILL", 10000) + end +}) diff --git a/assets/scripts/events/act_0/enemies.lua b/assets/scripts/events/act_0/enemies.lua index 8db430f..cc519db 100644 --- a/assets/scripts/events/act_0/enemies.lua +++ b/assets/scripts/events/act_0/enemies.lua @@ -7,7 +7,7 @@ It seems to be eating the metal from the walls. It looks at you and after a few **It seems to be hostile!** ]], - tags = {"_ACT_0_FIGHT"}, + tags = { "_ACT_0_FIGHT" }, choices = { { description = "Fight!", @@ -32,7 +32,7 @@ It looks at you and says "Corpse. Clean. Engage.". **You're not sure what it means, but it doesn't seem to be friendly!** ]], - tags = {"_ACT_0_FIGHT"}, + tags = { "_ACT_0_FIGHT" }, choices = { { description = "Fight!", @@ -54,7 +54,7 @@ register_event("CYBER_SPIDER", { You come around a corner and see a strange creature hanging from the ceiling. It looks like a spider, but it's made out of metal. It seems to be waiting for its prey to come closer and there is no way around it. ]], - tags = {"_ACT_0_FIGHT"}, + tags = { "_ACT_0_FIGHT" }, choices = { { description = "Fight!", @@ -68,3 +68,44 @@ It seems to be waiting for its prey to come closer and there is no way around it } } }) + +register_event("LASER_DRONE", { + name = "A menacing drone appears...", + description = + [[As you explore the facility, you hear a high-pitched whirring sound. A drone equipped with a powerful laser cannon appears in front of you. + +**It looks ready to attack!** + ]], + tags = { "_ACT_0_FIGHT" }, + choices = { + { + description = "Fight!", + callback = function() + add_actor_by_enemy("LASER_DRONE") + if math.random() < 0.10 then + add_actor_by_enemy("LASER_DRONE") + end + return GAME_STATE_FIGHT + end + } + } +}) + +register_event("PLASMA_GOLEM", { + name = "A glowing figure emerges...", + description = + [[As you delve deeper into the facility, you notice a bright glow emanating from a nearby chamber. A massive golem made of pure plasma energy steps into view. + +**It looks ready to unleash its power!** + ]], + tags = { "_ACT_0_FIGHT" }, + choices = { + { + description = "Fight!", + callback = function() + add_actor_by_enemy("PLASMA_GOLEM") + return GAME_STATE_FIGHT + end + } + } +}) diff --git a/assets/scripts/events/act_0/other.lua b/assets/scripts/events/act_0/other.lua index 5358288..cd91cf0 100644 --- a/assets/scripts/events/act_0/other.lua +++ b/assets/scripts/events/act_0/other.lua @@ -1,3 +1,33 @@ +register_event("MERCHANT", { + name = "A strange figure", + description = + [[!!merchant.jpg + +The merchant is a tall, lanky figure draped in a long, tattered coat made of plant fibers and animal hides. Their face is hidden behind a mask made of twisted roots and vines, giving them an unsettling, almost alien appearance. + +Despite their strange appearance, the merchant is a shrewd negotiator and a skilled trader. They carry with them a collection of bizarre and exotic items, including plant-based weapons, animal pelts, and strange, glowing artifacts that seem to pulse with an otherworldly energy. + +The merchant is always looking for a good deal, and they're not above haggling with potential customers...]], + tags = { "_ACT_0" }, + choices = { + { + description = "Trade", + callback = function() + return GAME_STATE_MERCHANT + end + }, { + description = "Pass", + callback = function() + return GAME_STATE_RANDOM + end + } + }, + on_end = function(ctx) + return nil + end +}) + + register_event("RANDOM_ARTIFACT_ACT_0", { name = "Random Artifact", description = [[!!artifact_chest.jpg @@ -6,7 +36,8 @@ You found a chest with a strange symbol on it. The chest is protected by a stran tags = { "_ACT_0" }, choices = { { - description = "Random Artifact " .. highlight_success("Gain 1 Artifact") .. " " .. highlight_warn("Take 5 damage"), + description = "Random Artifact " .. + highlight_success("Gain 1 Artifact") .. " " .. highlight_warn("Take 5 damage"), callback = function() local possible = find_artifacts_by_tags({ "_ACT_0" }) local choosen = choose_weighted_by_price(possible) @@ -34,7 +65,8 @@ You found a chest with a strange symbol on it. The chest is protected by a stran tags = { "_ACT_0" }, choices = { { - description = "Random Artifact " .. highlight_success("Gain 1 Consumeable") .. " " .. highlight_warn("Take 2 damage"), + description = "Random Artifact " .. + highlight_success("Gain 1 Consumeable") .. " " .. highlight_warn("Take 2 damage"), callback = function() local possible = fun.iter(find_cards_by_tags({ "_ACT_0" })) :filter(function(card) @@ -161,7 +193,8 @@ You find a room with a strange device in the middle. It seems to be some kind of tags = { "_ACT_0" }, choices = { { - description = "50% " .. highlight_success("Gain Artifact & Consumeable") .. " 50% " .. highlight_warn("Take 5 damage"), + description = "50% " .. + highlight_success("Gain Artifact & Consumeable") .. " 50% " .. highlight_warn("Take 5 damage"), callback = function() local possible_artifacts = find_artifacts_by_tags({ "_ACT_0" }) local possible_consumeables = fun.iter(find_cards_by_tags({ "_ACT_0" })) @@ -200,7 +233,8 @@ You find a old automatic workstation. You are able to get it working again. You tags = { "_ACT_0" }, choices = { { - description = "Upgrade a card " .. highlight_success("Upgrade a card") .. " " .. highlight_warn("Take 5 damage"), + description = "Upgrade a card " .. + highlight_success("Upgrade a card") .. " " .. highlight_warn("Take 5 damage"), callback = function() local cards = fun.iter(get_cards(PLAYER_ID)) :filter(function(guid) @@ -229,4 +263,4 @@ You find a old automatic workstation. You are able to get it working again. You end } } -}) \ No newline at end of file +}) diff --git a/assets/scripts/events/act_0/start.lua b/assets/scripts/events/act_0/start.lua index b5a9f33..a836890 100644 --- a/assets/scripts/events/act_0/start.lua +++ b/assets/scripts/events/act_0/start.lua @@ -16,7 +16,6 @@ As you struggle to gather your bearings, you notice a blinking panel on the wall description = "Try to find a weapon. " .. highlight('Find melee weapon') .. " " .. highlight_warn("Take 4 damage"), callback = function() - deal_damage(PLAYER_ID, PLAYER_ID, 4, true) give_artifact( choose_weighted_by_price(find_artifacts_by_tags({ "HND", "M" })), PLAYER_ID ) @@ -38,9 +37,16 @@ As you struggle to gather your bearings, you notice a blinking panel on the wall on_enter = function() play_music("energetic_orthogonal_expansions") end, - on_end = function() - actor_set_max_hp(PLAYER_ID, 10) - actor_set_hp(PLAYER_ID, 10) + on_end = function(ctx) + local player_hp = 12 + + actor_set_max_hp(PLAYER_ID, player_hp) + + if ctx.choice == 1 then + actor_set_hp(PLAYER_ID, player_hp - 4) + else + actor_set_hp(PLAYER_ID, player_hp) + end give_card("BLOCK", PLAYER_ID) give_card("BLOCK", PLAYER_ID) diff --git a/assets/scripts/story_teller/act_0.lua b/assets/scripts/story_teller/act_0.lua index e320112..43e7a82 100644 --- a/assets/scripts/story_teller/act_0.lua +++ b/assets/scripts/story_teller/act_0.lua @@ -1,16 +1,19 @@ register_story_teller("_ACT_0", { active = function() - if #get_event_history() <= 6 then - return 1 - end - return 0 + -- if #get_event_history() <= 6 then + -- return 1 + -- end + -- + -- Keep active for now + return 1 end, decide = function() local history = get_event_history() - local possible = { } + local possible = {} -- every 3 events, play a non-combat event - if #get_event_history() % 2 == 0 then + local events = #history - 1; + if events ~= 0 and events % 2 == 0 then possible = find_events_by_tags({ "_ACT_0" }) else possible = find_events_by_tags({ "_ACT_0_FIGHT" }) @@ -20,12 +23,12 @@ register_story_teller("_ACT_0", { -- filter out events by id that have already been played possible = fun.iter(possible):filter(function(event) - return not table.contains(history, event.id) + return event == "MERCHANT" or not table.contains(history, event.id) end):totable() -- fallback for now if #possible == 0 then - possible = find_events_by_tags({ "_ACT_0" }) + possible = find_events_by_tags({ "_ACT_0_FIGHT" }) end set_event(possible[math.random(#possible)].id) diff --git a/docs/GAME_CONTENT_DOCS.md b/docs/GAME_CONTENT_DOCS.md index 323fc0f..1a77307 100644 --- a/docs/GAME_CONTENT_DOCS.md +++ b/docs/GAME_CONTENT_DOCS.md @@ -11,9 +11,9 @@ Content that is dynamically generated at runtime is not included in this documen |----------------|-------| | Artifacts | 10 | | Cards | 18 | -| Status Effects | 8 | -| Enemies | 4 | -| Events | 16 | +| Status Effects | 9 | +| Enemies | 6 | +| Events | 18 | ## Artifacts @@ -86,6 +86,7 @@ title Card Types | ID | Name | Description | Look | Foreground | Can Stack | Decay | Rounds | Used Callbacks | Test Present | |------------------------|--------------------|---------------------------------------------------|------|------------|--------------------|-----------|--------|------------------|--------------------| | ``CHARGED`` | Charged | Attacks will deal more damage per stack. | CHRG | #207BE7 | :heavy_check_mark: | DecayNone | 0 | ``OnDamageCalc`` | :no_entry_sign: | +| ``CHARGING`` | Charging | The drone is charging up for a powerful attack. | CHRG | #ff0000 | :no_entry_sign: | DecayNone | 1 | ``OnDamageCalc`` | :no_entry_sign: | | ``FLASH_BANG`` | Blinded | Causing **25%** less damage. | FL | #725e9c | :heavy_check_mark: | DecayOne | 1 | ``OnDamageCalc`` | :heavy_check_mark: | | ``KNOCK_OUT`` | Knock Out | Can't act | KO | #725e9c | :heavy_check_mark: | DecayOne | 1 | ``OnTurn`` | :no_entry_sign: | | ``BLOCK`` | Block | Decreases incoming damage for each stack | B | #219ebc | :heavy_check_mark: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: | @@ -97,12 +98,14 @@ title Card Types ## Enemies -| ID | Name | Description | Initial HP | Max HP | Color | Used Callbacks | Test Present | -|------------------|--------------|--------------------------------------|------------|--------|---------|------------------------------|-----------------| -| ``CYBER_SPIDER`` | CYBER Spider | It waits for its prey to come closer | 8 | 8 | #ff4d6d | ``OnTurn`` | :no_entry_sign: | -| ``CLEAN_BOT`` | Cleaning Bot | It never stopped cleaning... | 13 | 13 | #32a891 | ``OnPlayerTurn``, ``OnTurn`` | :no_entry_sign: | -| ``DUMMY`` | Dummy | End me... | 100 | 100 | #deeb6a | ``OnTurn`` | :no_entry_sign: | -| ``RUST_MITE`` | Rust Mite | A small robot that eats metal. | 12 | 12 | #e6e65a | ``OnTurn`` | :no_entry_sign: | +| ID | Name | Description | Initial HP | Max HP | Color | Used Callbacks | Test Present | +|------------------|--------------|------------------------------------------------|------------|--------|---------|------------------------------|-----------------| +| ``CYBER_SPIDER`` | CYBER Spider | It waits for its prey to come closer | 8 | 8 | #ff4d6d | ``OnTurn`` | :no_entry_sign: | +| ``CLEAN_BOT`` | Cleaning Bot | It never stopped cleaning... | 13 | 13 | #32a891 | ``OnPlayerTurn``, ``OnTurn`` | :no_entry_sign: | +| ``DUMMY`` | Dummy | End me... | 100 | 100 | #deeb6a | ``OnTurn`` | :no_entry_sign: | +| ``LASER_DRONE`` | Laser Drone | A drone equipped with a powerful laser cannon. | 7 | 7 | #ff0000 | ``OnTurn`` | :no_entry_sign: | +| ``PLASMA_GOLEM`` | Plasma Golem | A golem made of pure plasma energy. | 12 | 12 | #ff69b4 | ``OnTurn`` | :no_entry_sign: | +| ``RUST_MITE`` | Rust Mite | A small robot that eats metal. | 12 | 12 | #e6e65a | ``OnTurn`` | :no_entry_sign: | ## Events @@ -110,6 +113,8 @@ title Card Types | ID | Name | Description | Tags | Choices | Test Present | |------------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|----------------------------------------------------------------------------------------------------------------------------------|-----------------| | ``GAIN_GOLD_ACT_0`` | | ... - | _ACT_0 | | :no_entry_sign: | +| ``PLASMA_GOLEM`` | A glowing figure emerges... | As you delve deeper into the facility, you notice a bright glow emanating from a nearby chamber. A massive golem made of pure plasma energy steps into view. - **It looks ready to unleash its power!** - | _ACT_0_FIGHT | | :no_entry_sign: | +| ``LASER_DRONE`` | A menacing drone appears... | As you explore the facility, you hear a high-pitched whirring sound. A drone equipped with a powerful laser cannon appears in front of you. - **It looks ready to attack!** - | _ACT_0_FIGHT | | :no_entry_sign: | | ``MERCHANT`` | A strange figure | !!merchant.jpg - - The merchant is a tall, lanky figure draped in a long, tattered coat made of plant fibers and animal hides. Their face is hidden behind a mask made of twisted roots and vines, giving them an unsettling, almost alien appearance. - Despite their strange appearance, the merchant is a shrewd negotiator and a skilled trader. They carry with them a collection of bizarre and exotic items, including plant-based weapons, animal pelts, and strange, glowing artifacts that seem to pulse with an otherworldly energy. - The merchant is always looking for a good deal, and they're not above haggling with potential customers... | _ACT_0, _ACT_1, _ACT_2, _ACT_3 | | :no_entry_sign: | | ``CLEAN_BOT`` | Corpse. Clean. Engage. | !!clean_bot.jpg - While exploring the facility you hear a strange noise. Suddenly a strange robot appears from one of the corridors. - It seems to be cleaning up the area, but it's not working properly anymore and you can see small sparks coming out of it. - It looks at you and says "Corpse. Clean. Engage.". - **You're not sure what it means, but it doesn't seem to be friendly!** - | _ACT_0_FIGHT | | :no_entry_sign: | | ``GAMBLE_1_ACT_0`` | Electro Barrier | You find a room with a strange device in the middle. It seems to be some kind of electro barrier protecting a storage container. You can either try to disable the barrier or leave. - | _ACT_0 | | :no_entry_sign: | diff --git a/docs/LUA_API_DOCS.md b/docs/LUA_API_DOCS.md index 720d4f0..10fc533 100644 --- a/docs/LUA_API_DOCS.md +++ b/docs/LUA_API_DOCS.md @@ -288,6 +288,18 @@ Functions that modify the general game state. None ### Functions +
get_action_points_per_round
+ +get the number of action points per round. + +**Signature:** + +``` +get_action_points_per_round() -> number +``` + +
+
get_event_history
Gets the ids of all the encountered events in the order of occurrence. @@ -372,6 +384,18 @@ had_events_any(eventIds : string[]) -> boolean
+
set_action_points_per_round
+ +set the number of action points per round. + +**Signature:** + +``` +set_action_points_per_round(points : number) -> None +``` + +
+
set_event
Set event by id. diff --git a/game/enemy.go b/game/enemy.go index 70352b7..0608df0 100644 --- a/game/enemy.go +++ b/game/enemy.go @@ -11,6 +11,7 @@ type Enemy struct { Description string InitialHP int MaxHP int + Gold int Look string Color string Intend luhelp.OwnedCallback diff --git a/game/lua.go b/game/lua.go index 84b6fb8..7ebdba6 100644 --- a/game/lua.go +++ b/game/lua.go @@ -1,14 +1,15 @@ package game import ( + "path/filepath" + "strings" + "github.com/BigJk/end_of_eden/internal/fs" "github.com/BigJk/end_of_eden/internal/lua/ludoc" luhelp2 "github.com/BigJk/end_of_eden/internal/lua/luhelp" "github.com/BigJk/end_of_eden/system/audio" "github.com/BigJk/end_of_eden/system/gen/faces" "github.com/BigJk/end_of_eden/system/localization" - "path/filepath" - "strings" "github.com/charmbracelet/lipgloss" "github.com/samber/lo" @@ -282,6 +283,18 @@ fun = require "fun" return 1 })) + d.Function("get_action_points_per_round", "get the number of action points per round.", "number") + l.SetGlobal("get_action_points_per_round", l.NewFunction(func(state *lua.LState) int { + state.Push(lua.LNumber(session.GetPointsPerRound())) + return 1 + })) + + d.Function("set_action_points_per_round", "set the number of action points per round.", "", "points : number") + l.SetGlobal("set_action_points_per_round", l.NewFunction(func(state *lua.LState) int { + session.SetPointsPerRound(int(state.ToNumber(1))) + return 0 + })) + // Actor Operations d.Category("Actor Operations", "Functions that modify or access the actors. Actors are either the player or enemies.", 6) diff --git a/game/saved_state.go b/game/saved_state.go index 8268ed8..8435062 100644 --- a/game/saved_state.go +++ b/game/saved_state.go @@ -15,6 +15,7 @@ type SavedState struct { StagesCleared int CurrentEvent string CurrentFight FightState + PointsPerRound int Merchant MerchantState EventHistory []string StateCheckpoints []StateCheckpoint diff --git a/game/session.go b/game/session.go index ee6e2df..4131c6d 100644 --- a/game/session.go +++ b/game/session.go @@ -6,6 +6,15 @@ import ( "encoding/gob" "errors" "fmt" + "io" + "log" + "math/rand" + "path/filepath" + "runtime" + "sort" + "strings" + "time" + "github.com/BigJk/end_of_eden/internal/fs" "github.com/BigJk/end_of_eden/internal/lua/ludoc" "github.com/BigJk/end_of_eden/system/gen" @@ -15,20 +24,12 @@ import ( "github.com/samber/lo" lua "github.com/yuin/gopher-lua" "golang.org/x/exp/slices" - "io" - "log" - "math/rand" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2renderers/d2svg" "oss.terrastruct.com/d2/d2themes/d2themescatalog" "oss.terrastruct.com/d2/lib/textmeasure" - "path/filepath" - "runtime" - "sort" - "strings" - "time" ) func init() { @@ -54,8 +55,8 @@ const ( // DefaultRemoveCost is the default cost for removing a card. DefaultRemoveCost = 50 - // PointsPerRound is the amount of points the player gets per round. - PointsPerRound = 3 + // DefaultPointsPerRound is the default amount of points the player gets per round. + DefaultPointsPerRound = 3 // DrawSize is the amount of cards the player draws per round. DrawSize = 3 @@ -103,17 +104,18 @@ type Session struct { luaDocs *ludoc.Docs resources *ResourcesManager - state GameState - actors map[string]Actor - instances map[string]any - stagesCleared int - currentEvent string - currentFight FightState - merchant MerchantState - eventHistory []string - randomHistory []string - ctxData map[string]any - hooks map[Hook][]func() + state GameState + actors map[string]Actor + instances map[string]any + stagesCleared int + currentEvent string + currentFight FightState + pointsPerRound int + merchant MerchantState + eventHistory []string + randomHistory []string + ctxData map[string]any + hooks map[Hook][]func() loadedMods []string stateCheckpoints []StateCheckpoint @@ -132,8 +134,9 @@ func NewSession(options ...func(s *Session)) *Session { actors: map[string]Actor{ PlayerActorID: NewActor(PlayerActorID), }, - instances: map[string]any{}, - ctxData: map[string]any{}, + pointsPerRound: DefaultPointsPerRound, + instances: map[string]any{}, + ctxData: map[string]any{}, hooks: map[Hook][]func(){ HookNextFightEnd: {}, }, @@ -244,6 +247,7 @@ func (s *Session) ToSavedState() SavedState { StagesCleared: s.stagesCleared, CurrentEvent: s.currentEvent, CurrentFight: s.currentFight, + PointsPerRound: s.pointsPerRound, Merchant: s.merchant, EventHistory: s.eventHistory, StateCheckpoints: s.stateCheckpoints, @@ -264,6 +268,7 @@ func (s *Session) LoadSavedState(save SavedState) { s.stagesCleared = save.StagesCleared s.currentEvent = save.CurrentEvent s.currentFight = save.CurrentFight + s.pointsPerRound = save.PointsPerRound s.merchant = save.Merchant s.eventHistory = save.EventHistory s.stateCheckpoints = lo.Map(save.StateCheckpoints, func(item StateCheckpoint, index int) StateCheckpoint { @@ -422,6 +427,11 @@ func (s *Session) GetFormerState(index int) *Session { // GetGameState returns the current game state. func (s *Session) GetGameState() GameState { + player := s.GetActor(PlayerActorID) + if player.HP == 0 { + return GameStateGameOver + } + return s.state } @@ -465,7 +475,7 @@ func (s *Session) GetEvent() *Event { // CleanUpFight resets the fight state. func (s *Session) CleanUpFight() { - s.currentFight.CurrentPoints = PointsPerRound + s.currentFight.CurrentPoints = s.pointsPerRound s.currentFight.Deck = lo.Shuffle(s.GetPlayer().Cards.ToSlice()) s.currentFight.Hand = []string{} s.currentFight.Exhausted = []string{} @@ -508,6 +518,16 @@ func (s *Session) GetStagesCleared() int { return s.stagesCleared } +// GetPointsPerRound returns the amount of action points the player gets each round. +func (s *Session) GetPointsPerRound() int { + return s.pointsPerRound +} + +// SetPointsPerRound sets the amount of action points the player gets each round. +func (s *Session) SetPointsPerRound(points int) { + s.pointsPerRound = points +} + // FinishPlayerTurn signals that the player is done with its turn. All enemies act now, status effects are // evaluated, if the fight is over is checked and if not this will advance to the next round and draw cards // for the player. @@ -573,7 +593,7 @@ func (s *Session) FinishPlayerTurn() { } // Advance to new Round - s.currentFight.CurrentPoints = PointsPerRound + s.currentFight.CurrentPoints = s.pointsPerRound s.currentFight.Round += 1 s.currentFight.Used = append(s.currentFight.Used, s.currentFight.Hand...) s.currentFight.Hand = []string{} @@ -637,8 +657,6 @@ func (s *Session) FinishFight() bool { // If an event is already set we switch to it if len(s.currentEvent) > 0 { s.SetGameState(GameStateEvent) - } else if s.stagesCleared%10 == 0 { - s.SetEvent("MERCHANT") } else { s.SetGameState(GameStateRandom) } @@ -777,7 +795,7 @@ func (s *Session) GetMerchant() MerchantState { // GetMerchantGoldMax returns what the max cost of a artifact or card is that the merchant might offer. func (s *Session) GetMerchantGoldMax() int { - return 150 + s.stagesCleared*30 + return 180 + s.stagesCleared*30 } func (s *Session) PushRandomHistory(id string) { @@ -790,7 +808,7 @@ func (s *Session) PushRandomHistory(id string) { // GetRandomArtifact returns the type id of a random artifact with a price lower than the given value. func (s *Session) GetRandomArtifact(maxGold int) string { possible := lo.Filter(lo.Values(s.resources.Artifacts), func(item *Artifact, index int) bool { - return item.Price >= 0 && item.Price < maxGold + return item.Price > 0 && item.Price < maxGold }) possibleNoDupes := lo.Filter(possible, func(item *Artifact, index int) bool { @@ -814,7 +832,7 @@ func (s *Session) GetRandomArtifact(maxGold int) string { // GetRandomCard returns the type id of a random card with a price lower than the given value. func (s *Session) GetRandomCard(maxGold int) string { possible := lo.Filter(lo.Values(s.resources.Cards), func(item *Card, index int) bool { - return item.Price >= 0 && item.Price < maxGold + return item.Price > 0 && item.Price < maxGold }) possibleNoDupes := lo.Filter(possible, func(item *Card, index int) bool { @@ -1868,6 +1886,7 @@ func (s *Session) AddActorFromEnemy(id string) string { actor.Description = base.Description actor.HP = base.InitialHP actor.MaxHP = base.MaxHP + actor.Gold = base.Gold // Its important we add the actor before any callbacks so that it's instance is available // to add cards etc. to!