From 79f8daf04be0bb06ec264a9536e82a135ae7927d Mon Sep 17 00:00:00 2001 From: Nicholas Hayashi Date: Wed, 4 Aug 2021 14:13:16 -0400 Subject: [PATCH] state -> gamestate --- src/entity.lua | 8 +-- src/game.lua | 154 ++++++++++++++++++++++----------------------- src/grid.lua | 10 +-- src/mob.lua | 58 ++++++++--------- src/projectile.lua | 14 ++--- src/tower.lua | 56 ++++++++--------- 6 files changed, 150 insertions(+), 150 deletions(-) diff --git a/src/entity.lua b/src/entity.lua index 5f1e1b0..af3d942 100644 --- a/src/entity.lua +++ b/src/entity.lua @@ -17,7 +17,7 @@ entity structure: function make_basic_entity(hex, update, position) local entity = {} - entity.TOB = state.time + entity.TOB = game_state.time -- usually you'll provide a hex and not a position, and the entity will spawn in the center -- of the hex. if you want an entity to exist not at the center of a hex, you can provide a @@ -41,14 +41,14 @@ end function register_entity(t, entity) table.insert(t, entity) - state.world:append(entity.node) + game_state.world:append(entity.node) end --- |t| is the source table, probably state.mobs, state.towers, or state.projectiles +-- |t| is the source table, probably game_state.mobs, game_state.towers, or game_state.projectiles function delete_entity(t, index) if not t then error("splat!") end - state.world:remove(t[index].node) + game_state.world:remove(t[index].node) t[index] = false -- leave empty indexes so other entities can learn that this entity was deleted end diff --git a/src/game.lua b/src/game.lua index bab8f67..eacd862 100644 --- a/src/game.lua +++ b/src/game.lua @@ -1,6 +1,6 @@ game = false -- flag to tell if there is a game running -state = {} +game_state = {} -- top right display types -- f1 toggles what is displayed in the top right of the screen @@ -48,10 +48,10 @@ local function get_initial_game_state(seed) end local function get_wave_timer_text() - if state.spawning then - return string.format("WAVE (%d) OVER: %.2f", state.current_wave, state.time_until_next_break) + if game_state.spawning then + return string.format("WAVE (%d) OVER: %.2f", game_state.current_wave, game_state.time_until_next_break) else - return string.format("NEXT WAVE (%d): %.2f", state.current_wave, state.time_until_next_wave) + return string.format("NEXT WAVE (%d): %.2f", game_state.current_wave, game_state.time_until_next_wave) end end @@ -73,10 +73,10 @@ local function get_top_right_display_text(hex, evenq, centered_evenq, display_ty str = table.tostring(am.perf_stats()) elseif display_type == TRDTS.SEED then - str = "SEED: " .. state.map.seed + str = "SEED: " .. game_state.map.seed elseif display_type == TRDTS.TILE then - str = table.tostring(hex_map_get(state.map, hex)) + str = table.tostring(hex_map_get(game_state.map, hex)) end return str end @@ -91,14 +91,14 @@ end local BASE_BREAK_TIME = 20 local function get_break_time(current_wave) - return BASE_BREAK_TIME - math.min(BASE_BREAK_TIME, BASE_BREAK_TIME / (1 / math.log(state.current_wave + 1))) + return BASE_BREAK_TIME - math.min(BASE_BREAK_TIME, BASE_BREAK_TIME / (1 / math.log(game_state.current_wave + 1))) end local function do_day_night_cycle() -- this is a bad idea, atleast with the current bad rendering strategy of not using a single draw call -- i get flickering as the light level increases - --local tstep = (math.sin(state.time * am.delta_time) + 1) / 100 - --state.world"negative_mask".color = vec4(tstep){a=1} + --local tstep = (math.sin(game_state.time * am.delta_time) + 1) / 100 + --game_state.world"negative_mask".color = vec4(tstep){a=1} end local function game_pause() @@ -110,48 +110,48 @@ end local function game_deserialize(json_string) local new_state = am.parse_json(json_string) - if new_state.version ~= version then + if new_game_state.version ~= version then log("loading incompatible old save data. starting a fresh game instead.") return get_initial_game_state() end - new_state.map = random_map(new_state.seed) - new_state.world = make_hex_grid_scene(new_state.map) - new_state.seed = nil + new_game_state.map = random_map(new_game_state.seed) + new_game_state.world = make_hex_grid_scene(new_game_state.map) + new_game_state.seed = nil - for i,t in pairs(new_state.towers) do + for i,t in pairs(new_game_state.towers) do if t then - new_state.towers[i] = tower_deserialize(t) + new_game_state.towers[i] = tower_deserialize(t) - for _,h in pairs(new_state.towers[i].hexes) do - local tile = hex_map_get(new_state.map, h.x, h.y) - tile.elevation = tile.elevation + new_state.towers[i].height + for _,h in pairs(new_game_state.towers[i].hexes) do + local tile = hex_map_get(new_game_state.map, h.x, h.y) + tile.elevation = tile.elevation + new_game_state.towers[i].height end -- @STATEFUL, shouldn't be done here - new_state.world:append(new_state.towers[i].node) + new_game_state.world:append(new_game_state.towers[i].node) end end -- after we have re-constituted all of the towers and modified the map's elevations accordingly, -- we should re-calc the flow-field - apply_flow_field(new_state.map, generate_flow_field(new_state.map, HEX_GRID_CENTER), new_state.world) + apply_flow_field(new_game_state.map, generate_flow_field(new_game_state.map, HEX_GRID_CENTER), new_game_state.world) - for i,m in pairs(new_state.mobs) do + for i,m in pairs(new_game_state.mobs) do if m then - new_state.mobs[i] = mob_deserialize(m) + new_game_state.mobs[i] = mob_deserialize(m) -- @STATEFUL, shouldn't be done here - new_state.world:append(new_state.mobs[i].node) + new_game_state.world:append(new_game_state.mobs[i].node) end end - for i,p in pairs(new_state.projectiles) do + for i,p in pairs(new_game_state.projectiles) do if p then - new_state.projectiles[i] = projectile_deserialize(p) + new_game_state.projectiles[i] = projectile_deserialize(p) -- @STATEFUL, shouldn't be done here - new_state.world:append(new_state.projectiles[i].node) + new_game_state.world:append(new_game_state.projectiles[i].node) end end @@ -162,7 +162,7 @@ local function game_serialize() local serialized = table.shallow_copy(state) serialized.version = version - serialized.seed = state.map.seed + serialized.seed = game_state.map.seed serialized.map = nil -- we re-generate the entire map from the seed on de-serialize -- in order to serialize the game state, we have to convert all relevant userdata into @@ -174,21 +174,21 @@ local function game_serialize() -- this is dumb and if i forsaw this i would have probably used float arrays instead of vectors serialized.towers = {} - for i,t in pairs(state.towers) do + for i,t in pairs(game_state.towers) do if t then serialized.towers[i] = tower_serialize(t) end end serialized.mobs = {} - for i,m in pairs(state.mobs) do + for i,m in pairs(game_state.mobs) do if m then serialized.mobs[i] = mob_serialize(m) end end serialized.projectiles = {} - for i,p in pairs(state.projectiles) do + for i,p in pairs(game_state.projectiles) do if p then serialized.projectiles[i] = projectile_serialize(p) end @@ -202,35 +202,35 @@ local function deselect_tile() end local function game_action(scene) - if state.score < 0 then game_end() return true end + if game_state.score < 0 then game_end() return true end local perf = am.perf_stats() - state.time = state.time + am.delta_time - state.score = state.score + am.delta_time + game_state.time = game_state.time + am.delta_time + game_state.score = game_state.score + am.delta_time - if state.spawning then - state.time_until_next_break = state.time_until_next_break - am.delta_time + if game_state.spawning then + game_state.time_until_next_break = game_state.time_until_next_break - am.delta_time - if state.time_until_next_break <= 0 then - state.time_until_next_break = 0 - state.current_wave = state.current_wave + 1 + if game_state.time_until_next_break <= 0 then + game_state.time_until_next_break = 0 + game_state.current_wave = game_state.current_wave + 1 - state.spawning = false + game_state.spawning = false - state.time_until_next_wave = get_break_time(state.current_wave) + game_state.time_until_next_wave = get_break_time(game_state.current_wave) end else - state.time_until_next_wave = state.time_until_next_wave - am.delta_time + game_state.time_until_next_wave = game_state.time_until_next_wave - am.delta_time - if state.time_until_next_wave <= 0 then - state.time_until_next_wave = 0 + if game_state.time_until_next_wave <= 0 then + game_state.time_until_next_wave = 0 - state.spawning = true + game_state.spawning = true -- calculate spawn chance for next wave - state.spawn_chance = math.log(state.current_wave)/80 + 0.002 + game_state.spawn_chance = math.log(game_state.current_wave)/80 + 0.002 - state.time_until_next_break = get_wave_time(state.current_wave) + game_state.time_until_next_break = get_wave_time(game_state.current_wave) end end @@ -240,18 +240,18 @@ local function game_action(scene) local evenq = hex_to_evenq(hex) local centered_evenq = evenq{ y = -evenq.y } - vec2(math.floor(HEX_GRID_WIDTH/2) , math.floor(HEX_GRID_HEIGHT/2)) - local tile = hex_map_get(state.map, hex) + local tile = hex_map_get(game_state.map, hex) local interactable = evenq_is_in_interactable_region(evenq{ y = -evenq.y }) - local buildable = tower_type_is_buildable_on(hex, tile, state.selected_tower_type) + local buildable = tower_type_is_buildable_on(hex, tile, game_state.selected_tower_type) if win:mouse_pressed"left" then deselect_tile() if interactable then if buildable then - local broken, flow_field = building_tower_breaks_flow_field(state.selected_tower_type, hex) - local cost = get_tower_cost(state.selected_tower_type) + local broken, flow_field = building_tower_breaks_flow_field(game_state.selected_tower_type, hex) + local cost = get_tower_cost(game_state.selected_tower_type) if broken then local node = win.scene("cursor"):child(2) @@ -260,7 +260,7 @@ local function game_action(scene) play_sfx(SOUNDS.BIRD2) alert("closes the circle") - elseif cost > state.money then + elseif cost > game_state.money then local node = win.scene("cursor"):child(2) node.color = COLORS.CLARET node:action(am.tween(0.1, { color = COLORS.TRANSPARENT })) @@ -269,10 +269,10 @@ local function game_action(scene) else update_money(-cost) - build_tower(hex, state.selected_tower_type, flow_field) + build_tower(hex, game_state.selected_tower_type, flow_field) if flow_field then - apply_flow_field(state.map, flow_field, state.world) + apply_flow_field(game_state.map, flow_field, game_state.world) end end else @@ -307,19 +307,19 @@ local function game_action(scene) game_pause() elseif win:key_pressed"f1" then - state.selected_top_right_display_type = (state.selected_top_right_display_type + 1) % #table.keys(TRDTS) + game_state.selected_top_right_display_type = (game_state.selected_top_right_display_type + 1) % #table.keys(TRDTS) elseif win:key_pressed"f2" then - state.world"flow_field".hidden = not state.world"flow_field".hidden + game_state.world"flow_field".hidden = not game_state.world"flow_field".hidden elseif win:key_pressed"f3" then game_save() elseif win:key_pressed"tab" then if win:key_down"lshift" then - select_toolbelt_button((state.selected_toolbelt_button + table.count(TOWER_TYPE) - 2) % table.count(TOWER_TYPE) + 1) + select_toolbelt_button((game_state.selected_toolbelt_button + table.count(TOWER_TYPE) - 2) % table.count(TOWER_TYPE) + 1) else - select_toolbelt_button((state.selected_toolbelt_button) % table.count(TOWER_TYPE) + 1) + select_toolbelt_button((game_state.selected_toolbelt_button) % table.count(TOWER_TYPE) + 1) end elseif win:key_pressed"1" then select_toolbelt_button( 1) elseif win:key_pressed"2" then select_toolbelt_button( 2) @@ -336,7 +336,7 @@ local function game_action(scene) end do_entity_updates() - do_mob_spawning(state.spawn_chance) + do_mob_spawning(game_state.spawn_chance) do_day_night_cycle() -- update the cursor @@ -344,7 +344,7 @@ local function game_action(scene) win.scene("cursor").hidden = true else - if state.selected_tower_type then + if game_state.selected_tower_type then if buildable then win.scene("cursor").hidden = false @@ -358,10 +358,10 @@ local function game_action(scene) win.scene("cursor_translate").position2d = rounded_mouse end - win.scene("score").text = string.format("SCORE: %.2f", state.score) - win.scene("money").text = string.format("MONEY: $%d", state.money) + win.scene("score").text = string.format("SCORE: %.2f", game_state.score) + win.scene("money").text = string.format("MONEY: $%d", game_state.money) win.scene("wave_timer").text = get_wave_timer_text() - win.scene("top_right_display").text = get_top_right_display_text(hex, evenq, centered_evenq, state.selected_top_right_display_type) + win.scene("top_right_display").text = get_top_right_display_text(hex, evenq, centered_evenq, game_state.selected_top_right_display_type) end local function make_game_toolbelt() @@ -474,8 +474,8 @@ local function make_game_toolbelt() end end else - if state.selected_tower_type then - win.scene:replace("tower_tooltip_text", get_tower_tooltip_text_node(state.selected_tower_type)) + if game_state.selected_tower_type then + win.scene:replace("tower_tooltip_text", get_tower_tooltip_text_node(game_state.selected_tower_type)) else win.scene:replace("tower_tooltip_text", am.group():tag"tower_tooltip_text") end @@ -506,7 +506,7 @@ local function make_game_toolbelt() ) select_tower_type = function(tower_type) - state.selected_tower_type = tower_type + game_state.selected_tower_type = tower_type if get_tower_spec(tower_type) then win.scene:replace( @@ -537,7 +537,7 @@ local function make_game_toolbelt() end select_toolbelt_button = function(i) - state.selected_toolbelt_button = i + game_state.selected_toolbelt_button = i if get_tower_spec(i) then select_tower_type(i) @@ -581,20 +581,20 @@ local function game_scene() self.color = COLORS.SUNRAY if win:mouse_pressed("left") then - if state.spawning then + if game_state.spawning then -- in this case, we don't exactly just send the next wave, we turn the current wave into the next -- wave, and add the amount of time it would have lasted to the amount of remaining time in the -- current wave - state.current_wave = state.current_wave + 1 + game_state.current_wave = game_state.current_wave + 1 -- calculate spawn chance for next wave - state.spawn_chance = math.log(state.current_wave)/100 + 0.002 + game_state.spawn_chance = math.log(game_state.current_wave)/100 + 0.002 - state.time_until_next_break = state.time_until_next_break + get_break_time(state.current_wave) + game_state.time_until_next_break = game_state.time_until_next_break + get_break_time(game_state.current_wave) play_sfx(SOUNDS.EXPLOSION4) else - state.time_until_next_wave = 0 + game_state.time_until_next_wave = 0 play_sfx(SOUNDS.EXPLOSION4) end @@ -620,7 +620,7 @@ local function game_scene() end)) local scene = am.group( - am.scale(1):tag"world_scale" ^ state.world, + am.scale(1):tag"world_scale" ^ game_state.world, am.translate(HEX_GRID_CENTER):tag"cursor_translate" ^ make_hex_cursor(0, COLORS.TRANSPARENT):tag"cursor", score, money, @@ -638,11 +638,11 @@ local function game_scene() return scene end -function update_score(diff) state.score = state.score + diff end -function update_money(diff) state.money = state.money + diff end +function update_score(diff) game_state.score = game_state.score + diff end +function update_money(diff) game_state.money = game_state.money + diff end function game_end() - state = {} + game_state = {} game = false end @@ -653,7 +653,7 @@ end function game_init(saved_state) if saved_state then - state = game_deserialize(saved_state) + game_state = game_deserialize(saved_state) if not state then -- failed to load a save @@ -665,7 +665,7 @@ function game_init(saved_state) -- but you don't have a built tower cursor node, so hovering a buildable tile throws an error select_tower_type(nil) else - state = get_initial_game_state() + game_state = get_initial_game_state() end game = true diff --git a/src/grid.lua b/src/grid.lua index 8c298e2..ce140af 100644 --- a/src/grid.lua +++ b/src/grid.lua @@ -122,7 +122,7 @@ function building_tower_breaks_flow_field(tower_type, hex) local all_impassable = true local hexes = hex_spiral_map(hex, get_tower_size(tower_type)) for _,h in pairs(hexes) do - local tile = hex_map_get(state.map, h) + local tile = hex_map_get(game_state.map, h) if all_impassable and mob_can_pass_through(nil, h) then all_impassable = false @@ -136,19 +136,19 @@ function building_tower_breaks_flow_field(tower_type, hex) -- if no mobs can pass over any of the tiles we're building on -- there is no need to regenerate the flow field, or do anything more - -- (besides return all the tile's elevations back to their original state) + -- (besides return all the tile's elevations back to their original game_state) if all_impassable then for i,h in pairs(hexes) do - hex_map_get(state.map, h).elevation = original_elevations[i] + hex_map_get(game_state.map, h).elevation = original_elevations[i] end return false end - local flow_field = generate_flow_field(state.map, HEX_GRID_CENTER) + local flow_field = generate_flow_field(game_state.map, HEX_GRID_CENTER) local result = not hex_map_get(flow_field, 0, 0) for i,h in pairs(hexes) do - hex_map_get(state.map, h).elevation = original_elevations[i] + hex_map_get(game_state.map, h).elevation = original_elevations[i] end return result, flow_field diff --git a/src/mob.lua b/src/mob.lua index 8fa25c0..2299d85 100644 --- a/src/mob.lua +++ b/src/mob.lua @@ -37,18 +37,18 @@ function get_mob_spec(mob_type) end local function grow_mob_health(mob_type, spec_health, time) - return spec_health + math.pow(state.current_wave - 1, 2) + return spec_health + math.pow(game_state.current_wave - 1, 2) end local function grow_mob_speed(mob_type, spec_speed, time) - return spec_speed + math.log(state.current_wave + 1) + return spec_speed + math.log(game_state.current_wave + 1) end local function grow_mob_bounty(mob_type, spec_bounty, time) - return spec_bounty + (state.current_wave - 1) * 2 + return spec_bounty + (game_state.current_wave - 1) * 2 end function mobs_on_hex(hex) local t = {} - for mob_index,mob in pairs(state.mobs) do + for mob_index,mob in pairs(game_state.mobs) do if mob and mob.hex == hex then table.insert(t, mob_index, mob) end @@ -58,25 +58,25 @@ end function mob_on_hex(hex) -- table.find returns i,v in the table - return table.find(state.mobs, function(mob) + return table.find(game_state.mobs, function(mob) return mob and mob.hex == hex end) end -- check if a the tile at |hex| is passable by |mob| function mob_can_pass_through(mob, hex) - local tile = hex_map_get(state.map, hex) + local tile = hex_map_get(game_state.map, hex) return tile_is_medium_elevation(tile) end function mob_die(mob, mob_index) vplay_sfx(SOUNDS.EXPLOSION1) - delete_entity(state.mobs, mob_index) + delete_entity(game_state.mobs, mob_index) end function mob_reach_center(mob, mob_index) update_score(-(mob.health + mob.bounty)) - delete_entity(state.mobs, mob_index) + delete_entity(game_state.mobs, mob_index) end local HEALTHBAR_WIDTH = HEX_PIXEL_WIDTH/2 @@ -89,7 +89,7 @@ function do_hit_mob(mob, damage, mob_index) mob_die(mob, mob_index) else mob.healthbar:action(coroutine.create(function(self) - local x2 = -HEALTHBAR_WIDTH/2 + mob.health/grow_mob_health(mob.type, get_mob_health(mob.type), state.time) * HEALTHBAR_WIDTH/2 + local x2 = -HEALTHBAR_WIDTH/2 + mob.health/grow_mob_health(mob.type, get_mob_health(mob.type), game_state.time) * HEALTHBAR_WIDTH/2 self:child(2).x2 = x2 self.hidden = false am.wait(am.delay(0.8)) @@ -185,16 +185,16 @@ local function resolve_frame_target_for_mob(mob, mob_index) end else -- use the map's flow field - gotta find the the best neighbour - local neighbours = grid_neighbours(state.map, mob.hex) + local neighbours = grid_neighbours(game_state.map, mob.hex) if #neighbours > 0 then local first_neighbour = neighbours[1] - tile = hex_map_get(state.map, first_neighbour) + tile = hex_map_get(game_state.map, first_neighbour) local lowest_cost_hex = first_neighbour local lowest_cost = tile.priority or 0 for _,n in pairs(neighbours) do - tile = hex_map_get(state.map, n) + tile = hex_map_get(game_state.map, n) if not tile.priority then -- if there's no stored priority, that should mean it's the center tile @@ -224,8 +224,8 @@ local function update_mob_velkooz(mob, mob_index) if mob.frame_target then if mob_can_pass_through(mob, mob.frame_target) then - local from = hex_map_get(state.map, mob.hex) - local to = hex_map_get(state.map, mob.frame_target) + local from = hex_map_get(game_state.map, mob.hex) + local to = hex_map_get(game_state.map, mob.frame_target) local rate = mob.speed * am.delta_time mob.position = mob.position + math.normalize(hex_to_pixel(mob.frame_target, vec2(HEX_SIZE)) - mob.position) * rate @@ -243,7 +243,7 @@ local function update_mob_velkooz(mob, mob_index) mob.node("rotate").angle = -theta + math.pi/2 - local roll = math.floor((state.time - mob.TOB) * 10) % 4 + local roll = math.floor((game_state.time - mob.TOB) * 10) % 4 if roll == 0 then mob.node"velk_sprite".source = "res/mob_velkooz0.png" @@ -267,8 +267,8 @@ local function update_mob_spooder(mob, mob_index) -- or between when we last calculated this target and now -- check for that now if mob_can_pass_through(mob, mob.frame_target) then - local from = hex_map_get(state.map, mob.hex) - local to = hex_map_get(state.map, mob.frame_target) + local from = hex_map_get(game_state.map, mob.hex) + local to = hex_map_get(game_state.map, mob.frame_target) local spider_speed = ((math.simplex(mob.hex) + 1.5) * 1.5) ^ 2 local rate = (spider_speed * mob.speed - math.abs(to.elevation - from.elevation)) * am.delta_time @@ -296,8 +296,8 @@ local function update_mob_beeper(mob, mob_index) -- or between when we last calculated this target and now -- check for that now if mob_can_pass_through(mob, mob.frame_target) then - local from = hex_map_get(state.map, mob.hex) - local to = hex_map_get(state.map, mob.frame_target) + local from = hex_map_get(game_state.map, mob.hex) + local to = hex_map_get(game_state.map, mob.frame_target) local rate = (4 * mob.speed - math.abs(to.elevation - from.elevation)) * am.delta_time mob.position = mob.position + math.normalize(hex_to_pixel(mob.frame_target, vec2(HEX_SIZE)) - mob.position) * rate @@ -339,14 +339,14 @@ local function make_and_register_mob(mob_type) mob.node = am.translate(mob.position) ^ make_mob_node(mob_type, mob) local spec = get_mob_spec(mob_type) - mob.health = grow_mob_health(mob_type, spec.health, state.time) - mob.speed = grow_mob_speed(mob_type, spec.speed, state.time) - mob.bounty = grow_mob_bounty(mob_type, spec.bounty, state.time) + mob.health = grow_mob_health(mob_type, spec.health, game_state.time) + mob.speed = grow_mob_speed(mob_type, spec.speed, game_state.time) + mob.bounty = grow_mob_bounty(mob_type, spec.bounty, game_state.time) mob.hurtbox_radius = spec.hurtbox_radius mob.healthbar = mob.node:child(1):child(2):child(1) -- lmao if mob.type == MOB_TYPE.VELKOOZ then - mob.states = { + mob.game_states = { pack_texture_into_sprite(TEXTURES.VELKOOZ, MOB_SIZE, MOB_SIZE):tag"velk_sprite", pack_texture_into_sprite(TEXTURES.VELKOOZ1, MOB_SIZE, MOB_SIZE):tag"velk_sprite", pack_texture_into_sprite(TEXTURES.VELKOOZ2, MOB_SIZE, MOB_SIZE):tag"velk_sprite", @@ -354,7 +354,7 @@ local function make_and_register_mob(mob_type) } end - register_entity(state.mobs, mob) + register_entity(game_state.mobs, mob) return mob end @@ -376,12 +376,12 @@ end local function can_spawn_mob() local MAX_SPAWN_RATE = 0.1 - if not state.spawning or (state.time - state.last_mob_spawn_time) < MAX_SPAWN_RATE then + if not game_state.spawning or (game_state.time - game_state.last_mob_spawn_time) < MAX_SPAWN_RATE then return false end - if math.random() <= state.spawn_chance then - state.last_mob_spawn_time = state.time + if math.random() <= game_state.spawn_chance then + game_state.last_mob_spawn_time = game_state.time return true else return false @@ -390,7 +390,7 @@ end function do_mob_spawning() if can_spawn_mob() then - if state.current_wave % 2 == 0 then + if game_state.current_wave % 2 == 0 then make_and_register_mob(MOB_TYPE.SPOODER) else make_and_register_mob(MOB_TYPE.BEEPER) @@ -399,7 +399,7 @@ function do_mob_spawning() end function do_mob_updates() - for mob_index,mob in pairs(state.mobs) do + for mob_index,mob in pairs(game_state.mobs) do if mob and mob.update then mob.update(mob, mob_index) end diff --git a/src/projectile.lua b/src/projectile.lua index 88afec4..afaff76 100644 --- a/src/projectile.lua +++ b/src/projectile.lua @@ -75,7 +75,7 @@ local function update_projectile_shell(projectile, projectile_index) x2 = win.right, y2 = win.top }) then - delete_entity(state.projectiles, projectile_index) + delete_entity(game_state.projectiles, projectile_index) return true end @@ -106,7 +106,7 @@ local function update_projectile_shell(projectile, projectile_index) end end - local tile = hex_map_get(state.map, projectile.hex) + local tile = hex_map_get(game_state.map, projectile.hex) if tile and tile.elevation >= projectile.props.z then --do_explode = true @@ -120,7 +120,7 @@ local function update_projectile_shell(projectile, projectile_index) do_hit_mob(mob, damage, index) end win.scene:append(make_shell_explosion_node(projectile.position)) - delete_entity(state.projectiles, projectile_index) + delete_entity(game_state.projectiles, projectile_index) return true end end @@ -135,7 +135,7 @@ local function update_projectile_laser(projectile, projectile_index) x2 = win.right, y2 = win.top }) then - delete_entity(state.projectiles, projectile_index) + delete_entity(game_state.projectiles, projectile_index) return true end @@ -192,7 +192,7 @@ local function update_projectile_bullet(projectile, projectile_index) x2 = win.right, y2 = win.top }) then - delete_entity(state.projectiles, projectile_index) + delete_entity(game_state.projectiles, projectile_index) return true end @@ -275,7 +275,7 @@ function make_and_register_projectile(hex, projectile_type, vector) projectile.damage = spec.damage projectile.hitbox_radius = spec.hitbox_radius - register_entity(state.projectiles, projectile) + register_entity(game_state.projectiles, projectile) return projectile end @@ -298,7 +298,7 @@ function projectile_deserialize(json_string) end function do_projectile_updates() - for projectile_index,projectile in pairs(state.projectiles) do + for projectile_index,projectile in pairs(game_state.projectiles) do if projectile and projectile.update then projectile.update(projectile, projectile_index) end diff --git a/src/tower.lua b/src/tower.lua index 369e2d7..6b7048c 100644 --- a/src/tower.lua +++ b/src/tower.lua @@ -141,14 +141,14 @@ function make_tower_node(tower_type) elseif tower_type == TOWER_TYPE.GATTLER then return am.group{ am.circle(vec2(0), HEX_SIZE - 4, COLORS.VERY_DARK_GRAY, 5), - am.rotate(state.time or 0) + am.rotate(game_state.time or 0) ^ pack_texture_into_sprite(TEXTURES.TOWER_HOWITZER, HEX_PIXEL_HEIGHT*1.5, HEX_PIXEL_WIDTH*2, COLORS.GREEN_YELLOW) } elseif tower_type == TOWER_TYPE.HOWITZER then return am.group{ am.circle(vec2(0), HEX_SIZE - 4, COLORS.VERY_DARK_GRAY, 6), - am.rotate(state.time or 0) ^ am.group{ + am.rotate(game_state.time or 0) ^ am.group{ pack_texture_into_sprite(TEXTURES.TOWER_HOWITZER, HEX_PIXEL_HEIGHT*1.5, HEX_PIXEL_WIDTH*2) -- CHONK } } @@ -223,7 +223,7 @@ end local function update_tower_redeye(tower, tower_index) if not tower.target_index then - for index,mob in pairs(state.mobs) do + for index,mob in pairs(game_state.mobs) do if mob then local d = math.distance(mob.hex, tower.hex) if d <= tower.range then @@ -233,11 +233,11 @@ local function update_tower_redeye(tower, tower_index) end end else - if not state.mobs[tower.target_index] then + if not game_state.mobs[tower.target_index] then tower.target_index = false - elseif (state.time - tower.last_shot_time) > tower.fire_rate then - local mob = state.mobs[tower.target_index] + elseif (game_state.time - tower.last_shot_time) > tower.fire_rate then + local mob = game_state.mobs[tower.target_index] make_and_register_projectile( tower.hex, @@ -245,7 +245,7 @@ local function update_tower_redeye(tower, tower_index) math.normalize(mob.position - tower.position) ) - tower.last_shot_time = state.time + tower.last_shot_time = game_state.time vplay_sfx(SOUNDS.LASER2) end end @@ -254,7 +254,7 @@ end local function update_tower_gattler(tower, tower_index) if not tower.target_index then -- we should try and acquire a target - for index,mob in pairs(state.mobs) do + for index,mob in pairs(game_state.mobs) do if mob then local d = math.distance(mob.hex, tower.hex) if d <= tower.range then @@ -268,23 +268,23 @@ local function update_tower_gattler(tower, tower_index) tower.node("rotate").angle = math.wrapf(tower.node("rotate").angle + 0.1 * am.delta_time, math.pi*2) else -- should have a target, so we should try and shoot it - if not state.mobs[tower.target_index] then + if not game_state.mobs[tower.target_index] then -- the target we have was invalidated tower.target_index = false else -- the target we have is valid - local mob = state.mobs[tower.target_index] + local mob = game_state.mobs[tower.target_index] local vector = math.normalize(mob.position - tower.position) - if (state.time - tower.last_shot_time) > tower.fire_rate then + if (game_state.time - tower.last_shot_time) > tower.fire_rate then local projectile = make_and_register_projectile( tower.hex, PROJECTILE_TYPE.BULLET, vector ) - tower.last_shot_time = state.time + tower.last_shot_time = game_state.time play_sfx(SOUNDS.HIT1) end @@ -300,7 +300,7 @@ end local function update_tower_howitzer(tower, tower_index) if not tower.target_index then -- we don't have a target - for index,mob in pairs(state.mobs) do + for index,mob in pairs(game_state.mobs) do if mob then local d = math.distance(mob.hex, tower.hex) if d <= tower.range then @@ -315,16 +315,16 @@ local function update_tower_howitzer(tower, tower_index) else -- we should have a target -- @NOTE don't compare to false, empty indexes appear on game reload - if not state.mobs[tower.target_index] then + if not game_state.mobs[tower.target_index] then -- the target we have was invalidated tower.target_index = false else -- the target we have is valid - local mob = state.mobs[tower.target_index] + local mob = game_state.mobs[tower.target_index] local vector = math.normalize(mob.position - tower.position) - if (state.time - tower.last_shot_time) > tower.fire_rate then + if (game_state.time - tower.last_shot_time) > tower.fire_rate then local projectile = make_and_register_projectile( tower.hex, PROJECTILE_TYPE.SHELL, @@ -336,7 +336,7 @@ local function update_tower_howitzer(tower, tower_index) -- if it's not enough the shell explodes before it leaves its spawning hex projectile.props.z = tower.props.z + 0.1 - tower.last_shot_time = state.time + tower.last_shot_time = game_state.time play_sfx(SOUNDS.EXPLOSION2) end @@ -360,7 +360,7 @@ local function update_tower_lighthouse(tower, tower_index) -- is within some angle range...? if the mob is heading directly away from the tower, then -- the lighthouse shouldn't do much - local path, made_it = hex_Astar(state.map, tower.hex, m.hex, grid_neighbours, grid_cost, grid_heuristic) + local path, made_it = hex_Astar(game_state.map, tower.hex, m.hex, grid_neighbours, grid_cost, grid_heuristic) if made_it then m.path = path @@ -369,7 +369,7 @@ local function update_tower_lighthouse(tower, tower_index) --[[ local area = spiral_map(tower.hex, tower.range) for _,h in pairs(area) do - local node = state.map[h.x][h.y].node"circle" + local node = game_state.map[h.x][h.y].node"circle" local initial_color = node.color local d = math.distance(h, tower.hex) @@ -426,7 +426,7 @@ end function towers_on_hex(hex) local t = {} - for tower_index,tower in pairs(state.towers) do + for tower_index,tower in pairs(game_state.towers) do if tower then for _,h in pairs(tower.hexes) do if h == hex then @@ -440,7 +440,7 @@ function towers_on_hex(hex) end function tower_on_hex(hex) - return table.find(state.towers, function(tower) + return table.find(game_state.towers, function(tower) for _,h in pairs(tower.hexes) do if h == hex then return true end end @@ -464,7 +464,7 @@ function tower_type_is_buildable_on(hex, tile, tower_type) table.merge(blocking_towers, towers_on_hex(h)) table.merge(blocking_mobs, mobs_on_hex(h)) - local tile = hex_map_get(state.map, h) + local tile = hex_map_get(game_state.map, h) -- this should always be true, unless it is possible to place a tower -- where part of the tower overflows the edge of the map if tile then @@ -488,7 +488,7 @@ function tower_type_is_buildable_on(hex, tile, tower_type) local has_mountain_neighbour = false local has_non_wall_non_moat_tower_neighbour = false for _,h in pairs(hex_neighbours(hex)) do - local tile = hex_map_get(state.map, h) + local tile = hex_map_get(game_state.map, h) if tile and tile.elevation >= 0.5 then has_mountain_neighbour = true @@ -518,7 +518,7 @@ function tower_type_is_buildable_on(hex, tile, tower_type) break end - local tile = hex_map_get(state.map, h) + local tile = hex_map_get(game_state.map, h) if not wall_on_hex and tile and tile.elevation >= 0.5 then has_mountain_neighbour = true break @@ -533,7 +533,7 @@ function tower_type_is_buildable_on(hex, tile, tower_type) elseif tower_type == TOWER_TYPE.LIGHTHOUSE then local has_water_neighbour = false for _,h in pairs(hex_neighbours(hex)) do - local tile = hex_map_get(state.map, h) + local tile = hex_map_get(game_state.map, h) if tile and tile.elevation < -0.5 then has_water_neighbour = true @@ -577,7 +577,7 @@ function make_and_register_tower(hex, tower_type) tower.height = spec.height for _,h in pairs(tower.hexes) do - local tile = hex_map_get(state.map, h.x, h.y) + local tile = hex_map_get(game_state.map, h.x, h.y) tile.elevation = tile.elevation + tower.height end @@ -591,7 +591,7 @@ function make_and_register_tower(hex, tower_type) tower.perimeter = hex_ring_map(tower.hex, tower.range) end - register_entity(state.towers, tower) + register_entity(game_state.towers, tower) return tower end @@ -603,7 +603,7 @@ function build_tower(hex, tower_type) end function do_tower_updates() - for tower_index,tower in pairs(state.towers) do + for tower_index,tower in pairs(game_state.towers) do if tower and tower.update then tower.update(tower, tower_index) end