Complete rewrite
parent
a0cabcda52
commit
bdc56d6f5d
|
@ -0,0 +1,171 @@
|
||||||
|
PATHOGEN
|
||||||
|
========
|
||||||
|
A minetest mod that enables users to get a pathogen.
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
- Easily define a new pathogen using the pathogen API
|
||||||
|
- Demo pathogens that are infectious and sometimes deadly.
|
||||||
|
|
||||||
|
Diseases
|
||||||
|
========
|
||||||
|
|
||||||
|
Influencia
|
||||||
|
----------
|
||||||
|
Highly contagious as it is airborne. Being around someone that has the diseases
|
||||||
|
increases the chances of getting the virus drastically. It is advised to eat well
|
||||||
|
and keep your distance from players that are coughing. Death is very unlikely.
|
||||||
|
|
||||||
|
Panola
|
||||||
|
------
|
||||||
|
Contagious threw body fluids. It is ok to be near someone that has the diseases.
|
||||||
|
Make sure that when cleaning up after someone that has expelled fluids, to
|
||||||
|
decontaminate the fluids first. This can be done with the Decontaminator.
|
||||||
|
|
||||||
|
Items
|
||||||
|
=====
|
||||||
|
- Comes with nodes like vomit, blood and feces that are infectious when dug.
|
||||||
|
- A bio hazard warning fence, in case a quarantine is required.
|
||||||
|
- A decontaminater for removing infectious fluids.
|
||||||
|
|
||||||
|
Crafts
|
||||||
|
======
|
||||||
|
**Decontaminater**
|
||||||
|
{'xpanes:bar','',''},
|
||||||
|
{'','default:steelblock',''},
|
||||||
|
{'','',''}
|
||||||
|
|
||||||
|
API
|
||||||
|
===
|
||||||
|
|
||||||
|
Register pathogens
|
||||||
|
------------------
|
||||||
|
```lua
|
||||||
|
pathogen.register_pathogen("influencia", {
|
||||||
|
description = "Highly contagious and possibly deadly for those with low health.",
|
||||||
|
symptoms = 12,
|
||||||
|
latent_period = 240,
|
||||||
|
infection_period = 740,
|
||||||
|
on_infect = function( infection )
|
||||||
|
minetest.sound_play( "pathogen_cough", { pos = pos, gain = 0.3 } )
|
||||||
|
end,
|
||||||
|
on_symptom = function( infection )
|
||||||
|
local player = minetest.get_player_by_name( infection.player )
|
||||||
|
local pos = player:getpos()
|
||||||
|
local players_nearby = pathogen.get_players_in_radius(pos, 5)
|
||||||
|
local hp = player:get_hp()
|
||||||
|
if hp <= 14 then
|
||||||
|
player:set_hp( hp - 1 )
|
||||||
|
if math.random(10) == 1 then
|
||||||
|
player:set_hp( 6 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if math.random(2) == 1 then
|
||||||
|
minetest.sound_play( "pathogen_sneeze", { pos = pos, gain = 0.3 } )
|
||||||
|
else
|
||||||
|
minetest.sound_play( "pathogen_cough", { pos = pos, gain = 0.3 } )
|
||||||
|
end
|
||||||
|
for index, player_nearby in ipairs(players_nearby) do
|
||||||
|
local player_nearby_name = player_nearby:get_player_name()
|
||||||
|
if player_nearby_name ~= infection.player then
|
||||||
|
if math.random(3) == 1 then
|
||||||
|
pathogen.infect( infection.pathogen, player_nearby_name )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Pathogen definition
|
||||||
|
-------------------
|
||||||
|
|key|type|description|
|
||||||
|
|---|----|-----------|
|
||||||
|
|symptom|number|the amount of times symptoms are shown|
|
||||||
|
|latent_period|number|seconds before the symptoms start showing|
|
||||||
|
|infection_period|number|seconds from infection till last symptom|
|
||||||
|
|on_infect( infection )|function|actions to perform when infected ( this happens as soon as the infection takes place )|
|
||||||
|
|on_symptom( infection )|function|happens as many times as the defined symptom amount|
|
||||||
|
|on_death( infection )|function|called when the player dies while having the pathogen|
|
||||||
|
|
||||||
|
###infection
|
||||||
|
All function in the pathogen definition give an infection table as callback.
|
||||||
|
The infection table includes.
|
||||||
|
|
||||||
|
|key|type|description|
|
||||||
|
|---|----|-----------|
|
||||||
|
|symptom|number|an integer that represents the index of current symptom|
|
||||||
|
|player|string|the name of the player|
|
||||||
|
|immune|bool|when true the infection has stopped. For now it does not mean that the player cant be reinfected|
|
||||||
|
|pathogen|string|the name of the pathogen|
|
||||||
|
|
||||||
|
Functions
|
||||||
|
---------
|
||||||
|
```lua
|
||||||
|
--pathogens
|
||||||
|
pathogen.register_pathogen( pathogen_name, definition )
|
||||||
|
|
||||||
|
--getters
|
||||||
|
pathogen.get_pathogen( pathogen_name )
|
||||||
|
pathogen.get_pathogens()
|
||||||
|
pathogen.get_infection( player_name, pathogen_name )
|
||||||
|
pathogen.get_infections()
|
||||||
|
pathogen.get_players_in_radius( pos, radius )
|
||||||
|
pathogen.get_player_infections( player_name )
|
||||||
|
|
||||||
|
--actions
|
||||||
|
pathogen.infect( pathogen_name, player_name )
|
||||||
|
pathogen.perform_symptom( pathogen_name, player_name, faze )
|
||||||
|
--this function allows to add a pathogen that is already in a certain face.
|
||||||
|
--Fade is a number that represents the id of the state of the infection
|
||||||
|
------
|
||||||
|
pathogen.immunize( pathogen_name, player_name )
|
||||||
|
pathogen.remove_infection( pathogen_name, player_name )
|
||||||
|
--the difference between immunize and remove is that immunize makes the player
|
||||||
|
--never get sick of the same sickness again and remove removes the current
|
||||||
|
--infection but also it's immunization, thus allowing the player to get
|
||||||
|
--infected again.
|
||||||
|
----------
|
||||||
|
|
||||||
|
--fluids (flat node boxes that represent contaminated fluids)
|
||||||
|
pathogen.register_fluid( name )
|
||||||
|
pathogen.spawn_fluid( name, pos, pathogen_name )
|
||||||
|
pathogen.decontaminate_fluid( pos )
|
||||||
|
--fluids are contaminated nodes that will infect a player that punches that
|
||||||
|
--node. Considering making this more generic by allowing to have a function
|
||||||
|
--that allows making any node contaminable. Something like.
|
||||||
|
--pathogen.contaminate( pos ).
|
||||||
|
----------
|
||||||
|
|
||||||
|
--makes the data persistent between server reloads (not yet implemented)
|
||||||
|
pathogen.save( infections )
|
||||||
|
pathogen.load( run )
|
||||||
|
```
|
||||||
|
Commands
|
||||||
|
========
|
||||||
|
Infections can be initiated by using commands. It requires the "pathogen"
|
||||||
|
privilege. /grant <playername> pathogen.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
/pathogens
|
||||||
|
--list all pathogens and their descriptions
|
||||||
|
|
||||||
|
/infect <player name> <pathogen name>
|
||||||
|
--infect the player
|
||||||
|
|
||||||
|
/immunize <player name> <pathogen name>
|
||||||
|
--make player immune to particular pathogen
|
||||||
|
```
|
||||||
|
|
||||||
|
Roadmap
|
||||||
|
=======
|
||||||
|
- saving infections for persistence between server restarts
|
||||||
|
- more pathogens and cures
|
||||||
|
- make the API more flexible, consistent and forgiving
|
||||||
|
- consider immunization mechanic. Immunity is not indefinite...
|
||||||
|
- pathogen.contaminate( pos ) function
|
||||||
|
|
||||||
|
Reference
|
||||||
|
=========
|
||||||
|
- https://en.wikipedia.org/wiki/Incubation_period#mediaviewer/File:Concept_of_incubation_period.svg
|
||||||
|
- https://www.freesound.org
|
21
commands.lua
21
commands.lua
|
@ -1,21 +0,0 @@
|
||||||
minetest.register_chatcommand("test1", {
|
|
||||||
params = "",
|
|
||||||
description = "Test 1: Modify player's inventory view",
|
|
||||||
func = function(name, param)
|
|
||||||
local player = minetest.get_player_by_name(name)
|
|
||||||
if not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
player:set_inventory_formspec(
|
|
||||||
"size[13,7.5]"..
|
|
||||||
"image[6,0.6;1,2;player.png]"..
|
|
||||||
"list[current_player;main;5,3.5;8,4;]"..
|
|
||||||
"list[current_player;craft;8,0;3,3;]"..
|
|
||||||
"list[current_player;craftpreview;12,1;1,1;]"..
|
|
||||||
"list[detached:test_inventory;main;0,0;4,6;0]"..
|
|
||||||
"button[0.5,7;2,1;button1;Button 1]"..
|
|
||||||
"button_exit[2.5,7;2,1;button2;Exit Button]"
|
|
||||||
)
|
|
||||||
minetest.chat_send_player(name, "Done.");
|
|
||||||
end,
|
|
||||||
})
|
|
|
@ -1,54 +0,0 @@
|
||||||
pathogen.register_pathogen = function(name, params)
|
|
||||||
local incubation_time = params.incubation_time --in minutes
|
|
||||||
local survival_rate = params.survival_rate --0 being absolutly deadly and 1 being will survive for sure
|
|
||||||
local survival_time = params.survival_time --time after incubation time where symptoms are visible.
|
|
||||||
local treatable = params.treatable --once infected the player will die.
|
|
||||||
local preventable = params.preventable --requires preventative medication
|
|
||||||
local infection_range = params.infection_range --range in which player could get infected
|
|
||||||
local infection_rate = params.infection_rate --chance that someone will get infected when within infection_range
|
|
||||||
pathogen.pathogens[name] = params
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.get_pathogen = function(name)
|
|
||||||
return pathogen.pathogens[name]
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.show_simptons = function(player)
|
|
||||||
local pos = player:getpos()
|
|
||||||
--spawn vomit particles
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.load = function(file_name) --Write neater TODO
|
|
||||||
local file_name = minetest.get_worldpath()..'/'..file_name
|
|
||||||
local file_data = io.open(file_name, 'r')
|
|
||||||
if file_data then
|
|
||||||
local data_stri = file_data:read();
|
|
||||||
local data_list = minetest.parse_json(data_stri)
|
|
||||||
if data_list == nil then
|
|
||||||
data_list = {}
|
|
||||||
end
|
|
||||||
data_file:close()
|
|
||||||
else
|
|
||||||
data_list = {}
|
|
||||||
end
|
|
||||||
return data_list
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.save = function()
|
|
||||||
local data_stri = minetest.write_json(pathogen.data)
|
|
||||||
local data_file = io.open(pathogen.file, 'w')
|
|
||||||
data_file:write(data_stri)
|
|
||||||
data_file:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.player_is_connected = function(player_name)
|
|
||||||
local players = minetest.get_connected_players()
|
|
||||||
for i, v in pairs(players) do
|
|
||||||
print(v)
|
|
||||||
if v:get_player_name() == player_name then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
pathogen.register_pathogen("influencia", {
|
||||||
|
description = "Highly contagious and possibly deadly for those with low health.",
|
||||||
|
symptoms = 12,
|
||||||
|
latent_period = 240,
|
||||||
|
infection_period = 740,
|
||||||
|
on_infect = function( infection )
|
||||||
|
minetest.sound_play( "pathogen_cough", { pos = pos, gain = 0.3 } )
|
||||||
|
end,
|
||||||
|
on_symptom = function( infection )
|
||||||
|
local player = minetest.get_player_by_name( infection.player )
|
||||||
|
local pos = player:getpos()
|
||||||
|
local players_nearby = pathogen.get_players_in_radius(pos, 5)
|
||||||
|
local hp = player:get_hp()
|
||||||
|
if hp <= 14 then
|
||||||
|
player:set_hp( hp - 1 )
|
||||||
|
if math.random(10) == 1 then
|
||||||
|
player:set_hp( 6 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if math.random(2) == 1 then
|
||||||
|
minetest.sound_play( "pathogen_sneeze", { pos = pos, gain = 0.3 } )
|
||||||
|
else
|
||||||
|
minetest.sound_play( "pathogen_cough", { pos = pos, gain = 0.3 } )
|
||||||
|
end
|
||||||
|
for index, player_nearby in ipairs(players_nearby) do
|
||||||
|
local player_nearby_name = player_nearby:get_player_name()
|
||||||
|
if player_nearby_name ~= infection.player then
|
||||||
|
if math.random(3) == 1 then
|
||||||
|
pathogen.infect( infection.pathogen, player_nearby_name )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
54
init.lua
54
init.lua
|
@ -1,54 +0,0 @@
|
||||||
pathogen = { name = "pathogen", version = "0.1" } --global mod namespace
|
|
||||||
local debug = true
|
|
||||||
|
|
||||||
local dofiles = function(files) --load multiple lua files from the mod directory
|
|
||||||
local modpath = minetest.get_modpath(pathogen.name)
|
|
||||||
for _,file in pairs(files) do
|
|
||||||
print("[pathogen] loading "..file..".lua")
|
|
||||||
dofile(modpath.."/"..file..".lua")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
print("[pathogen] version: "..pathogen.version)
|
|
||||||
|
|
||||||
if debug then
|
|
||||||
print("[pathogen] debug enabled")
|
|
||||||
dofiles({"commands", "config", "functions", "pathogens" })
|
|
||||||
else
|
|
||||||
dofiles({"commands", "config", "functions", "pathogens", "nodes"})
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.init = function()
|
|
||||||
local infections = pathogen.load("infections.json")
|
|
||||||
print(infections)
|
|
||||||
for infection in ipairs(infections) do
|
|
||||||
print("[pathogen] infecting "..infecting.player.." with "..infection.pathogen)
|
|
||||||
pathogen.update_infection(infection)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.initiate_infection = function(params)
|
|
||||||
pathogen.register_infection(params)
|
|
||||||
pathogen.update_infection(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.register_infection = function(params)
|
|
||||||
self = {}
|
|
||||||
self.player = params.player
|
|
||||||
self.pathogen = params.pathogen
|
|
||||||
self.state = 'incubating'
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.update_infection = function(params)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.update = function()
|
|
||||||
--minetest.after(pathogen.interval, pathogen.update())
|
|
||||||
--local players = minetest.get_connected_players()
|
|
||||||
end
|
|
||||||
|
|
||||||
pathogen.init()
|
|
||||||
|
|
||||||
print("[pathogen] Loaded!")
|
|
|
@ -1,5 +0,0 @@
|
||||||
--[[
|
|
||||||
syringe-empty
|
|
||||||
syringe-with-blood
|
|
||||||
syringe-with-antidote
|
|
||||||
]]--
|
|
23
nodes.lua
23
nodes.lua
|
@ -1,23 +0,0 @@
|
||||||
minetest.register_node('pathogen:centrifuge',{
|
|
||||||
description = 'medical centrifuge',
|
|
||||||
tiles = {'pathogen_centrifuge.png'},
|
|
||||||
formspec = '',
|
|
||||||
on_rightclick = function(pos, node, puncher)
|
|
||||||
print('hello world')
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node('pathogen:sequencer',{
|
|
||||||
description = 'genetic_sequencer',
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node('pathogen:bodyly_fluids', {
|
|
||||||
description = 'excretions',
|
|
||||||
tiles = {'pathogen_excretions'},
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node('pathogen:pathogen', {
|
|
||||||
description = 'pathogen',
|
|
||||||
tiles = {'pathogen_pathogen.png'},
|
|
||||||
groups = {pathogen = 1},
|
|
||||||
})
|
|
|
@ -0,0 +1 @@
|
||||||
|
pathogen
|
|
@ -0,0 +1,32 @@
|
||||||
|
pathogen.register_pathogen("panola", {
|
||||||
|
description = "Panola virus is highly contagious. It spreads threw bodily fluids.",
|
||||||
|
symptoms = 10,
|
||||||
|
latent_period = 840,
|
||||||
|
infection_period = 1200,
|
||||||
|
--latent_period = 8400,
|
||||||
|
--infection_period = 12000,
|
||||||
|
on_death = function( infection )
|
||||||
|
local _player = minetest.get_player_by_name( infection.player )
|
||||||
|
local _pos = _player:getpos()
|
||||||
|
pathogen.spawn_fluid( "blood", _pos, infection.pathogen )
|
||||||
|
minetest.sound_play( "pathogen_bleed", { pos = _pos, gain = 0.3} )
|
||||||
|
end,
|
||||||
|
on_symptom = function( infection )
|
||||||
|
local player = minetest.get_player_by_name( infection.player )
|
||||||
|
local pos = player:getpos()
|
||||||
|
local hp = player:get_hp()
|
||||||
|
if hp > 12 then
|
||||||
|
player:set_hp( math.floor(hp /2 ) )
|
||||||
|
else
|
||||||
|
player:set_hp( hp - 1 )
|
||||||
|
end
|
||||||
|
if math.random(0, 2) == 1 then
|
||||||
|
pathogen.spawn_fluid( "vomit", pos, infection.pathogen )
|
||||||
|
minetest.sound_play( "pathogen_vomit", { pos = pos, gain = 0.3} )
|
||||||
|
elseif math.random(0, 2 ) == 1 then
|
||||||
|
pathogen.spawn_fluid( "feces", pos, infection.pathogen )
|
||||||
|
minetest.sound_play( "pathogen_poop", { pos = pos, gain = 0.3} )
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
|
@ -0,0 +1,233 @@
|
||||||
|
pathogen.register_pathogen = function( pathogen_name, definition )
|
||||||
|
--the command that is used to register pathogens
|
||||||
|
----
|
||||||
|
if not pathogen.get_pathogen( pathogen_name ) then
|
||||||
|
definition.name = pathogen_name;
|
||||||
|
pathogen.pathogens[pathogen_name] = definition
|
||||||
|
else
|
||||||
|
print( " pathogen already registered" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.spawn_fluid = function( name, pos, pathogen_name )
|
||||||
|
--spawn the infectious juices
|
||||||
|
----
|
||||||
|
if minetest.get_node( pos ).name == "air" then
|
||||||
|
local node_name = "pathogen:fluid_"..name
|
||||||
|
minetest.set_node( pos, { name = node_name, param2=1 } )
|
||||||
|
local meta = minetest.get_meta( pos )
|
||||||
|
meta:set_string( "pathogen", pathogen_name )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.register_fluid = function( name )
|
||||||
|
--registering a fluid(juice). This assumes that all fluids are flat on the
|
||||||
|
--floor
|
||||||
|
------
|
||||||
|
local texture = "pathogen_fluid_"..name..".png"
|
||||||
|
local node_name = "pathogen:fluid_"..name
|
||||||
|
pathogen.fluids[ name ] = node_name
|
||||||
|
minetest.register_node( node_name, {
|
||||||
|
description= name,
|
||||||
|
drawtype = "signlike",
|
||||||
|
inventory_image = texture,
|
||||||
|
tiles = { texture },
|
||||||
|
paramtype = "light",
|
||||||
|
paramtype2 = "wallmounted",
|
||||||
|
walkable = false,
|
||||||
|
sunlight_propagates = true,
|
||||||
|
drop = "",
|
||||||
|
groups = { oddly_breakable_by_hand = 2, crumbly = 2 },
|
||||||
|
on_punch = function(pos, node, puncher, pointed_thing)
|
||||||
|
local meta = minetest.get_meta( pos )
|
||||||
|
local pathogen_name = meta:get_string( "pathogen" )
|
||||||
|
local player_name = puncher:get_player_name()
|
||||||
|
pathogen.infect( pathogen_name, player_name )
|
||||||
|
end,
|
||||||
|
selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-0.5, -0.5, -0.5, 0.5, -7.9/16, 0.5},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.decontaminate_fluid = function( pos )
|
||||||
|
if not pos then return end
|
||||||
|
local _meta = minetest.get_meta( pos )
|
||||||
|
local _pathogen = _meta:get_string( 'pathogen' )
|
||||||
|
if #_pathogen ~= 0 then
|
||||||
|
_meta:set_string( 'pathogen', '' )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.infect = function( pathogen_name, player_name )
|
||||||
|
--notice that all parameters are strings. Threwout the mod the arguments are
|
||||||
|
--all primitive strings. is that good practice or should i use complex types?
|
||||||
|
--infect a player with a pathogen
|
||||||
|
--------
|
||||||
|
|
||||||
|
local _pathogen = pathogen.get_pathogen( pathogen_name, player_name )
|
||||||
|
if not _pathogen then return end
|
||||||
|
--do not perform infection if infection has already occured
|
||||||
|
----
|
||||||
|
local _player = minetest.get_player_by_name( player_name )
|
||||||
|
|
||||||
|
if _pathogen == nil then return false end
|
||||||
|
--check if pathogen exists
|
||||||
|
------
|
||||||
|
|
||||||
|
local _infection = {
|
||||||
|
--The table containing all the data that a infection cinsists out of. See
|
||||||
|
--the README.md for a more extensive explanation
|
||||||
|
------
|
||||||
|
symptom = 0,
|
||||||
|
pathogen = pathogen_name,
|
||||||
|
player = player_name,
|
||||||
|
immune = false
|
||||||
|
}
|
||||||
|
|
||||||
|
pathogen.infections[ player_name..pathogen_name ] = _infection
|
||||||
|
print( "infected: "..player_name.." with "..pathogen_name )
|
||||||
|
--store the infection in a table for later use. This table is also saved and
|
||||||
|
--loaded if the persistent option is set
|
||||||
|
------
|
||||||
|
if _pathogen.on_infect then
|
||||||
|
--check if on_infect has been registered
|
||||||
|
----
|
||||||
|
_pathogen.on_infect( _infection )
|
||||||
|
end
|
||||||
|
--perform the on_infect command that is defined in the regsiter function
|
||||||
|
--this is not the same as the on_symptoms. It is called only once at the
|
||||||
|
--beginning of the infection
|
||||||
|
--------
|
||||||
|
minetest.after( _pathogen.latent_period, function()
|
||||||
|
--latent perios is the time till the first symptom shows
|
||||||
|
----
|
||||||
|
pathogen.perform_symptom( pathogen_name, player_name, 1 )
|
||||||
|
--show the first symptom
|
||||||
|
----
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_players_in_radius = function( pos, radius )
|
||||||
|
local objects = minetest.get_objects_inside_radius(pos, 5)
|
||||||
|
local players = {}
|
||||||
|
for index, object in ipairs(objects) do
|
||||||
|
if object:is_player() then
|
||||||
|
players[#players+1] = object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return players
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.perform_symptom = function( pathogen_name, player_name, symptom_n )
|
||||||
|
--An infection can also be initiated without having to perform the on_infect.
|
||||||
|
--you can can cut straight to a particular symptom by using this function
|
||||||
|
--notice the symptom_n argument.
|
||||||
|
--------
|
||||||
|
local _infection = pathogen.infections[ player_name..pathogen_name ]
|
||||||
|
local _pathogen = pathogen.pathogens[pathogen_name]
|
||||||
|
if not _infection.immune then
|
||||||
|
--only keep showing symptoms if there is no immunity against the pathogen
|
||||||
|
----
|
||||||
|
local symptom_n = symptom_n + 1
|
||||||
|
if ( _pathogen.symptoms > symptom_n ) then --check if all symptoms have occured
|
||||||
|
--only show symptoms not all symptoms have occured.
|
||||||
|
_infection.symptom = symptom_n
|
||||||
|
_pathogen.on_symptom( _infection )
|
||||||
|
local _interval = ( ( _pathogen.infection_period - _pathogen.latent_period ) / _pathogen.symptoms )
|
||||||
|
minetest.after( _interval , function()
|
||||||
|
--set the time till the next symptom and then perfrom it again
|
||||||
|
----
|
||||||
|
pathogen.perform_symptom( pathogen_name, player_name, symptom_n )
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
--survives and is now immunized, immunization lasts till the server is
|
||||||
|
--restarted
|
||||||
|
------
|
||||||
|
pathogen.immunize( pathogen_name, player_name )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_pathogen = function( pathogen_name )
|
||||||
|
--get the datat of a particular pathogen
|
||||||
|
----
|
||||||
|
return pathogen.pathogens[pathogen_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_infection = function( player_name, pathogen_name )
|
||||||
|
--get an infection of a certain player
|
||||||
|
----
|
||||||
|
return pathogen.infections[ player_name..pathogen_name ]
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.immunize = function( pathogen_name, player_name )
|
||||||
|
--immunize a player so the next symptom won"t show.
|
||||||
|
----
|
||||||
|
print( "immunized: "..player_name.." from "..pathogen_name )
|
||||||
|
local _infection = pathogen.get_infection( player_name, pathogen_name )
|
||||||
|
if _infection.on_immunize then _infection.on_immunize( _infection ) end
|
||||||
|
if _infection then
|
||||||
|
_infection.immune = true
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.remove_infection = function( pathogen_name, player_name )
|
||||||
|
--removes the immunization and the infection all together
|
||||||
|
----
|
||||||
|
if pathogen.infections[player_name..pathogen_name] then
|
||||||
|
pathogen.infections[player_name..pathogen_name] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.save = function( infections )
|
||||||
|
--TODO save the infections so it won"t get lost between server reloads
|
||||||
|
local serialized = minetest.serialize( infections )
|
||||||
|
return serialized
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.load = function( run )
|
||||||
|
--TODO if run is true the loaded pathogens will run immediatly
|
||||||
|
local deserialized = minetest.deserialize(string)
|
||||||
|
return deserialized
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_infections = function()
|
||||||
|
return pathogen.infections
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_pathogens = function()
|
||||||
|
return pathogen.pathogens
|
||||||
|
end
|
||||||
|
|
||||||
|
pathogen.get_player_infections = function( player_name )
|
||||||
|
local _infections = pathogen.get_infections()
|
||||||
|
local _output = {}
|
||||||
|
for index, infection in pairs(_infections) do
|
||||||
|
if infection.player == player_name then
|
||||||
|
_output[#_output+1] = infection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _output
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_dieplayer( function( player )
|
||||||
|
--when dying while having a pathogen it will trigger the on_death and it will
|
||||||
|
--remove the current infections
|
||||||
|
------
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
local _infections = pathogen.get_player_infections( player_name )
|
||||||
|
for index, infection in pairs(_infections) do
|
||||||
|
local _pathogen = pathogen.get_pathogen( infection.pathogen )
|
||||||
|
local on_death = _pathogen.on_death
|
||||||
|
if on_death then
|
||||||
|
on_death( infection )
|
||||||
|
pathogen.remove_infection( pathogen_name, player_name )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
minetest.register_privilege('pathogen', "infect and cure players of pathogens")
|
||||||
|
|
||||||
|
minetest.register_chatcommand("infect", {
|
||||||
|
params = "pathogen player",
|
||||||
|
description = "infect a player with a pathogen",
|
||||||
|
privs = { pathogen=true },
|
||||||
|
func = function(name, params)
|
||||||
|
local params = params:split(' ')
|
||||||
|
local player_name = params[1]
|
||||||
|
local pathogen_name = params[2]
|
||||||
|
if minetest.get_player_by_name( player_name ) then
|
||||||
|
pathogen.infect( pathogen_name, player_name )
|
||||||
|
minetest.chat_send_player(name, 'infected '..player_name..' with '..pathogen_name)
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, 'player does not exist')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("pathogens", {
|
||||||
|
params = "",
|
||||||
|
description = "list all available pathogens",
|
||||||
|
privs = {},
|
||||||
|
func = function(name, params)
|
||||||
|
local _pathogens = pathogen.get_pathogens()
|
||||||
|
for key, pathogen in pairs(_pathogens ) do
|
||||||
|
minetest.chat_send_player( name, pathogen.name..' - '..pathogen.description )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("immunize", {
|
||||||
|
params = "pathogen player",
|
||||||
|
description = "cure a player from an infection",
|
||||||
|
privs = { pathogen=true },
|
||||||
|
func = function(name, params)
|
||||||
|
local _params = params:split(' ')
|
||||||
|
local _player_name = _params[1]
|
||||||
|
local _pathogen_name = _params[2]
|
||||||
|
local _infection = pathogen.infections[ _player_name.._pathogen_name ]
|
||||||
|
if pathogen.immunize( _pathogen_name, _player_name ) then
|
||||||
|
minetest.chat_send_player( name, 'succesfully immunized '.._player_name..' against '.._pathogen_name)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
minetest.chat_send_player( name, 'immunization failed: requires player name and the pathogen name to work' )
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
|
@ -0,0 +1,8 @@
|
||||||
|
minetest.register_craft({
|
||||||
|
output = 'pathogen:decontaminator',
|
||||||
|
recipe = {
|
||||||
|
{'xpanes:bar','',''},
|
||||||
|
{'','default:steelblock',''},
|
||||||
|
{'','',''}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,2 @@
|
||||||
|
default
|
||||||
|
xpanes
|
|
@ -0,0 +1,12 @@
|
||||||
|
pathogen = {
|
||||||
|
pathogens = {},
|
||||||
|
infections = {},
|
||||||
|
fluids = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/options.lua" ) --WIP
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/api.lua" )
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/tools.lua" )
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/crafts.lua" )
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/nodes.lua" )
|
||||||
|
dofile( minetest.get_modpath( "pathogen" ) .. "/commands.lua" )
|
|
@ -0,0 +1,48 @@
|
||||||
|
pathogen.register_fluid( 'vomit' )
|
||||||
|
pathogen.register_fluid( 'blood' )
|
||||||
|
pathogen.register_fluid( 'feces' )
|
||||||
|
|
||||||
|
|
||||||
|
--[[ in case you do not want the xpanes dependency
|
||||||
|
minetest.register_node("pathogen:fence", {
|
||||||
|
description = "Infection Hazard Fence",
|
||||||
|
drawtype = 'nodebox',
|
||||||
|
tiles = {"pathogen_fence.png"},
|
||||||
|
inventory_image = 'pathogen_fence.png',
|
||||||
|
paramtype = "light",
|
||||||
|
sunlight_propagates = true,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||||
|
sounds = default.node_sound_wood_defaults(),
|
||||||
|
--visual_scale = 33/32,
|
||||||
|
node_box = {
|
||||||
|
type = 'fixed',
|
||||||
|
fixed = {
|
||||||
|
{-0.5, -0.5, 63/128,
|
||||||
|
0.5, 0.5 , 63/128},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
]]--
|
||||||
|
|
||||||
|
xpanes.register_pane("fence_warning", {
|
||||||
|
description = "Infection Hazard Fence",
|
||||||
|
tiles = {"pathogen_fence.png"},
|
||||||
|
drawtype = "airlike",
|
||||||
|
paramtype = "light",
|
||||||
|
sunlight_propagates = true,
|
||||||
|
walkable = false,
|
||||||
|
pointable = false,
|
||||||
|
diggable = false,
|
||||||
|
buildable_to = true,
|
||||||
|
air_equivalent = true,
|
||||||
|
textures = {"pathogen_fence.png", "pathogen_fence.png", 'xpanes_space.png'},
|
||||||
|
inventory_image = "pathogen_fence.png",
|
||||||
|
wield_image = "pathogen_fence.png",
|
||||||
|
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
|
||||||
|
recipe = {
|
||||||
|
{'default:glass', 'default:glass', 'default:glass'},
|
||||||
|
{'default:glass', 'default:glass', 'default:glass'}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
--DOES NOT WORK YET WIP
|
||||||
|
pathogen.options = {
|
||||||
|
persistent = false
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 488 B |
Binary file not shown.
After Width: | Height: | Size: 212 B |
Binary file not shown.
After Width: | Height: | Size: 870 B |
Binary file not shown.
After Width: | Height: | Size: 805 B |
Binary file not shown.
After Width: | Height: | Size: 866 B |
|
@ -0,0 +1,10 @@
|
||||||
|
minetest.register_tool( 'pathogen:decontaminator', {
|
||||||
|
description = 'Decontaminator',
|
||||||
|
inventory_image = "pathogen_decontaminator.png",
|
||||||
|
on_use = function(itemstack, user, pt)
|
||||||
|
minetest.sound_play( 'pathogen_spray', { pos = user:getpos(), gain = 0.2, max_hear_distance = 5 })
|
||||||
|
if not pt then return itemstack end
|
||||||
|
if math.random(5) == 1 then return itemstack end
|
||||||
|
pathogen.decontaminate_fluid( pt.under )
|
||||||
|
end
|
||||||
|
})
|
|
@ -1,8 +0,0 @@
|
||||||
pathogen.pathogens = {}
|
|
||||||
|
|
||||||
pathogen.register_pathogen('ebola', {
|
|
||||||
incubation_time = 3600,
|
|
||||||
survival_time = 1500,
|
|
||||||
survival_rate = 0.5,
|
|
||||||
infection_range = 2,
|
|
||||||
})
|
|
77
readme.txt
77
readme.txt
|
@ -1,77 +0,0 @@
|
||||||
PATHOGEN
|
|
||||||
--------
|
|
||||||
BY: Bas080
|
|
||||||
DESCRIPTION: Infect and cure players from infections
|
|
||||||
VERSION: 0.1
|
|
||||||
LICENSE: WTFPL
|
|
||||||
FORUM: http://TODO
|
|
||||||
|
|
||||||
DOCUMENTATION CONTENTS
|
|
||||||
----------------------
|
|
||||||
1.0 FEATURES
|
|
||||||
2.0 API
|
|
||||||
2.1 pathogens
|
|
||||||
2.2 infections
|
|
||||||
|
|
||||||
1.0 FEATURES
|
|
||||||
------------
|
|
||||||
* Register pathogens with the use of an API (see api documentation)
|
|
||||||
* Demonstration pathogen named "ebola" and another named "cold"
|
|
||||||
* Infect a player with a pathogen which results in the consequences of the pathogen
|
|
||||||
|
|
||||||
2.0 API
|
|
||||||
-------
|
|
||||||
|
|
||||||
2.1 pathogens
|
|
||||||
-------------
|
|
||||||
|
|
||||||
FUNCTION: pathogen.register_pathogen( name , params )
|
|
||||||
DESCRIPTION: register pathogen in table pathogen.pathogens which is global
|
|
||||||
EXAMPLE: pathogen.register_pathogen('cold', {
|
|
||||||
description = "The common cold which results in sneezing and a slight fever.",
|
|
||||||
incubation_time = 10, --time elapsed before becoming infectious
|
|
||||||
infection_time = 100, --time before infection stops
|
|
||||||
survival_rate = 0.95, --chance of survival 0 to 1=will always survive
|
|
||||||
sympton_time = 10, --average intervals between on_sympton
|
|
||||||
on_exposure = function(player, infected, pathogen) --when player gets
|
|
||||||
print('exposed')
|
|
||||||
end,
|
|
||||||
on_infection = function(player, pathogen) --
|
|
||||||
print('infectious')
|
|
||||||
end,
|
|
||||||
on_sympton = function(player, pathogen)
|
|
||||||
print('cough or poop')
|
|
||||||
end,
|
|
||||||
on_cured = function(player, pathogen)
|
|
||||||
print('survives')
|
|
||||||
end,
|
|
||||||
on_death = function(player, pathogen)
|
|
||||||
print('died')
|
|
||||||
end
|
|
||||||
})
|
|
||||||
OUTPUT: returns table of the registered pathogen
|
|
||||||
|
|
||||||
FUNCTION: pathogen.get_pathogen_by_name( name )
|
|
||||||
DESCRIPTION: returns table containing pathogen properties. If pathogen not registered it returns false
|
|
||||||
EXAMPLE: pathogen.get_pathogen_by_name( 'abola' )
|
|
||||||
OUTPUT: returns false because ebola was spelled wrong,
|
|
||||||
if spelled correctly it would return ebola pathogen properties
|
|
||||||
|
|
||||||
2.2 infections
|
|
||||||
--------------
|
|
||||||
|
|
||||||
FUNCTION: pathogen.register_infection( player_name, pathogen_name )
|
|
||||||
DESCRIPTION: infect a player with a certain pathogen
|
|
||||||
EXAMPLE: pathogen.register_infection( 'singleplayer', 'cold' )
|
|
||||||
OUTPUT: returns an infection table { player = player_name , pathogen = pathogen_name },
|
|
||||||
and registers the infection in pathogen.infections table
|
|
||||||
|
|
||||||
FUNCTION: pathogen.terminate_infection( player_name, pathogen_name )
|
|
||||||
DESCRIPTION: can be used to stop an infection. Can be used to make the use of an item cure an infection
|
|
||||||
EXAMPLE: pathogen.terminate_infection( 'bas080' , 'ebola' ) --player bas080 now no longer has ebola.
|
|
||||||
OUTPUT: returns false if such infection does not exist, and true if termination was succesfull
|
|
||||||
|
|
||||||
FUNCTION: pathogen.treat_infection( player_name, pathogen_name )
|
|
||||||
DESCRIPTION: start the treatment. Triggers the on_treatment function
|
|
||||||
EXAMPLE: pathogen.treat_infection( player_name, pathogen_name )
|
|
||||||
OUTPUT: false if such infection does not exist else returns infection table
|
|
Loading…
Reference in New Issue