diff --git a/mods/lobby/formspec.lua b/mods/lobby/formspec.lua index e82a5cf..203b687 100644 --- a/mods/lobby/formspec.lua +++ b/mods/lobby/formspec.lua @@ -13,9 +13,7 @@ local page_2 = "Tasks\n".. "There are a wide variety of tasks, different tasks can give different amounts of XP. ".. "Map makers are able to set their own XP requirements, but don't worry, every time you earn XP ".. "you'll get a helpful chat message telling you how much more XP you need to defeat the traitor.\n".. - "Some tasks require you to get a replacement part, click a button, enter a code, or even just punch the node. ".. - "We won't get into detail about every task here, because there are more being added all the time, and you'll ".. - "have an oppertunity to try some different tasks out upon completing this short corse." + "Some tasks require you to get a replacement part, click a button, enter a code, or even just punch the node. " local page_3 = "Voting\n".. "Voting is one way to try and defeat the traitor. When a corpse is reported all players on a level will teleport ".. diff --git a/mods/lobby/functions.lua b/mods/lobby/functions.lua index fefb4eb..abf0e47 100644 --- a/mods/lobby/functions.lua +++ b/mods/lobby/functions.lua @@ -78,8 +78,10 @@ end function lobby.corpse_removal(map_id) local corpse_pos = lobby.corpses[map_id] - for key, value in pairs(corpse_pos) do - minetest.set_node(value, {name='air'}) + if corpse_pos then + for key, value in pairs(corpse_pos) do + minetest.set_node(value, {name='air'}) + end end end @@ -197,7 +199,12 @@ function lobby.team_win(map_id) lobby.map[map_id] = 0 lobby.update_stats(map_id, '', 'team') local game_data = lobby.savedata.data[map_id] - local map_name = game_data['map_name'] or map_id + local map_name + if game_data then + map_name = game_data['map_name'] + else + map_name = map_id + end minetest.chat_send_all('The traitor was defeated on this round in the '..map_name) end diff --git a/mods/sabotage/formspecs.lua b/mods/sabotage/formspecs.lua new file mode 100644 index 0000000..f1a1e09 --- /dev/null +++ b/mods/sabotage/formspecs.lua @@ -0,0 +1,51 @@ +function sabotage.traitor_formspec(pos) + local meta = minetest.get_meta(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 formspec = + 'formspec_version[3]'.. + 'size[10,8]'.. + 'textarea[.5,.5;9,6;;;Sabotage the crew, and risk life and limb. '.. + 'If the crew doesn\'t fix it in time you win, but you could die sabotaging.\n'.. + 'If you fail in sabotaging you could take up '..damage..' damage. '.. + 'The other players will be alerted and have time to attempt to \'repair\' the node, '.. + 'if they are successful they win the round, otherwise you win!'.. + '\n\nRisk Factor: '..chance..'/10 \nPotential Health Impact: '..damage..' \nFailure Timer: '..timer..' seconds]'.. + 'button_exit[3.5,7;3,.75;sabotage;Do It]' + return formspec +end + +function sabotage.builder_formspec(pos) + local meta = minetest.get_meta(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 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..']'.. + 'button_exit[6.5,7.5;3,1;save;Save]' + return formspec +end + +function sabotage.player_formspec(pos) + local meta = minetest.get_meta(pos) + local chance = meta:get_int('chance') or 1 + local damage = meta:get_int('damage') or 1 + local formspec = + 'formspec_version[3]'.. + 'size[10,8]'.. + 'textarea[.5,.5;9,6;;;Careful now, you could get hurt messing around here, '.. + 'but you could save the lives of the entire party. Ultimately it\'s your choice.\n'.. + '\nRisk Factor: '..chance..'/10 \nPotential Health Impact: '..damage..']'.. + 'button_exit[1.5,7;3,.75;repair;Attempt Repairs]'.. + 'button_exit[5.5,7;3,.75;leave;Cower in Fear]' + return formspec +end diff --git a/mods/sabotage/functions.lua b/mods/sabotage/functions.lua new file mode 100644 index 0000000..9c40563 --- /dev/null +++ b/mods/sabotage/functions.lua @@ -0,0 +1,54 @@ +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}, + }) + } + 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) + 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 + minetest.after(1, function() + sabotage.update_hud(map_id) + end) +end diff --git a/mods/sabotage/init.lua b/mods/sabotage/init.lua new file mode 100644 index 0000000..85c836e --- /dev/null +++ b/mods/sabotage/init.lua @@ -0,0 +1,119 @@ +--[[ +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 = {} +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) + 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) + 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) + 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') + sabotage.player_pos[name] = pos + if mode == 'traitor' 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' then + local timer = minetest.get_node_timer(pos) + if timer:is_started() then + minetest.show_formspec(name, 'sabotage:player', sabotage.player_formspec(pos)) + end + else + minetest.chat_send_player(name, 'Only traitors and builders can interact with this node.') + 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, +}) diff --git a/mods/sabotage/mod.conf b/mods/sabotage/mod.conf new file mode 100644 index 0000000..0d368ec --- /dev/null +++ b/mods/sabotage/mod.conf @@ -0,0 +1 @@ +name = sabotage diff --git a/mods/sabotage/textures/sabotage_test.png b/mods/sabotage/textures/sabotage_test.png new file mode 100644 index 0000000..eae83f9 Binary files /dev/null and b/mods/sabotage/textures/sabotage_test.png differ diff --git a/mods/vents/data_base.lua b/mods/vents/data_base.lua index d46fc48..26ab805 100644 --- a/mods/vents/data_base.lua +++ b/mods/vents/data_base.lua @@ -41,12 +41,12 @@ vents.Stations:deserialize(storage:get_string("Stations")) vents.Elevators:deserialize(storage:get_string("Elevators")) local function update_mod_storage() - minetest.log("action", "[Hyperloop] Store data...") + minetest.log("action", "[Vents] Store data...") storage:set_string("Stations", vents.Stations:serialize()) storage:set_string("Elevators", vents.Elevators:serialize()) -- store data each hour minetest.after(60*60, update_mod_storage) - minetest.log("action", "[Hyperloop] Data stored") + minetest.log("action", "[Vents] Data stored") end minetest.register_on_shutdown(function() diff --git a/mods/vents/station.lua b/mods/vents/station.lua index 034fa0e..82ca473 100644 --- a/mods/vents/station.lua +++ b/mods/vents/station.lua @@ -43,6 +43,7 @@ local function naming_formspec(pos) local formspec = 'size[7,4.4]'.. 'label[0,0;'..S('Please enter the vent name.')..']' .. + 'label[0,.35;Punch the vent to see locations you can teleport too.]' .. 'field[0.2,1.5;7.1,1;name;'..S('Vent name')..';'..vent..']' .. 'field[0.2,2.7;7.1,1;info;'..S('Additional vent information')..';'..info..']' .. 'button_exit[2.5,3.7;2,1;exit;Save]' @@ -200,7 +201,7 @@ minetest.register_node('vents:station', { local player_attributes = clicker:get_meta() local mode = player_attributes:get_string('mode') vents.player_pos[name] = pos - if mode == 'traitor' or mode == 'solo' or mode == 'ghost' then --allow everybody but crew mambers to use. + if mode == 'traitor' or mode == 'solo' or mode == 'ghost' then minetest.show_formspec(name, 'vents:station_list', station_list_as_string(pos)) elseif mode == 'builder' then minetest.show_formspec(name, 'vents:setup', naming_formspec(pos)) @@ -209,6 +210,22 @@ minetest.register_node('vents:station', { end end, + on_punch = function(pos, node, puncher) + local wield = puncher:get_wielded_item() + local wield_name = wield:get_name() + if wield_name == 'creative:tool_breaking' then + return + else + local name = puncher:get_player_name() + local player_attributes = puncher:get_meta() + local mode = player_attributes:get_string('mode') + vents.player_pos[name] = pos + if mode == 'builder' then + minetest.show_formspec(name, 'vents:station_list', station_list_as_string(pos)) + end + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_node(pos) Stations:delete(pos)