Compare commits

...

10 Commits

Author SHA1 Message Date
Auri Collings
03aa30b528
Create README.md 2021-12-22 14:10:50 -08:00
Auri
4906995ffb Fix conveyors! 2021-12-21 16:47:39 -08:00
Auri
c87736b60b Add inputs to map 2021-12-21 16:36:12 -08:00
Auri
137c07783d Fix spider spawning and map 2021-12-21 16:31:49 -08:00
Auri
1aebb07540 Fix map and placing machines 2021-12-21 16:21:29 -08:00
Auri
9f1c0cab85 add map 2021-12-21 16:01:13 -08:00
Auri
2f3d73a90c final commit 2021-12-21 16:00:38 -08:00
Auri
523589897f final 2021-12-21 15:58:20 -08:00
Auri
33f1750a24 Fix unbreakable 2021-12-21 15:07:51 -08:00
Auri
19912305c4 New stuff 2021-12-21 14:59:24 -08:00
40 changed files with 590 additions and 182 deletions

13
README.md Normal file
View File

@ -0,0 +1,13 @@
# Tower Defense Game
Unfortunately, this ended up very unfinished. Time management is a bitch, right? Anyways, to play, **move the `map` file from the game folder into your your `worlds` folder and use that.**
KNOWN ISSUES I DIDNT HAVE TIME TO FIX
- Junctions don't work
- Turrets don't work
- Enemies spawn, but don't attack or get damaged. Instant-kill from punching
STUFF THAT DOES WORK
- Resources
- Cool custom hud
- Mining and conveyoring ores into the inputs

BIN
map/auth.sqlite Normal file

Binary file not shown.

7
map/env_meta.txt Normal file
View File

@ -0,0 +1,7 @@
day_count = 0
lbm_introduction_times =
lbm_introduction_times_version = 1
last_clear_objects_time = 0
time_of_day = 12000
game_time = 13544
EnvArgsEnd

1
map/force_loaded.txt Normal file
View File

@ -0,0 +1 @@
return {}

0
map/ipban.txt Normal file
View File

BIN
map/map.sqlite Normal file

Binary file not shown.

47
map/map_meta.txt Normal file
View File

@ -0,0 +1,47 @@
mg_biome_np_humidity_blend = {
flags = defaults
lacunarity = 2
persistence = 1
seed = 90003
spread = (8,8,8)
scale = 1.5
octaves = 2
offset = 0
}
mg_biome_np_heat_blend = {
flags = defaults
lacunarity = 2
persistence = 1
seed = 13
spread = (8,8,8)
scale = 1.5
octaves = 2
offset = 0
}
mg_flags = caves, dungeons, light, decorations, biomes, ores
chunksize = 5
mapgen_limit = 31000
mg_biome_np_heat = {
flags = defaults
lacunarity = 2
persistence = 0.5
seed = 5349
spread = (1000,1000,1000)
scale = 50
octaves = 3
offset = 50
}
water_level = 1
mg_biome_np_humidity = {
flags = defaults
lacunarity = 2
persistence = 0.5
seed = 842
spread = (1000,1000,1000)
scale = 50
octaves = 3
offset = 50
}
seed = 16976184375715180803
mg_name = singlenode
[end_of_params]

BIN
map/players.sqlite Normal file

Binary file not shown.

BIN
map/schems/map_3.mts Normal file

Binary file not shown.

54
map/world.mt Normal file
View File

@ -0,0 +1,54 @@
enable_damage = true
creative_mode = true
auth_backend = sqlite3
player_backend = sqlite3
backend = sqlite3
gameid = lexa
world_name = game test
load_mod_worldeditadditions_farwand = true
load_mod_worldeditadditions = true
load_mod_worldedit_hud_helper = true
load_mod_worldedit_shortcommands = true
load_mod_worldedit_gui = true
load_mod_worldedit_commands = true
load_mod_worldedit = true
load_mod_unified_inventory = true
load_mod_worldeditadditions_commands = true
load_mod_we_undo = true
load_mod_tech_reborn = false
load_mod_skinmaker = false
load_mod_sfinv_home = false
load_mod_sfinv = false
load_mod_vines = false
load_mod_trunks = false
load_mod_poisonivy = false
load_mod_testing = false
load_mod_nature_classic = false
load_mod_3d_armor_sfinv = false
load_mod_3dmushrooms = false
load_mod_3d_armor_ip = false
load_mod_3d_armor_ui = false
load_mod_3d_armor_stand = false
load_mod_along_shore = false
load_mod_3d_armor = false
load_mod_worldedit_brush = true
load_mod_sfinv_buttons = false
load_mod_youngtrees = false
load_mod_dryplants = false
load_mod_wieldview = false
load_mod_oddbar = false
load_mod_aurora_tech = false
load_mod_junglegrass = false
load_mod_woodsoils = false
load_mod_caverealms = false
load_mod_burble = false
load_mod_cavestuff = false
load_mod_ferns = false
load_mod_bushes = false
load_mod_moretrees = false
load_mod_shields = false
load_mod_bushes_classic = false
load_mod_flowers_plus = false
load_mod_molehills = false
server_announce = false
load_mod_dreambuilder_hotbar = false

View File

