Add crash site and escape ship

This commit is contained in:
LoneWolfHT 2022-11-20 18:00:40 -08:00
parent a129e51c8a
commit ecebdd6de0
39 changed files with 673 additions and 90 deletions

View File

@ -2,13 +2,15 @@ unused_args = false
globals = {
"torrl_core",
"torrl_tools", "torrl_effects", "torrl_nodes", "torrl_aliens",
"torrl_tools", "torrl_effects", "torrl_nodes", "torrl_aliens", "torrl_player",
"torrl_voiceover",
"trec_unit",
"creatura",
"creatura", "fire",
"VoxelManip", "VoxelArea", "PseudoRandom", "ItemStack",
"Settings",
"vector", "table", "string",
math = {
fields = {

View File

@ -1,8 +1,8 @@
# Torrlund
RIP
# Things not created during the jam
* `scripts/update_mtg.sh` script taken from CTF
# Big things not created during the jam
* `mods/mtg/*` Mods from MTG
* `mods/torrl_map/torrl_mapgen/` Base code taken from Voxel Knights
* tnt mod code in torr effects explosion
* tnt mod code is used in torrl_effects explosion
* `mods/modgen_mod_export` was generated by the `modgen` mod, and is used to override parts of the map

View File

@ -0,0 +1,58 @@
local import_mod = ...
local function get_mod_chunk_mtime(chunk_pos)
local _,_,mtime = import_mod.read_chunk_header(chunk_pos)
return mtime
end
local function get_world_chunk_mtime(chunk_pos)
local mtime = import_mod.storage:get_int(minetest.pos_to_string(chunk_pos))
if mtime == 0 then
return nil
else
return mtime
end
end
local cache = {}
local function check_player_pos(player)
local ppos = player:get_pos()
local chunk_pos = import_mod.get_chunkpos(ppos)
-- cache access
local cache_key = minetest.pos_to_string(chunk_pos)
if cache[cache_key] then
return
end
cache[cache_key] = true
-- retrieve timestamps
local mod_mtime = get_mod_chunk_mtime(chunk_pos)
local world_mtime = get_world_chunk_mtime(chunk_pos)
if not mod_mtime then
-- the chunk isn't available in the mod
return
end
if world_mtime and world_mtime >= mod_mtime then
-- world chunk is same or newer (?) than the one in the mod
return
end
local mapblock_min, mapblock_max = import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
local min = import_mod.get_mapblock_bounds_from_mapblock(mapblock_min)
local _, max = import_mod.get_mapblock_bounds_from_mapblock(mapblock_max)
minetest.delete_area(min, max)
end
local function check_players()
for _, player in ipairs(minetest.get_connected_players()) do
check_player_pos(player)
end
minetest.after(1, check_players)
end
print("[modgen] map auto-update enabled")
minetest.after(1, check_players)

View File

@ -0,0 +1,20 @@
local import_mod = ...
function import_mod.decode_uint16(str, ofs)
ofs = ofs or 0
local a, b = string.byte(str, ofs + 1, ofs + 2)
return a + b * 0x100
end
local function lshift(x, by)
return x * 2 ^ by
end
function import_mod.decode_uint32(data, offset)
return (
string.byte(data,1+offset) +
lshift(string.byte(data,2+offset), 8) +
lshift(string.byte(data,3+offset), 16) +
lshift(string.byte(data,4+offset), 24)
)
end

View File

@ -0,0 +1,52 @@
local import_mod = ...
function import_mod.deserialize(data, mapblock_pos)
local pos1 = vector.multiply(mapblock_pos, 16)
local pos2 = vector.add(pos1, 15) -- inclusive
local manip = minetest.get_voxel_manip()
local e1, e2 = manip:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
local node_data = manip:get_data()
local param1 = manip:get_light_data()
local param2 = manip:get_param2_data()
local j = 1
for z=pos1.z,pos2.z do
for x=pos1.x,pos2.x do
for y=pos1.y,pos2.y do
local i = area:index(x,y,z)
node_data[i] = data.node_ids[j]
param1[i] = data.param1[j]
param2[i] = data.param2[j]
j = j + 1
end
end
end
manip:set_data(node_data)
manip:set_light_data(param1)
manip:set_param2_data(param2)
manip:write_to_map(false)
-- deserialize metadata
if data.metadata and data.metadata.meta then
for pos_str, md in pairs(data.metadata.meta) do
local relative_pos = minetest.string_to_pos(pos_str)
local absolute_pos = vector.add(pos1, relative_pos)
minetest.get_meta(absolute_pos):from_table(md)
end
end
-- deserialize node timers
if data.metadata and data.metadata.timers then
for pos_str, timer_data in pairs(data.metadata.timers) do
local relative_pos = minetest.string_to_pos(pos_str)
local absolute_pos = vector.add(pos1, relative_pos)
minetest.get_node_timer(absolute_pos):set(timer_data.timeout, timer_data.elapsed)
end
end
end

View File

@ -0,0 +1,46 @@
--- Modgen import mod
-- writes the mapblocks back to the world
-- hard-dependency- and global-free
-- mod name and path
local modname = minetest.get_current_modname()
local MP = minetest.get_modpath(modname)
local import_mod = {
-- storage
storage = minetest.get_mod_storage()
}
-- local functions/helpers
loadfile(MP .. "/decode.lua")(import_mod)
loadfile(MP .. "/util.lua")(import_mod)
loadfile(MP .. "/load_chunk.lua")(import_mod)
loadfile(MP .. "/register_mapgen.lua")(import_mod)
loadfile(MP .. "/read_manifest.lua")(import_mod)
loadfile(MP .. "/nodename_check.lua")(import_mod)
loadfile(MP .. "/uid_check.lua")(import_mod)
loadfile(MP .. "/localize_nodeids.lua")(import_mod)
loadfile(MP .. "/deserialize.lua")(import_mod)
local manifest = import_mod.read_manifest()
-- check world uid
import_mod.uid_check(manifest)
-- check if the nodes are available in the current world
minetest.register_on_mods_loaded(function()
import_mod.nodename_check(manifest)
end)
-- initialize mapgen
import_mod.register_mapgen(manifest)
if minetest.get_modpath("modgen") then
-- modgen available, make it aware of the loaded import_mod
modgen.register_import_mod(manifest, MP)
end
-- check if the auto-update feature is enabled
if minetest.settings:get_bool("import_mod.auto_update.enabled") then
loadfile(MP .. "/auto_update.lua")(import_mod)
end

View File

@ -0,0 +1,78 @@
local import_mod = ...
local modname = minetest.get_current_modname()
local MP = minetest.get_modpath(modname)
local function get_chunk_name(chunk_pos)
return MP .. "/map/chunk_" .. chunk_pos.x .. "_" .. chunk_pos.y .. "_" .. chunk_pos.z .. ".bin"
end
function import_mod.read_chunk_header(chunk_pos)
local filename = get_chunk_name(chunk_pos)
local file = io.open(filename, "rb")
if file then
local version = string.byte(file:read(1))
local mapblock_count = string.byte(file:read(1))
local mtime = import_mod.decode_uint32(file:read(4), 0)
return version, mapblock_count, mtime
end
end
local function read_chunkdata(chunk_pos)
local filename = get_chunk_name(chunk_pos)
local file = io.open(filename, "rb")
if file then
local version = string.byte(file:read(1))
local mapblock_count = string.byte(file:read(1))
local mtime = import_mod.decode_uint32(file:read(4), 0)
local data = file:read("*all")
return version, mapblock_count, mtime, minetest.decompress(data, "deflate"), #data
end
end
-- local vars for faster access
local insert, byte, decode_uint16 = table.insert, string.byte, import_mod.decode_uint16
function import_mod.load_chunk(chunk_pos, manifest)
local version, mapblock_count, _, chunk_data = read_chunkdata(chunk_pos)
if not chunk_data then
-- write current os.time to modstorage
import_mod.storage:set_int(minetest.pos_to_string(chunk_pos), os.time())
return
end
if version ~= manifest.version then
error("couldn't load chunk " .. minetest.pos_to_string(chunk_pos) ..
" serialization-version: " .. version)
end
local manifest_offset = 1 + (4096 * 4 * mapblock_count)
local chunk_manifest = minetest.parse_json(string.sub(chunk_data, manifest_offset))
for mbi=1, mapblock_count do
local mapblock_manifest = chunk_manifest.mapblocks[mbi]
local mapblock = {
node_ids = {},
param1 = {},
param2 = {},
metadata = mapblock_manifest.metadata
}
for i=1,4096 do
local node_id = decode_uint16(chunk_data, ((mbi-1) * 4096 * 2) + (i * 2) - 2)
local param1 = byte(chunk_data, (4096 * 2 * mapblock_count) + ((mbi-1) * 4096) + i)
local param2 = byte(chunk_data, (4096 * 3 * mapblock_count) + ((mbi-1) * 4096) + i)
insert(mapblock.node_ids, node_id)
insert(mapblock.param1, param1)
insert(mapblock.param2, param2)
end
import_mod.localize_nodeids(manifest.node_mapping, mapblock.node_ids)
import_mod.deserialize(mapblock, mapblock_manifest.pos)
end
if chunk_manifest.mtime then
-- write emerge chunk mtime to modstorage
import_mod.storage:set_int(minetest.pos_to_string(chunk_pos), chunk_manifest.mtime)
end
end

View File

@ -0,0 +1,32 @@
local import_mod = ...
local air_content_id = minetest.get_content_id("air")
-- local nodename->id cache
local local_nodename_to_id_mapping = {} -- name -> id
function import_mod.localize_nodeids(node_mapping, node_ids)
local foreign_nodeid_to_name_mapping = {} -- id -> name
for k, v in pairs(node_mapping) do
foreign_nodeid_to_name_mapping[v] = k
end
for i, node_id in ipairs(node_ids) do
local node_name = foreign_nodeid_to_name_mapping[node_id]
local local_node_id = local_nodename_to_id_mapping[node_name]
if not local_node_id then
if minetest.registered_nodes[node_name] then
-- node is locally available
local_node_id = minetest.get_content_id(node_name)
else
-- node is not available here
-- TODO: make replacements configurable
local_node_id = air_content_id
end
local_nodename_to_id_mapping[node_name] = local_node_id
end
node_ids[i] = local_node_id
end
end

View File

@ -0,0 +1,43 @@
{
"bounds" :
{
"max" :
{
"x" : 0.0,
"y" : 125.0,
"z" : 0.0
},
"min" :
{
"x" : -1.0,
"y" : 0.0,
"z" : -1.0
}
},
"chunks" : 17.0,
"mtime" : 1668972914.0,
"next_id" : 17.0,
"node_mapping" :
{
"air" : 0.0,
"fire_m:permanent_flame" : 7.0,
"torrl_aliens:ship_armor" : 10.0,
"torrl_aliens:ship_core" : 11.0,
"torrl_meteors:meteorite" : 9.0,
"torrl_nodes:dirt" : 3.0,
"torrl_nodes:grass" : 4.0,
"torrl_nodes:leaves" : 5.0,
"torrl_nodes:sand" : 2.0,
"torrl_nodes:ship_armor" : 14.0,
"torrl_nodes:ship_armor_cracked" : 8.0,
"torrl_nodes:ship_light" : 16.0,
"torrl_nodes:ship_tile" : 12.0,
"torrl_nodes:ship_window" : 15.0,
"torrl_nodes:stone" : 1.0,
"torrl_nodes:trec_unit" : 13.0,
"torrl_nodes:tree" : 6.0
},
"size" : 119237.0,
"uid" : "830565",
"version" : 4.0
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
optional_depends = modgen, technic_worldgen

View File

@ -0,0 +1,25 @@
local import_mod = ...
function import_mod.nodename_check(manifest)
-- assemble node-list from registered lbm's
local lbm_nodes = {}
for _, lbm in ipairs(minetest.registered_lbms) do
if type(lbm.nodenames) == "string" then
-- duh, list as string
lbm_nodes[lbm.nodenames] = true
else
-- proper list, add all regardless if they are a "group:*"
for _, nodename in ipairs(lbm.nodenames) do
lbm_nodes[nodename] = true
end
end
end
for nodename in pairs(manifest.node_mapping) do
if not minetest.registered_nodes[nodename]
and not minetest.registered_aliases[nodename]
and not lbm_nodes[nodename] then
error("node not found and not aliased: " .. nodename)
end
end
end

View File

@ -0,0 +1,12 @@
local import_mod = ...
local modname = minetest.get_current_modname()
local MP = minetest.get_modpath(modname)
function import_mod.read_manifest()
local infile = io.open(MP .. "/manifest.json", "r")
local instr = infile:read("*a")
infile:close()
return minetest.parse_json(instr or "{}")
end

View File

@ -0,0 +1,6 @@
## Modgen import mod
**This folder and its contents are autogenerated, do not edit directly**
For more infos, see: https://github.com/Buckaroobanzay/modgen

View File

@ -0,0 +1,7 @@
local import_mod = ...
function import_mod.register_mapgen(manifest)
minetest.register_on_generated(function(minp)
import_mod.load_chunk(import_mod.get_chunkpos(minp), manifest)
end)
end

View File

@ -0,0 +1,12 @@
local import_mod = ...
function import_mod.uid_check(manifest)
local world_uid = import_mod.storage:get_string("uid")
if world_uid ~= "" and world_uid ~= manifest.uid then
-- abort if the uids don't match, something fishy might be going on
error("modgen uids don't match, aborting for your safety!")
end
-- write modgen uid to world-storage
import_mod.storage:set_string("uid", manifest.uid)
end

View File

@ -0,0 +1,40 @@
local import_mod = ...
function import_mod.get_mapblock_pos(pos)
return vector.floor( vector.divide(pos, 16))
end
function import_mod.get_mapblock(pos)
return vector.floor( vector.divide(pos, 16))
end
function import_mod.get_chunkpos(pos)
local mapblock_pos = import_mod.get_mapblock_pos(pos)
local aligned_mapblock_pos = vector.add(mapblock_pos, 2)
return vector.floor( vector.divide(aligned_mapblock_pos, 5) )
end
function import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
local min = vector.subtract( vector.multiply(chunk_pos, 5), 2)
local max = vector.add(min, 4)
return min, max
end
function import_mod.get_chunk_bounds(pos)
local chunk_pos = import_mod.get_chunkpos(pos)
local mapblock_min, mapblock_max = import_mod.get_mapblock_bounds_from_chunk(chunk_pos)
local min = import_mod.get_mapblock_bounds(mapblock_min)
local _, max = import_mod.get_mapblock_bounds(mapblock_max)
return min, max
end
function import_mod.get_mapblock_bounds_from_mapblock(mapblock)
local min = vector.multiply(mapblock, 16)
local max = vector.add(min, 15)
return min, max
end
function import_mod.get_mapblock_bounds(pos)
local mapblock = import_mod.get_mapblock(pos)
return import_mod.get_mapblock_bounds_from_mapblock(mapblock)
end

View File

@ -115,6 +115,14 @@ creatura.register_mob("torrl_aliens:alien_mini", {
width = 0.4,
height = 0.8,
},
sounds = {
hurt = {
name = "torrl_aliens_hit",
gain = 1,
distance = 16,
variations = 3
}
},
static_save = false,
animations = {
anim = {range = {x = 1, y = 10}, speed = 30, frame_blend = 0.3, loop = true}
@ -141,7 +149,7 @@ creatura.register_mob("torrl_aliens:alien_mini", {
step_func = function(self, dtime, moveresult)
self.look_timer = (self.look_timer or math.random(-1, 1)) + dtime
if self.target_pos and self.look_timer >= 2 then
if self.target_pos and self.look_timer >= 3 then
self.look_timer = 0
local pos = self.object:get_pos()
@ -184,17 +192,6 @@ creatura.register_mob("torrl_aliens:alien_mini", {
if collision.type == "node" and (collision.node_pos.y >= pos.y or collision.old_velocity.y >= 0) then
collision = collision.node_pos
minetest.add_particle({
pos = collision,
expirationtime = 2,
size = 5,
collisiondetection = false,
collision_removal = false,
object_collision = false,
texture = "torrl_nodes_trec_unit_interactable.png",
glow = 13,
})
if collision.y == pos.y and math.abs(pos.y - target.y) > 1 then
local offset = collision:offset(0, (pos.y - collision.y > 0 and 0 or 1), 0)

View File

@ -71,8 +71,14 @@ minetest.register_entity("torrl_aliens:laser_beam", {
})
local SHIP_SHOOT_INTERVAL = 30
local ALIEN_SHIP_INTERVAL = function() return math.random(60, 60 * 3) end
local ALIEN_SHIP_INTERVAL = function()
return math.random(60, math.max(60 * (5 - #minetest.get_connected_players()), 90))
end
local ALIEN_LASER_RADIUS = function()
return math.ceil(#minetest.get_connected_players()/2)
end
local ALIEN_SHIP_YPOS = 66
local ALIEN_SHIP_PR = 40
local SHIP_SIZE = 20
local MAX_ALIEN_COUNT = 8
@ -153,8 +159,19 @@ local function shoot(ship)
obj:set_properties({visual_size = {x = 0.2, y = 0.2, z = math.round(dist/2)}})
end
minetest.sound_play({name = "torrl_aliens_laser"}, {
pos = pointed_thing.intersection_point,
gain = 1.3,
max_hear_distance = 40,
}, true)
minetest.sound_play({name = "torrl_aliens_laser"}, {
pos = pos,
gain = 1,
max_hear_distance = 20,
}, true)
if pointed_thing.above then
torrl_effects.explosion(pointed_thing.above, 2, torrl_effects.type.alien)
torrl_effects.explosion(pointed_thing.above, ALIEN_LASER_RADIUS(), torrl_effects.type.alien)
elseif pointed_thing.type == "object" and pointed_thing.ref then
pointed_thing.ref:punch(
minetest.add_entity(vector.new(0, 0, 0), "torrl_aliens:laser_beam"),
@ -173,8 +190,9 @@ end
local timer = 0
local target_timer = 0
local creative = minetest.settings:get_bool("creative_mode", false)
local target_interval = 20
minetest.register_globalstep(function(dtime)
timer = timer + dtime
target_timer = target_timer + dtime
if target_timer >= 5 then
@ -200,23 +218,35 @@ minetest.register_globalstep(function(dtime)
end
end
if timer >= ALIEN_SHIP_INTERVAL() then
timer = 0
if creative then return end
local time = minetest.get_timeofday()
if time >= 0.82 or time <= 0.18 then
torrl_voiceover.say_followed()
timer = timer + dtime
if timer >= target_interval then
target_interval = ALIEN_SHIP_INTERVAL()
timer = 0
local time = minetest.get_timeofday()
if time >= 0.82 or time <= 0.18 then
local players = minetest.get_connected_players()
if #players >= 1 then
local pos = players[math.random(#players)]:get_pos():offset(math.random(-30, 30), 0, math.random(-30, 30))
local pos = players[math.random(#players)]:get_pos():offset(
math.random(-ALIEN_SHIP_PR, ALIEN_SHIP_PR),
0,
math.random(-ALIEN_SHIP_PR, ALIEN_SHIP_PR)
)
pos.y = ALIEN_SHIP_YPOS
torrl_voiceover.say_detected()
local pos1, pos2 = pos:add(SHIP_SIZE), pos:subtract(SHIP_SIZE)
minetest.emerge_area(pos:add(SHIP_SIZE), pos:subtract(SHIP_SIZE), function(_, _, remaining)
if remaining <= 0 then
torrl_effects.explosion(pos, SHIP_SIZE, torrl_effects.type.alien, function()
minetest.after(1, function()
torrl_effects.explosion(pos, SHIP_SIZE/1.5, torrl_effects.type.alien, function()
minetest.after(4, function()
minetest.place_schematic(pos, schempath .. "torrl_aliens_ship.mts", "random", nil, false, {
place_center_x = true, place_center_y = true, place_center_z = true
})

View File

@ -1,3 +1,9 @@
local config = Settings(minetest.get_worldpath() .. "/world.mt")
if config:get("backend") ~= "dummy" then
config:set("backend","dummy")
config:write()
end
minetest.set_mapgen_setting("mg_name", "flat", true)
minetest.set_mapgen_setting("mg_flags", "nocaves, nodungeons, light, decorations, biomes", true)
minetest.set_mapgen_setting("mgflat_spflags", "hills, lakes", true)

View File

@ -4,7 +4,7 @@ local function spawn_meteors()
local connected = minetest.get_connected_players()
if #connected >= 1 then
local pos = connected[math.random(#connected)]:get_pos()
local pos = connected[math.random(#connected)]:get_pos():offset(math.random(-30, 30), 0, math.random(-30, 30))
local offset = math.max(140, pos.y+50)
pos.y = offset
@ -45,7 +45,13 @@ minetest.register_node("torrl_meteors:meteorite", {
description = "Meteorite",
tiles = {"torrl_meteors_meteorite.png"},
light_source = 5,
groups = {meltable = 1, blastable = 1, falling_node = 1},
droppable = true,
groups = {meltable = 1, blastable = 1, falling_node = 1, compressable = 1},
after_dig_node = function(_, _, _, digger)
if digger and digger:is_player() then
torrl_voiceover.say_meteorite(digger:get_player_name())
end
end
})
local fall_speed = 40
@ -91,7 +97,7 @@ minetest.register_entity("torrl_meteors:meteor", {
loop = true,
})
self.object:set_velocity(vector.new(math.random(-30, 30), -fall_speed, math.random(-30, 30)))
self.object:set_velocity(vector.new(math.random(-20, 20), -fall_speed, math.random(-20, 20)))
end,
on_step = function(self, dtime, moveresult)
self.timer = (self.timer or 0) + dtime

View File

@ -5,6 +5,7 @@ torrl_nodes = {
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/repairs.lua")
dofile(modpath.."/ship_nodes.lua")
--
--- Processed Blocks, T.R.E.C Unit
@ -20,6 +21,7 @@ local function register_compressable(name, max, def)
paramtype = def.paramtype,
sunlight_propogates = def.sunlight_propogates,
blast_replace = name.."_2",
droppable = true,
on_dig = function(pos, node, digger)
if digger and digger:is_player() then
minetest.node_dig(pos, node, digger)
@ -94,6 +96,7 @@ dofile(modpath.."/trec_unit.lua")({
["torrl_nodes:sand" ] = "torrl_nodes:glass",
["torrl_nodes:tree"] = "torrl_nodes:repair_tape",
["torrl_nodes:leaves"] = "torrl_nodes:repair_tape",
["torrl_meteors:meteorite"] = "score",
})
--
@ -111,18 +114,21 @@ minetest.register_node("torrl_nodes:dirt", {
description = "Dirt",
tiles = {"torrl_nodes_dirt.png"},
groups = {breakable = 1, compressable = 1},
droppable = true,
})
minetest.register_node("torrl_nodes:sand", {
description = "Sand",
tiles = {"torrl_nodes_sand.png"},
groups = {breakable = 1, compressable = 1},
droppable = true,
})
minetest.register_node("torrl_nodes:stone", {
description = "Stone",
tiles = {"torrl_nodes_stone.png"},
groups = {blastable = 1, compressable = 1},
droppable = true,
})
--
@ -133,6 +139,7 @@ minetest.register_node("torrl_nodes:tree", {
description = "Tree",
tiles = {"torrl_nodes_tree.png"},
groups = {breakable = 1},
droppable = true,
})
minetest.register_node("torrl_nodes:leaves", {
@ -142,6 +149,7 @@ minetest.register_node("torrl_nodes:leaves", {
sunlight_propogates = true,
tiles = {"torrl_nodes_leaves.png"},
groups = {breakable = 1},
droppable = true,
})
for name, def in pairs(minetest.registered_nodes) do

View File

@ -1,4 +1,5 @@
local huds = {}
local score = 0
trec_unit = {
add_hud = function(player, pos)
@ -66,6 +67,39 @@ minetest.register_globalstep(function(dtime)
end
end)
local scoretimer = 0
minetest.register_globalstep(function(dtime)
scoretimer = scoretimer + dtime
if scoretimer >= 2 then
scoretimer = 0
local players = minetest.get_connected_players()
if score >= #players * 5 then
minetest.chat_send_all(minetest.colorize(
"cyan",
"<C.O.M.P Unit> Repairing ship, stand by..."
))
torrl_player.won = true
score = 0
minetest.after(1, function()
local shippos = vector.new(0, 10001, 0)
for _, p in pairs(players) do
p:get_inventory():set_list("main", {})
p:set_pos(shippos)
p:set_hp(20)
end
end)
end
end
end)
torrl_core.register_on_game_restart(function()
score = 0
end)
return function(compressables)
minetest.register_node("torrl_nodes:trec_unit", {
description = "T.R.E.C Unit",
@ -85,11 +119,19 @@ return function(compressables)
for from, to in pairs(compressables) do
if iname == from then
itemstack:set_name(to)
if to == "score" then
score = score + itemstack:get_count()
minetest.after(0, function()
clicker:get_inventory():add_item("main", itemstack)
end)
minetest.chat_send_player(clicker:get_player_name(), ("Need %d more to repair ship"):format(
math.max((#minetest.get_connected_players() * 5) - score, 0)
))
else
itemstack:set_name(to)
minetest.after(0, function()
clicker:get_inventory():add_item("main", itemstack)
end)
end
return ""
end
@ -97,7 +139,7 @@ return function(compressables)
end
end,
on_torrl_blast = function(pos, type)
if type == torrl_effects.type.alien then
if type == torrl_effects.type.alien and math.random(10) == 1 then
local owner = minetest.get_meta(pos):get_string("owner")
if owner then
@ -117,6 +159,7 @@ return function(compressables)
if pointed_thing and pointed_thing.above and
placer and placer:is_player() then
local pos = pointed_thing.above
local name = placer:get_player_name()
if minetest.get_node(pos:offset(0, 1, 0)).name == "air" and
minetest.get_node(pos:offset(0, 2, 0)).name == "air"
@ -124,7 +167,7 @@ return function(compressables)
local meta = placer:get_meta()
if meta:get_string("torrl_player:trec_unit_status") ~= "inv" then
minetest.chat_send_player(placer:get_player_name(), "You can only have 1 trec unit at a time")
minetest.chat_send_player(name, "You can only have 1 trec unit at a time")
return
end
@ -132,15 +175,17 @@ return function(compressables)
itemstack:set_count(itemstack:get_count() - 1)
local nmeta = minetest.get_meta(pos)
nmeta:set_string("owner", placer:get_player_name())
nmeta:set_string("owner", name)
meta:set_string("torrl_player:trec_unit_status", "placed")
meta:set_string("torrl_player:trec_unit_pos", minetest.pos_to_string(pos))
torrl_voiceover.say_trec(name)
trec_unit.add_hud(placer, pos)
return itemstack
else
minetest.chat_send_player(placer:get_player_name(), "You need 2 nodes of space above your T.R.E.C unit")
minetest.chat_send_player(name, "You need 2 nodes of space above your T.R.E.C unit")
end
end
end,

View File

@ -74,6 +74,7 @@ minetest.register_entity("torrl_player:comp_unit", {
if not self.follow or not self.follow:is_player() then
self.object:remove()
return
end
local target_pos = self.follow:get_pos():offset(0, 1.5, 0)

View File

@ -1,17 +1,39 @@
torrl_player = {
won = false,
}
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. "/"
dofile(modpath.."comp_unit.lua")
local function newplayer(player)
torrl_core.register_on_game_restart(function()
minetest.set_timeofday(0.22)
torrl_player.won = false
end)
local function reset_inv(player)
local inv = player:get_inventory()
local pos = player:get_pos()
local meta = player:get_meta()
for _, i in pairs(inv:get_list("main")) do
if i:get_definition().droppable then
minetest.after(0.1, minetest.add_item, pos, i)
end
end
player:get_inventory():set_list("main", {})
inv:add_item("main", "torrl_tools:hammer")
inv:add_item("main", "torrl_nodes:trec_unit")
player:get_meta():set_string("torrl_player:trec_unit_status", "inv")
if meta:get_string("torrl_player:trec_unit_status") ~= "placed" then
inv:add_item("main", "torrl_nodes:trec_unit")
meta:set_string("torrl_player:trec_unit_status", "inv")
end
end
minetest.register_on_newplayer(newplayer)
minetest.register_on_newplayer(reset_inv)
local function place_trec_unit(pos, oname)
if minetest.get_node(pos).name == "ignore" then
@ -32,7 +54,7 @@ minetest.register_on_respawnplayer(function(player)
local meta = player:get_meta()
local status = meta:get_string("torrl_player:trec_unit_status")
if status == "dead" or status == "inv" then
if torrl_player.won or status == "dead" or status == "inv" then
local name = player:get_player_name()
meta:set_int("torrl_player:dead", 1)
@ -52,25 +74,43 @@ minetest.register_on_respawnplayer(function(player)
privs.noclip = true
minetest.set_player_privs(name, privs)
gameover_huds[name] = player:hud_add({
position = {x = 0.5, y = 0.5},
scale = {x = 100, y = 100},
text = "Game Over. A restart will happen when all players are dead",
number = 0xFF0000,
alignment = {x = 0, y = -1},
offset = {x = 0, y = -12},
size = {x = 2},
})
if not torrl_player.won then
gameover_huds[name] = player:hud_add({
position = {x = 0.5, y = 0.5},
scale = {x = 100, y = 100},
text = "Game Over. It will restart when everyone is dead",
number = 0xFF0000,
alignment = {x = 0, y = -1},
offset = {x = 0, y = -12},
size = {x = 2},
})
else
gameover_huds[name] = player:hud_add({
position = {x = 0.5, y = 0.5},
scale = {x = 100, y = 100},
text = "Game Won! It will restart when all players exit the ship",
number = 0x00FF00,
alignment = {x = 0, y = -1},
offset = {x = 0, y = -12},
size = {x = 2},
})
end
player:get_inventory():set_list("main", {})
else
reset_inv(player)
end
if status == "placed" or status == "dead" then
if status == "placed" then
player:set_pos(minetest.string_to_pos(meta:get_string("torrl_player:trec_unit_pos")):offset(0, 1, 0))
return true
end
player:set_pos(vector.new(0, 9, 0))
if torrl_player.won then
player:set_pos(vector.new(0, 10001, 0))
else
player:set_pos(vector.new(0, 9, 0))
end
return true
end)
@ -99,7 +139,7 @@ local function resurrect(player, name, meta)
player:hud_remove(gameover_huds[name])
end
newplayer(player)
reset_inv(player)
end
local timer = 0
@ -119,6 +159,11 @@ minetest.register_globalstep(function(dtime)
end
if not found then
if torrl_player.won then
minetest.request_shutdown("Resetting Map...", true)
return
end
torrl_core.game_restart()
for _, player in pairs(players) do
@ -133,7 +178,9 @@ minetest.register_on_joinplayer(function(player)
local status = meta:get_string("torrl_player:trec_unit_status")
local name = player:get_player_name()
player:set_armor_groups({fleshy = 100})
torrl_voiceover.say_greeting(name)
reset_inv(player)
if meta:get_int("torrl_player:dead") > 0 then
resurrect(player, name, meta)
@ -149,23 +196,8 @@ minetest.register_on_joinplayer(function(player)
return
end
minetest.sound_play({name = "welcome_message" .. (math.random(15) == 1 and "_rare" or "")}, {
to_player = name,
gain = 1.2,
}, true)
minetest.chat_send_player(name, minetest.colorize(
"cyan",
"<C.O.M.P Unit> Greetings, your ship is badly damaged. "..
"Use your T.R.E.C Unit to synthesize the materials needed to repair it"
))
player:set_pos(vector.new(0, 9, 0))
player:set_look_horizontal(math.pi) -- Face the mountain across the spawn ravine
end)
torrl_core.register_on_game_restart(function()
minetest.set_timeofday(0.2)
end)
minetest.after(0, torrl_core.game_restart)

View File

@ -26,11 +26,21 @@ minetest.register_tool("torrl_tools:hammer", {
breakable = {times={[1] = 0.1}, uses = 0, maxlevel = 1},
blastable = {times={[1] = 7.0}, uses = 0, maxlevel = 1},
},
damage_groups = {alien = 6},
damage_groups = {alien = 4},
},
on_secondary_use = function(itemstack, user, pointed_thing)
local meta = user:get_meta()
local name = user:get_player_name()
if meta:get_string("torrl_player:trec_unit_status") ~= "placed" then
minetest.sound_play({name = "torrl_tools_error"}, {
to_player = name,
gain = 1,
}, true)
return
end
if pointed_thing and pointed_thing.type == "object" then
if not flinging[name] then
itemstack:set_wear(0)
@ -94,9 +104,13 @@ minetest.register_tool("torrl_tools:hammer", {
minetest.register_on_player_hpchange(function(player, hp_change, reason)
local name = player:get_player_name()
if reason.type == "fall" and flinging[name] then
return 0, true
else
return hp_change
if reason.type == "fall" then
if flinging[name] then
return 0, true
elseif player:get_wielded_item():get_name() == "torrl_tools:hammer" then
torrl_voiceover.say_hammer(name)
end
end
return hp_change
end, true)

View File

@ -4,13 +4,23 @@ minetest.register_on_dieplayer(function(player)
levitating[player:get_player_name()] = nil
end)
local RECHARGE_TIME = 1.5 * 10 -- 10 second cooldown
local RECHARGE_TIME = 1.5 * 8 -- 8 second cooldown
local SMASH_RADIUS = 4
local SMASH_DAMAGE = 15
local SMASH_KNOCKBACK = 15
local SMASH_KNOCKBACK = 20
local function power_func(itemstack, user, pointed_thing)
local meta = user:get_meta()
local name = user:get_player_name()
if meta:get_string("torrl_player:trec_unit_status") ~= "placed" then
minetest.sound_play({name = "torrl_tools_error"}, {
to_player = name,
gain = 1,
}, true)
return
end
if pointed_thing and pointed_thing.type == "object" then
if not levitating[name] then
itemstack:set_wear(0)
@ -20,10 +30,9 @@ local function power_func(itemstack, user, pointed_thing)
end
if not levitating[name] then
local vel = vector.new(0, 16, 0)
local vel = vector.new(0, 20, 0)
user:add_velocity(vel)
user:set_physics_override({gravity = 0.5})
torrl_effects.particle_effect(user, {
type = torrl_effects.type.fire,
@ -45,7 +54,7 @@ local function power_func(itemstack, user, pointed_thing)
local player = minetest.get_player_by_name(name)
if player then
player:set_physics_override({gravity = 1})
torrl_voiceover.say_sword(name)
minetest.sound_play({name = "torrl_tools_error"}, {
to_player = name,
@ -71,13 +80,13 @@ local function power_func(itemstack, user, pointed_thing)
end)
return itemstack
elseif type(levitating[name]) ~= "string" then
elseif type(levitating[name]) == "table" and levitating[name].cancel then
local pos = user:get_pos()
local target = pos:add(user:get_look_dir():multiply(20))
local pointed = minetest.raycast(user:get_pos(), target, false):next()
local pointed = minetest.raycast(user:get_pos():offset(0, user:get_properties().eye_height, 0), target, false):next()
if pointed then
user:set_pos(pointed.above)
user:set_pos(pointed.above:offset(0, 0.5, 0))
minetest.sound_play({name = "torrl_tools_woosh"}, {
object = user,
@ -112,10 +121,11 @@ local function power_func(itemstack, user, pointed_thing)
end
end
user:set_physics_override({gravity = 1})
levitating[name]:cancel()
levitating[name] = "done"
levitating[name] = {"done"}
minetest.after(1, function()
levitating[name] = "done"
end)
else
minetest.sound_play({name = "torrl_tools_error"}, {
to_player = name,
@ -128,7 +138,7 @@ end
minetest.register_tool("torrl_tools:sword", {
description = "Sword of Fire\n" ..
"Powers: Melting, Area Damage",
"Powers: Melting, Jump Boost->Ground Smash",
inventory_image = "torrl_tools_sword.png",
tool_capabilities = {
full_punch_interval = 0.8,
@ -139,7 +149,7 @@ minetest.register_tool("torrl_tools:sword", {
blastable = {times={[1] = 5.0}, uses = 0, maxlevel = 1},
meltable = {times={[1] = 1.0}, uses = 0, maxlevel = 1},
},
damage_groups = {alien = 7},
damage_groups = {alien = 8},
},
on_place = power_func,
on_secondary_use = power_func,

View File

@ -2,7 +2,7 @@
# Taken from my CTF script
MOD_PREFIX=mtg_
MODS_TO_KEEP=(creative fire player_api screwdriver sfinv tnt)
MODS_TO_KEEP=(creative player_api screwdriver sfinv)
cd ./mods/mtg/ && {
git clone git@github.com:minetest/minetest_game.git