Further changes to sabotage.

master
Nathan Salapat 2022-05-26 21:40:20 -05:00
parent 9da11683bc
commit 40e5dfe52b
7 changed files with 189 additions and 174 deletions

View File

@ -103,7 +103,7 @@ minetest.register_on_respawnplayer(function(player)
minetest.chat_send_player(name, 'Immortallity has ended.')
end)
if map_id ~= 'lobby' and mode == 'ghost' then
if lobby.map[map_id] > 1 then
if lobby.map[map_id] and lobby.map[map_id] > 1 then
player:set_pos(pos)
return true
else

View File

@ -21,16 +21,21 @@ function sabotage.builder_formspec(pos)
local timer = meta:get_int('timer') or 120
local chance = meta:get_int('chance') or 1
local damage = meta:get_int('damage') or 1
local alert = meta:get_string('alert') or ''
local formspec =
'formspec_version[3]'..
'size[16,9]'..
'textarea[1,1;14,4;;;Sabotaging is a risky business, the traitor can fail and take damage. '..
'Chance is the probability of failure when attempting to sabotage. (1-10 Traitor\'s luck level comes in play here.)'..
'Damage is the MAX amount of damage the traitor will incur. Keep in mind the default health level is 20.'..
'Timer is the amount of time the crew is given to \'repair\' the sabotaged node before the traitor wins the level. Must be over 30 seconds.]'..
'field[1,6;2.5,.75;chance;Chance:;'..chance..']'..
'field[6.75,6;2.5,.75;damage;Damage:;'..damage..']'..
'field[12.5,6;2.5,.75;timer;Timer:;'..timer..']'..
'Timer is the amount of time the crew is given to \'repair\' the sabotaged node before the traitor wins the level. Must be over 30 seconds.\n'..
'Alert text will be sent to all players on the level, \n'..
'and should include something to let them know where/what was sabotaged and needs to be fixed. \n'..
'This will be a chat message. The node description will also be included in the HUD display.]'..
'textarea[1,5;14,1;alert;Alert Text:;'..alert..']'..
'field[1,6.5;2.5,.75;chance;Chance:;'..chance..']'..
'field[6.75,6.5;2.5,.75;damage;Damage:;'..damage..']'..
'field[12.5,6.5;2.5,.75;timer;Timer:;'..timer..']'..
'button_exit[6.5,7.5;3,1;save;Save]'
return formspec
end

View File

@ -1,57 +1,74 @@
function sabotage.show_hud(map_id, timer)
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
sabotage.hud[name] = {
title = player:hud_add({
hud_elem_type = 'text',
position = {x = 1, y = 0.125},
offset = {x = -20, y = 0},
text = 'Time until traitor victory:',
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
}),
timer = player:hud_add({
hud_elem_type = 'text',
position = {x = 1, y = 0.125},
offset = {x = -60, y = 20},
text = timer..' seconds',
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
})
}
minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
if formname == 'sabotage:traitor' then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
if fields.sabotage then
local chance = meta:get_int('chance') or 1
local damage = meta:get_int('damage') or 1
local player_attributes = player:get_meta()
local luck = player_attributes:get_int('luck')
if math.random(10) + luck >= chance then
local hurt = math.random(damage)
local health = player:get_hp()
local new_health = health - hurt
player:set_hp(new_health)
end
if math.random(10) + luck >= chance then
local node = minetest.get_node(pos).name
local def = minetest.registered_nodes[node]
local desc = def.description
local map_id = lobby.game[name]
meta:set_string('traitor', name)
meta:set_string('map_id', map_id)
meta:set_string('sabotaged', 'true')
local time = meta:get_int('timer')
local timer = minetest.get_node_timer(pos)
local alert = meta:get_string('alert')
timer:start(time)
lobby.message_to_level(map_id, 'Warning!!! Level has been sabotaged. Proceed with caution!!!')
lobby.message_to_level(map_id, alert)
minetest.chat_send_player(name, 'You dirty dog, you just doomed the lives of all other players.')
sabotage.show_hud(map_id, time, desc)
sabotage.timer[map_id] = time
end
end
elseif formname == 'sabotage:builder' then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
if fields.save then
local timer = math.max((tonumber(fields.timer) or 30), 30)
local chance = math.min((fields.chance or 2), 10)
local damage = fields.damage or 1
local alert = fields.alert or ''
meta:set_int('timer', timer)
meta:set_int('chance', chance)
meta:set_int('damage', damage)
meta:set_string('sabotaged', 'false')
meta:set_string('alert', alert)
end
elseif formname == 'sabotage:player' then
if fields.repair then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
local chance = meta:get_int('chance') or 1
local damage = meta:get_int('damage') or 1
local player_attributes = player:get_meta()
local luck = player_attributes:get_int('luck')
if math.random(10) + luck >= chance then
local hurt = math.random(damage)
local health = player:get_hp()
local new_health = health - hurt
player:set_hp(new_health)
end
if math.random(10) + luck >= chance then
local map_id = lobby.game[name]
local timer = minetest.get_node_timer(pos)
sabotage.clear_hud(map_id)
meta:set_string('sabotaged', 'false')
timer:stop()
lobby.team_win(map_id)
end
end
end
minetest.after(1, function()
sabotage.update_hud(map_id)
end)
end
function sabotage.clear_hud(map_id)
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
local idx = sabotage.hud[name]
player:hud_remove(idx.title)
player:hud_remove(idx.timer)
end
end
end
function sabotage.update_hud(map_id)
print 'updating hud.'
local time = sabotage.timer[map_id] - 1
sabotage.timer[map_id] = time
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
local idx = sabotage.hud[name]
player:hud_change(idx.timer, 'text', time..' seconds')
end
end
if time > 0 then
minetest.after(1, function()
sabotage.update_hud(map_id)
end)
end
end
end)

