Add the rest of the game.
BIN
menu/icon.png
Normal file
|
After Width: | Height: | Size: 348 B |
|
|
@ -5,7 +5,7 @@ artifact = {
|
|||
-- This toggles a lot of things, including whether initialization takes place,
|
||||
-- whether nodes can be pointed, and whether the player is permitted to
|
||||
-- bypass certain restrictions imposed by the story.
|
||||
debug = true,
|
||||
debug = false,
|
||||
colors = {
|
||||
gold = "#faf17a",
|
||||
red = "#e94f3f",
|
||||
|
|
@ -54,6 +54,25 @@ function Promise(fn)
|
|||
}
|
||||
end
|
||||
|
||||
|
||||
function artifact.play_sound(def)
|
||||
def.max_hear_distance = def.range
|
||||
--def.gain = nil
|
||||
if def.pos then
|
||||
for _, m in pairs(artifact.players) do
|
||||
local dist = m.pos:distance(def.pos)
|
||||
if dist <= (def.range or 32) and m.name ~= def.exclude_player and not (def.to_player and m.name ~= def.to_player) then
|
||||
def.to_player = m.name
|
||||
def.gain = (def.gain or 1) *(1 -math.sqrt(dist /(def.range or 32)))
|
||||
minetest.sound_play(def, def)
|
||||
end
|
||||
end
|
||||
else
|
||||
minetest.sound_play(def.name, def)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- HACK: Lookup table for getting a rotation from a
|
||||
-- facedir (because Minetest doesn't have any way
|
||||
-- to get this information normally)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,15 @@ function ns.apply_vix(m)
|
|||
end
|
||||
|
||||
function ns._swap_character(m)
|
||||
-- If Key was pointing at something Vix shouldn't be able to interact with,
|
||||
-- but Vix is also pointing at it, then remove the interaction marker since
|
||||
-- it would be misleading.
|
||||
if m.pointed_obj and m.interaction_marker and (not m.pointed_obj._can_interact or m.pointed_obj:_can_interact(m)) then
|
||||
m.object:hud_remove(m.interaction_marker)
|
||||
m.interaction_marker = nil
|
||||
m.interaction_start = nil
|
||||
end
|
||||
|
||||
if m.character == "vix" then
|
||||
artifact.sidekick.character = "vix"
|
||||
m:set_character("key")
|
||||
|
|
@ -52,6 +61,17 @@ function ns._swap_character(m)
|
|||
ns.apply_vix(m)
|
||||
end
|
||||
|
||||
-- If Vix was pointing at something whackable, and the player then switches
|
||||
-- to Key who is pointing at the same thing, we should show the whack icon.
|
||||
if m.character == "key" and m.pointed_node and minetest.registered_nodes[m.pointed_node.node_under.name].groups.whackable then
|
||||
m.whack_hud = m.object:hud_add {
|
||||
type = "image_waypoint",
|
||||
world_pos = m.pointed_node.under,
|
||||
scale = {x=3,y=3},
|
||||
text = "artifact_icon_whack.png"
|
||||
}
|
||||
end
|
||||
|
||||
-- We don't need to have the sidekick entity during testing.
|
||||
if artifact.sidekick.pos or not artifact.debug then
|
||||
-- `m.pos` includes eye_height, and we don't want that here.
|
||||
|
|
@ -124,6 +144,10 @@ function ns.swap_character(m)
|
|||
duration = 0.3
|
||||
}
|
||||
}
|
||||
artifact.play_sound {
|
||||
name = "artifact_character_swap",
|
||||
to_player = m.name
|
||||
}
|
||||
minetest.after(0.3, function()
|
||||
ns._swap_character(m)
|
||||
fade:animate {
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1,005 B After Width: | Height: | Size: 1.9 KiB |
BIN
mods/artifact_characters/textures/artifact_tav_splash.png
Normal file
|
After Width: | Height: | Size: 749 KiB |
BIN
mods/artifact_characters/textures/artifact_tav_splash_low.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -13,26 +13,28 @@ minetest.register_entity(":artifact:burst", {
|
|||
},
|
||||
static_save = false,
|
||||
},
|
||||
on_activate = function(e, rot)
|
||||
on_activate = function(e)
|
||||
e.object:set_armor_groups{immortal = 1}
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
for _, x in ipairs(e._particles) do
|
||||
for _, x in ipairs(e._particles or {}) do
|
||||
minetest.delete_particlespawner(x)
|
||||
end
|
||||
end,
|
||||
on_step = function(e, dtime, movement)
|
||||
-- Minetest's collision is rather bad, but we also shouldn't collide with players,
|
||||
-- hence we must implement our own rudimentary collision detection.
|
||||
-- In this case, any intersection on the segment betwee our last position and our
|
||||
-- In this case, any intersection on the segment between our last position and our
|
||||
-- current one should be considered a collision and result in detonation (and
|
||||
-- at the exact intersection point, if available).
|
||||
local collision
|
||||
if not e._critical then
|
||||
for x in minetest.raycast(e.old_pos or e.object:get_pos(), e.object:get_pos(), true, true, {nodes = {}, objects = {playser = false}}) do
|
||||
collision = x
|
||||
break
|
||||
end
|
||||
if collision or movement.collides then
|
||||
end
|
||||
if collision or movement and movement.collides then
|
||||
if collision then
|
||||
e.object:set_pos(collision.intersection_point)
|
||||
end
|
||||
|
|
@ -61,6 +63,10 @@ minetest.register_entity(":artifact:burst", {
|
|||
drag = 1,
|
||||
time = 0.1,
|
||||
}
|
||||
artifact.play_sound {
|
||||
name = "artifact_burst_impact",
|
||||
pos = e.object:get_pos()
|
||||
}
|
||||
e.object:remove()
|
||||
if movement and movement.collisions[1] and movement.collisions[1].type == "node" then
|
||||
local pos = movement.collisions[1].node_pos
|
||||
|
|
@ -116,6 +122,10 @@ minetest.register_entity(":artifact:burst", {
|
|||
end
|
||||
})
|
||||
|
||||
function ns.do_shoot(m)
|
||||
minetest.add_entity(m.pos +m.dir, "artifact:burst", tostring(m.yaw)):get_luaentity():impulse(m.dir *30)
|
||||
function ns.do_shoot(m, dir)
|
||||
artifact.play_sound {
|
||||
name = "artifact_burst_fire",
|
||||
pos = dir and m or m.pos
|
||||
}
|
||||
minetest.add_entity(dir and m +dir or m.pos +m.dir, "artifact:burst"):get_luaentity():impulse((dir or m.dir) *30)
|
||||
end
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 186 B After Width: | Height: | Size: 194 B |
|
|
@ -59,6 +59,11 @@ minetest.register_entity(":artifact:color_swapper_display", {
|
|||
e._no_interact = true
|
||||
e.object:set_animation({x=7,y=8}, 1, 1, false)
|
||||
m:set_color(e.color)
|
||||
artifact.play_sound {
|
||||
name = "artifact_color_swap",
|
||||
pos = e.object:get_pos(),
|
||||
range = 8,
|
||||
}
|
||||
minetest.after(1, function()
|
||||
if not e._active then return end
|
||||
e.object:set_animation({x=0,y=6}, 1, 1, true)
|
||||
|
|
@ -227,10 +232,11 @@ minetest.register_entity(":artifact:color_target_display", {
|
|||
if m.color == e.color then
|
||||
e._no_interact = true
|
||||
m:set_color(nil)
|
||||
local receivers = minetest.deserialize(minetest.get_meta(e.object:get_pos():round()):get("receivers") or "return nil")
|
||||
if receivers then
|
||||
artifact.dispatch_event(receivers, {type = "pulse"})
|
||||
end
|
||||
artifact.play_sound {
|
||||
name = "artifact_color_use",
|
||||
pos = e.object:get_pos(),
|
||||
range = 8,
|
||||
}
|
||||
-- Update the entity's texture every globalstep, because that's the only way to do a texture animation.
|
||||
local progress = 0
|
||||
local delay = 0
|
||||
|
|
@ -241,6 +247,10 @@ minetest.register_entity(":artifact:color_target_display", {
|
|||
if progress >= 255 then
|
||||
dir = false
|
||||
minetest.after(1, update)
|
||||
local receivers = minetest.deserialize(minetest.get_meta(e.object:get_pos():round()):get("receivers") or "return nil")
|
||||
if receivers then
|
||||
artifact.dispatch_event(receivers, {type = "pulse"})
|
||||
end
|
||||
return
|
||||
end
|
||||
else
|
||||
|
|
@ -303,6 +313,7 @@ artifact.register_node("color_target", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {call_on_load = 1},
|
||||
sounds = artifact.sounds.metal,
|
||||
on_construct = target_onload,
|
||||
on_load = target_onload,
|
||||
on_destruct = function(pos)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ minetest.register_entity(":artifact:door", {
|
|||
if e._locked then
|
||||
e._no_interact = true
|
||||
end
|
||||
if e.inverted then e:invert() end
|
||||
if e.inverted or nm:get("inverted") == "true" then e:invert() end
|
||||
doors[e.object:get_pos():round():to_string()] = e
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
|
|
@ -200,6 +200,10 @@ minetest.register_entity(":artifact:door", {
|
|||
texture = "artifact_door_wood.png^[sheet:2x8:0,3",
|
||||
time = 0.1
|
||||
}
|
||||
artifact.play_sound {
|
||||
name = "artifact_door_break",
|
||||
pos = pos
|
||||
}
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ artifact.register_node("forcefield_generator", {
|
|||
1, 0.5, 0.5
|
||||
}
|
||||
},
|
||||
sounds = artifact.sounds.metal,
|
||||
on_construct = onload,
|
||||
on_load = onload,
|
||||
on_rightclick = artifact.debug and function(pos)
|
||||
|
|
@ -286,6 +287,10 @@ artifact.register_node("forcefield_generator", {
|
|||
minetest.after(0, function()
|
||||
minetest.set_node(pos, node)
|
||||
end)
|
||||
artifact.play_sound {
|
||||
name = "artifact_forcefield_generator_destruct",
|
||||
pos = pos,
|
||||
}
|
||||
minetest.add_particlespawner {
|
||||
pos = pos,
|
||||
vel = vector.zero(),
|
||||
|
|
@ -338,6 +343,7 @@ artifact.register_node("forcefield_generator_off", {
|
|||
1, 0.5, 0.5
|
||||
}
|
||||
},
|
||||
sounds = artifact.sounds.metal,
|
||||
on_impact = artifact.debug and function(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = "forcefield_generator"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
local large_doors = {}
|
||||
artifact.large_doors = large_doors
|
||||
|
||||
minetest.register_entity(":artifact:large_door_display", {
|
||||
initial_properties = {
|
||||
|
|
@ -99,6 +100,23 @@ minetest.register_entity(":artifact:large_door_display", {
|
|||
local pos = e.object:get_pos():round()
|
||||
minetest.get_meta(pos):set_string("open", "true")
|
||||
|
||||
artifact.play_sound {
|
||||
name = "artifact_large_door_open",
|
||||
pos = e.object:get_pos(),
|
||||
range = 10,
|
||||
}
|
||||
|
||||
local m = minetest.get_meta(pos)
|
||||
local on_open = m:get("on_open")
|
||||
if not artifact.debug and on_open then
|
||||
if on_open == "play_final_scene" then
|
||||
artifact.story.play_final_scene()
|
||||
elseif on_open == "play_end_scene" then
|
||||
artifact.story.play_end_scene()
|
||||
end
|
||||
m:set_string("on_open", "")
|
||||
end
|
||||
|
||||
minetest.after(0.75, function()
|
||||
e._animating = nil
|
||||
end)
|
||||
|
|
@ -110,6 +128,13 @@ minetest.register_entity(":artifact:large_door_display", {
|
|||
e.object:set_animation({x=1,y=2}, 1.25, 0.1, false)
|
||||
local pos = e.object:get_pos():round()
|
||||
minetest.get_meta(pos):set_string("open", "false")
|
||||
|
||||
artifact.play_sound {
|
||||
name = "artifact_large_door_close",
|
||||
pos = e.object:get_pos(),
|
||||
range = 10,
|
||||
}
|
||||
|
||||
minetest.after(0.75, function()
|
||||
e._animating = nil
|
||||
end)
|
||||
|
|
@ -185,9 +210,9 @@ local function onload(pos)
|
|||
if not m:contains("initialized") then
|
||||
m:set_string("initialized", "true")
|
||||
local rot = artifact.facedir_to_rotation(minetest.get_node(pos).param2)
|
||||
local locks = {red = false, blue = false, green = false, "red", "green", "blue"}
|
||||
local locks = minetest.deserialize(m:get("locks") or "return nil") or {red = false, blue = false, green = false, "red", "green", "blue"}
|
||||
minetest.add_entity(pos, "artifact:large_door_display", minetest.serialize{locks = locks}):get_luaentity():rotate(rot)
|
||||
minetest.get_meta(pos):set_string("locks", minetest.serialize(locks))
|
||||
m:set_string("locks", minetest.serialize(locks))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -204,6 +229,47 @@ local function onsignal(pos, event, channel)
|
|||
if locks[channel] ~= nil then
|
||||
locks[channel] = true
|
||||
end
|
||||
artifact.play_sound {
|
||||
name = "artifact_lock_light",
|
||||
pos = e.object:get_pos(),
|
||||
range = 10,
|
||||
}
|
||||
local idx = table.indexof(locks, channel)
|
||||
local rot = artifact.facedir_to_rotation(minetest.get_node(pos).param2)
|
||||
minetest.add_particlespawner {
|
||||
pos = pos +vector.new(-0.6 +(idx *0.3), 2.25, -0.2):rotate(rot),
|
||||
vel = {
|
||||
min = vector.new(-1, 0, -1):rotate(rot),
|
||||
max = vector.new(1, 2, -0.2):rotate(rot),
|
||||
},
|
||||
acc = vector.new(0, -9.81, 0),
|
||||
texture = {
|
||||
name = "[fill:1x1:0,0:"..artifact.colors[channel],
|
||||
alpha_tween = {1, 0}
|
||||
},
|
||||
glow = 8,
|
||||
time = 0.1,
|
||||
size = 0.25,
|
||||
amount = 20,
|
||||
exptime = 0.3
|
||||
}
|
||||
minetest.add_particlespawner {
|
||||
pos = pos +vector.new(-0.6 +(idx *0.3), 2.25, 0.2):rotate(rot),
|
||||
vel = {
|
||||
min = vector.new(-1, 0, 0.2):rotate(rot),
|
||||
max = vector.new(1, 2, 1):rotate(rot),
|
||||
},
|
||||
acc = vector.new(0, -8, 0),
|
||||
texture = {
|
||||
name = "[fill:1x1:0,0:"..artifact.colors[channel],
|
||||
alpha_tween = {1, 0}
|
||||
},
|
||||
glow = 8,
|
||||
time = 0.1,
|
||||
size = 0.25,
|
||||
amount = 20,
|
||||
exptime = 0.3
|
||||
}
|
||||
e:set_locks(locks)
|
||||
minetest.get_meta(pos):set_string("locks", minetest.serialize(locks))
|
||||
else
|
||||
|
|
|
|||
|
|
@ -528,13 +528,22 @@ Player = setmetatable({
|
|||
end
|
||||
})
|
||||
|
||||
-- Skip the death screen. Once we have an actual damage
|
||||
-- system, this can be customized properly.
|
||||
function minetest.show_death_screen(p, reason)
|
||||
p:respawn()
|
||||
end
|
||||
|
||||
-- Override respawning, so we can save progress.
|
||||
minetest.register_on_respawnplayer(function(p)
|
||||
local m = artifact.players[p:get_player_name()]
|
||||
return true
|
||||
--[[ Disabled due to current lack of purpose.
|
||||
if m.spawn_point then
|
||||
p:set_pos(m.spawn_point)
|
||||
return true
|
||||
end
|
||||
--]]
|
||||
end)
|
||||
|
||||
-- Mirror the player's HP in our custom HUD.
|
||||
|
|
@ -584,14 +593,6 @@ function artifact.register_input(name)
|
|||
local m = artifact.players[p:get_player_name()]
|
||||
if not m._swapping_character and (artifact.debug or artifact.story.get_state() > artifact.story.states.pre_vix) then
|
||||
artifact.swap_character(m)
|
||||
-- If Key was pointing at something Vix shouldn't be able to interact with,
|
||||
-- but Vix is also pointing at it, then remove the interaction marker since
|
||||
-- it would be misleading.
|
||||
if m.pointed_obj and m.interaction_marker and (not m.pointed_obj._can_interact or m.pointed_obj:_can_interact(m)) then
|
||||
m.object:hud_remove(m.interaction_marker)
|
||||
m.interaction_marker = nil
|
||||
m.interaction_start = nil
|
||||
end
|
||||
end
|
||||
return s
|
||||
end,
|
||||
|
|
@ -634,6 +635,13 @@ minetest.register_on_joinplayer(function(p)
|
|||
end
|
||||
end)
|
||||
|
||||
-- Imposters will be kicked. (But why would you run this on a server anyway?)
|
||||
minetest.register_on_prejoinplayer(function(name)
|
||||
if name == "Key" or name == "Vix" then
|
||||
return "That name is already taken by one of the characters!"
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(p)
|
||||
artifact.players[p:get_player_name()] = nil
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ artifact.story = {
|
|||
"init", -- For the opening cutscene.
|
||||
"pre_vix", -- The player doesn't have Vix yet.
|
||||
"main", -- The main game state. Progress is managed by checkpoints here.
|
||||
"end", -- The game is over.
|
||||
"ended", -- The game is over.
|
||||
},
|
||||
poi = {
|
||||
initial_cutscene = {
|
||||
|
|
@ -30,14 +30,36 @@ minetest.register_entity(":artifact:vix_scene", {
|
|||
initial_properties = {
|
||||
visual = "mesh",
|
||||
mesh = "artifact_scene_vix.gltf",
|
||||
textures = {"artifact_vix.png"}
|
||||
textures = {"artifact_vix.png"},
|
||||
backface_culling = false
|
||||
},
|
||||
on_activate = function(e)
|
||||
if state > ns.states.pre_vix then
|
||||
e.object:remove()
|
||||
return
|
||||
end
|
||||
e.object:set_armor_groups{immortal = 1}
|
||||
e.object:set_animation({x=0,y=2}, 0.5, 0.1, true)
|
||||
|
||||
e.particles = minetest.add_particlespawner {
|
||||
pos = e.object:get_pos():offset(0, 0.15, 0),
|
||||
vel = {
|
||||
min = vector.new(-0.5, 0,-0.5),
|
||||
max = vector.new( 0.5, 0, 0.5)
|
||||
},
|
||||
acc = vector.new(0, -9.81, 0),
|
||||
texture = {
|
||||
name = "artifact_light_gold.png",
|
||||
alpha_tween = {0.75, 0}
|
||||
},
|
||||
collisiondetection = true,
|
||||
time = 0,
|
||||
amount = 100,
|
||||
exptime = 5
|
||||
}
|
||||
e._track_pos = e.object:get_pos():offset(0, 0.5, 0)
|
||||
e._rot = vector.zero()
|
||||
|
||||
vix_scene = e
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
|
|
@ -51,6 +73,21 @@ minetest.register_entity(":artifact:vix_scene", {
|
|||
e._can_check = false
|
||||
end
|
||||
end
|
||||
elseif e._track then
|
||||
local m = artifact.players[next(artifact.players)]
|
||||
local rot = e._track_pos:direction(m.pos):rotate(e._rot):dir_to_rotation()
|
||||
if rot.y > -math.pi *(2/3) and rot.y < math.pi *(2/3) then
|
||||
rot.y = math.pi *(2/3) *math.sign(rot.y)
|
||||
end
|
||||
rot.y = -rot.y +math.pi
|
||||
rot.x = -math.max(-math.pi /3, math.min(math.pi /3, rot.x)) +0.25
|
||||
|
||||
e.object:set_bone_override("Head", {
|
||||
rotation = {
|
||||
vec = rot,
|
||||
interpolation = 0.4
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
|
@ -81,7 +118,7 @@ function ns.enter_pre_vix_state()
|
|||
end
|
||||
db:set_string("checkpoint:pre_vix", "in_room")
|
||||
elseif checkpoint == "in_room" then -- We're actually in the room.
|
||||
if target.node_under.name:find "forcefield_generator" then
|
||||
if type == "node" and target.node_under.name:find "forcefield_generator" then
|
||||
local num = db:get_int("checkpoint:pre_vix_fields_broken") +1
|
||||
db:set_int("checkpoint:pre_vix_fields_broken", num)
|
||||
if num == 1 then -- Key breaks his first generator.
|
||||
|
|
@ -90,6 +127,10 @@ function ns.enter_pre_vix_state()
|
|||
end)
|
||||
elseif num == 5 then -- All generators are down.
|
||||
vix_scene._can_check = nil
|
||||
-- Wait just a bit, so the player can look up.
|
||||
minetest.after(0.5, function()
|
||||
ns.play_vix_scene()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -97,9 +138,55 @@ function ns.enter_pre_vix_state()
|
|||
end
|
||||
|
||||
function ns.enter_main_state()
|
||||
minetest.add_entity(vix_scene.object:get_pos():offset(1.5, -0.8, -0.5), "artifact:sidekick"):set_rotation(vector.new(0, -math.pi /2, 0))
|
||||
vix_scene.object:remove()
|
||||
end
|
||||
|
||||
function ns.enter_ended_state()
|
||||
for _, m in pairs(artifact.players) do
|
||||
local bg = artifact.hud_add(m, {
|
||||
type = "image",
|
||||
image = "[fill:16x16:0,0:#000",
|
||||
opacity = 0,
|
||||
pos = {x=0.5,y=0.5},
|
||||
scale = {x=1000,y=1000},
|
||||
})
|
||||
bg:animate {
|
||||
opacity = {
|
||||
value = 256,
|
||||
duration = 0.3
|
||||
}
|
||||
}
|
||||
minetest.after(0.3, function()
|
||||
local txt = artifact.hud_add(m, {
|
||||
type = "text",
|
||||
color = "#000",
|
||||
text = "To be continued...",
|
||||
pos = {x=0.5,y=0.5},
|
||||
size = {x=3,y=0},
|
||||
color = minetest.colorspec_to_table("#000")
|
||||
})
|
||||
txt:animate {
|
||||
color = {
|
||||
value = minetest.colorspec_to_table("#888"),
|
||||
duration = 0.3
|
||||
}
|
||||
}
|
||||
minetest.after(8, function()
|
||||
txt:animate {
|
||||
color = {
|
||||
value = minetest.colorspec_to_table("#000"),
|
||||
duration = 0.3
|
||||
}
|
||||
}
|
||||
minetest.after(0.3, function()
|
||||
minetest.request_shutdown("You completed the game.")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ns.enter_state(to)
|
||||
state = to
|
||||
if state == ns.states.init then
|
||||
|
|
@ -108,6 +195,8 @@ function ns.enter_state(to)
|
|||
ns.enter_pre_vix_state()
|
||||
elseif state == ns.states.main then
|
||||
ns.enter_main_state()
|
||||
elseif state == ns.states.ended then
|
||||
ns.enter_ended_state()
|
||||
end
|
||||
db:set_int("state", state)
|
||||
end
|
||||
|
|
@ -133,7 +222,7 @@ function artifact.look_at(m, pos, pos2)
|
|||
m.object:set_look_vertical(-rot.x)
|
||||
end
|
||||
|
||||
|
||||
if artifact.debug then
|
||||
minetest.register_chatcommand("splash", {
|
||||
func = function(name)
|
||||
local m = artifact.players[name]
|
||||
|
|
@ -147,6 +236,478 @@ minetest.register_chatcommand("splash", {
|
|||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("flash", {
|
||||
func = function(name)
|
||||
minetest.add_particle {
|
||||
pos = artifact.origin:offset(-16.5, -71.5, -17),
|
||||
velocity = vector.zero(),
|
||||
texture = {
|
||||
name = "artifact_flash.png",
|
||||
alpha_tween = {0, 1}
|
||||
},
|
||||
size = 60,
|
||||
expirationtime = 0.1
|
||||
}
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
artifact.register_node("stasis_beacon", {
|
||||
drawtype = "mesh",
|
||||
mesh = "artifact_stasis_beacon.gltf",
|
||||
tiles = {"artifact_stasis_beacon.png"},
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light"
|
||||
})
|
||||
|
||||
-- The 'cutscene' playerd after the player frees Vix.
|
||||
function ns.play_vix_scene()
|
||||
-- Kaboom.
|
||||
minetest.add_particle {
|
||||
pos = artifact.origin:offset(-16.5, -71.5, -17),
|
||||
velocity = vector.zero(),
|
||||
texture = {
|
||||
name = "artifact_flash.png",
|
||||
alpha_tween = {0, 1}
|
||||
},
|
||||
size = 60,
|
||||
expirationtime = 0.1
|
||||
}
|
||||
artifact.play_sound {
|
||||
name = "artifact_free_vix",
|
||||
pos = artifact.origin:offset(-16.5, -72.5, -17)
|
||||
}
|
||||
vix_scene.object:set_animation({x=3,y=150}, 1, 0.1, false)
|
||||
minetest.delete_particlespawner(vix_scene.particles)
|
||||
vix_scene.particles = nil
|
||||
-- Key can walk around freely, so Vix should try to face him once she wakes.
|
||||
local i = 7
|
||||
minetest.after(i, function()
|
||||
vix_scene._track = true
|
||||
end)
|
||||
i = i +1
|
||||
minetest.after(i, function()
|
||||
-- Is he the one they sent?
|
||||
artifact.push_chat_message("...Who are you?", minetest.colorize("#f5dd66", "???"), "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
-- Awkward.
|
||||
artifact.push_chat_message("Uh... Wow, this is awkward. I did not think that through far enough.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
-- Oops, that didn't help.
|
||||
artifact.push_chat_message("Wait, that was bad, let's try this again.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
-- Better.
|
||||
artifact.push_chat_message("Hi. I'm Key.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
-- ...He's not?
|
||||
artifact.push_chat_message("...Hi.", minetest.colorize("#f5dd66", "???"), "artifact_vix_splash_low.png")
|
||||
-- [ She sits up ]
|
||||
vix_scene._track = nil
|
||||
vix_scene.object:set_bone_override("Head", {
|
||||
rotation = {
|
||||
vec = vector.zero(), interpolation = 0.4
|
||||
}
|
||||
})
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
vix_scene._track = true
|
||||
-- So what's the deal?
|
||||
artifact.push_chat_message("How did you get here?", minetest.colorize("#f5dd66", "???"), "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("It's actually a long story, but the short version is that I fell in a hole.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("...", minetest.colorize("#f5dd66", "???"), "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Maintenance might want to have a look at the closet over there.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
-- Okay... Wait, how long has it been, anyway? The room is awfully overgrown...
|
||||
artifact.push_chat_message("I don't think maintenance will mind...", minetest.colorize("#f5dd66", "???"), "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Probably so...", "Key", "artifact_key_splash_low.png")
|
||||
-- [ Vix climbs off the pedestal ]
|
||||
vix_scene._track = nil
|
||||
vix_scene.object:set_bone_override("Head", {
|
||||
rotation = {
|
||||
vec = vector.zero(), interpolation = 0.4
|
||||
}
|
||||
})
|
||||
vix_scene._track_pos = vix_scene.object:get_pos():offset(1.5, 0, -0.5)
|
||||
vix_scene._rot = vector.new(0, -math.pi /2, 0)
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
vix_scene._track = true
|
||||
artifact.push_chat_message("So, uh, what's _your_ name?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("...Vix.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Formally pleased to meet you.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
-- How trustworthy is he?
|
||||
artifact.push_chat_message("Why did you... break the forcefields?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Well, when I saw you locked inside all those forcefields, I thought 'Wow, she doesn't look too happy'.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Then I thought, 'Hmm, she must have been there a while, what with all the vines over here and not over there.'", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("_Then_ I thought, 'Whoever's fault this is probably isn't going to be back. Why not help her out?'", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("So then I used this cool stick I found to trash all the forcefields and let you out.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
-- ..._Are_ they going to be back...?
|
||||
artifact.push_chat_message("What year is it?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I dunno, I lost count a while back. Somewhere around the turn of the century.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
-- ... I guess not.
|
||||
artifact.push_chat_message("...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
-- You know what, what am I even doing here?
|
||||
-- (It's not like staying is a workable option, but that's not really what Vix has in mind.)
|
||||
artifact.push_chat_message("We need to leave... I don't suppose we could get out the way you got in?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("...Nah.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I guess that leaves the hard way.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Let's see if this works...", "Vix", "artifact_vix_splash_low.png")
|
||||
minetest.after(1, function()
|
||||
local burst = minetest.add_entity(vix_scene.object:get_pos():offset(0, 1, -1.5), "artifact:burst")
|
||||
burst:get_luaentity()._critical = true
|
||||
burst:set_attach(vix_scene.object, "RightArm", vector.new(0, 100, 0))
|
||||
minetest.after(0, function()
|
||||
burst:set_detach()
|
||||
artifact.play_sound {
|
||||
name = "artifact_burst_fire",
|
||||
pos = burst:get_pos()
|
||||
}
|
||||
burst:get_luaentity():impulse(burst:get_pos():direction(artifact.origin:offset(18, -71, -13)) *30)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
i = i +8
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Wow, that's epic.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +2
|
||||
minetest.after(i, function()
|
||||
ns.enter_state(ns.states.main)
|
||||
minetest.after(10, function()
|
||||
local m = artifact.players[next(artifact.players)]
|
||||
if m.character ~= "vix" then
|
||||
artifact.show_help_message(m, "You can switch between Key and Vix using the Drop control.", "info")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
i = i +45
|
||||
minetest.after(i, ns.dialogue_1)
|
||||
end
|
||||
|
||||
function ns.dialogue_1()
|
||||
local i = 0
|
||||
artifact.push_chat_message("So, what's the long version of you you got here?", "Vix", "artifact_vix_splash_low.png")
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Well, one fine day, I was strolling along through a little town called Birchwood.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("On the street corner, some guy was doing a huge ad for an adventuring supply company.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Naturally, I suggested that his wares were overpriced because he was spending so much on advertising.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I won't bore you with the details, but there was a whole thing that ended with me betting him five gold pieces that I could steal some artifact whose name I forget without any supplies at all.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +8
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("(I told him it was probably guarded by a few bats and a couple average-sized spiders, but he wouldn't believe me.)", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I was wrong about there not being any traps, though. That's why I'm down here and not five gold pieces richer. (Yet.)", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("So you came all this way for five gold pieces?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("No, no, I came all this way to prove a point. I'd probably forget I had the gold pieces within the hour.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Wow.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +15
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("So, how about you? What's the story with that awesome burst ability?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Have you ever heard of Iron Dragon?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Nope.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("They're... Well, they were... a vigilante group, who were fairly powerful fifty-some years ago. My father was one of the generals.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Early on, they learned to synthesize a controlled form of energy to power tools; you saw some of that in the forcefields.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Eventually, someone — my aunt, actually — floated the idea that feeding that energy into a human might give them new abilities.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("No one liked it at first. Eventually, though, when we were weakened and all but defeated, my father became desperate enough to consider it.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("He wanted me to be the first test subject. Looking back, I think he wanted to protect me, keep me out of the combat if things got that bad.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I trusted his judgement.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Incredibly, though, he was right... It makes no sense physiologically, but somehow it worked.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +8
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Now here I am half a century later, and it's all gone...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Wow. Imagine an experiment that worked on the first try.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Right? I though there could be something to it, but this? It's been half a century, and I feel even better than I did before.", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("That's what I was thinking. You look sixteen, not 60.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Really?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Yep.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("...Huh. That's...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Really weird?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Yeah. That's exactly how old I was when this happened...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Most intriguing...", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
end
|
||||
|
||||
-- Play the final scene.
|
||||
function ns.play_final_scene()
|
||||
local scn = minetest.add_entity(artifact.origin:offset(132, -69.5, -22), "display")
|
||||
scn:set_properties {
|
||||
visual = "mesh",
|
||||
mesh = "artifact_scene_final.gltf",
|
||||
textures = {"artifact_tav.png"}
|
||||
}
|
||||
local i = 2
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Hey, who's that?", "Key", "artifact_key_splash_low.png")
|
||||
minetest.after(1, function()
|
||||
scn:set_animation({x=0,y=120}, 1, 0, false)
|
||||
end)
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I don't know...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("You.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +3
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Huh?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("What have you done?", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I just walked in here, why?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Vix.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("What?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Hm.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +3
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("So you really did?", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I don't understand...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Is that so?", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Yes?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Traitor.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +2
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Wow.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +2
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Huh? Iron Dragon is gone. What are you accusing me of?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("So you don't know. Unfortunate.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Who are you, anyway?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("A ghost.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Whoa, stop being so ambiguous! I don't think we know what you think we know.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("I'd love to banter, but right now I have more important things to do.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("As far as I'm concerned, you can rot down here — mother.", minetest.colorize("#666", "???"), "artifact_tav_splash_low.png")
|
||||
minetest.after(1, function()
|
||||
local door = artifact.large_doors[artifact.origin:offset(137, -69, -22):round():to_string()]
|
||||
door:open()
|
||||
minetest.after(3, function()
|
||||
door:close()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
i = i +5
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Excuse me!?", "Key", "artifact_key_splash_low.png")
|
||||
artifact.push_chat_message("Excuse me!?", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +3
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Hey! You're being so cliche right now!", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +7
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Well, that was weird.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +9
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("...So, Vix, you wouldn't happen to know of any ventilation shafts conveniently placed nearby, would you?", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +6
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Well, there is one...", "Vix", "artifact_vix_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
artifact.push_chat_message("Nice. Let's get out of this place.", "Key", "artifact_key_splash_low.png")
|
||||
end)
|
||||
i = i +4
|
||||
minetest.after(i, function()
|
||||
ns.enter_state(ns.states.ended)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Play the opening cutscene.
|
||||
function ns.play_intro_cutscene()
|
||||
ns.camera = minetest.add_entity(artifact.origin:offset(0,-0.75,0), "display")
|
||||
|
|
@ -391,7 +952,7 @@ function ns.load_map()
|
|||
m.hud.loading_map_bg.remove_after = 0.3
|
||||
m.object:set_pos(start)
|
||||
end
|
||||
ns.enter_state(artifact.story.states.pre_vix)
|
||||
ns.enter_state(artifact.story.states.init)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
@ -402,6 +963,11 @@ include "objectives.lua"
|
|||
local started = false
|
||||
minetest.register_on_joinplayer(function(p)
|
||||
local m = artifact.players[p:get_player_name()]
|
||||
|
||||
if state == ns.states.ended then
|
||||
minetest.request_shutdown("You completed the game.")
|
||||
end
|
||||
|
||||
-- Only add the HUD etc. if the player is actually in the game.
|
||||
if state == ns.states.init then
|
||||
m.object:set_attach(ns.camera)
|
||||
|
|
@ -417,6 +983,11 @@ minetest.register_on_joinplayer(function(p)
|
|||
wielditem = true
|
||||
}
|
||||
end
|
||||
|
||||
if state == ns.states.pre_vix and db:get_int("checkpoint:pre_vix_fields_broken") >= 5 then
|
||||
-- If the player left during the scene for some reason, start it over when they join back.
|
||||
ns.play_vix_scene()
|
||||
end
|
||||
-- So we only call this when the _first_ player joins.
|
||||
-- Sure, we're technically a singleplayer game, but,
|
||||
-- as they say, better to have it and not need it than
|
||||
|
|
|
|||
1
mods/artifact_story/models/artifact_scene_final.gltf
Normal file
1
mods/artifact_story/models/artifact_stasis_beacon.gltf
Normal file
BIN
mods/artifact_story/textures/artifact_flash.png
Normal file
|
After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 147 KiB |
BIN
mods/artifact_story/textures/artifact_stasis_beacon.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -103,6 +103,35 @@ local function rep(tx, size)
|
|||
end
|
||||
|
||||
|
||||
-- Sound tables for material types.
|
||||
artifact.sounds = {
|
||||
stone = {
|
||||
footstep = "artifact_step_stone"
|
||||
},
|
||||
mossy_stone = {
|
||||
footstep = "artifact_step_stone_mossy"
|
||||
},
|
||||
metal = {
|
||||
footstep = "artifact_step_stone" -- We don't have a separate sound for this, so just use stone for now.
|
||||
},
|
||||
wood = {
|
||||
footstep = "artifact_step_stone"
|
||||
},
|
||||
leaves = {
|
||||
footstep = "artifact_step_leaves"
|
||||
},
|
||||
dry_leaves = {
|
||||
footstep = "artifact_step_leaves_dry"
|
||||
},
|
||||
glass = {
|
||||
footstep = "artifact_step_glass"
|
||||
},
|
||||
water = {
|
||||
footstep = "artifact_water"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- These nodes are only used for the intro cutscene.
|
||||
|
||||
artifact.register_node("stone_brown", {
|
||||
|
|
@ -144,38 +173,49 @@ artifact.register_node("torch_standing", {
|
|||
|
||||
-- End ad-hoc nodes.
|
||||
|
||||
|
||||
artifact.register_node("stone", {
|
||||
tiles = {{name = "artifact_stone.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"}
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.stone,
|
||||
})
|
||||
artifact.register_node("stone_mossy", {
|
||||
tiles = {{name = rep("artifact_stone.png", 4).."^artifact_moss.png", align_style = "world", scale = 4}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.mossy_stone,
|
||||
})
|
||||
|
||||
artifact.register_node("stone_bricks", {
|
||||
tiles = {{name = "artifact_stone_bricks.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.stone,
|
||||
})
|
||||
artifact.register_node("stone_bricks_mossy", {
|
||||
tiles = {{name = rep("artifact_stone_bricks.png", 4).."^artifact_moss_bricks.png", align_style = "world", scale = 4}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.mossy_stone,
|
||||
})
|
||||
|
||||
artifact.register_node("stone_bricks_small", {
|
||||
tiles = {{name = "artifact_stone_bricks_small.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.stone,
|
||||
})
|
||||
artifact.register_node("stone_bricks_small_mossy", {
|
||||
tiles = {{name = rep("artifact_stone_bricks_small.png", 4).."^artifact_moss_bricks_small.png", align_style = "world", scale = 4}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.mossy_stone,
|
||||
})
|
||||
|
||||
artifact.register_node("stone_tile", {
|
||||
tiles = {{name = "artifact_stone_tile.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.stone,
|
||||
})
|
||||
|
||||
artifact.register_node("stone_tile_small", {
|
||||
tiles = {{name = "artifact_stone_tile_small.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.stone,
|
||||
})
|
||||
|
||||
-- Why does making this texture a tile animation darken it!?
|
||||
|
|
@ -188,6 +228,7 @@ artifact.register_node("water", {
|
|||
pointable = artifact.debug,
|
||||
liquid_move_physics = true,
|
||||
post_effect_color = "#2d5a7c55",
|
||||
sounds = artifact.sounds.water,
|
||||
|
||||
liquidtype = "source",
|
||||
-- Minetest pro tip: Do not try to use aliases for these.
|
||||
|
|
@ -213,6 +254,7 @@ artifact.register_node("water_flowing", {
|
|||
liquid_move_physics = true,
|
||||
post_effect_color = "#2d5a7c55",
|
||||
drop = "",
|
||||
sounds = artifact.sounds.water,
|
||||
|
||||
liquidtype = "flowing",
|
||||
liquid_alternative_source = "artifact:water",
|
||||
|
|
@ -240,6 +282,7 @@ artifact.register_node("water_static", {
|
|||
pointable = artifact.debug,
|
||||
liquid_move_physics = true,
|
||||
post_effect_color = "#2d5a7c55",
|
||||
sounds = artifact.sounds.water,
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -263,7 +306,8 @@ artifact.register_node("vines", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"artifact_vines.png"},
|
||||
use_texture_alpha = "clip"
|
||||
use_texture_alpha = "clip",
|
||||
sounds = artifact.sounds.leaves,
|
||||
})
|
||||
artifact.register_node("vines_dry", {
|
||||
drawtype = "nodebox",
|
||||
|
|
@ -286,27 +330,50 @@ artifact.register_node("vines_dry", {
|
|||
paramtype2 = "facedir",
|
||||
tiles = {"artifact_vines_dry.png"},
|
||||
use_texture_alpha = "clip",
|
||||
groups = {whackable = 1}
|
||||
groups = {whackable = 1},
|
||||
sounds = artifact.sounds.dry_leaves,
|
||||
on_destruct = function(pos)
|
||||
artifact.play_sound {
|
||||
name = "artifact_step_leaves",
|
||||
pos = pos,
|
||||
gain = 1.5
|
||||
}
|
||||
end
|
||||
})
|
||||
|
||||
artifact.register_node("leaves", {
|
||||
drawtype = "allfaces",
|
||||
-- paramtype = "light",
|
||||
tiles = {"artifact_leaves.png"},
|
||||
use_texture_alpha = "clip"
|
||||
use_texture_alpha = "clip",
|
||||
sounds = artifact.sounds.leaves,
|
||||
})
|
||||
artifact.register_node("leaves_dry", {
|
||||
drawtype = "allfaces",
|
||||
-- paramtype = "light",
|
||||
tiles = {"artifact_leaves_dry.png"},
|
||||
use_texture_alpha = "clip",
|
||||
groups = {whackable = 1}
|
||||
groups = {whackable = 1},
|
||||
sounds = artifact.sounds.dry_leaves,
|
||||
on_destruct = function(pos)
|
||||
artifact.play_sound {
|
||||
name = "artifact_step_leaves",
|
||||
pos = pos,
|
||||
gain = 1.5
|
||||
}
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
artifact.register_node("wood_planks", {
|
||||
tiles = {{name = "artifact_wood_planks.png", align_style = "world"}},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.wood,
|
||||
})
|
||||
|
||||
artifact.register_node("crate", {
|
||||
tiles = {{name = "artifact_crate.png", align_style = "world"}},
|
||||
sounds = artifact.sounds.wood,
|
||||
})
|
||||
|
||||
artifact.register_node("ladder_wood", {
|
||||
|
|
@ -316,7 +383,8 @@ artifact.register_node("ladder_wood", {
|
|||
paramtype2 = "facedir",
|
||||
tiles = {"artifact_ladder_wood.png"},
|
||||
walkable = false,
|
||||
climbable = true
|
||||
climbable = true,
|
||||
sounds = artifact.sounds.wood,
|
||||
})
|
||||
|
||||
artifact.register_node("ladder_iron", {
|
||||
|
|
@ -326,7 +394,8 @@ artifact.register_node("ladder_iron", {
|
|||
paramtype2 = "facedir",
|
||||
tiles = {"artifact_ladder_iron.png"},
|
||||
walkable = false,
|
||||
climbable = true
|
||||
climbable = true,
|
||||
sounds = artifact.sounds.metal,
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -335,6 +404,7 @@ artifact.register_node("glass", {
|
|||
use_texture_alpha = "clip",
|
||||
tiles = {"artifact_glass.png"},
|
||||
_variants = {"stair", "slab"},
|
||||
sounds = artifact.sounds.glass,
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -364,6 +434,7 @@ local function register_lamp(color, brightness)
|
|||
}
|
||||
}
|
||||
},
|
||||
sounds = artifact.sounds.glass,
|
||||
})
|
||||
artifact.register_node("lamp_"..color.."_wall", {
|
||||
drawtype = "mesh",
|
||||
|
|
@ -398,7 +469,8 @@ local function register_lamp(color, brightness)
|
|||
1/16, 6/16, 8/16
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = artifact.sounds.glass,
|
||||
})
|
||||
artifact.register_node("lamp_"..color.."_hanging", {
|
||||
drawtype = "mesh",
|
||||
|
|
@ -424,7 +496,8 @@ local function register_lamp(color, brightness)
|
|||
2/16, 4/16, 2/16
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = artifact.sounds.glass,
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
local vm_data = {}
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_stone = minetest.get_content_id("artifact:stone")
|
||||
|
||||
-- Singlenode, but the single node is stone.
|
||||
|
|
@ -11,9 +12,12 @@ minetest.register_on_generated(function(vm, minp, maxp)
|
|||
|
||||
vm:get_data(vm_data)
|
||||
|
||||
for i in va:iterp(minp, maxp) do
|
||||
vm_data[i] = c_stone
|
||||
end
|
||||
-- If we load a giant schematic initially, the parts outside view range get eaten by mapgen.
|
||||
-- for i in va:iterp(minp, maxp) do
|
||||
-- if vm_data[i] == c_air then
|
||||
-- vm_data[i] = c_stone
|
||||
-- end
|
||||
-- end
|
||||
|
||||
vm:set_data(vm_data)
|
||||
vm:calc_lighting()
|
||||
|
|
|
|||
BIN
mods/artifact_world/sounds/artifact_burst_fire.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_burst_impact.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_character_swap.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_color_swap.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_color_use.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_door_break.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_free_vix.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_large_door_close.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_large_door_open.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_lock_light.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_step_glass.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_step_leaves.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_step_leaves_dry.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_step_stone.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_step_stone_mossy.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_sticks.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_water.0.ogg
Normal file
BIN
mods/artifact_world/sounds/artifact_water.ogg
Normal file
BIN
mods/artifact_world/textures/artifact_crate.png
Normal file
|
After Width: | Height: | Size: 331 B |
BIN
mods/artifact_world/textures/artifact_moss_bricks_small.png
Normal file
|
After Width: | Height: | Size: 8 KiB |