@ -1,4 +1,5 @@
time_speed = 0
active_block_range = 16
max_forceloaded_blocks = 10000
recent_chat_messages = 0
active_object_send_range_blocks = 8

View File

@ -2,4 +2,4 @@ title = Conveyors
name = lexa_conveyor
author = Aurailus
description = Conveyor belts and entities.
depends = lexa_base
depends = lexa_base, lexa_materials

View File

@ -53,6 +53,91 @@ local conveyor_functions = {
item.object:set_velocity(obj_vel)
end
end,
vertical_mid = function(node_pos, item, delta)
local node = minetest.get_node(node_pos)
local dir = minetest.facedir_to_dir(node.param2)
local obj_pos = item.object:get_pos()
local obj_vel = item.object:get_velocity()
local obj_pos_rel = vector.subtract(obj_pos, node_pos)
-- Move the item along the conveyor's normal towards the middle.
local main_axis = dir.x ~= 0 and 'x' or 'z'
local norm_axis = dir.x == 0 and 'x' or 'z'
obj_vel.y = lexa.conveyor.speed
if obj_pos_rel[norm_axis] > 0.05 then
obj_vel[norm_axis] = -1 * lexa.conveyor.speed
elseif obj_pos_rel[norm_axis] < -0.05 then
obj_vel[norm_axis] = lexa.conveyor.speed
else
obj_vel[norm_axis] = 0
-- Move the item along the conveyor's direction.
obj_vel[main_axis] = dir[main_axis] * lexa.conveyor.speed
end
item.object:set_pos(obj_pos)
item.object:set_velocity(obj_vel)
end,
vertical_bottom = function(node_pos, item, delta)
local node = minetest.get_node(node_pos)
local dir = minetest.facedir_to_dir(node.param2)
local obj_pos = item.object:get_pos()
local obj_vel = item.object:get_velocity()
local obj_pos_rel = vector.subtract(obj_pos, node_pos)
-- Move the item along the conveyor's normal towards the middle.
local main_axis = dir.x ~= 0 and 'x' or 'z'
local norm_axis = dir.x == 0 and 'x' or 'z'
local across = obj_pos_rel[main_axis] * ((node.param2 == 3 or node.param2 == 2) and -1 or 1)
obj_vel.y = across > 0 and lexa.conveyor.speed or 0
if obj_pos_rel[norm_axis] > 0.05 then
obj_vel[norm_axis] = -1 * lexa.conveyor.speed
elseif obj_pos_rel[norm_axis] < -0.05 then
obj_vel[norm_axis] = lexa.conveyor.speed
else
obj_vel[norm_axis] = 0
-- Move the item along the conveyor's direction.
obj_vel[main_axis] = dir[main_axis] * lexa.conveyor.speed
end
item.object:set_pos(obj_pos)
item.object:set_velocity(obj_vel)
end,
vertical_top = function(node_pos, item, delta)
local node = minetest.get_node(node_pos)
local dir = minetest.facedir_to_dir(node.param2)
local obj_pos = item.object:get_pos()
local obj_vel = item.object:get_velocity()
local obj_pos_rel = vector.subtract(obj_pos, node_pos)
-- Move the item along the conveyor's normal towards the middle.
local main_axis = dir.x ~= 0 and 'x' or 'z'
local norm_axis = dir.x == 0 and 'x' or 'z'
local across = obj_pos_rel[main_axis] * ((node.param2 == 3 or node.param2 == 2) and -1 or 1)
obj_vel.y = across < 0 and lexa.conveyor.speed or 0
if obj_pos_rel[norm_axis] > 0.05 then
obj_vel[norm_axis] = -1 * lexa.conveyor.speed
elseif obj_pos_rel[norm_axis] < -0.05 then
obj_vel[norm_axis] = lexa.conveyor.speed
else
obj_vel[norm_axis] = 0
-- Move the item along the conveyor's direction.
obj_vel[main_axis] = dir[main_axis] * lexa.conveyor.speed
end
item.object:set_pos(obj_pos)
item.object:set_velocity(obj_vel)
end
}
@ -169,6 +254,8 @@ function handle_destruct_conveyor(pos, node)
end
end
local build_cost = { copper = 2 }
for _, type in ipairs({ 'horizontal_start', 'horizontal_mid', 'horizontal_end',
'mono', 'vertical_bottom', 'vertical_mid', 'vertical_top' }) do
@ -185,7 +272,7 @@ for _, type in ipairs({ 'horizontal_start', 'horizontal_mid', 'horizontal_end',
length = 0.25
} }, 'lexa_conveyor_belt_frame.png' },
description = 'Belt',
_cost = { copper = 2 },
_cost = build_cost,
selection_box = {
type = 'fixed',
fixed = selection_box
@ -200,10 +287,13 @@ for _, type in ipairs({ 'horizontal_start', 'horizontal_mid', 'horizontal_end',
groups = {
dig_game = 1,
conveyor = type:match('vertical') and 2 or 1,
not_in_creative_inventory = type ~= 'mono' and 1 or 0
not_in_creative_inventory = type ~= 'mono' and 1 or 0,
enemy_target = 70
},
_conveyor_function = conveyor_functions[type] or conveyor_functions.horizontal,
drop = '',
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
on_construct = handle_construct_conveyor,
after_destruct = handle_destruct_conveyor
})

View File

@ -1,6 +1,8 @@
local build_cost = { copper = 5 }
minetest.register_node('lexa_conveyor:distributor', {
description = 'Distributor',
_cost = { copper = 5 },
_cost = build_cost,
drawtype = 'mesh',
use_texture_alpha = 'clip',
mesh = 'lexa_conveyor_machine.b3d',
@ -23,6 +25,7 @@ minetest.register_node('lexa_conveyor:distributor', {
groups = {
conveyor = 3,
dig_game = 1,
enemy_target = 70
},
_conveyor_function = function(node_pos, item, delta)
local node = minetest.get_node(node_pos)
@ -82,5 +85,7 @@ minetest.register_node('lexa_conveyor:distributor', {
end
end
end,
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
drop = ''
})

View File

@ -60,3 +60,30 @@ lexa.conveyor.entity.on_step = function(self, delta)
end
end
end
minetest.register_entity('lexa_conveyor:ore_chunk', {
visual = 'mesh',
mesh = 'lexa_materials_chunk.b3d',
visual_size = vector.new(10, 10, 10),
collisionbox = { -4/16, -8/16 -4/16, 4/16, -4/16, 4/16 },
selectionbox = { -4/16, -8/16, -4/16, 4/16, -4/16, 4/16 },
on_activate = function(self, static_data)
lexa.conveyor.entity.on_activate(self)
self.type = static_data
self.object:set_properties({ textures = { 'lexa_materials_chunk_' .. self.type .. '.png' } })
self.object:set_rotation(vector.new(0, math.rad(math.floor(math.random() * 12) * 30), 0))
end,
on_punch = function(self) self.object:remove() end,
on_step = lexa.conveyor.entity.on_step,
get_staticdata = function(self) return self.type end
})
minetest.register_chatcommand('spawn_ore', {
params = '<type>',
privs = { cheats = true },
description = 'Spawns an ore chunk of the type specified.',
func = function(name, type)
local player = minetest.get_player_by_name(name)
minetest.add_entity(vector.round(player:get_pos()), 'lexa_conveyor:ore_chunk', type)
end
})

View File

@ -1,6 +1,8 @@
local build_cost = { copper = 5 }
minetest.register_node('lexa_conveyor:junction', {
description = 'Junction',
_cost = { copper = 5 },
_cost = build_cost,
drawtype = 'mesh',
use_texture_alpha = 'clip',
mesh = 'lexa_conveyor_machine.b3d',
@ -22,6 +24,7 @@ minetest.register_node('lexa_conveyor:junction', {
groups = {
conveyor = 3,
dig_game = 1,
enemy_target = 70
},
_conveyor_function = function(node_pos, item, delta)
local obj_pos = item.object:get_pos()
@ -44,5 +47,7 @@ minetest.register_node('lexa_conveyor:junction', {
item.object:set_velocity(obj_vel)
end
end,
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
drop = ''
})

View File

@ -14,25 +14,28 @@ minetest.register_entity('lexa_enemy:spider', {
end,
on_step = function(self, dtime, collision)
if not self.path then
if not navigation.graph then return end
local start = minetest.get_us_time()
self.path = navigation.find_path(
navigation.graph, vector.round(self.object:get_pos()), navigation.graph.player_spawn)
minetest.chat_send_all('Pathfinding took ' .. (minetest.get_us_time() - start) / 1000)
if not self.path then return end
self.path_index = #self.path - 1
for _, node in ipairs(self.path) do
minetest.add_particle({
pos = node,
size = 16,
expirationtime = 3,
texture = 'navigation_indicator.png'
})
end
self.object:remove()
return
end
-- if not lexa.match.state.graph then return end
-- local start = minetest.get_us_time()
-- self.path = lexa.nav.find_path(
-- lexa.match.state.graph, vector.round(self.object:get_pos()), lexa.match.state.graph.player_spawn)
-- minetest.chat_send_all('Pathfinding took ' .. (minetest.get_us_time() - start) / 1000)
-- if not self.path then return end
-- self.path_index = #self.path - 1
-- for _, node in ipairs(self.path) do
-- minetest.add_particle({
-- pos = node,
-- size = 16,
-- expirationtime = 3,
-- texture = 'navigation_indicator.png'
-- })
-- end
-- end
local pos_2d = self.object:get_pos()
pos_2d.y = 0

View File

@ -2,4 +2,4 @@ title = Factory
name = lexa_factory
author = Aurailus
description = Machines to place in the world.
depends = lexa_base
depends = lexa_base, lexa_materials

View File

@ -14,9 +14,38 @@ minetest.register_entity('lexa_factory:drill_entity', {
end
})
local function get_ores(pos)
local count = { copper = 0, titanium = 0, cobalt = 0 }
for _, pos in ipairs({
vector.add(pos, vector.new(0, -1, 0)),
vector.add(pos, vector.new(1, -1, 0)),
vector.add(pos, vector.new(0, -1, 1)),
vector.add(pos, vector.new(1, -1, 1))
}) do
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
if def and def._ore_type then count[def._ore_type] = count[def._ore_type] + 1 end
end
local max = count.copper > count.titanium and count.copper > count.cobalt and 'copper' or count.cobalt > count.titanium and 'titanium' or 'cobalt'
return max, count[max] / 4
end
local build_cost = { copper = 10 }
local spawn_offset = {
[0] = vector.new(0, 0, -0.6),
[1] = vector.new(-0.6, 0, 0),
[2] = vector.new(0, 0, 0.5),
[3] = vector.new(0.5, 0, 0)
}
minetest.register_node('lexa_factory:drill', {
description = 'Drill',
_cost = { copper = 10 },
_cost = build_cost,
drawtype = 'mesh',
use_texture_alpha = 'clip',
mesh = 'lexa_factory_drill_node.b3d',
@ -33,20 +62,49 @@ minetest.register_node('lexa_factory:drill', {
fixed = { -8/16, -8/16, -8/16, 24/16, 24/16, 24/16 }
},
paramtype = 'light',
paramtype2 = 'facedier',
paramtype2 = 'facedir',
sunlight_propagates = true,
groups = {
oddly_breakable_by_hand = 3,
dig_game = 1,
enemy_target = 70
},
drop = '',
on_construct = function(pos)
minetest.add_entity(pos, 'lexa_factory:drill_entity', minetest.serialize({ node_pos = pos }))
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
after_place_node = function(pos)
local node = minetest.get_node(pos)
minetest.chat_send_all(tostring(node.param2))
local base_pos = table.copy(pos)
if node.param2 == 1 or node.param2 == 2 then base_pos.z = base_pos.z - 1 end
if node.param2 == 3 or node.param2 == 2 then base_pos.x = base_pos.x - 1 end
local type, count = get_ores(base_pos)
local meta = minetest.get_meta(pos)
meta:set_string('type', type)
if count > 0 then
local timer = minetest.get_node_timer(pos)
timer:start(3 - count * 2.5)
end
minetest.add_entity(base_pos, 'lexa_factory:drill_entity', minetest.serialize({ node_pos = pos }))
end,
on_timer = function(pos)
local node = minetest.get_node(pos)
local type = minetest.get_meta(pos):get_string('type')
minetest.add_entity(vector.add(pos, spawn_offset[node.param2]), 'lexa_conveyor:ore_chunk', type)
return true
end,
after_destruct = function(pos)
local entities = minetest.get_objects_in_area(pos, pos)
local entities = minetest.get_objects_in_area(vector.add(pos, vector.new(-1, -1, -1)), vector.add(pos, vector.new(1, 1, 1)))
for _, entity in ipairs(entities) do
local lua_entity = entity:get_luaentity()
if lua_entity and lua_entity.node_pos.x == pos.x and lua_entity.node_pos.y == pos.y
if lua_entity and lua_entity.node_pos and lua_entity.node_pos.x == pos.x and lua_entity.node_pos.y == pos.y
and lua_entity.node_pos.z == pos.z then
entity:remove()
end

View File

@ -25,10 +25,22 @@ minetest.register_craftitem('lexa_hud:item_placeholder', {
local inv = player:get_inventory()
local item = inv:get_stack('menu_category_' .. menu.selected._, menu.selected[menu.selected._])
local def = minetest.registered_items[item:get_name()]
if def.on_place then
def.on_place(item, player, target)
else
minetest.item_place(item, player, target)
local above = minetest.get_node(target.above).name
local above_def = minetest.registered_nodes[above]
if above_def and above_def._navigation and above_def._navigation.placeable then
minetest.set_node(target.above, { name = 'air' })
if def.on_place then
def.on_place(item, player, target)
else
minetest.item_place(item, player, target)
end
if minetest.get_node(target.above).name == 'air' then
minetest.set_node(target.above, { name = above })
end
local meta = minetest:get_meta(target.above)
meta:set_string('nav_node', above)
end
end,
on_drop = function(stack)
@ -36,6 +48,11 @@ minetest.register_craftitem('lexa_hud:item_placeholder', {
end
})
minetest.register_on_dignode(function(pos)
local node = minetest:get_meta(pos):get_string('nav_node')
if node then minetest.set_node(pos, { name = node }) end
end)
local function get_list_background(size)
local str = '[combine:' .. (size * 19) .. 'x19'
for i = 0, size - 1 do

View File

@ -9,16 +9,16 @@ lexa.text.register_glyph('count_wave_active', glyph_path .. 'lexa_hud_glyph_wave
local BAR_FULL_WIDTH = 239
-- The current wave status
local last_progress_pixel = 0
local last_status = nil
local status = {
wave = 1,
wave_max = 10,
wait = 180,
wait_max = 180,
enemies = 10,
enemies_max = 10
}
-- local last_progress_pixel = 0
-- local last_status = nil
-- local status = {
-- wave = 1,
-- wave_max = 10,
-- wait = 180,
-- wait_max = 180,
-- enemies = 10,
-- enemies_max = 10
-- }
-- Formats a time in seconds into a 0:00 format.
local function format_time(time)
@ -29,15 +29,18 @@ local function format_time(time)
end
-- Updates the necessary hud elements to keep the match status accurate.
local function refresh_hud(force)
function lexa.hud.refresh_bar(force)
if not lexa.match.state then return end
local status = lexa.match.state.status
for name, state in pairs(lexa.hud.state) do
local elems = state.elements
local player = minetest.get_player_by_name(name)
local wave_active_changed =
force or not last_status or
(status.wait == 0 and last_status.wait > 0) or
(status.wait > 0 and last_status.wait == 0)
-- local wave_active_changed =
-- force or not last_status or
-- (status.wait == 0 and last_status.wait > 0) or
-- (status.wait > 0 and last_status.wait == 0)
local wave_progress = math.min(math.max(status.wait == 0
and status.enemies / math.max(status.enemies_max, 1)
@ -45,35 +48,35 @@ local function refresh_hud(force)
local wave_progress_pixel = math.floor(wave_progress * BAR_FULL_WIDTH)
if wave_active_changed or wave_progress_pixel ~= last_progress_pixel then
-- if wave_active_changed or wave_progress_pixel ~= last_progress_pixel then
local image = '[combine:' .. wave_progress_pixel .. 'x16:0,0=' ..
(status.wait == 0 and 'lexa_hud_progress_bar_fill_active.png' or 'lexa_hud_progress_bar_fill.png')
player:hud_change(elems.match_bar_fill, 'text', image)
last_progress_pixel = wave_progress_pixel
end
-- end
--
-- local wave_status_changed = wave_active_changed or
-- force or not last_status or
-- (status.wait == 0 and status.enemies ~= last_status.enemies) or
-- (status.wait > 0 and math.floor(status.wait) ~= math.floor(last_status.wait))
local wave_status_changed = wave_active_changed or
force or not last_status or
(status.wait == 0 and status.enemies ~= last_status.enemies) or
(status.wait > 0 and math.floor(status.wait) ~= math.floor(last_status.wait))
if wave_status_changed then
-- if wave_status_changed then
player:hud_change(elems.match_wave_status, 'text', lexa.text.render_text(
(status.wait == 0 and ('[!count_enemies] ' .. status.enemies)
or ('[!count_time] ' .. format_time(math.floor(status.wait)))) .. ' Remaining...'))
end
-- end
local match_status_changed =
force or not last_status or
last_status.wave_max ~= status.wave_max or
last_status.wave ~= status.wave
-- local match_status_changed =
-- force or not last_status or
-- last_status.wave_max ~= status.wave_max or
-- last_status.wave ~= status.wave
if match_status_changed or wave_active_changed then
-- if match_status_changed or wave_active_changed then
player:hud_change(elems.match_match_status, 'text', lexa.text.render_text('[!count_wave' ..
(status.wait == 0 and '_active' or '') .. '] Wave ' .. status.wave ..
(status.wave_max and status.wave_max > 0 and ('/' .. status.wave_max) or '')))
end
-- end
last_status = table.copy(status)
end
@ -128,10 +131,5 @@ table.insert(lexa.hud.callbacks.register, function(player)
offset = { x = 336, y = 22 }
})
refresh_hud(true)
end)
minetest.register_globalstep(function(delta)
status.wait = math.max(0, status.wait - delta)
if not last_status or math.ceil(status.wait * 10) ~= math.ceil(last_status.wait * 10) then refresh_hud() end
lexa.hud.refresh_bar(true)
end)

View File

@ -1,4 +1,4 @@
return {
size = { x = 320, y = 153, z = 323 },
spawn = { x = 86, y = 39, z = 127 }
spawn = { x = 89, y = 39, z = 117 }
}

Binary file not shown.

View File

@ -67,31 +67,33 @@ lexa.match.start_match = function(def)
def.map = def.map or 'mountain'
local map_meta = dofile(map_root .. def.map .. '.meta.lua')
minetest.place_schematic(vector.new(0, 0, 0), map_root .. def.map .. '.mts')
for _, player in ipairs(minetest.get_connected_players()) do player:set_pos(map_meta.spawn) end
lexa.nav.load_area(vector.new(0, 0, 0), map_meta.size, function()
for _, player in ipairs(minetest.get_connected_players()) do player:set_pos(map_meta.spawn) end
lexa.match.state = {
def = def,
map_meta = map_meta,
status = {
wave = 1,
wave_max = def.waves or 10,
wait = def.wait or 180,
wait_max = def.wait or 180,
enemies = 0,
enemies_max = 0
},
materials = def.materials or {},
graph = lexa.nav.build_graph(map_meta.spawn)
}
-- minetest.place_schematic(vector.new(0, 0, 0), map_root .. def.map .. '.mts')
lexa.match.state = {
def = def,
map_meta = map_meta,
status = {
wave = 1,
wave_max = def.waves or 180,
wait = def.wait or 180,
wait_max = def.wait or 180,
enemies = 0,
enemies_max = 0
},
materials = def.materials or {},
graph = lexa.nav.build_graph(map_meta.spawn)
}
lexa.hud.update_materials(lexa.match.state.materials)
lexa.hud.update_materials(lexa.match.state.materials)
minetest.chat_send_all(' ')
minetest.chat_send_all('Match started, have fun!')
minetest.chat_send_all(' ')
minetest.after(5, function() minetest.chat_send_all(' ') end)
minetest.chat_send_all(' ')
minetest.chat_send_all('Match started, have fun!')
minetest.chat_send_all(' ')
minetest.after(5, function() minetest.chat_send_all(' ') end)
end)
end
minetest.register_on_joinplayer(function()
@ -135,3 +137,48 @@ function lexa.match.set_materials(materials)
lexa.hud.update_materials(materials)
end
end
function lexa.match.use_materials(use)
if not lexa.match.state then
minetest.chat_send_player(name, 'Please run /start_match first!')
return
end
local new = table.copy(lexa.match.state.materials)
if use.copper then new.copper = new.copper - use.copper end
if use.titanium then new.titanium = new.titanium - use.titanium end
if use.cobalt then new.cobalt = new.cobalt - use.cobalt end
if (new.copper and new.copper < 0) or (new.titanium and new.titanium < 0)
or (new.cobalt and new.cobalt < 0) then return false end
lexa.match.set_materials(new)
return true
end
minetest.register_globalstep(function(delta)
if not lexa.match.state then return end
lexa.match.state.status.wait = math.max(0, lexa.match.state.status.wait - delta)
lexa.hud.refresh_bar()
if lexa.match.state.status.wait == 0 and lexa.match.state.status.enemies == 0 then
lexa.match.spawn_wave()
end
end)
function lexa.match.spawn_wave()
print(dump(lexa.match.state.graph.enemy_spawns))
for _, spawn in pairs(lexa.match.state.graph.enemy_spawns) do
local path = lexa.nav.find_path(lexa.match.state.graph, spawn, lexa.match.state.map_meta.spawn)
for i = 0, 10 do
minetest.after(i, function()
minetest.chat_send_all('Spawning enemy at ... ' .. minetest.pos_to_string(spawn))
local ent = minetest.add_entity(spawn, 'lexa_enemy:spider', '')
ent:get_luaentity().path = path
ent:get_luaentity().path_index = #path - 1
end)
end
end
lexa.match.state.status.enemies = 10
end

View File

@ -2,4 +2,6 @@ lexa.materials = {}
lexa.require('ore')
lexa.require('chunk')
lexa.require('input')
lexa.require('helpers')
lexa.require('register')

View File

@ -2,4 +2,4 @@ title = Materials
name = lexa_materials
author = Aurailus
description = Registers ores and their materials.
depends = lexa_base, lexa_map, lexa_text, lexa_conveyor
depends = lexa_base, lexa_map, lexa_text

View File

@ -1,26 +1,3 @@
minetest.register_entity('lexa_materials:ore_chunk', {
visual = 'mesh',
mesh = 'lexa_materials_chunk.b3d',
visual_size = vector.new(10, 10, 10),
collisionbox = { -4/16, -8/16 -4/16, 4/16, -4/16, 4/16 },
selectionbox = { -4/16, -8/16, -4/16, 4/16, -4/16, 4/16 },
on_activate = function(self, static_data)
lexa.conveyor.entity.on_activate(self)
self.type = static_data
self.object:set_properties({ textures = { 'lexa_materials_chunk_' .. self.type .. '.png' } })
self.object:set_rotation(vector.new(0, math.rad(math.floor(math.random() * 12) * 30), 0))
end,
on_punch = function(self) self.object:remove() end,
on_step = lexa.conveyor.entity.on_step,
get_staticdata = function(self) return self.type end
})
minetest.register_chatcommand('spawn_ore', {
params = '<type>',
privs = { cheats = true },
description = 'Spawns an ore chunk of the type specified.',
func = function(name, type)
local player = minetest.get_player_by_name(name)
minetest.add_entity(vector.round(player:get_pos()), 'lexa_materials:ore_chunk', type)
end
})
--
-- temporarily moved
--

View File

@ -0,0 +1,17 @@
function lexa.materials.place(cost)
return function(stack, player, target)
if not lexa.match.use_materials(cost) then return end
minetest.item_place_node(stack, player, target)
end
end
function lexa.materials.dig(cost)
return function(pos, node, player)
local last = table.copy(lexa.match.state.materials)
for type, val in pairs(cost) do
last[type] = last[type] + math.floor(val / 2)
end
lexa.match.set_materials(last)
minetest.node_dig(pos, node, player)
end
end

View File

@ -0,0 +1,20 @@
minetest.register_node('lexa_materials:input', {
description = 'Input',
tiles = {
'lexa_materials_input_top.png',
'lexa_materials_input.png'
},
groups = {
dig_build = 1,
conveyor = 3,
enemy_target = 100
},
_conveyor_function = function(node_pos, item, delta)
local type = item.type
item.object:remove()
local new = table.copy(lexa.match.state.materials)
new[type] = new[type] + 1
lexa.match.set_materials(new)
end,
})

View File

@ -10,7 +10,7 @@ lexa.materials.register_ore = function(type)
},
paramtype2 = 'facedir',
groups = {
build_dig = 1,
dig_build = 1,
ore = 1
},
_ore_type = type

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -2,6 +2,7 @@ lexa.nav = {}
lexa.require('rpq')
lexa.require('astar')
lexa.require('load')
lexa.require('nodes')
lexa.require('graph')
@ -10,16 +11,18 @@ minetest.register_chatcommand('test_paths', {
privs = { cheats = true },
description = 'Graphs paths from enemy spawns to player spawn',
func = function(name)
if lexa.nav.graph == nil then
if lexa.match.state.graph == nil then
minetest.chat_send_all('Graph not initialized')
return
end
minetest.chat_send_all('Graphing paths.')
for i, spawn in ipairs(lexa.nav.graph.enemy_spawns) do
print(dump(lexa.match.state.graph))
for i, spawn in ipairs(lexa.match.state.graph.enemy_spawns) do
local start_time = minetest.get_us_time()
local path = lexa.nav.find_path(lexa.nav.graph, spawn, lexa.nav.graph.player_spawn, i + 4)
local path = lexa.nav.find_path(lexa.match.state.graph, spawn, lexa.match.state.graph.player_spawn, i + 4)
local duration = math.floor((minetest.get_us_time() - start_time) / 1000)
if path then

View File

@ -53,7 +53,7 @@ function lexa.nav.find_path(graph, from, to)
break
end
for adj, cost in pairs(navigation.adjacent_list) do
for adj, cost in pairs(lexa.nav.adjacent_list) do
local adj_pos = { x = lowest.pos.x + adj.x, y = lowest.pos.y + adj.y, z = lowest.pos.z + adj.z }
local adj_pos_str = serialize_pos(adj_pos)

View File

@ -1,59 +1,59 @@
-- -- The minimum max_forceloaded_blocks for the game to work
-- local REQUIRED_FORCELOADED_BLOCKS = 10000
-- The minimum max_forceloaded_blocks for the game to work
local REQUIRED_FORCELOADED_BLOCKS = 10000
-- -- If the max_forceloaded_blocks is less than what is required, prevent the game from being run.
-- local forceload_is_good = tonumber((minetest.settings:get('max_forceloaded_blocks') or 0)) >= REQUIRED_FORCELOADED_BLOCKS
-- If the max_forceloaded_blocks is less than what is required, prevent the game from being run.
local forceload_is_good = tonumber((minetest.settings:get('max_forceloaded_blocks') or 0)) >= REQUIRED_FORCELOADED_BLOCKS
-- if not forceload_is_good then
-- minetest.register_on_joinplayer(function(player)
-- minetest.kick_player(player:get_player_name(),
-- '\n\nThe server is misconfigured, please set max_forceloaded_blocks = 10000 in minetest.conf.')
-- end)
-- end
if not forceload_is_good then
minetest.register_on_joinplayer(function(player)
minetest.kick_player(player:get_player_name(),
'\n\nThe server is misconfigured, please set max_forceloaded_blocks = 10000 in minetest.conf.')
end)
end
-- --
-- -- Emerges and forceloads the area between min_pos and max_pos (inclusive)
-- -- When the load is complete, calls the callback function with three parameters:
-- -- A function to unload the loaded area, the number of blocks loaded, and the time it took to emerge the area in ms.
-- --
-- -- @param min_pos - The minimum position of the area to emerge
-- -- @param max_pos - The maximum position of the area to emerge
-- -- @param callback - The callback to call when the area is emerged.
-- --
--
-- Emerges and forceloads the area between min_pos and max_pos (inclusive)
-- When the load is complete, calls the callback function with three parameters:
-- A function to unload the loaded area, the number of blocks loaded, and the time it took to emerge the area in ms.
--
-- @param min_pos - The minimum position of the area to emerge
-- @param max_pos - The maximum position of the area to emerge
-- @param callback - The callback to call when the area is emerged.
--
-- function lexa.nav.load_area(min_pos, max_pos, cb)
-- local start_time = minetest.get_us_time()
function lexa.nav.load_area(min_pos, max_pos, cb)
local start_time = minetest.get_us_time()
-- local function free()
-- for x = math.floor(min_pos.x / 16), math.ceil(max_pos.x / 16) do
-- for z = math.floor(min_pos.y / 16), math.ceil(max_pos.y / 16) do
-- for y = math.floor(min_pos.z / 16), math.ceil(max_pos.z / 16) do
-- minetest.forceload_free_block({ x = x, y = y, z = z }, true)
-- end
-- end
-- end
-- end
local function free()
for x = math.floor(min_pos.x / 16), math.ceil(max_pos.x / 16) do
for z = math.floor(min_pos.y / 16), math.ceil(max_pos.y / 16) do
for y = math.floor(min_pos.z / 16), math.ceil(max_pos.z / 16) do
minetest.forceload_free_block({ x = x, y = y, z = z }, true)
end
end
end
end
-- local function forceload()
-- local loaded = 0
local function forceload()
local loaded = 0
-- for x = math.floor(min_pos.x / 16), math.ceil(max_pos.x / 16) do
-- for z = math.floor(min_pos.y / 16), math.ceil(max_pos.y / 16) do
-- for y = math.floor(min_pos.z / 16), math.ceil(max_pos.z / 16) do
-- local pos = { x = x, y = y, z = z }
-- if not minetest.forceload_block(pos, true) then
-- minetest.chat_send_all('[Error] Failed to forceload block at ' .. minetest.pos_to_string(pos) .. '.')
-- end
-- loaded = loaded + 1
-- end
-- end
-- end
for x = math.floor(min_pos.x / 16), math.ceil(max_pos.x / 16) do
for z = math.floor(min_pos.y / 16), math.ceil(max_pos.y / 16) do
for y = math.floor(min_pos.z / 16), math.ceil(max_pos.z / 16) do
local pos = { x = x, y = y, z = z }
if not minetest.forceload_block(pos, true) then
minetest.chat_send_all('[Error] Failed to forceload block at ' .. minetest.pos_to_string(pos) .. '.')
end
loaded = loaded + 1
end
end
end
-- local duration = math.floor((minetest.get_us_time() - start_time) / 1000)
-- cb(free, loaded, duration)
-- end
local duration = math.floor((minetest.get_us_time() - start_time) / 1000)
cb(free, loaded, duration)
end
-- minetest.emerge_area(min_pos, max_pos, function(_, _, remaining)
-- if remaining == 0 then forceload() end
-- end)
-- end
minetest.emerge_area(min_pos, max_pos, function(_, _, remaining)
if remaining == 0 then forceload() end
end)
end

View File

@ -2,4 +2,4 @@ title = Turrets
name = lexa_turret
author = Aurailus
description = Turrets that shoot enemies.
depends = lexa_base, lexa_enemy
depends = lexa_base, lexa_enemy, lexa_materials

View File

@ -1,6 +1,8 @@
local build_cost = { copper = 50 }
minetest.register_node('lexa_turret:turret_base', {
description = 'Turret',
_cost = { copper = 50 },
_cost = build_cost,
drawtype = 'mesh',
use_texture_alpha = 'clip',
mesh = 'lexa_turret_base.b3d',
@ -22,8 +24,11 @@ minetest.register_node('lexa_turret:turret_base', {
groups = {
conveyor = 3,
dig_game = 1,
enemy_target = 70
},
drop = '',
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
after_place_node = function(pos)
minetest.set_node(vector.add(pos, vector.new(0, 1, 0)), { name = 'lexa_turret:turret_mid' })
minetest.set_node(vector.add(pos, vector.new(0, 2, 0)), { name = 'lexa_turret:turret_top' })

View File

@ -2,4 +2,4 @@ title = Walls
name = lexa_wall
author = Aurailus
description = Player constructable walls for the game.
depends = lexa_base
depends = lexa_base, lexa_materials

View File

@ -19,9 +19,13 @@ local node_box_ladder = {
}
}
local build_cost = { copper = 5 }
local place_check = lexa.materials.place(build_cost)
minetest.register_node('lexa_wall:ladder', {
description = 'Ladder',
_cost = { copper = 5 },
_cost = build_cost,
drawtype = 'nodebox',
tiles = { 'lexa_wall_ladder.png' },
inventory_image = 'lexa_wall_ladder_inventory.png',
@ -40,15 +44,17 @@ minetest.register_node('lexa_wall:ladder', {
on_place = function(_, player, target)
local node = minetest.get_node(target.under).name
if not (minetest.registered_nodes[node].groups or {}).wall then return end
if not place_check() then return end
local pos = target.above
local param2 = minetest.dir_to_wallmounted(vector.direction(pos, target.under))
minetest.set_node(pos, { name = 'lexa_wall:ladder', param2 = param2 })
minetest.set_node(vector.add(pos, vector.new(0, pos.y == target.under.y and 1 or -1, 0)),
{ name = 'lexa_wall:ladder', param2 = param2 })
{ name = 'lexa_wall:ladder', param2 = param2 })
end,
on_dig = function(pos)
on_dig = lexa.materials.dig(build_cost),
after_dig_node = function(pos)
minetest.set_node(pos, { name = 'air' })
if minetest.get_node(vector.add(pos, vector.new(0, 1, 0))).name == 'lexa_wall:ladder' then
minetest.set_node(vector.add(pos, vector.new(0, 1, 0)), { name = 'air' })

View File

@ -43,6 +43,8 @@ end
for _, type in ipairs({ 'copper', 'titanium', 'cobalt' }) do
local build_cost = { [type] = 25 }
local shared_props = {
description = lexa.util.title_case(type) .. ' Wall',
drawtype = 'nodebox',
@ -54,7 +56,7 @@ for _, type in ipairs({ 'copper', 'titanium', 'cobalt' }) do
minetest.register_node('lexa_wall:bottom_' .. type, table.merge(shared_props, {
description = lexa.util.title_case(type) .. ' Wall',
_cost = { [type] = 20 },
_cost = build_cost,
inventory_image = 'lexa_wall_' .. type .. '_inventory.png',
tiles = {
'lexa_wall_' .. type .. '_bottom_top.png',
@ -70,11 +72,14 @@ for _, type in ipairs({ 'copper', 'titanium', 'cobalt' }) do
groups = {
dig_game = 1,
wall_bottom = 1,
wall = 1
wall = 1,
enemy_target = 70
},
on_construct = function(pos)
minetest.set_node(vector.add(pos, vector.new(0, 1, 0)), { name = 'lexa_wall:top_' .. type })
end,
on_place = lexa.materials.place(build_cost),
on_dig = lexa.materials.dig(build_cost),
after_destruct = break_wall
}))