65
mods/sabotage/huds.lua Normal file
View File

@ -0,0 +1,65 @@
function sabotage.show_hud(map_id, timer, desc)
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
sabotage.hud[name] = {
desc = player:hud_add({
hud_elem_type = 'text',
position = {x = 1, y = 0.125},
offset = {x = -20, y = -20},
text = 'Find '..desc,
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
}),
title = player:hud_add({
hud_elem_type = 'text',
position = {x = 1, y = 0.125},
offset = {x = -20, y = 0},
text = 'Time until traitor victory:',
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
}),
timer = player:hud_add({
hud_elem_type = 'text',
position = {x = 1, y = 0.125},
offset = {x = -60, y = 20},
text = timer..' seconds',
alignment = {x = -1, y = 0},
scale = {x = 100, y = 100},
})
}
end
end
minetest.after(1, function()
sabotage.update_hud(map_id)
end)
end
function sabotage.clear_hud(map_id)
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
local idx = sabotage.hud[name]
player:hud_remove(idx.title)
player:hud_remove(idx.timer)
player:hud_remove(idx.desc)
end
end
end
function sabotage.update_hud(map_id)
local time = sabotage.timer[map_id] - 1
sabotage.timer[map_id] = time
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if lobby.game[name] == map_id then
local idx = sabotage.hud[name]
player:hud_change(idx.timer, 'text', time..' seconds')
end
end
if time > 0 then
minetest.after(1, function()
sabotage.update_hud(map_id)
end)
end
end

View File

