berry bushes are working
parent
657ba694ae
commit
89e7b3f885
|
@ -0,0 +1,50 @@
|
|||
3d_armor
|
||||
ambience
|
||||
beacon
|
||||
beds
|
||||
bees
|
||||
boats
|
||||
bones
|
||||
bucket
|
||||
compassgps
|
||||
creative
|
||||
crops
|
||||
default
|
||||
denseores
|
||||
doors
|
||||
dye
|
||||
farming
|
||||
fire
|
||||
flowers
|
||||
food
|
||||
furniture
|
||||
gate
|
||||
give_initial_stuff
|
||||
glow
|
||||
goblins
|
||||
hiking
|
||||
hud
|
||||
hunger
|
||||
intersecting
|
||||
item_drop
|
||||
mobs
|
||||
mods.txt
|
||||
more_fire
|
||||
mymonths
|
||||
mytreasure
|
||||
pathv6alt
|
||||
plantlife_modpack
|
||||
railcorridors
|
||||
screwdriver
|
||||
sethome
|
||||
soil
|
||||
stairs
|
||||
survival
|
||||
thirsty
|
||||
trail
|
||||
unified_inventory
|
||||
valleys_mapgen
|
||||
vessels
|
||||
walking_light
|
||||
wool
|
||||
xpanes
|
|
@ -1,3 +1,8 @@
|
|||
2016-02-11:
|
||||
Updated mobs again.
|
||||
Fixed plantlife modpack so the berry bushes actually spawn in world, I think it was a humidity problem.
|
||||
Removed the pathogen mod, as I heard it caused some crashes and it currently wasn't doing anything.
|
||||
|
||||
2016-02-03:
|
||||
Updated mobs to latest version from TenPlus1
|
||||
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
thirsty
|
||||
pathogen
|
||||
|
|
|
@ -6,12 +6,18 @@ local s_fruit = {
|
|||
|
||||
--Group groups
|
||||
local g_fruit = {fleshy=3,dig_immediate=3,flammable=2,leafdecay=3,leafdecay_drop=1,flora=1}
|
||||
local g_berry = {flora=1, berry=1}
|
||||
|
||||
--Foods Table
|
||||
local food_table = { --craft, desc, health, hydration, selection box, groups
|
||||
{'apple', 'Apple', .25, .3, s_fruit, g_fruit},
|
||||
{'pear', 'Pear', .25, .3, s_fruit, g_fruit},
|
||||
{'banana', 'Banana', .2, .15, s_fruit, g_fruit},
|
||||
{'blackberry', 'Blackberry', .1, .1, s_fruit, g_berry},
|
||||
{'blueberry', 'Blueberry', .1, .1, s_fruit, g_berry},
|
||||
{'raspberry', 'Raspberry', .1, .1, s_fruit, g_berry},
|
||||
{'gooseberry', 'Gooseberry', .1, .1, s_fruit, g_berry},
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit b6932befb680be9d87a40668477f060b932dbe66
|
|
@ -28,6 +28,7 @@ This mod contains the following additions:
|
|||
|
||||
Changelog:
|
||||
|
||||
1.26- Pathfinding feature added thanks to rnd, when monsters attack they become scary smart in finding you :)
|
||||
1.25- Mobs no longer spawn within 12 blocks of player or despawn within same range, spawners now have player detection, Code tidy and tweak.
|
||||
1.24- Added feature where certain animals run away when punched (runaway = true in mob definition)
|
||||
1.23- Added mob spawner block for admin to setup spawners in-game (place and right click to enter settings)
|
||||
|
@ -63,4 +64,4 @@ beta- Npc mob added, kills monsters, attacks player when punched, right click wi
|
|||
0.4 - Dungeon Masters and Mese Monsters have much better aim due to shoot_offset, also they can both shoot through nodes that aren't walkable (flowers, grass etc) plus new sheep sound :)
|
||||
0.3 - Added LOTT's Spider mob, made Cobwebs, added KPavel's Bee with Honey and Beehives (made texture), Warthogs now have sound and can be tamed, taming of shaved sheep or milked cow with 8 wheat so it will not despawn, many bug fixes :)
|
||||
0.2 - Cooking bucket of milk into cheese now returns empty bucket
|
||||
0.1 - Initial Release
|
||||
0.1 - Initial Release
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- Mobs Api (2nd February 2016)
|
||||
-- Mobs Api (9th February 2016)
|
||||
mobs = {}
|
||||
mobs.mod = "redo"
|
||||
|
||||
|
@ -10,6 +10,11 @@ local creative = minetest.setting_getbool("creative_mode")
|
|||
local spawn_protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1
|
||||
local remove_far = minetest.setting_getbool("remove_far_mobs")
|
||||
|
||||
-- pathfinding settings
|
||||
local enable_pathfinding = true
|
||||
local stuck_timeout = 5 -- how long before mob gets stuck in place and starts searching
|
||||
local stuck_path_timeout = 15 -- how long will mob follow path before giving up
|
||||
|
||||
-- internal functions
|
||||
|
||||
local pi = math.pi
|
||||
|
@ -1433,6 +1438,32 @@ minetest.register_entity(name, {
|
|||
|
||||
end
|
||||
|
||||
-- rnd: new movement direction
|
||||
if self.path.stuck
|
||||
and self.path.way then
|
||||
|
||||
-- no paths longer than 50
|
||||
if #self.path.way > 50 then
|
||||
self.path.stuck = false
|
||||
return
|
||||
end
|
||||
|
||||
local p1 = self.path.way[1]
|
||||
|
||||
if not p1 then
|
||||
self.path.stuck = false
|
||||
return
|
||||
end
|
||||
|
||||
if math.abs(p1.x-s.x) + math.abs(p1.z - s.z) < 0.75 then
|
||||
-- reached waypoint, remove it from queue
|
||||
table.remove(self.path.way, 1)
|
||||
end
|
||||
|
||||
-- set new temporary target
|
||||
p = {x = p1.x, y = p1.y, z = p1.z}
|
||||
end
|
||||
|
||||
local vec = {
|
||||
x = p.x - s.x,
|
||||
y = p.y - s.y,
|
||||
|
@ -1454,6 +1485,86 @@ minetest.register_entity(name, {
|
|||
-- move towards enemy if beyond mob reach
|
||||
if dist > self.reach then
|
||||
|
||||
-- PATH FINDING by rnd
|
||||
if enable_pathfinding then
|
||||
|
||||
local s1 = self.path.lastpos
|
||||
|
||||
if math.abs(s1.x - s.x) + math.abs(s1.z - s.z) < 2 then
|
||||
|
||||
-- rnd: almost standing still, to do: insert path finding here
|
||||
self.path.stuck_timer = self.path.stuck_timer + dtime
|
||||
else
|
||||
self.path.stuck_timer = 0
|
||||
end
|
||||
|
||||
self.path.lastpos = {x = s.x, y = s.y, z = s.z}
|
||||
|
||||
if (self.path.stuck_timer > stuck_timeout and not self.path.stuck)
|
||||
or (self.path.stuck_timer > stuck_path_timeout and self.path.stuck) then
|
||||
|
||||
-- im stuck, search for path
|
||||
self.path.stuck = true
|
||||
|
||||
local sheight = self.collisionbox[5] - self.collisionbox[2]
|
||||
|
||||
-- round position to center of node to avoid stuck in walls,
|
||||
-- also adjust height for player models!
|
||||
s.x = math.floor(s.x + 0.5)
|
||||
s.y = math.floor(s.y + 0.5) - sheight
|
||||
s.z = math.floor(s.z + 0.5)
|
||||
|
||||
local ssight, sground
|
||||
|
||||
ssight, sground = minetest.line_of_sight(s,
|
||||
{x = s.x, y = s. y - 4, z = s.z}, 1)
|
||||
|
||||
-- determine node above ground
|
||||
if not ssight then
|
||||
s.y = sground.y + 1
|
||||
end
|
||||
|
||||
--minetest.chat_send_all("stuck at " .. s.x .." " .. s.y .. " " .. s.z .. ", calculating path")
|
||||
|
||||
local p1 = self.attack:getpos()
|
||||
|
||||
p1.x = math.floor(p1.x + 0.5)
|
||||
p1.y = math.floor(p1.y + 0.5)
|
||||
p1.z = math.floor(p1.z + 0.5)
|
||||
|
||||
--minetest.find_path(pos1, pos2, searchdistance, max_jump, max_drop, algorithm)
|
||||
|
||||
self.path.way = minetest.find_path(s, p1, 16, 2, 6, "A*_noprefetch")
|
||||
|
||||
if not self.path.way then
|
||||
|
||||
self.path.stuck = false
|
||||
|
||||
-- can't find path, play sound
|
||||
if self.sounds.random then
|
||||
minetest.sound_play(self.sounds.random, {
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
end
|
||||
else
|
||||
-- found path, play sound
|
||||
if self.sounds.attack then
|
||||
minetest.sound_play(self.sounds.attack, {
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
end
|
||||
|
||||
--minetest.chat_send_all("found path with length " .. #self.path.way);
|
||||
end
|
||||
|
||||
self.path.stuck_timer = 0
|
||||
|
||||
end -- END if pathfinding enabled
|
||||
end
|
||||
-- END PATH FINDING
|
||||
|
||||
-- jump attack
|
||||
if (self.jump
|
||||
and get_velocity(self) <= 0.5
|
||||
|
@ -1499,6 +1610,9 @@ minetest.register_entity(name, {
|
|||
})
|
||||
end
|
||||
|
||||
-- rnd: not stuck
|
||||
self.path.stuck = false
|
||||
|
||||
-- punch player
|
||||
self.attack:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
|
@ -1629,10 +1743,16 @@ minetest.register_entity(name, {
|
|||
local v = self.object:getvelocity()
|
||||
local r = 1.4 - math.min(punch_interval, 1.4)
|
||||
local kb = r * 5
|
||||
local up = 2
|
||||
|
||||
-- if already in air then dont go up anymore when hit
|
||||
if v.y > 0 then
|
||||
up = 0
|
||||
end
|
||||
|
||||
self.object:setvelocity({
|
||||
x = (dir.x or 0) * kb,
|
||||
y = 2,
|
||||
y = up,
|
||||
z = (dir.z or 0) * kb
|
||||
})
|
||||
|
||||
|
@ -1668,15 +1788,16 @@ minetest.register_entity(name, {
|
|||
self.following = nil
|
||||
end
|
||||
|
||||
|
||||
-- attack puncher and call other mobs for help
|
||||
if self.passive == false
|
||||
and self.child == false
|
||||
and hitter:get_player_name() ~= self.owner then
|
||||
|
||||
if self.state ~= "attack" then
|
||||
--if self.state ~= "attack" then
|
||||
-- attack whoever punched mob
|
||||
self.state = ""
|
||||
do_attack(self, hitter)
|
||||
end
|
||||
--end
|
||||
|
||||
-- alert others to the attack
|
||||
local obj = nil
|
||||
|
@ -1770,6 +1891,14 @@ minetest.register_entity(name, {
|
|||
self.health = math.random (self.hp_min, self.hp_max)
|
||||
end
|
||||
|
||||
-- rnd: pathfinding init
|
||||
self.path = {}
|
||||
self.path.way = {} -- path to follow, table of positions
|
||||
self.path.lastpos = {x = 0, y = 0, z = 0}
|
||||
self.path.stuck = false
|
||||
self.path.stuck_timer = 0 -- if stuck for too long search for path
|
||||
-- end init
|
||||
|
||||
self.object:set_hp(self.health)
|
||||
self.object:set_armor_groups({fleshy = self.armor})
|
||||
self.old_y = self.object:getpos().y
|
||||
|
@ -1836,7 +1965,7 @@ end -- END mobs:register_mob function
|
|||
mobs.spawning_mobs = {}
|
||||
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
interval, chance, active_object_count, min_height, max_height)
|
||||
interval, chance, active_object_count, min_height, max_height, day_toggle)
|
||||
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
|
@ -1845,7 +1974,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
|||
|
||||
if new_chance ~= nil then
|
||||
|
||||
if chance == 0 then
|
||||
if new_chance == 0 then
|
||||
print("[Mobs Redo] " .. name .. " has spawning disabled")
|
||||
return
|
||||
end
|
||||
|
@ -1871,6 +2000,24 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
|||
return
|
||||
end
|
||||
|
||||
-- if toggle set to nil then ignore day/night check
|
||||
if day_toggle ~= nil then
|
||||
|
||||
local tod = (minetest.get_timeofday() or 0) * 24000
|
||||
|
||||
if tod > 4500 and tod < 19500 then
|
||||
-- daylight, but mob wants night
|
||||
if day_toggle == false then
|
||||
return
|
||||
end
|
||||
else
|
||||
-- night time but mob wants day
|
||||
if day_toggle == true then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- spawn above node
|
||||
pos.y = pos.y + 1
|
||||
|
||||
|
@ -1930,10 +2077,10 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
|||
end
|
||||
|
||||
-- compatibility with older mob registration
|
||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height)
|
||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
|
||||
|
||||
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
|
||||
chance, active_object_count, -31000, max_height)
|
||||
chance, active_object_count, -31000, max_height, day_toggle)
|
||||
end
|
||||
|
||||
-- set content id's
|
||||
|
@ -2082,7 +2229,8 @@ function mobs:register_arrow(name, def)
|
|||
|
||||
local node = node_ok(pos).name
|
||||
|
||||
if minetest.registered_nodes[node].walkable then
|
||||
--if minetest.registered_nodes[node].walkable then
|
||||
if node ~= "air" then
|
||||
|
||||
self.hit_node(self, pos, node)
|
||||
|
||||
|
|
|
@ -50,11 +50,11 @@ minetest.register_node("mobs:spawner", {
|
|||
local num = tonumber(comm[4]) -- total mobs in area
|
||||
local pla = tonumber(comm[5])-- player distance (0 to disable)
|
||||
|
||||
if mob and mob ~= ""
|
||||
if mob and mob ~= "" and mobs.spawning_mobs[mob] == true
|
||||
and num and num >= 0 and num <= 10
|
||||
and mlig and mlig >= 0 and mlig <= 15
|
||||
and xlig and xlig >= 0 and xlig <= 15
|
||||
and pla >=0 and pla <= 20 then
|
||||
and pla and pla >=0 and pla <= 20 then
|
||||
|
||||
meta:set_string("command", fields.text)
|
||||
meta:set_string("infotext", "Spawner Active (" .. mob .. ")")
|
||||
|
|
|
@ -29,10 +29,8 @@ mobs:register_mob("mobs:spider", {
|
|||
view_range = 15,
|
||||
floats = 0,
|
||||
drops = {
|
||||
{name = "farming:string",
|
||||
chance = 1, min = 1, max = 2},
|
||||
{name = "ethereal:crystal_spike",
|
||||
chance = 15, min = 1, max = 2},
|
||||
{name = "farming:string", chance = 1, min = 1, max = 2},
|
||||
{name = "ethereal:crystal_spike", chance = 15, min = 1, max = 2},
|
||||
},
|
||||
water_damage = 5,
|
||||
lava_damage = 5,
|
||||
|
@ -51,7 +49,8 @@ mobs:register_mob("mobs:spider", {
|
|||
},
|
||||
})
|
||||
|
||||
mobs:register_spawn("mobs:spider", {"default:desert_stone", "ethereal:crystal_dirt"}, 13, 0, 7000, 2, 71)
|
||||
mobs:register_spawn("mobs:spider",
|
||||
{"default:desert_stone", "ethereal:crystal_dirt"}, 13, 0, 7000, 2, 71)
|
||||
|
||||
mobs:register_egg("mobs:spider", "Spider", "mobs_cobweb.png", 1)
|
||||
|
||||
|
@ -88,4 +87,4 @@ minetest.register_craft({
|
|||
{"", "farming:string", ""},
|
||||
{"farming:string", "", "farming:string"},
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
# API
|
||||
|
||||
## Register pathogens
|
||||
```lua
|
||||
pathogen.register_pathogen("pathogenia", {
|
||||
description = "An example disease",
|
||||
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 )
|
||||
minetest.sound_play( "pathogen_cough", { pos = pos, gain = 0.3 } )
|
||||
end
|
||||
on_death = function( infection )
|
||||
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|
|
||||
|
||||
# API Functions
|
||||
|
||||
```lua
|
||||
-----------
|
||||
--PATHOGENS
|
||||
-----------
|
||||
|
||||
pathogen.register_pathogen = function( pathogen_name, definition )
|
||||
--checks if pathogen is registererd and registers if not
|
||||
----
|
||||
|
||||
pathogen.get_pathogen = function( pathogen_name )
|
||||
--get the table of a particular pathogen
|
||||
----
|
||||
|
||||
pathogen.get_pathogens = function()
|
||||
--gives all the pathogens that are registered
|
||||
----
|
||||
|
||||
--------------
|
||||
--CONTAMINENTS
|
||||
--------------
|
||||
|
||||
pathogen.spawn_fluid = function( name, pos, pathogen_name )
|
||||
--spawn the infectious juices
|
||||
----
|
||||
|
||||
pathogen.register_fluid = function( name )
|
||||
--registering a fluid(juice). This assumes that all fluids are flat on the
|
||||
--floor
|
||||
------
|
||||
|
||||
pathogen.contaminate = function( pos, pathogen_name )
|
||||
--contaminates a node which when dug infects the player that dug the node
|
||||
----
|
||||
|
||||
pathogen.decontaminate = function( pos )
|
||||
--remove the contamination from the node
|
||||
----
|
||||
|
||||
pathogen.get_contaminant = function( pos )
|
||||
--used to check if the node is infected and to get the name of the pathogen
|
||||
--with which it is infected
|
||||
------
|
||||
------------
|
||||
--INFECTIONS
|
||||
------------
|
||||
pathogen.infect = function( _pathogen, player_name )
|
||||
--infects the player with a pathogen. If not able returns false
|
||||
----
|
||||
--return false if pathogen does not exist or player is immune
|
||||
--consider making an is_immune function
|
||||
----
|
||||
--The table containing all the data that a infection cinsists out of. See
|
||||
--the README.md for a more extensive explanation
|
||||
-----
|
||||
|
||||
--store the infection in a table for later use. This table is also saved and
|
||||
--loaded if the persistent option is set
|
||||
------
|
||||
--check if on_infect has been registered in pathogen
|
||||
----
|
||||
--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
|
||||
--------
|
||||
--latent perios is the time till the first symptom shows
|
||||
----
|
||||
--show the first symptom
|
||||
----
|
||||
|
||||
pathogen.perform_symptom = function( infection, symptom )
|
||||
--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. This is a number that determines the state of
|
||||
--the infection.
|
||||
--
|
||||
--only keep showing symptoms if there is no immunity against the pathogen
|
||||
----
|
||||
--only show symptoms if not all symptoms have occured.
|
||||
----
|
||||
--set the time till the next symptom and then perfrom it again
|
||||
----
|
||||
--survives and is now immunized, immunization lasts till the server is
|
||||
--restarted
|
||||
|
||||
pathogen.immunize = function( infection )
|
||||
--immunize a player so the next symptom won't show. It also disables the
|
||||
--abilty to reinfect the player. Use pathogen.disinfect to also remove
|
||||
--the immunization It will also trigger the on_cured when the next symptom
|
||||
--would have triggered.
|
||||
----
|
||||
--do not immunize if alread y immunized, return false
|
||||
--else immunize the player and return true
|
||||
|
||||
pathogen.disinfect = function( infection )
|
||||
--removes the immunization and the infection all together
|
||||
----
|
||||
--only is the is infected does it do this, return true
|
||||
-- else it will only return false
|
||||
|
||||
pathogen.get_infection = function( player_name, pathogen_name )
|
||||
--get an infection of a certain player
|
||||
----
|
||||
--only if the infection is registered
|
||||
--otherwise return nil
|
||||
|
||||
pathogen.get_infections = function( )
|
||||
--gives all the infections of all the players. If not infections are defined
|
||||
--it returns an empty table. That's it.
|
||||
|
||||
pathogen.get_player_infections = function( player_name )
|
||||
--helper function for getting the infections of a certain player
|
||||
----
|
||||
--gets and loops through the infections
|
||||
----
|
||||
--and adds the infection to the output of matches the player_name
|
||||
|
||||
-------------
|
||||
--PERSISTENCE
|
||||
-------------
|
||||
|
||||
pathogen.save = function( )
|
||||
--TODO save the infections so it won"t get lost between server reloads
|
||||
|
||||
pathogen.load = function( )
|
||||
--TODO reinfect the players when they rejoin the server. it remembers the
|
||||
--infection fase thus the infection continues and does not get reset.
|
||||
|
||||
---------
|
||||
--HELPERS
|
||||
---------
|
||||
|
||||
pathogen.get_players_in_radius = function( pos, radius )
|
||||
--helper to get players within the radius.
|
||||
----
|
||||
--loops threw all objects in within a radius
|
||||
----
|
||||
--and check if the object is a player
|
||||
|
||||
pathogen.on_dieplayer = function( player )
|
||||
--when dying while having a pathogen it will trigger the on_death of the
|
||||
--pathogen and it will remove all player infections
|
||||
----
|
||||
--loops through the player infections
|
||||
----
|
||||
--checks if it is a valid and still registered pathogen
|
||||
----
|
||||
--it then triggers the on_death if the on_death is defined
|
||||
|
||||
pathogen.on_dignode = function( pos, digger )
|
||||
--infects players that dig a node that is infected with a pathogen
|
||||
----
|
||||
```
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
# 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
|
||||
|
||||
## Gravititus
|
||||
Occurs when ascending too quickly. Symptons include hiccups and random sense of
|
||||
gravity. There is no known cure yet. ( any suggestions? stone soup anyone? )
|
||||
|
||||
## 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 through body fluids. It is ok to be near someone that has the disease.
|
||||
Make sure that when cleaning up after someone that has expelled fluids, to
|
||||
decontaminate the fluids first. This can be done with the Decontaminator
|
||||
![Decontaminator](pathogen/textures/pathogen_decontaminator.png).
|
||||
|
||||
## Gosirea
|
||||
Symptons include gas and burps. Occasionaly a shard.
|
||||
Carrier contaminates nearby surfaces when symptoms show. These can intern infect
|
||||
players that dig the infected nodes. Not deadly for those that have good health.
|
||||
|
||||
# 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
|
||||
|
||||
```lua
|
||||
pathogen.recipes['xpanes:fence_warning'] = {
|
||||
{'group:stick', 'wool:red', 'group:stick'},
|
||||
{'group:stick', 'wool:red', 'group:stick'},
|
||||
{'group:stick', 'wool:red', 'group:stick'}
|
||||
}
|
||||
|
||||
pathogen.recipes['pathogen:decontaminator'] = {
|
||||
{'xpanes:bar','',''},
|
||||
{'','default:steelblock',''},
|
||||
{'','',''}
|
||||
}
|
||||
```
|
||||
|
||||
# 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
|
||||
- register immunization with pathogen in seconds
|
||||
|
||||
# Reference
|
||||
|
||||
- https://en.wikipedia.org/wiki/Incubation_period#mediaviewer/File:Concept_of_incubation_period.svg
|
||||
- https://www.freesound.org
|
||||
|
||||
# License
|
||||
|
||||
- Code WTFPL
|
||||
- Images WTFPL
|
||||
- Sounds CC
|
|
@ -1 +0,0 @@
|
|||
pathogen
|
|
@ -1,44 +0,0 @@
|
|||
pathogen.register_pathogen("food_poisoning", {
|
||||
description = "Symptoms include vomiting and loss of health.",
|
||||
symptoms = 10,
|
||||
latent_period = 10,
|
||||
infection_period = 600,
|
||||
on_infect = function( infection )
|
||||
print "gah, I've been poisoned."
|
||||
local _player = minetest.get_player_by_name( infection.player )
|
||||
local _pos = _player:getpos()
|
||||
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 burp = function()
|
||||
if math.random(2) == 1 then
|
||||
return 'pathogen_burp_1'
|
||||
else
|
||||
return 'pathogen_burp_2'
|
||||
end
|
||||
end
|
||||
local contaminate = function( pos )
|
||||
local contaminate_pos = {
|
||||
x = pos.x + math.random( -5,5 ),
|
||||
y = pos.y + math.random( -5,5 ),
|
||||
z = pos.z + math.random( -5,5 )
|
||||
}
|
||||
pathogen.contaminate( contaminate_pos )
|
||||
end
|
||||
local hp = player:get_hp()
|
||||
if hp <= 5 then
|
||||
player:set_hp( hp - 1 )
|
||||
end
|
||||
if math.random(25) == 1 then
|
||||
pathogen.spawn_fluid( "feces", pos, infection.pathogen )
|
||||
minetest.sound_play( "pathogen_poop", { pos = pos, gain = 0.3} )
|
||||
else
|
||||
minetest.sound_play( burp(), { pos = pos, gain = 0.3 } )
|
||||
end
|
||||
for i=0,3 do
|
||||
contaminate( pos )
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
pathogen
|
|
@ -1,43 +0,0 @@
|
|||
pathogen.register_pathogen("gosirea", {
|
||||
description = "Symptons include gas. Carrier contaminates surfaces nearby. Not deadly for those that have good health",
|
||||
symptoms = 10,
|
||||
latent_period = 120,
|
||||
infection_period = 420,
|
||||
on_infect = function( infection )
|
||||
local _player = minetest.get_player_by_name( infection.player )
|
||||
local _pos = _player:getpos()
|
||||
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 burp = function()
|
||||
if math.random(2) == 1 then
|
||||
return 'pathogen_burp_1'
|
||||
else
|
||||
return 'pathogen_burp_2'
|
||||
end
|
||||
end
|
||||
local contaminate = function( pos )
|
||||
local contaminate_pos = {
|
||||
x = pos.x + math.random( -5,5 ),
|
||||
y = pos.y + math.random( -5,5 ),
|
||||
z = pos.z + math.random( -5,5 )
|
||||
}
|
||||
pathogen.contaminate( contaminate_pos )
|
||||
end
|
||||
local hp = player:get_hp()
|
||||
if hp <= 5 then
|
||||
player:set_hp( hp - 1 )
|
||||
end
|
||||
if math.random(25) == 1 then
|
||||
pathogen.spawn_fluid( "feces", pos, infection.pathogen )
|
||||
minetest.sound_play( "pathogen_poop", { pos = pos, gain = 0.3} )
|
||||
else
|
||||
minetest.sound_play( burp(), { pos = pos, gain = 0.3 } )
|
||||
end
|
||||
for i=0,3 do
|
||||
contaminate( pos )
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
pathogen
|
|
@ -1,51 +0,0 @@
|
|||
local gravititus = {}
|
||||
|
||||
local set_player_gravity = function( player_name, gravity )
|
||||
local player = minetest.get_player_by_name( player_name )
|
||||
local pos = player:getpos()
|
||||
minetest.sound_play( "gravititus_hiccup", { pos = pos, gain = 0.3 } )
|
||||
player:set_physics_override({
|
||||
gravity = gravity
|
||||
})
|
||||
end
|
||||
|
||||
pathogen.register_pathogen("gravititus", {
|
||||
description = "Occurs when ascending too quickly. Symptons are hiccups and random sense of gravity.",
|
||||
symptoms = 10,
|
||||
latent_period = 120,
|
||||
infection_period = 420,
|
||||
on_infect = function( infection )
|
||||
set_player_gravity( infection.player, 2 / math.random( 1, 5 ) )
|
||||
minetest.sound_play( "gravititus_hiccup", { pos = pos, gain = 0.3 } )
|
||||
end,
|
||||
on_symptom = function( infection )
|
||||
set_player_gravity( infection.player, 2/ math.random( 1, 5 ) )
|
||||
minetest.sound_play( "gravititus_hiccup", { pos = pos, gain = 0.3 } )
|
||||
end,
|
||||
on_death = function( infection )
|
||||
set_player_gravity( infection.player, 1 )
|
||||
end,
|
||||
on_cured = function( infection )
|
||||
set_player_gravity( infection.player, 1 )
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_on_dignode( function( pos, node, digger )
|
||||
--determines when infection occurs.
|
||||
----
|
||||
local pln = digger:get_player_name()
|
||||
local pos = pos
|
||||
local pre = gravititus[pln]
|
||||
gravititus[pln] = pos
|
||||
if ( pre == nil ) then
|
||||
minetest.after( 15, function()
|
||||
local pre = gravititus[pln]
|
||||
local dis = math.abs( pre.y - pos.y )
|
||||
if ( dis > 20 ) then
|
||||
local pat = pathogen.get_pathogen( 'gravititus' )
|
||||
pathogen.infect( pat, pln )
|
||||
end
|
||||
gravititus[pln] = nil
|
||||
end)
|
||||
end
|
||||
end )
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
pathogen
|
|
@ -1,37 +0,0 @@
|
|||
pathogen.register_pathogen("influencia", {
|
||||
description = "Highly contagious and possibly deadly for those with low health.",
|
||||
symptoms = 12,
|
||||
latent_period = 10,
|
||||
infection_period = 10,
|
||||
on_infect = function( infection )
|
||||
local _player = minetest.get_player_by_name( infection.player )
|
||||
local _pos = _player:getpos()
|
||||
print 'got sick'
|
||||
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
|
||||
})
|
|
@ -1,52 +0,0 @@
|
|||
lunit = {}
|
||||
|
||||
lunit.tests = function( name, tests )
|
||||
print("TEST: "..name)
|
||||
local succes = function( description )
|
||||
print( 'succes: '..description )
|
||||
return true
|
||||
end
|
||||
local failed = function( description, expected, value )
|
||||
print( 'failed: '..description..'\texpected '..tostring(expected)..' got '..tostring(value) )
|
||||
return false
|
||||
end
|
||||
local unit = {
|
||||
ok = function( value, description )
|
||||
if value then
|
||||
succes( description )
|
||||
else
|
||||
failed( description, 'true-ish', value )
|
||||
end
|
||||
return value
|
||||
end,
|
||||
equal = function( value, expected, description)
|
||||
if value == expected then
|
||||
succes( description )
|
||||
else
|
||||
failed( description, expected, value )
|
||||
end
|
||||
return value
|
||||
end,
|
||||
}
|
||||
return tests( unit )
|
||||
end
|
||||
|
||||
if false then
|
||||
--used to test the framewrk itself
|
||||
lunit.tests( 'lunit succes', function( unit )
|
||||
unit.ok( true, 'true is ok')
|
||||
unit.ok( {}, 'table is ok')
|
||||
unit.equal( true, true, 'equals true')
|
||||
unit.equal( false, false, 'equals false')
|
||||
unit.equal( 'hello', 'hello', 'equals string')
|
||||
unit.equal( type(''), 'string', 'is type')
|
||||
end)
|
||||
--fail
|
||||
lunit.tests( 'lunit fails', function( unit )
|
||||
unit.ok( false, 'true is ok')
|
||||
unit.equal( false, true, 'equals true')
|
||||
unit.equal( false , {}, 'false equals table')
|
||||
unit.equal( true, false, 'equals false')
|
||||
unit.equal( 'hello', 'world', 'does not equal string')
|
||||
end)
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
pathogen
|
|
@ -1,29 +0,0 @@
|
|||
pathogen.register_pathogen("panola", {
|
||||
description = "Panola virus is highly contagious. It spreads threw bodily fluids.",
|
||||
symptoms = 20,
|
||||
latent_period = 840,
|
||||
infection_period = 1200,
|
||||
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, 1) == 1 then
|
||||
pathogen.spawn_fluid( "vomit", pos, infection.pathogen )
|
||||
minetest.sound_play( "pathogen_vomit", { pos = pos, gain = 0.3} )
|
||||
else
|
||||
pathogen.spawn_fluid( "feces", pos, infection.pathogen )
|
||||
minetest.sound_play( "pathogen_poop", { pos = pos, gain = 0.3} )
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1,374 +0,0 @@
|
|||
-----------
|
||||
--PATHOGENS
|
||||
-----------
|
||||
pathogen.register_pathogen = function( pathogen_name, definition )
|
||||
--checks if pathogen is registererd and registers if not
|
||||
----
|
||||
if not pathogen.get_pathogen( pathogen_name ) then
|
||||
definition.name = pathogen_name;
|
||||
pathogen.pathogens[pathogen_name] = definition
|
||||
return pathogen.pathogens[pathogen_name]
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.get_pathogen = function( pathogen_name )
|
||||
--get the table of a particular pathogen
|
||||
----
|
||||
return pathogen.pathogens[pathogen_name]
|
||||
end
|
||||
|
||||
pathogen.get_pathogens = function()
|
||||
--gives all the pathogens that are registered
|
||||
----
|
||||
return pathogen.pathogens
|
||||
end
|
||||
--------------
|
||||
--CONTAMINENTS
|
||||
--------------
|
||||
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 } )
|
||||
pathogen.contaminate( pos, 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()
|
||||
local _pathogen = pathogen.get_pathogen( pathogen_name )
|
||||
if _pathogen then
|
||||
pathogen.infect( _pathogen, player_name )
|
||||
end
|
||||
end,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -7.9/16, 0.5},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
pathogen.contaminate = function( pos, pathogen_name )
|
||||
--contaminates a node which when dug infects the player that dug the node
|
||||
----
|
||||
local meta = minetest.get_meta( pos )
|
||||
if meta then
|
||||
meta:set_string( 'pathogen', pathogen_name )
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.decontaminate = function( pos )
|
||||
--remove the contamination from the node
|
||||
----
|
||||
local meta = minetest.get_meta( pos )
|
||||
if meta then
|
||||
local str = meta:get_string('pathogen')
|
||||
if str ~= '' then
|
||||
meta:set_string( 'pathogen', '' )
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.get_contaminant = function( pos )
|
||||
--used to check if the node is infected and to get the name of the pathogen
|
||||
--with which it is infected
|
||||
------
|
||||
local meta = minetest.get_meta( pos )
|
||||
if not meta then return false end
|
||||
local pathogen_name = meta:get_string( 'pathogen' )
|
||||
if pathogen_name then
|
||||
if pathogen_name ~= '' then
|
||||
return pathogen_name
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
------------
|
||||
--INFECTIONS
|
||||
------------
|
||||
pathogen.infect = function( _pathogen, player_name )
|
||||
--infects the player with a pathogen. If not able returns false
|
||||
----
|
||||
local infection = pathogen.get_infection( player_name, _pathogen.name )
|
||||
if ( infection ~= nil ) then
|
||||
--return false if pathogen does not exist or player is immune
|
||||
if ( infection.immune ) then return false end
|
||||
end
|
||||
--consider making an is_immune function
|
||||
----
|
||||
local infection = {
|
||||
--The table containing all the data that a infection cinsists out of. See
|
||||
--the README.md for a more extensive explanation
|
||||
-----
|
||||
id = player_name.._pathogen.name,
|
||||
symptom = 0,
|
||||
pathogen = _pathogen,
|
||||
immune = false,
|
||||
player = player_name
|
||||
}
|
||||
|
||||
pathogen.infections[ player_name.._pathogen.name ] = infection
|
||||
--store the infection in a table for later use. This table is also saved and
|
||||
--loaded if the persistent option is set
|
||||
------
|
||||
local on_infect = _pathogen.on_infect
|
||||
if on_infect then
|
||||
--check if on_infect has been registered in pathogen
|
||||
----
|
||||
if minetest.get_player_by_name( player_name ) then
|
||||
on_infect( infection )
|
||||
end
|
||||
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( infection, 0 )
|
||||
--show the first symptom
|
||||
----
|
||||
end)
|
||||
return infection
|
||||
end
|
||||
|
||||
pathogen.perform_symptom = function( infection, symptom )
|
||||
--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. This is a number that determines the state of
|
||||
--the infection.
|
||||
----------
|
||||
if infection.immune then return false end
|
||||
--only keep showing symptoms if there is no immunity against the pathogen
|
||||
----
|
||||
local symptom = symptom + 1
|
||||
if ( infection.pathogen.symptoms >= symptom ) then --check if all symptoms have occured
|
||||
--only show symptoms if not all symptoms have occured.
|
||||
----
|
||||
infection.symptom = symptom
|
||||
|
||||
local on_symptom = infection.pathogen.on_symptom
|
||||
if on_symptom then
|
||||
if minetest.get_player_by_name( infection.player ) then
|
||||
on_symptom( infection )
|
||||
end
|
||||
end
|
||||
|
||||
local interval = ( ( infection.pathogen.infection_period - infection.pathogen.latent_period ) / infection.pathogen.symptoms )
|
||||
minetest.after( interval , function()
|
||||
--set the time till the next symptom and then perfrom it again
|
||||
--
|
||||
pathogen.perform_symptom( infection, symptom )
|
||||
end)
|
||||
infection.symptom = symptom
|
||||
return true
|
||||
elseif ( infection.pathogen.symptoms < symptom ) then
|
||||
----
|
||||
--survives and is now immunized, immunization lasts till the server is
|
||||
--restarted
|
||||
------
|
||||
local on_recover = infection.pathogen.on_recover
|
||||
if on_recover and ( infection.pathogen.symptoms+1 == symptom ) then
|
||||
pathogen.immunize( infection )
|
||||
local result = on_recover( infection )
|
||||
if minetest.get_player_by_name( infection.player ) then
|
||||
on_recover( infection )
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.immunize = function( infection )
|
||||
--immunize a player so the next symptom won't show. It also disables the
|
||||
--abilty to reinfect the player. Use pathogen.disinfect to also remove
|
||||
--the immunization It will also trigger the on_cured when the next symptom
|
||||
--would have triggered.
|
||||
----
|
||||
if infection.immune == true then
|
||||
--do not immunize if alread y immunized, return false
|
||||
--
|
||||
return false
|
||||
else
|
||||
--else immunize the player and return true
|
||||
infection.immune = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.disinfect = function( infection )
|
||||
--removes the immunization and the infection all together
|
||||
----
|
||||
if pathogen.infections[ infection.player..infection.pathogen.name ] then
|
||||
--only is the is infected does it do this, return true
|
||||
pathogen.infections[ infection.player..infection.pathogen.name ]= nil
|
||||
return true
|
||||
else
|
||||
-- else it will only return false
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.get_infection = function( player_name, pathogen_name )
|
||||
--get an infection of a certain player
|
||||
----
|
||||
if player_name and pathogen_name then
|
||||
--only if the infection is registered
|
||||
return pathogen.infections[ player_name..pathogen_name ]
|
||||
else
|
||||
--otherwise return nil
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
pathogen.get_infections = function( )
|
||||
--gives all the infections of all the players. If not infections are defined
|
||||
--it returns an empty table. That's it.
|
||||
return pathogen.infections
|
||||
end
|
||||
|
||||
pathogen.get_player_infections = function( player_name )
|
||||
--helper function for getting the infections of a certain player
|
||||
----
|
||||
local infections = pathogen.get_infections()
|
||||
local output = {}
|
||||
for index, infection in pairs(infections) do
|
||||
--gets and loops through the infections
|
||||
----
|
||||
if infection.player == player_name then
|
||||
--and adds the infection to the output of matches the player_name
|
||||
output[#output+1] = infection
|
||||
end
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
-------------
|
||||
--PERSISTENCE
|
||||
-------------
|
||||
|
||||
-------------
|
||||
--PERSISTENCE
|
||||
-------------
|
||||
|
||||
pathogen.save = function( )
|
||||
--TODO save the infections so it won"t get lost between server reloads
|
||||
local serialized = minetest.serialize( infections )
|
||||
return serialized
|
||||
end
|
||||
|
||||
pathogen.load = function( )
|
||||
--TODO reinfect the players when they rejoin the server. it remembers the
|
||||
--infection fase thus the infection continues and does not get reset.
|
||||
local deserialized = minetest.deserialize(string)
|
||||
return deserialized
|
||||
end
|
||||
|
||||
---------
|
||||
--HELPERS
|
||||
---------
|
||||
|
||||
---------
|
||||
--HELPERS
|
||||
---------
|
||||
|
||||
pathogen.get_players_in_radius = function( pos, radius )
|
||||
--helper to get players within the radius.
|
||||
----
|
||||
local objects = minetest.get_objects_inside_radius(pos, 5)
|
||||
local players = {}
|
||||
for index, object in ipairs(objects) do
|
||||
--loops threw all objects in within a radius
|
||||
----
|
||||
if object:is_player() then
|
||||
--and check if the object is a player
|
||||
players[#players+1] = object
|
||||
end
|
||||
end
|
||||
return players
|
||||
end
|
||||
|
||||
pathogen.on_dieplayer = function( player )
|
||||
--when dying while having a pathogen it will trigger the on_death of the
|
||||
--pathogen and it will remove all player infections
|
||||
----
|
||||
local player_name = player:get_player_name()
|
||||
local _infections = pathogen.get_player_infections( player_name )
|
||||
for index, infection in pairs(_infections) do
|
||||
--loops through the player infections
|
||||
----
|
||||
local _pathogen = pathogen.get_pathogen( infection.pathogen )
|
||||
if _pathogen then
|
||||
--checks if it is a valid and still registered pathogen
|
||||
----
|
||||
local on_death = _pathogen.on_death
|
||||
if on_death then
|
||||
--it then triggers the on_death if the on_death is defined
|
||||
pathogen.disinfect( infection )
|
||||
on_death( infection )
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
pathogen.on_dignode = function( pos, digger )
|
||||
--infects players that dig a node that is infected with a pathogen
|
||||
----
|
||||
local pathogen_name = pathogen.get_contaminant( pos )
|
||||
if pathogen_name then
|
||||
local _pathogen = pathogen.get_pathogen( pathogen_name )
|
||||
local player_name = digger:get_player_name( )
|
||||
return pathogen.infect( _pathogen, player_name )
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
minetest.register_on_dignode( function( pos, oldnode, digger)
|
||||
pathogen.on_dignode( pos, digger )
|
||||
end)
|
||||
|
||||
minetest.register_on_dieplayer( function( player )
|
||||
pathogen.on_dieplayer( player )
|
||||
end)
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
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 not minetest.get_player_by_name( player_name ) then
|
||||
minetest.chat_send_player(name, 'could not infect: player '..player_name..' does not exist')
|
||||
end
|
||||
local _pathogen = pathogen.get_pathogen( pathogen_name )
|
||||
if _pathogen then
|
||||
local infection = pathogen.infect( _pathogen, player_name )
|
||||
if infection then
|
||||
minetest.chat_send_player(name, 'infected: '..player_name..' with '..pathogen_name )
|
||||
else
|
||||
minetest.chat_send_player(name, 'could not infect: '..pathogen_name..' is immune')
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name, 'could not infect: pathogen '..pathogen_name..' 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
|
||||
if _pathogen.description then
|
||||
minetest.chat_send_player( name, _pathogen.name..' - '.._pathogen.description )
|
||||
else
|
||||
minetest.chat_send_player( name, _pathogen.name )
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("immunize", {
|
||||
params = "<pathogen> <player>",
|
||||
description = "immunize 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.get_infection( player_name, pathogen_name )
|
||||
if infection then
|
||||
pathogen.immunize( infection )
|
||||
minetest.chat_send_player(name, 'immunized: player '..player_name..' from '..pathogen_name)
|
||||
else
|
||||
minetest.chat_send_player(name, 'could not immunize: infection does not exist' )
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1,4 +0,0 @@
|
|||
minetest.register_craft({
|
||||
output = 'pathogen:decontaminator',
|
||||
recipe = pathogen.recipes['pathogen:decontaminator']
|
||||
})
|
|
@ -1,3 +0,0 @@
|
|||
default
|
||||
wool
|
||||
xpanes?
|
|
@ -1,13 +0,0 @@
|
|||
pathogen = {
|
||||
pathogens = {},
|
||||
infections = {},
|
||||
fluids = {},
|
||||
}
|
||||
|
||||
dofile( minetest.get_modpath( "pathogen" ) .. "/options.lua" ) --WIP
|
||||
dofile( minetest.get_modpath( "pathogen" ) .. "/recipes.lua")
|
||||
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" )
|
|
@ -1,47 +0,0 @@
|
|||
pathogen.register_fluid( 'vomit' )
|
||||
pathogen.register_fluid( 'blood' )
|
||||
pathogen.register_fluid( 'feces' )
|
||||
|
||||
if not minetest.get_modpath( "xpanes" ) then
|
||||
|
||||
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(),
|
||||
node_box = {
|
||||
type = 'fixed',
|
||||
fixed = {
|
||||
{-0.5, -0.5, 63/128,
|
||||
0.5, 0.5 , 63/128},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
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 = pathogen.recipes['xpanes:fence_warning']
|
||||
})
|
||||
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
--DOES NOT WORK YET WIP
|
||||
pathogen.options = {
|
||||
persistence = false,
|
||||
immunization = false,
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
pathogen.recipes = {}
|
||||
|
||||
pathogen.recipes['xpanes:fence_warning'] = {
|
||||
{'group:stick', 'wool:red', 'group:stick'},
|
||||
{'group:stick', 'wool:red', 'group:stick'},
|
||||
{'group:stick', 'wool:red', 'group:stick'}
|
||||
}
|
||||
|
||||
pathogen.recipes['pathogen:decontaminator'] = {
|
||||
{'xpanes:bar','',''},
|
||||
{'','default:steelblock',''},
|
||||
{'','',''}
|
||||
}
|
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.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 488 B |
Binary file not shown.
Before Width: | Height: | Size: 212 B |
Binary file not shown.
Before Width: | Height: | Size: 870 B |
Binary file not shown.
Before Width: | Height: | Size: 805 B |
Binary file not shown.
Before Width: | Height: | Size: 866 B |
|
@ -1,10 +0,0 @@
|
|||
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( pt.under )
|
||||
end
|
||||
})
|
|
@ -34,36 +34,22 @@ for i, berry in ipairs(bushes_classic.bushes) do
|
|||
inventory_image = "bushes_"..berry.."_pie_raw.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
|
||||
minetest.register_craftitem(":bushes:"..berry, {
|
||||
description = desc,
|
||||
inventory_image = "bushes_"..berry..".png",
|
||||
groups = {berry = 1, [berry] = 1},
|
||||
on_use = minetest.item_eat(1),
|
||||
})
|
||||
|
||||
if berry ~= "mixed_berry" then
|
||||
|
||||
if berry == "strawberry" and minetest.registered_nodes["farming_plus:strawberry"] then
|
||||
-- Special case for strawberries, when farming_plus is in use. Use
|
||||
-- the item from that mod, but redefine it so it has the right
|
||||
-- groups and does't look so ugly!
|
||||
minetest.register_craftitem(":farming_plus:strawberry_item", {
|
||||
description = S("Strawberry"),
|
||||
inventory_image = "bushes_"..berry..".png",
|
||||
on_use = minetest.item_eat(2),
|
||||
groups = {berry=1, strawberry=1}
|
||||
})
|
||||
minetest.register_alias("bushes:strawberry", "farming_plus:strawberry_item")
|
||||
else
|
||||
minetest.register_craftitem(":bushes:"..berry, {
|
||||
description = desc,
|
||||
inventory_image = "bushes_"..berry..".png",
|
||||
groups = {berry = 1, [berry] = 1},
|
||||
on_use = minetest.item_eat(1),
|
||||
})
|
||||
end
|
||||
minetest.register_craft({
|
||||
output = "bushes:"..berry.."_pie_raw 1",
|
||||
recipe = {
|
||||
{ "group:food_sugar", "farming:flour", "group:food_sugar" },
|
||||
{ "group:"..berry, "group:"..berry, "group:"..berry },
|
||||
},
|
||||
})
|
||||
end
|
||||
minetest.register_craft({
|
||||
output = "bushes:"..berry.."_pie_raw 1",
|
||||
recipe = {
|
||||
{ "group:food_sugar", "farming:flour", "group:food_sugar" },
|
||||
{ "group:"..berry, "group:"..berry, "group:"..berry },
|
||||
},
|
||||
})
|
||||
-- end
|
||||
|
||||
-- Cooked pie
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
plants_lib
|
||||
farming?
|
||||
farming_plus?
|
||||
mymonths
|
||||
|
|
|
@ -8,21 +8,19 @@ local S = plantslib.intllib
|
|||
bushes_classic = {}
|
||||
|
||||
bushes_classic.bushes = {
|
||||
"strawberry",
|
||||
"blackberry",
|
||||
"blueberry",
|
||||
"raspberry",
|
||||
"gooseberry",
|
||||
"mixed_berry"
|
||||
"mixed_berry",
|
||||
}
|
||||
|
||||
bushes_classic.bushes_descriptions = {
|
||||
"Strawberry",
|
||||
"Blackberry",
|
||||
"Blueberry",
|
||||
"Raspberry",
|
||||
"Gooseberry",
|
||||
"Mixed Berry"
|
||||
"Mixed Berry",
|
||||
}
|
||||
|
||||
bushes_classic.spawn_list = {}
|
||||
|
@ -31,7 +29,7 @@ dofile(minetest.get_modpath('bushes_classic') .. '/cooking.lua')
|
|||
dofile(minetest.get_modpath('bushes_classic') .. '/nodes.lua')
|
||||
|
||||
plantslib:spawn_on_surfaces({
|
||||
spawn_delay = 3600,
|
||||
spawn_delay = 600,
|
||||
spawn_plants = bushes_classic.spawn_list,
|
||||
avoid_radius = 10,
|
||||
spawn_chance = 100,
|
||||
|
@ -44,6 +42,8 @@ plantslib:spawn_on_surfaces({
|
|||
"farming:soil_wet",
|
||||
"valleys_mapgen:dirt_with_grass",
|
||||
"valleys_mapgen:clayey_with_grass",
|
||||
"valleys_mapgen:dirt_sandy_with_grass",
|
||||
"valleys_mapgen:dirt_silty_with_grass",
|
||||
},
|
||||
avoid_nodes = {"group:bush"},
|
||||
seed_diff = 545342534, -- chosen by a fair mashing of the keyboard - guaranteed to be random :P
|
||||
|
@ -51,10 +51,8 @@ plantslib:spawn_on_surfaces({
|
|||
light_min = 10,
|
||||
temp_min = 0.15, -- approx 20C
|
||||
temp_max = -0.15, -- approx 35C
|
||||
humidity_min = 0, -- 50% RH
|
||||
humidity_max = -1, -- 100% RH
|
||||
-- humidity_min = 0, -- 50% RH
|
||||
-- humidity_max = -1, -- 100% RH
|
||||
})
|
||||
|
||||
minetest.register_alias("bushes:basket_pies", "bushes:basket_strawberry")
|
||||
|
||||
print(S("[Bushes] Loaded."))
|
||||
|
|
|
@ -54,7 +54,7 @@ plantlife_bushes.after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|||
-- only bushes that have grown fruits can actually give fruits
|
||||
if can_harvest then
|
||||
local amount = "4"
|
||||
harvested = "bushes:" .. bush_name .. " " .. amount
|
||||
harvested = "food:" .. bush_name .. " " .. amount
|
||||
end
|
||||
|
||||
-- something like a shovel
|
||||
|
@ -126,17 +126,20 @@ minetest.register_abm({
|
|||
interval = 500,
|
||||
chance = 5,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local bush_name = meta:get_string("bush_type")
|
||||
|
||||
if bush_name and bush_name ~= "" then
|
||||
local dirtpos = {x = pos.x, y = pos.y-1, z = pos.z}
|
||||
local dirt = minetest.get_node(dirtpos)
|
||||
local is_soil = minetest.get_item_group(dirt.name, "soil") or minetest.get_item_group(dirt.name, "potting_soil")
|
||||
if mymonths.month == 'June' or mymonths.month == 'July' or mymonths.month == 'August' then
|
||||
|
||||
if is_soil and (dirt.name == "farming:soil_wet" or math.random(1,3) == 1) then
|
||||
minetest.set_node( pos, {name = "bushes:" .. bush_name .. "_bush"})
|
||||
if bush_name and bush_name ~= "" then
|
||||
local dirtpos = {x = pos.x, y = pos.y-1, z = pos.z}
|
||||
local dirt = minetest.get_node(dirtpos)
|
||||
local is_soil = minetest.get_item_group(dirt.name, "soil") or minetest.get_item_group(dirt.name, "potting_soil")
|
||||
|
||||
if is_soil and (dirt.name == "farming:soil_wet" or math.random(1,3) == 1) then
|
||||
minetest.set_node( pos, {name = "bushes:" .. bush_name .. "_bush"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue