Browse Source

sorta fix some stuff

master
Nicholas Hayashi 4 years ago
parent
commit
1dbdb44b5b
  1. 4
      main.lua
  2. BIN
      res/thing.png
  3. 36
      src/game.lua
  4. 28
      src/grid.lua
  5. 40
      src/gui.lua
  6. 15
      src/projectile.lua
  7. 39
      src/tower.lua

4
main.lua

@ -15,6 +15,7 @@ do
title = title, title = title,
highdpi = true, highdpi = true,
letterbox = true, letterbox = true,
--mode = "fullscreen",
--projection = projection --projection = projection
} }
@ -32,17 +33,14 @@ require "src/geometry"
require "src/hexyz" require "src/hexyz"
require "src/game" require "src/game"
require "src/grid" require "src/grid"
require "src/gui"
require "src/mob" require "src/mob"
require "src/projectile" require "src/projectile"
require "src/tower" require "src/tower"
-- global audio settings -- global audio settings
MUSIC_VOLUME = 0.1 MUSIC_VOLUME = 0.1
SFX_VOLUME = 0.1 SFX_VOLUME = 0.1
function main_action() end function main_action() end
function main_scene() end function main_scene() end

BIN
res/thing.png

Before

Width: 287  |  Height: 309  |  Size: 6.7 KiB

After

Width: 287  |  Height: 309  |  Size: 5.8 KiB

36
src/game.lua

@ -38,7 +38,7 @@ local function get_initial_game_state(seed)
money = STARTING_MONEY, -- current money money = STARTING_MONEY, -- current money
current_wave = 1, current_wave = 1,
time_until_next_wave = 15,
time_until_next_wave = 0,
time_until_next_break = 0, time_until_next_break = 0,
spawning = false, spawning = false,
spawn_chance = 55, spawn_chance = 55,
@ -142,7 +142,7 @@ local function game_action(scene)
state.time = state.time + am.delta_time state.time = state.time + am.delta_time
state.score = state.score + am.delta_time state.score = state.score + am.delta_time
--state.spawn_chance = math.clamp(state.spawn_chance - math.floor(state.time / 100), 1, 25)
state.spawn_chance = math.clamp(state.spawn_chance - math.floor(state.time / 100), 1, 25)
if state.spawning then if state.spawning then
state.time_until_next_break = state.time_until_next_break - am.delta_time state.time_until_next_break = state.time_until_next_break - am.delta_time
@ -187,15 +187,15 @@ local function game_action(scene)
local node = WIN.scene("cursor"):child(2) local node = WIN.scene("cursor"):child(2)
node.color = COLORS.CLARET node.color = COLORS.CLARET
node:action(am.tween(0.1, { color = COLORS.TRANSPARENT })) node:action(am.tween(0.1, { color = COLORS.TRANSPARENT }))
alert("breaks flow field")
play_sfx(SOUNDS.BIRD2) play_sfx(SOUNDS.BIRD2)
alert("breaks flow field")
elseif cost > state.money then elseif cost > state.money then
local node = WIN.scene("cursor"):child(2) local node = WIN.scene("cursor"):child(2)
node.color = COLORS.CLARET node.color = COLORS.CLARET
node:action(am.tween(0.1, { color = COLORS.TRANSPARENT })) node:action(am.tween(0.1, { color = COLORS.TRANSPARENT }))
alert("not enough $$$$")
play_sfx(SOUNDS.BIRD2) play_sfx(SOUNDS.BIRD2)
alert("not enough $$$$")
else else
update_money(-cost) update_money(-cost)
@ -232,15 +232,15 @@ local function game_action(scene)
else else
select_toolbelt_button((state.selected_toolbelt_button) % table.count(TOWER_TYPE) + 1) select_toolbelt_button((state.selected_toolbelt_button) % table.count(TOWER_TYPE) + 1)
end end
elseif WIN:key_pressed"1" then select_toolbelt_button(1)
elseif WIN:key_pressed"2" then select_toolbelt_button(2)
elseif WIN:key_pressed"3" then select_toolbelt_button(3)
elseif WIN:key_pressed"4" then select_toolbelt_button(4)
elseif WIN:key_pressed"q" then select_toolbelt_button(5)
elseif WIN:key_pressed"w" then select_toolbelt_button(6)
elseif WIN:key_pressed"e" then select_toolbelt_button(7)
elseif WIN:key_pressed"r" then select_toolbelt_button(8)
elseif WIN:key_pressed"a" then select_toolbelt_button(9)
elseif WIN:key_pressed"1" then select_toolbelt_button( 1)
elseif WIN:key_pressed"2" then select_toolbelt_button( 2)
elseif WIN:key_pressed"3" then select_toolbelt_button( 3)
elseif WIN:key_pressed"4" then select_toolbelt_button( 4)
elseif WIN:key_pressed"q" then select_toolbelt_button( 5)
elseif WIN:key_pressed"w" then select_toolbelt_button( 6)
elseif WIN:key_pressed"e" then select_toolbelt_button( 7)
elseif WIN:key_pressed"r" then select_toolbelt_button( 8)
elseif WIN:key_pressed"a" then select_toolbelt_button( 9)
elseif WIN:key_pressed"s" then select_toolbelt_button(10) elseif WIN:key_pressed"s" then select_toolbelt_button(10)
elseif WIN:key_pressed"d" then select_toolbelt_button(11) elseif WIN:key_pressed"d" then select_toolbelt_button(11)
elseif WIN:key_pressed"f" then select_toolbelt_button(12) elseif WIN:key_pressed"f" then select_toolbelt_button(12)
@ -248,7 +248,6 @@ local function game_action(scene)
do_entity_updates() do_entity_updates()
do_mob_spawning(state.spawn_chance) do_mob_spawning(state.spawn_chance)
do_gui_updates()
do_day_night_cycle() do_day_night_cycle()
if interactable then if interactable then
@ -379,7 +378,6 @@ local function make_game_toolbelt()
end end
select_tower_type = function(tower_type) select_tower_type = function(tower_type)
log(tower_type)
state.selected_tower_type = tower_type state.selected_tower_type = tower_type
if get_tower_spec(tower_type) then if get_tower_spec(tower_type) then
@ -475,9 +473,11 @@ end
function game_init() function game_init()
state = get_initial_game_state() state = get_initial_game_state()
build_tower(HEX_GRID_CENTER, TOWER_TYPE.RADAR)
-- @HACK to make the center tile passable even though there's a tower on it
state.map.get(HEX_GRID_CENTER.x, HEX_GRID_CENTER.y).elevation = 0
local home_tower = build_tower(HEX_GRID_CENTER, TOWER_TYPE.RADAR)
for _,h in pairs(home_tower.hexes) do
-- @HACK to make the center tile(s) passable even though there's a tower on it
state.map.get(h.x, h.y).elevation = 0
end
WIN.scene:remove("game") WIN.scene:remove("game")
WIN.scene:append(game_scene()) WIN.scene:append(game_scene())