@ -1,15 +1,3 @@
--[[
A sabotage node should have a few options the map maker can set.
How long the crew has to fix the node.
The chance the sabotage will be successful.
The amount of damage the traitor will take from trying and failing.
To keep the players on the map from being completely screwed they need to be alerted to the sabotage.
Players need to be given the location or something to point them in the direction of the node that needs to be fixed. HUD message probably
Upon the node time running out the node MUST check that the level is still active, and that the traitor is the same player as the one who sabotaged.
If/when the node is fixed the HUD should be cleared from all players, and the traitor possibly looses, or a ghost comes back. Some perk for the players. Maybe a bunch of XP.
]]
sabotage = {}
sabotage.player_pos = {}
sabotage.hud = {}
@ -17,105 +5,6 @@ sabotage.timer = {}
dofile(minetest.get_modpath('sabotage')..'/formspecs.lua')
dofile(minetest.get_modpath('sabotage')..'/functions.lua')
minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
if formname == 'sabotage:traitor' then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
if fields.sabotage then
local chance = meta:get_int('chance') or 1
local damage = meta:get_int('damage') or 1
local player_attributes = player:get_meta()
local luck = player_attributes:get_int('luck')
if math.random(10) + luck >= chance then
local hurt = math.random(damage)
local health = player:get_hp()
local new_health = health - hurt
player:set_hp(new_health)
end
if math.random(10) + luck >= chance then
local map_id = lobby.game[name]
meta:set_string('traitor', name)
meta:set_string('map_id', map_id)
meta:set_string('sabotaged', 'true')
local time = meta:get_int('timer')
local timer = minetest.get_node_timer(pos)
timer:start(time)
lobby.message_to_level(map_id, 'Warning!!! Level has been sabotaged. Proceed with caution!!!')
minetest.chat_send_player(name, 'You dirty dog, you just doomed the lives of all other players.')
sabotage.show_hud(map_id, time)
sabotage.timer[map_id] = time
end
end
elseif formname == 'sabotage:builder' then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
if fields.save then
local timer = math.max((tonumber(fields.timer) or 30), 30)
local chance = math.min((fields.chance or 2), 10)
local damage = fields.damage or 1
meta:set_int('timer', timer)
meta:set_int('chance', chance)
meta:set_int('damage', damage)
meta:set_string('sabotaged', 'false')
end
elseif formname == 'sabotage:player' then
if fields.repair then
local pos = sabotage.player_pos[name]
local meta = minetest.get_meta(pos)
local chance = meta:get_int('chance') or 1
local damage = meta:get_int('damage') or 1
local player_attributes = player:get_meta()
local luck = player_attributes:get_int('luck')
if math.random(10) + luck >= chance then
local hurt = math.random(damage)
local health = player:get_hp()
local new_health = health - hurt
player:set_hp(new_health)
end
if math.random(10) + luck >= chance then
local map_id = lobby.game[name]
local timer = minetest.get_node_timer(pos)
sabotage.clear_hud(map_id)
meta:set_string('sabotaged', 'false')
timer:stop()
lobby.team_win(map_id)
end
end
end
end)
minetest.register_node('sabotage:test', {
description = 'Sabotage Testing',
tiles = {'sabotage_test.png'},
groups = {breakable=1, not_in_creative_inventory=1},
on_rightclick = function(pos, node, clicker)
local name = clicker:get_player_name()
local player_attributes = clicker:get_meta()
local mode = player_attributes:get_string('mode')
local meta = minetest.get_meta(pos)
local sabotaged = meta:get_string('sabotaged')
sabotage.player_pos[name] = pos
if mode == 'traitor' and sabotaged == 'false' then
minetest.show_formspec(name, 'sabotage:traitor', sabotage.traitor_formspec(pos))
elseif mode == 'builder' then
minetest.show_formspec(name, 'sabotage:builder', sabotage.builder_formspec(pos))
elseif mode == 'player' and sabotaged == 'true' then
minetest.show_formspec(name, 'sabotage:player', sabotage.player_formspec(pos))
else
minetest.chat_send_player(name, 'You can\'t interact with this now.')
end
end,
on_timer = function(pos)
local meta = minetest.get_meta(pos)
local traitor = meta:get_string('traitor')
local map_id = meta:get_string('map_id')
if lobby.map[map_id] then
if lobby.map[map_id] > 1 and lobby.traitors[map_id] == traitor then
sabotage.clear_hud(map_id)
lobby.traitor_win(traitor, map_id)
end
end
end,
})
dofile(minetest.get_modpath('sabotage')..'/huds.lua')
dofile(minetest.get_modpath('sabotage')..'/node_callbacks.lua')
dofile(minetest.get_modpath('sabotage')..'/nodes.lua')

View File

@ -0,0 +1,31 @@
function sabotage.on_rightclick(pos, node, clicker)
local name = clicker:get_player_name()
local player_attributes = clicker:get_meta()
local mode = player_attributes:get_string('mode')
local meta = minetest.get_meta(pos)
local sabotaged = meta:get_string('sabotaged')
sabotage.player_pos[name] = pos
if mode == 'traitor' and sabotaged == 'false' then
minetest.show_formspec(name, 'sabotage:traitor', sabotage.traitor_formspec(pos))
elseif mode == 'builder' then
if not minetest.is_protected(pos, name) or minetest.check_player_privs(name, {server = true}) then
minetest.show_formspec(name, 'sabotage:builder', sabotage.builder_formspec(pos))
end
elseif mode == 'player' and sabotaged == 'true' then
minetest.show_formspec(name, 'sabotage:player', sabotage.player_formspec(pos))
else
minetest.chat_send_player(name, 'You can\'t interact with this now.')
end
end
function sabotage.on_timer(pos)
local meta = minetest.get_meta(pos)
local traitor = meta:get_string('traitor')
local map_id = meta:get_string('map_id')
if lobby.map[map_id] then
if lobby.map[map_id] > 1 and lobby.traitors[map_id] == traitor then
sabotage.clear_hud(map_id)
lobby.traitor_win(traitor, map_id)
end
end
end

8
mods/sabotage/nodes.lua Normal file
View File

@ -0,0 +1,8 @@
--[[minetest.register_node('sabotage:test', {
description = 'Sabotage Testing',
tiles = {'sabotage_test.png'},
groups = {breakable=1, not_in_creative_inventory=1},
on_rightclick = sabotage.on_rightclick,
on_timer = sabotage.on_timer
})
]]