forked from VoxeLibre/VoxeLibre
Compare commits
15 Commits
Author | SHA1 | Date |
---|---|---|
cora | a0c83e72b9 | |
cora | ad6326271e | |
cora | bf50fd4bef | |
cora | 4b0da270d5 | |
cora | 952e88bdef | |
cora | 62ba054906 | |
cora | 1e2ae7e006 | |
cora | 771192d2f9 | |
cora | d22aad03f5 | |
cora | 9ec4f7847b | |
cora | 2c3aeb3b4d | |
PrairieWind | 250bb0fe22 | |
PrairieWind | 2fdda8ca30 | |
PrairieWind | a57da30742 | |
PrairieAstronomer | 007c238e4f |
|
@ -0,0 +1,190 @@
|
|||
mcl_events = {}
|
||||
mcl_events.registered_events = {}
|
||||
local DBG = minetest.settings:get_bool("mcl_logging_event_api",false)
|
||||
local active_events = {}
|
||||
|
||||
local tpl_eventdef = {
|
||||
stage = 0,
|
||||
max_stage = 1,
|
||||
percent = 100,
|
||||
bars = {},
|
||||
--pos = vector.zero(),
|
||||
--time_start = 0,
|
||||
completed = false,
|
||||
cond_start = function(event) end, --return table of positions
|
||||
on_step = function(event) end,
|
||||
on_start = function(event) end,
|
||||
on_stage_begin = function(event) end,
|
||||
cond_progress = function(event) end, --return next stage
|
||||
cond_complete = function(event) end, --return success
|
||||
}
|
||||
|
||||
local function mcl_log(m,l)
|
||||
if DBG then
|
||||
if not l then l = "action" end
|
||||
minetest.log(l,"[mcl_events] "..m)
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_events.register_event(name,def)
|
||||
mcl_events.registered_events[name] = {}
|
||||
--setmetatable(mcl_events.registered_events[name],tpl_eventdef)
|
||||
mcl_events.registered_events[name] = def
|
||||
mcl_events.registered_events[name].name = name
|
||||
end
|
||||
|
||||
local function addbars(self)
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
if vector.distance(self.pos,player:get_pos()) < 75 then
|
||||
local bar = mcl_bossbars.add_bar(player, {color = "red", text = self.name .. " stage "..self.stage.." / "..self.max_stage, percentage = self.percent }, true,1)
|
||||
table.insert(self.bars,bar)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_bars(self)
|
||||
for _,b in pairs(self.bars) do
|
||||
mcl_bossbars.update_bar(b,{text = self.name .. " stage "..self.stage,percentage=self.percent})
|
||||
end
|
||||
end
|
||||
|
||||
local function start_event(p,e)
|
||||
mcl_log("event started: "..e.name.." at "..minetest.pos_to_string(vector.round(p.pos)))
|
||||
local idx = #active_events + 1
|
||||
active_events[idx] = table.copy(e)
|
||||
setmetatable(active_events[idx],e)
|
||||
for k,v in pairs(p) do active_events[idx][k] = v end
|
||||
active_events[idx].stage = 0
|
||||
active_events[idx].percent = 100
|
||||
active_events[idx].bars = {}
|
||||
active_events[idx].time_start = os.time()
|
||||
active_events[idx]:on_start(p.pos)
|
||||
addbars(active_events[idx])
|
||||
end
|
||||
|
||||
local function finish_event(self,idx)
|
||||
mcl_log("Finished: "..self.name.." at "..minetest.pos_to_string(vector.round(self.pos)))
|
||||
if self.on_complete then self:on_complete() end
|
||||
for _,b in pairs(self.bars) do
|
||||
mcl_bossbars.remove_bar(b)
|
||||
end
|
||||
table.remove(active_events,idx)
|
||||
end
|
||||
|
||||
local etime = 0
|
||||
function check_events(dtime)
|
||||
for idx,ae in pairs(active_events) do
|
||||
if ae.cond_complete and ae:cond_complete() then
|
||||
ae.finished = true
|
||||
finish_event(ae,idx)
|
||||
elseif not ae.cond_complete and ae.max_stage and ae.max_stage <= ae.stage then
|
||||
ae.finished = true
|
||||
finish_event(ae,idx)
|
||||
elseif not ae.finished and ae.cond_progress then
|
||||
local p = ae:cond_progress()
|
||||
if p == true then
|
||||
ae.stage = ae.stage + 1
|
||||
ae:on_stage_begin()
|
||||
elseif tonumber(p) then
|
||||
ae.stage = tonumber(p) or ae.stage + 1
|
||||
ae:on_stage_begin()
|
||||
end
|
||||
elseif not ae.finished and ae.on_step then
|
||||
ae:on_step()
|
||||
end
|
||||
addbars(ae)
|
||||
--update_bars(ae)
|
||||
end
|
||||
etime = etime - dtime
|
||||
if etime > 0 then return end
|
||||
etime = 10
|
||||
for _,e in pairs(mcl_events.registered_events) do
|
||||
local pp = e.cond_start()
|
||||
if pp then
|
||||
for _,p in pairs(pp) do
|
||||
local start = true
|
||||
if e.exclusive_to_area then
|
||||
for _,ae in pairs(active_events) do
|
||||
if e.name == ae.name and vector.distance(p.pos,ae.pos) < e.exclusive_to_area then start = false end
|
||||
end
|
||||
end
|
||||
if start then
|
||||
start_event(p,e)
|
||||
elseif DBG then
|
||||
mcl_log("event "..e.name.." already active at "..minetest.pos_to_string(vector.round(p.pos)))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(check_events)
|
||||
|
||||
mcl_events.register_event("infestation",{
|
||||
max_stage = 5,
|
||||
health = 1,
|
||||
health_max = 1,
|
||||
cond_start = function(self)
|
||||
local r = {}
|
||||
for _,p in pairs(minetest.get_connected_players()) do
|
||||
if p:get_meta():get_string("infestation-omen") == "yes" then
|
||||
p:get_meta():set_string("infestation-omen","")
|
||||
table.insert(r,p:get_pos())
|
||||
end
|
||||
end
|
||||
if #r > 0 then return r end
|
||||
end,
|
||||
on_start = function(self)
|
||||
self.mobs = {}
|
||||
self.health_max = 1
|
||||
self.health = 0
|
||||
end,
|
||||
cond_progress = function(self)
|
||||
local m = {}
|
||||
local h = 0
|
||||
for k,o in pairs(self.mobs) do
|
||||
if o and o:get_pos() then
|
||||
local l = o:get_luaentity()
|
||||
h = h + l.health
|
||||
table.insert(m,o)
|
||||
end
|
||||
end
|
||||
self.mobs = m
|
||||
self.health = h
|
||||
self.percent = math.max(0,(self.health / self.health_max ) * 100)
|
||||
if #m < 1 then
|
||||
return true end
|
||||
end,
|
||||
on_stage_begin = function(self)
|
||||
self.health_max = 0
|
||||
for i=1,15 * self.stage do
|
||||
local m = mcl_mobs.spawn(vector.add(self.pos,vector.new(math.random(20)-10,0,math.random(20)-10)),"mobs_mc:silverfish")
|
||||
local l = m:get_luaentity()
|
||||
if l then
|
||||
self.health_max = self.health_max + l.health
|
||||
table.insert(self.mobs,m)
|
||||
end
|
||||
end
|
||||
end,
|
||||
cond_complete = function(self)
|
||||
local m = {}
|
||||
for k,o in pairs(self.mobs) do
|
||||
if o and o:get_pos() then
|
||||
local l = o:get_luaentity()
|
||||
table.insert(m,o)
|
||||
end
|
||||
end
|
||||
return self.stage >= self.max_stage and #m < 1
|
||||
end,
|
||||
on_complete = function(self)
|
||||
mcl_log("INFESTATION complete")
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("infest",{
|
||||
privs = {debug = true},
|
||||
func = function(n,param)
|
||||
local p = minetest.get_player_by_name(n)
|
||||
p:get_meta():set_string("infestation-omen","yes")
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
name = mcl_events
|
||||
author = cora
|
||||
depends = mcl_mobs,mcl_bossbars
|
|
@ -0,0 +1,166 @@
|
|||
-- mcl_raids
|
||||
mcl_raids = {}
|
||||
|
||||
-- Define the amount of illagers to spawn each wave.
|
||||
local waves = {
|
||||
{
|
||||
["mobs_mc:pillager"] = 5,
|
||||
["mobs_mc:vindicator"] = 1,
|
||||
},
|
||||
{
|
||||
["mobs_mc:pillager"] = 4,
|
||||
["mobs_mc:vindicator"] = 3,
|
||||
},
|
||||
{
|
||||
["mobs_mc:pillager"] = 4,
|
||||
["mobs_mc:vindicator"] = 1,
|
||||
["mobs_mc:witch"] = 1,
|
||||
--["mobs_mc:ravager"] = 1,
|
||||
},
|
||||
{
|
||||
["mobs_mc:pillager"] = 5,
|
||||
["mobs_mc:vindicator"] = 2,
|
||||
["mobs_mc:witch"] = 3,
|
||||
},
|
||||
{
|
||||
["mobs_mc:pillager"] = 5,
|
||||
["mobs_mc:vindicator"] = 5,
|
||||
["mobs_mc:witch"] = 1,
|
||||
["mobs_mc:evoker"] = 1,
|
||||
},
|
||||
}
|
||||
|
||||
local extra_wave = {
|
||||
["mobs_mc:pillager"] = 5,
|
||||
["mobs_mc:vindicator"] = 5,
|
||||
["mobs_mc:witch"] = 1,
|
||||
["mobs_mc:evoker"] = 1,
|
||||
--["mobs_mc:ravager"] = 2,
|
||||
}
|
||||
|
||||
function mcl_raids.spawn_raid(event)
|
||||
local pos = event.pos
|
||||
local wave = event.stage
|
||||
local illager_count = 0
|
||||
local spawnable = false
|
||||
local r = 32
|
||||
local n = 12
|
||||
local i = math.random(1, n)
|
||||
local raid_pos = vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r * math.sin(((i-1)/n) * (2*math.pi)))
|
||||
local sn = minetest.find_nodes_in_area_under_air(vector.offset(raid_pos,-5,-50,-5), vector.offset(raid_pos,5,50,5), {"group:grass_block", "group:grass_block_snow", "group:snow_cover", "group:sand"})
|
||||
mcl_bells.ring_once(pos)
|
||||
if sn and #sn > 0 then
|
||||
local spawn_pos = sn[math.random(#sn)]
|
||||
if spawn_pos then
|
||||
minetest.log("action", "[mcl_raids] Raid Spawn Position chosen at " .. minetest.pos_to_string(spawn_pos) .. ".")
|
||||
event.health_max = 0
|
||||
local w
|
||||
if event.stage <= #waves then
|
||||
w= waves[event.stage]
|
||||
else
|
||||
w = extra_wave
|
||||
end
|
||||
for m,c in pairs(w) do
|
||||
for i=1,c do
|
||||
local mob = mcl_mobs.spawn(spawn_pos,m)
|
||||
local l = mob:get_luaentity()
|
||||
if l then
|
||||
event.health_max = event.health_max + l.health
|
||||
table.insert(event.mobs,mob)
|
||||
end
|
||||
end
|
||||
end
|
||||
minetest.log("action", "[mcl_raids] Raid Spawned. Illager Count: " .. #event.mobs .. ".")
|
||||
else
|
||||
minetest.log("action", "[mcl_raids] Raid Spawn Postion not chosen.")
|
||||
end
|
||||
elseif not sn then
|
||||
minetest.log("action", "[mcl_raids] Raid Spawn Position error, no appropriate site found.")
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_raids.find_villager(pos)
|
||||
local obj = minetest.get_objects_inside_radius(pos, 8)
|
||||
for _, objects in ipairs(obj) do
|
||||
local object = objects:get_luaentity()
|
||||
if object then
|
||||
if object.name ~= "mobs_mc:villager" then
|
||||
return
|
||||
elseif object.name == "mobs_mc:villager" then
|
||||
minetest.log("action", "[mcl_raids] Villager Found.")
|
||||
return true
|
||||
else
|
||||
minetest.log("action", "[mcl_raids] No Villager Found.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_raids.find_bed(pos)
|
||||
return minetest.find_node_near(pos,128,{"mcl_beds:bed_red_bottom"})
|
||||
end
|
||||
|
||||
function mcl_raids.find_village(pos)
|
||||
local bed = mcl_raids.find_bed(pos)
|
||||
if bed and mcl_raids.find_villager(bed) then
|
||||
return bed
|
||||
end
|
||||
end
|
||||
|
||||
mcl_events.register_event("raid",{
|
||||
max_stage = 5,
|
||||
health = 1,
|
||||
health_max = 1,
|
||||
exclusive_to_area = 128,
|
||||
cond_start = function(self)
|
||||
local r = {}
|
||||
for _,p in pairs(minetest.get_connected_players()) do
|
||||
if mcl_potions.player_has_effect(p,"bad_omen") then
|
||||
local raid_pos = mcl_raids.find_village(p:get_pos())
|
||||
if raid_pos then
|
||||
table.insert(r,{ player = p:get_player_name(), pos = raid_pos })
|
||||
end
|
||||
end
|
||||
end
|
||||
if #r > 0 then return r end
|
||||
end,
|
||||
on_start = function(self)
|
||||
self.mobs = {}
|
||||
self.health_max = 1
|
||||
self.health = 0
|
||||
local lv = mcl_potions.player_get_effect(minetest.get_player_by_name(self.player), "bad_omen").factor
|
||||
if lv and lv > 1 then self.max_stage = 6 end
|
||||
end,
|
||||
cond_progress = function(self)
|
||||
local m = {}
|
||||
local h = 0
|
||||
for k,o in pairs(self.mobs) do
|
||||
if o and o:get_pos() then
|
||||
local l = o:get_luaentity()
|
||||
h = h + l.health
|
||||
table.insert(m,o)
|
||||
end
|
||||
end
|
||||
self.mobs = m
|
||||
self.health = h
|
||||
self.percent = math.max(0,(self.health / self.health_max ) * 100)
|
||||
if #m < 1 then
|
||||
return true end
|
||||
end,
|
||||
on_stage_begin = mcl_raids.spawn_raid,
|
||||
cond_complete = function(self)
|
||||
local m = {}
|
||||
for k,o in pairs(self.mobs) do
|
||||
if o and o:get_pos() then
|
||||
local l = o:get_luaentity()
|
||||
table.insert(m,o)
|
||||
end
|
||||
end
|
||||
return self.stage >= self.max_stage and #m < 1
|
||||
end,
|
||||
on_complete = function(self)
|
||||
--minetest.log("RAID complete")
|
||||
awards.unlock(self.player,"mcl:hero_of_the_village")
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
name = mcl_raids
|
||||
author = PrairieWind
|
||||
depends = mcl_events, mcl_mobs, mcl_potions, mcl_bells, mcl_achievements
|
|
@ -487,3 +487,11 @@ awards.register_achievement("mcl:obsidian", {
|
|||
type = "Advancement",
|
||||
group = "Overworld",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:hero_of_the_village", {
|
||||
title = S("Hero of the village"),
|
||||
description = S("Successfully defend a village from a raid"),
|
||||
icon = "mcl_raids_hero_of_the_village_icon.png",
|
||||
type = "Advancement",
|
||||
group = "Overworld",
|
||||
})
|
||||
|
|
|
@ -19,6 +19,7 @@ get_chat_function["water_breathing"] = mcl_potions.water_breathing_func
|
|||
get_chat_function["leaping"] = mcl_potions.leaping_func
|
||||
get_chat_function["swiftness"] = mcl_potions.swiftness_func
|
||||
get_chat_function["heal"] = mcl_potions.healing_func
|
||||
get_chat_function["bad_omen"] = mcl_potions.bad_omen_func
|
||||
|
||||
minetest.register_chatcommand("effect",{
|
||||
params = S("<effect> <duration> [<factor>]"),
|
||||
|
|
|
@ -9,6 +9,7 @@ EF.leaping = {}
|
|||
EF.swift = {} -- for swiftness AND slowness
|
||||
EF.night_vision = {}
|
||||
EF.fire_proof = {}
|
||||
EF.bad_omen = {}
|
||||
|
||||
local EFFECT_TYPES = 0
|
||||
for _,_ in pairs(EF) do
|
||||
|
@ -350,6 +351,26 @@ minetest.register_globalstep(function(dtime)
|
|||
|
||||
end
|
||||
|
||||
-- Check for Bad Omen
|
||||
for player, vals in pairs(EF.bad_omen) do
|
||||
|
||||
is_player = player:is_player()
|
||||
|
||||
EF.bad_omen[player].timer = EF.bad_omen[player].timer + dtime
|
||||
|
||||
if player:get_pos() then mcl_potions._add_spawner(player, "#0b6138") end
|
||||
|
||||
if EF.bad_omen[player] and EF.bad_omen[player].timer >= EF.bad_omen[player].dur then
|
||||
EF.bad_omen[player] = nil
|
||||
if is_player then
|
||||
meta = player:get_meta()
|
||||
meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player]))
|
||||
potions_set_hud(player)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
-- Prevent damage to player with Fire Resistance enabled
|
||||
|
@ -386,7 +407,8 @@ function mcl_potions._clear_cached_player_data(player)
|
|||
EF.swift[player] = nil
|
||||
EF.night_vision[player] = nil
|
||||
EF.fire_proof[player] = nil
|
||||
|
||||
EF.bad_omen[player] = nil
|
||||
|
||||
meta = player:get_meta()
|
||||
meta:set_int("night_vision", 0)
|
||||
end
|
||||
|
@ -400,9 +422,9 @@ function mcl_potions._reset_player_effects(player, set_hud)
|
|||
mcl_potions.make_invisible(player, false)
|
||||
|
||||
playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping")
|
||||
|
||||
|
||||
playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness")
|
||||
|
||||
|
||||
mcl_weather.skycolor.update_sky_color({player})
|
||||
|
||||
mcl_potions._clear_cached_player_data(player)
|
||||
|
@ -429,6 +451,7 @@ function mcl_potions._save_player_effects(player)
|
|||
meta:set_string("_is_swift", minetest.serialize(EF.swift[player]))
|
||||
meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player]))
|
||||
meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player]))
|
||||
meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player]))
|
||||
|
||||
end
|
||||
|
||||
|
@ -480,6 +503,10 @@ function mcl_potions._load_player_effects(player)
|
|||
EF.fire_proof[player] = minetest.deserialize(meta:get_string("_is_fire_proof"))
|
||||
end
|
||||
|
||||
if minetest.deserialize(meta:get_string("_has_bad_omen")) then
|
||||
EF.bad_omen[player] = minetest.deserialize(meta:get_string("_has_bad_omen"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Returns true if player has given effect
|
||||
|
@ -490,6 +517,13 @@ function mcl_potions.player_has_effect(player, effect_name)
|
|||
return EF[effect_name][player] ~= nil
|
||||
end
|
||||
|
||||
function mcl_potions.player_get_effect(player, effect_name)
|
||||
if not EF[effect_name] or not EF[effect_name][player] then
|
||||
return false
|
||||
end
|
||||
return EF[effect_name][player]
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer( function(player)
|
||||
mcl_potions._save_player_effects(player)
|
||||
mcl_potions._clear_cached_player_data(player) -- clearout the buffer to prevent looking for a player not there
|
||||
|
@ -966,3 +1000,18 @@ function mcl_potions._extinguish_nearby_fire(pos, radius)
|
|||
end
|
||||
return exting
|
||||
end
|
||||
|
||||
function mcl_potions.bad_omen_func(player, factor, duration)
|
||||
if not EF.bad_omen[player] then
|
||||
EF.bad_omen[player] = {dur = duration, timer = 0, factor = factor}
|
||||
else
|
||||
local victim = EF.bad_omen[player]
|
||||
victim.dur = math.max(duration, victim.dur - victim.timer)
|
||||
victim.timer = 0
|
||||
victim.factor = factor
|
||||
end
|
||||
|
||||
if player:is_player() then
|
||||
potions_set_icons(player)
|
||||
end
|
||||
end
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
|
@ -221,4 +221,7 @@ mcl_logging_mapgen (Chunk generation logging) bool false
|
|||
mcl_logging_structures (Structure generation logging) bool true
|
||||
|
||||
#Complete debug logging for mcl_signs events. Use this if you have issues with signs.
|
||||
mcl_logging_mcl_signs (Complete debug logging for mcl_signs) bool true
|
||||
mcl_logging_mcl_signs (Complete debug logging for mcl_signs) bool false
|
||||
|
||||
#Debug logging for mcl_events.
|
||||
mcl_logging_event_api (Debug logging for mcl_events) bool false
|
||||
|
|
Loading…
Reference in New Issue