28
src/grid.lua

@ -130,13 +130,14 @@ function apply_flow_field(map, flow_field, world)
end end
function building_tower_breaks_flow_field(tower_type, hex) function building_tower_breaks_flow_field(tower_type, hex)
local hexes = spiral_map(hex, get_tower_size(tower_type))
local original_elevations = {} local original_elevations = {}
local all_impassable = true
local hexes = spiral_map(hex, get_tower_size(tower_type))
for _,h in pairs(hexes) do for _,h in pairs(hexes) do
local tile = state.map.get(h.x, h.y) local tile = state.map.get(h.x, h.y)
if not mob_can_pass_through(nil, h, tile) then
return false
if all_impassable and mob_can_pass_through(nil, h) then
all_impassable = false
end end
table.insert(original_elevations, tile.elevation) table.insert(original_elevations, tile.elevation)
@ -145,9 +146,18 @@ function building_tower_breaks_flow_field(tower_type, hex)
tile.elevation = 999 tile.elevation = 999
end end
-- 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)
if all_impassable then
for i,h in pairs(hexes) do
state.map.get(h.x, h.y).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(state.map, HEX_GRID_CENTER)
local result = not hex_map_get(flow_field, 0, 0) local result = not hex_map_get(flow_field, 0, 0)
log(result)
for i,h in pairs(hexes) do for i,h in pairs(hexes) do
state.map.get(h.x, h.y).elevation = original_elevations[i] state.map.get(h.x, h.y).elevation = original_elevations[i]
@ -164,7 +174,14 @@ function random_map(seed)
-- tone to give the appearance of light or darkness -- tone to give the appearance of light or darkness
-- @NOTE replace this with a shader program -- @NOTE replace this with a shader program
-- interestingly, if it's colored white, it almost gives the impression of a winter biome -- interestingly, if it's colored white, it almost gives the impression of a winter biome
local neg_mask = am.rect(0, 0, HEX_GRID_PIXEL_WIDTH, HEX_GRID_PIXEL_HEIGHT, COLORS.TRUE_BLACK):tag"negative_mask"
local neg_mask = am.rect(
0,
0,
HEX_GRID_PIXEL_WIDTH,
HEX_GRID_PIXEL_HEIGHT,
COLORS.TRUE_BLACK
)
:tag"negative_mask"
local world = am.group(neg_mask):tag"world" local world = am.group(neg_mask):tag"world"
for i,_ in pairs(map) do for i,_ in pairs(map) do
@ -209,6 +226,7 @@ function random_map(seed)
getmetatable(map).__index.neighbours = function(hex) getmetatable(map).__index.neighbours = function(hex)
return table.filter(hex_neighbours(hex), function(_hex) return table.filter(hex_neighbours(hex), function(_hex)
--local interactable = evenq_is_in_interactable_region(hex_to_evenq(_hex))
local tile = map.get(_hex.x, _hex.y) local tile = map.get(_hex.x, _hex.y)
return tile and tile_is_medium_elevation(tile) return tile and tile_is_medium_elevation(tile)
end) end)

40
src/gui.lua

@ -1,40 +0,0 @@
local hot, active = false, false
local widgets = {}
function get_widgets() return widgets end
function register_widget(id, poll)
widgets[id] = { id = id, poll = poll }
end
function set_hot(id)
if not active then hot = { id = id } end
end
function register_button_widget(id, rect, onclick)
register_widget(id, function(i)
local click = false
if active and active.id == id then
if WIN:mouse_released"left" then
if hot and hot.id == id then click = true end
active = false
end
elseif hot and hot.id == id then
if WIN:mouse_pressed"left" then active = { id = id } end
end
if point_in_rect(WIN:mouse_position(), rect) then set_hot(id) end
if click then onclick() end
end)
end
function do_gui_updates()
for i,w in pairs(widgets) do
w.poll(i)
end
end

15
src/projectile.lua

@ -10,7 +10,7 @@ PROJECTILE_TYPE = {
local PROJECTILE_SPECS = { local PROJECTILE_SPECS = {
[PROJECTILE_TYPE.SHELL] = { [PROJECTILE_TYPE.SHELL] = {
velocity = 13, velocity = 13,
damage = 20,
damage = 15,
hitbox_radius = 20 hitbox_radius = 20
}, },
[PROJECTILE_TYPE.LASER] = { [PROJECTILE_TYPE.LASER] = {
@ -105,10 +105,10 @@ local function update_projectile_shell(projectile, projectile_index)
local tile = state.map.get(projectile.hex.x, projectile.hex.y) local tile = state.map.get(projectile.hex.x, projectile.hex.y)
if tile and tile.elevation >= projectile.props.z then if tile and tile.elevation >= projectile.props.z then
do_explode = true
--do_explode = true
elseif projectile.props.z <= 0 then elseif projectile.props.z <= 0 then
do_explode = true
--do_explode = true
end end
if do_explode then if do_explode then
@ -200,9 +200,12 @@ function get_projectile_update_function(projectile_type)
end end
function make_and_register_projectile(hex, projectile_type, vector) function make_and_register_projectile(hex, projectile_type, vector)
local projectile = make_basic_entity(hex
, make_projectile_node(projectile_type, vector)
, get_projectile_update_function(projectile_type))
local projectile = make_basic_entity(
hex,
make_projectile_node(projectile_type, vector),
get_projectile_update_function(projectile_type)
)
projectile.type = projectile_type projectile.type = projectile_type
projectile.vector = vector projectile.vector = vector

39
src/tower.lua

@ -30,7 +30,7 @@ TOWER_SPECS = {
}, },
[TOWER_TYPE.HOWITZER] = { [TOWER_TYPE.HOWITZER] = {
name = "Howitzer", name = "Howitzer",
placement_rules_text = "Place on non-Water",
placement_rules_text = "Place on non-Water, non-Mountain or on Walls",
short_description = "Fires artillery. Range increases with elevation of terrain underneath.", short_description = "Fires artillery. Range increases with elevation of terrain underneath.",
texture = TEXTURES.TOWER_HOWITZER, texture = TEXTURES.TOWER_HOWITZER,
icon_texture = TEXTURES.TOWER_HOWITZER_ICON, icon_texture = TEXTURES.TOWER_HOWITZER_ICON,
@ -73,7 +73,7 @@ TOWER_SPECS = {
cost = 20, cost = 20,
range = 0, range = 0,
fire_rate = 1, fire_rate = 1,
size = 1,
size = 0,
height = 1, height = 1,
}, },
[TOWER_TYPE.LIGHTHOUSE] = { [TOWER_TYPE.LIGHTHOUSE] = {
@ -133,7 +133,9 @@ local function make_tower_node(tower_type)
elseif tower_type == TOWER_TYPE.HOWITZER then elseif tower_type == TOWER_TYPE.HOWITZER then
return am.group{ return am.group{
pack_texture_into_sprite(TEXTURES.HEX_FLOWER, HEX_FLOWER_DIMENSIONS.x, HEX_FLOWER_DIMENSIONS.y), pack_texture_into_sprite(TEXTURES.HEX_FLOWER, HEX_FLOWER_DIMENSIONS.x, HEX_FLOWER_DIMENSIONS.y),
am.rotate(0) ^ pack_texture_into_sprite(TEXTURES.CANNON1, 100, 100)
am.rotate(state.time or 0) ^ am.group{
pack_texture_into_sprite(TEXTURES.CANNON1, 100, 100)
}
} }
elseif tower_type == TOWER_TYPE.LIGHTHOUSE then elseif tower_type == TOWER_TYPE.LIGHTHOUSE then
return am.group{ return am.group{
@ -286,7 +288,7 @@ function tower_type_is_buildable_on(hex, tile, tower_type)
end end
end end
end end
return not (blocked or has_water)
return not (blocked or has_water or has_mountain)
elseif tower_type == TOWER_TYPE.REDEYE then elseif tower_type == TOWER_TYPE.REDEYE then
if not mobs_blocking and towers_blocking then if not mobs_blocking and towers_blocking then
@ -359,6 +361,7 @@ end
function update_tower_howitzer(tower, tower_index) function update_tower_howitzer(tower, tower_index)
if not tower.target_index then if not tower.target_index then
-- we don't have a target
for index,mob in pairs(MOBS) do for index,mob in pairs(MOBS) do
if mob then if mob then
local d = math.distance(mob.hex, tower.hex) local d = math.distance(mob.hex, tower.hex)
@ -368,19 +371,23 @@ function update_tower_howitzer(tower, tower_index)
end end
end end
end end
tower.node("rotate").angle = math.wrapf(tower.node("rotate").angle + 0.2 * am.delta_time, math.pi*2)
else else
-- we should have a target
if MOBS[tower.target_index] == false then if MOBS[tower.target_index] == false then
-- the target we have was invalidated
tower.target_index = false tower.target_index = false
elseif (state.time - tower.last_shot_time) > tower.fire_rate then
else
-- the target we have is valid
local mob = MOBS[tower.target_index] local mob = MOBS[tower.target_index]
local theta = math.atan((tower.hex.y - mob.hex.y)/(tower.hex.x - mob.hex.x))
local vector = math.normalize(mob.position - tower.position)
if (theta - tower.node("rotate").angle) < 0.1 then
if (state.time - tower.last_shot_time) > tower.fire_rate then
local projectile = make_and_register_projectile( local projectile = make_and_register_projectile(
tower.hex, tower.hex,
PROJECTILE_TYPE.SHELL, PROJECTILE_TYPE.SHELL,
math.normalize(mob.position - tower.position)
vector
) )
-- @HACK, the projectile will explode if it encounters something taller than it, -- @HACK, the projectile will explode if it encounters something taller than it,
@ -391,11 +398,13 @@ function update_tower_howitzer(tower, tower_index)
tower.last_shot_time = state.time tower.last_shot_time = state.time
play_sfx(SOUNDS.EXPLOSION2) play_sfx(SOUNDS.EXPLOSION2)
end end
else
tower.node("rotate").angle = tower.node("rotate").angle + state.time * 0.5
local theta = math.rad(90) - math.atan((tower.position.y - mob.position.y)/(tower.position.x - mob.position.x))
local diff = tower.node("rotate").angle - theta
tower.node("rotate").angle = -theta + math.pi/2
end end
end end
tower.node("rotate").angle = math.wrapf(tower.node("rotate").angle, math.pi*2)
end end
function update_tower_lighthouse(tower, tower_index) function update_tower_lighthouse(tower, tower_index)
@ -449,7 +458,11 @@ function make_and_register_tower(hex, tower_type)
tower.fire_rate = spec.fire_rate tower.fire_rate = spec.fire_rate
tower.last_shot_time = -spec.fire_rate tower.last_shot_time = -spec.fire_rate
tower.size = spec.size tower.size = spec.size
if tower.size == 0 then
tower.hexes = { tower.hex }
else
tower.hexes = spiral_map(tower.hex, tower.size) tower.hexes = spiral_map(tower.hex, tower.size)
end
tower.height = spec.height tower.height = spec.height
for _,h in pairs(tower.hexes) do for _,h in pairs(tower.hexes) do
@ -466,8 +479,10 @@ function make_and_register_tower(hex, tower_type)
end end
function build_tower(hex, tower_type) function build_tower(hex, tower_type)
make_and_register_tower(hex, tower_type)
local tower = make_and_register_tower(hex, tower_type)
vplay_sfx(SOUNDS.EXPLOSION4) vplay_sfx(SOUNDS.EXPLOSION4)
return tower
end end
function delete_all_towers() function delete_all_towers()

Loading…
Cancel
Save