Boss fight
This commit is contained in:
parent
877a06eb21
commit
83005711a0
@ -6,13 +6,13 @@ local DEFAULT_DURATION = 4000000
|
||||
local speakers = {
|
||||
light_orb = { image = "sf_messages_speaker_light_orb.png", sound = {name="sf_messages_speaker_light_orb", gain=0.5} },
|
||||
wizard = { image = "sf_messages_speaker_wizard.png", sound = {name="sf_messages_speaker_wizard", gain=0.5} },
|
||||
shadow_orb = { image = "sf_messages_speaker_shadow_orb.png", sound = {name="sf_messages_speaker_shadow_orb", gain=0.5} },
|
||||
shadow_orb = { image = "sf_messages_speaker_shadow_orb.png", sound = {name="sf_messages_speaker_light_orb", gain=0.6, pitch=0.5} },
|
||||
meta = { image = "blank.png", sound = {name="sf_messages_speaker_light_orb", gain=0.5} },
|
||||
}
|
||||
local orb = speakers.light_orb
|
||||
local wiz = speakers.wizard
|
||||
local sha = speakers.boss
|
||||
local met = speakers.dev
|
||||
local sha = speakers.shadow_orb
|
||||
local met = speakers.meta
|
||||
|
||||
local dialog_texts = {
|
||||
["intro"] = { texts = {
|
||||
@ -34,14 +34,15 @@ local dialog_texts = {
|
||||
["enemy_hint"] = { texts = {
|
||||
{ met, S("Use the staff of light to defend yourself."), },
|
||||
}},
|
||||
["boss"] = { texts = {
|
||||
{ sha, S("I am the mighty Shadow Orb! Prepare to die!") },
|
||||
}},
|
||||
["outro"] = { texts = {
|
||||
{ wiz, S("BOOM! Take that, shadow creature!"), },
|
||||
{ orb, S("Peace, at last."), },
|
||||
{ orb, S("So will the forest return to normal?"), },
|
||||
{ wiz, S("Yes. But it will take time to heal …"), },
|
||||
{ met, S("THANK YOU FOR PLAYING SHADOW FOREST!") },
|
||||
{ met, S("Game over. You can either exit the game now …") },
|
||||
{ met, S("… or try to find the remaining vases.") },
|
||||
}},
|
||||
["chimneys"] = { texts = {
|
||||
{ orb, S("What is this?") },
|
||||
@ -86,9 +87,9 @@ local dialog_texts = {
|
||||
{ wiz, S("OMENA TENMU GNURF PELMI!"), },
|
||||
{ orb, S("Oh, THAT’S what the light crystals are for!"), },
|
||||
}},
|
||||
["darkness_warning"] = { texts =
|
||||
{ orb, S("This place is so dark, not even I can light it up."),
|
||||
{ orb, S("I sense a great danger …") }
|
||||
["darkness_warning"] = { texts = {
|
||||
{ orb, S("This place is so dark, not even I can light it up.") },
|
||||
{ orb, S("I sense a great danger …") },
|
||||
}},
|
||||
["darkness_damage"] = { texts = {
|
||||
{ orb, S("The shadows are violent! Turn back!") }
|
||||
|
BIN
mods/sf_messages/textures/sf_messages_speaker_shadow_orb.png
Normal file
BIN
mods/sf_messages/textures/sf_messages_speaker_shadow_orb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
@ -1,2 +1,2 @@
|
||||
name = sf_mobs
|
||||
depends = sf_util, sf_particles, sf_projectiles, sf_upgrade, sf_resources
|
||||
depends = sf_util, sf_particles, sf_projectiles, sf_upgrade, sf_resources, sf_zones
|
||||
|
@ -33,7 +33,7 @@ local SHADOW_ORB_ATTACK_TIMER = 0.5
|
||||
local SHADOW_ORB_ATTACK_RANGE = 32
|
||||
local SHADOW_ORB_PROJECTILE_SPEED = 15
|
||||
local SHADOW_ORB_SPAWN_TIMER = 5
|
||||
local SHADOW_ORB_SPAWN_CHECK_RANGE = 5
|
||||
local SHADOW_ORB_SPAWN_CHECK_RANGE = 30
|
||||
local SHADOW_ORB_SPAWN_COUNT = 4
|
||||
local SHADOW_ORB_SPAWN_MAX_COUNT = 10
|
||||
local SHADOW_ORB_FRAGMENTS = 80
|
||||
@ -450,7 +450,7 @@ minetest.register_entity("sf_mobs:shadow_orb", {
|
||||
on_activate = function(self)
|
||||
self.object:set_armor_groups({shadow_physical=100})
|
||||
end,
|
||||
on_death = function(self, killer)
|
||||
on_death = function(self)
|
||||
local pos = self.object:get_pos()
|
||||
minetest.add_particlespawner({
|
||||
amount = 13,
|
||||
@ -527,6 +527,20 @@ minetest.register_entity("sf_mobs:shadow_orb", {
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local boss_arena = sf_zones.get_zone("boss_arena")
|
||||
sf_util.break_nodes_in_area(boss_arena.pos_min, boss_arena.pos_max, "sf_nodes:weak_concrete", nil)
|
||||
|
||||
local player = sf_util.get_closest_player(pos)
|
||||
if player and player:is_player() then
|
||||
local pmeta = player:get_meta()
|
||||
pmeta:set_int("sf_mobs:boss_defeated", 1)
|
||||
end
|
||||
minetest.after(3, function(player)
|
||||
if player and player:is_player() then
|
||||
sf_dialog.show_dialog(player, "outro", true)
|
||||
end
|
||||
end, player)
|
||||
end,
|
||||
on_punch = on_punch_default,
|
||||
on_step = function(self, dtime, moveresult)
|
||||
|
@ -31,6 +31,9 @@ local register_mob_spawner = function(id, def)
|
||||
if EDITOR then
|
||||
return
|
||||
end
|
||||
if def.limit == 0 then
|
||||
return
|
||||
end
|
||||
local objs = minetest.get_objects_inside_radius(pos, math.max(SPAWNER_PREVENT_RANGE, SPAWNER_LIMIT_RANGE))
|
||||
local mobs_of_same_kind = 0
|
||||
for o=1, #objs do
|
||||
|
@ -339,6 +339,18 @@ minetest.register_node("sf_nodes:concrete", {
|
||||
})
|
||||
make_leveled_node("sf_nodes:concrete", S("Leveled Concrete"))
|
||||
|
||||
local wconcrete_tiles
|
||||
if EDITOR then
|
||||
wconcrete_tiles = { "sf_nodes_concrete.png^sf_nodes_weak_concrete_overlay.png" }
|
||||
else
|
||||
wconcrete_tiles = { "sf_nodes_concrete.png" }
|
||||
end
|
||||
minetest.register_node("sf_nodes:weak_concrete", {
|
||||
description = S("Weak Concrete"),
|
||||
tiles = wconcrete_tiles,
|
||||
groups = { editor_breakable = 1 },
|
||||
sounds = sf_sounds.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("sf_nodes:tree", {
|
||||
description = S("Tree"),
|
||||
|
BIN
mods/sf_nodes/textures/sf_nodes_weak_concrete_overlay.png
Normal file
BIN
mods/sf_nodes/textures/sf_nodes_weak_concrete_overlay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 B |
@ -1,3 +1,5 @@
|
||||
local GRAVITY = 9.81
|
||||
|
||||
sf_util = {}
|
||||
|
||||
sf_util.get_singleplayer = function()
|
||||
@ -115,3 +117,47 @@ function sf_util.set_xz_nodes(pos, min_y, nodename, leveled_nodename, vmanip_are
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
sf_util.break_nodes_in_area = function(pos_min, pos_max, nodename, sound)
|
||||
local nodes = minetest.find_nodes_in_area(pos_min, pos_max, nodename)
|
||||
local broken = 0
|
||||
for n=1,#nodes do
|
||||
local nodepos = nodes[n]
|
||||
minetest.remove_node(nodepos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 16,
|
||||
time = 0.05,
|
||||
exptime = {
|
||||
min = 1,
|
||||
max = 1.5,
|
||||
},
|
||||
pos = {
|
||||
min = vector.add(nodepos, vector.new(-0.2, -0.2, -0.2)),
|
||||
max = vector.add(nodepos, vector.new(0.2, 0.2, 0.2)),
|
||||
},
|
||||
vel = {
|
||||
min = vector.new(-2, -2, -2),
|
||||
max = vector.new(2, 2, 2),
|
||||
},
|
||||
size = 2,
|
||||
drag = vector.new(2, 0, 2),
|
||||
acc = vector.new(0, -GRAVITY, 0),
|
||||
collisiondetection = true,
|
||||
node = {name=nodename},
|
||||
})
|
||||
broken = broken + 1
|
||||
end
|
||||
if broken > 0 then
|
||||
local pos = table.copy(pos_min)
|
||||
-- Get area middle to play sound
|
||||
pos.x = pos_min.x + (pos_max.x - pos_min.x)/2
|
||||
pos.y = pos_min.y + (pos_max.y - pos_min.y)/2
|
||||
pos.z = pos_min.z + (pos_max.z - pos_min.z)/2
|
||||
if sound then
|
||||
minetest.sound_play(sound, {pos=pos}, true)
|
||||
end
|
||||
minetest.log("action", "[sf_util] "..broken.." node(s) of type '"..nodename.."' broken in area")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -158,45 +158,8 @@ sf_zones.register_zone("chimneys", {
|
||||
sf_dialog.show_dialog(player, "chimneys", true)
|
||||
end,
|
||||
})
|
||||
|
||||
local break_weak_spikeplants_in_area = function(pos_min, pos_max)
|
||||
local bushes = minetest.find_nodes_in_area(pos_min, pos_max, "sf_nodes:spikeplant_weak")
|
||||
local broken = 0
|
||||
for b=1,#bushes do
|
||||
local bush = bushes[b]
|
||||
minetest.remove_node(bush)
|
||||
minetest.add_particlespawner({
|
||||
amount = 16,
|
||||
time = 0.05,
|
||||
exptime = {
|
||||
min = 1,
|
||||
max = 1.5,
|
||||
},
|
||||
pos = {
|
||||
min = vector.add(bush, vector.new(-0.2, -0.2, -0.2)),
|
||||
max = vector.add(bush, vector.new(0.2, 0.2, 0.2)),
|
||||
},
|
||||
vel = {
|
||||
min = vector.new(-2, -2, -2),
|
||||
max = vector.new(2, 2, 2),
|
||||
},
|
||||
size = 2,
|
||||
drag = vector.new(2, 0, 2),
|
||||
acc = vector.new(0, -GRAVITY, 0),
|
||||
collisiondetection = true,
|
||||
node = {name="sf_nodes:spikeplant_weak"},
|
||||
})
|
||||
broken = broken + 1
|
||||
end
|
||||
if broken > 0 then
|
||||
local pos = table.copy(pos_min)
|
||||
-- Get zone middle
|
||||
pos.x = pos_min.x + (pos_max.x - pos_min.x)/2
|
||||
pos.y = pos_min.y + (pos_max.y - pos_min.y)/2
|
||||
pos.z = pos_min.z + (pos_max.z - pos_min.z)/2
|
||||
minetest.sound_play({name = "sf_zones_spikeplant_break", gain=1.0}, {pos=pos}, true)
|
||||
minetest.log("action", "[sf_dialog] "..broken.." weak shadow bush(es) broken!")
|
||||
end
|
||||
sf_util.break_nodes_in_area(pos_min, pos_max, "sf_nodes:spikeplant_weak", {name = "sf_zones_spikeplant_break", gain=1.0})
|
||||
end
|
||||
|
||||
sf_zones.register_zone("shadow_bush_barrier", {
|
||||
@ -216,6 +179,43 @@ sf_zones.register_zone("shadow_bush_barrier", {
|
||||
end,
|
||||
})
|
||||
|
||||
sf_zones.register_zone("boss_arena", {
|
||||
pos_min = vector.new(52, 12, 20),
|
||||
pos_max = vector.new(76, 41, 64),
|
||||
})
|
||||
|
||||
sf_zones.register_zone("boss_arena_enter", {
|
||||
pos_min = vector.new(52, 12, 40),
|
||||
pos_max = vector.new(76, 30, 64),
|
||||
on_enter = function(zonename, player)
|
||||
local zone = sf_zones.get_zone("boss_arena")
|
||||
local objs = minetest.get_objects_in_area(zone.pos_min, zone.pos_max)
|
||||
local boss_exists = false
|
||||
local pmeta = player:get_meta()
|
||||
if pmeta:get_int("sf_mobs:boss_defeated") == 1 then
|
||||
minetest.log("action", "[sf_zones] "..player:get_player_name().." entered boss arena but boss already defeated")
|
||||
return
|
||||
end
|
||||
for o=1, #objs do
|
||||
local lua = objs[o]:get_luaentity()
|
||||
if lua and lua.name == "sf_mobs:shadow_orb" then
|
||||
boss_exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not boss_exists then
|
||||
local spawners = minetest.find_nodes_in_area(zone.pos_min, zone.pos_max, "sf_mobs:spawner_shadow_orb")
|
||||
for s=1, #spawners do
|
||||
minetest.add_entity(spawners[s], "sf_mobs:shadow_orb")
|
||||
minetest.log("action", "[sf_zones] Shadow orb boss spawed at "..minetest.pos_to_string(spawners[s]))
|
||||
end
|
||||
end
|
||||
sf_dialog.show_dialog(player, "boss", true)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
-- TODO: The music for the "shrine" zones is kinda hacky, this only
|
||||
-- works as long these are embedded completely in another zone
|
||||
sf_zones.register_zone("snow_mountain_shrine", {
|
||||
|
@ -1,2 +1,2 @@
|
||||
name = sf_zones
|
||||
depends = sf_sky, sf_music, sf_dialog
|
||||
depends = sf_sky, sf_music, sf_dialog, sf_util
|
||||
|
Loading…
x
Reference in New Issue
Block a user