my_mobs 0.3

master
R.M. HildigerR V 2014-01-11 23:50:26 -08:00
parent adb4efc370
commit c5a0f86048
14 changed files with 448 additions and 31 deletions

View File

@ -1,6 +1,6 @@
FILE: hildigerr/my_mobs/Read Me.txt
[wulfsdad -- December 2012 -- WTFPL -- Version 0.2]
[wulfsdad -- December 2012 -- WTFPL -- Version 0.3]
This MOD provides additional mobs to extend upon PilzAdam's Simple Mobs.
<http://minetest.net/forum/viewtopic.php?id=3063>.
@ -12,12 +12,15 @@ It Includes:
Rabbit
Overcooking and using the result to make dye
Meat spoilage if it remains uncooked
Cages for Pet Rodents
They must be fed apples and have a bucket of water available to survive
Raw meet can be preserved through "cheating" or using a refridgerator provided
by VanessaE's Home Decor Mod <http://minetest.net/forum/viewtopic.php?id=2041>.
KNOWN BUGS:
If you drink milk from a stack of vessels, you will not recieve the empty vessel.
The cage is sometimes placed sideways or upside down
@ -46,17 +49,22 @@ remove it and delete all copies of it, at you're request.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
----Aditional TODO:
--HIGH PRIORITY:
-- cages for pet rodents
-- feeding,breeding
-- add more animals,
-- add monsters,
-- cheese
-- support more food,
-- pet rodent breeding,
-- configurable chat message warning of pet starvation,
--MED PRIORITY:
-- add fresh meat and remove rotten meat litter periodically
-- cheese [additional mod: proidge, seaweed stew]
-- fork mobs
-- add AI tweaks and knockback
-- for animals:breeding & extinction possibility
-- cows lift head in water and sometimes when walking
-- fork mobs and add ai tweaks, and for animals:
-- breeding & extinction possibility
-- cows lift head in water and when walking sometimes
-- cows eat grass
-- Separate init file into multiple files
-- add config settings to load only parts desired
-- empty cage shall reset timers
--LOW PRIORITY:
-- add sound effect variety
-- add sound effect variety
-- make better cage graphics

View File

@ -9,4 +9,9 @@ V0.1-->0.2:
-provided constants as config options for timers and chances
-refactored redundant code into a function spoil_meat()
-added abm for meat in furnace/oven to rot too
-stacks of meat may now be divided if there is room for only part of it to rot
-stacks of meat may now be divided if there is room for only part of it to rot
v0.2-->0.3:
-Commented out residual debug barf line
-moved cow right-click sound effects to only sound with poper tool
-added cages for pet rodents, require apples for food and buckets of water to drink

View File

@ -17,14 +17,16 @@
-- Known bugs:
-- drinking from a stack of vessels does not return an empty vessel
--
-- Written by wulfsdad -- December 2012 -- WTFPL -- Version 0.2
-- Written by wulfsdad -- December 2012 -- WTFPL -- Version 0.3
--------------------------------------------------------------------------------
----Aditional TODO:
--HIGH PRIORITY:
-- cages for pet rodents
-- feeding,breeding
-- add more animals,
-- add monsters,
-- cheese [additional mod: proidge, seaweed stew]
-- support more food,
-- pet rodent breeding,
-- configurable chat message warning of pet starvation,
--MED PRIORITY:
-- add fresh meat and remove rotten meat litter periodically
-- cheese [additional mod: proidge, seaweed stew]
@ -32,8 +34,12 @@
-- breeding & extinction possibility
-- cows lift head in water and when walking sometimes
-- cows eat grass
-- Separate init file into multiple files
-- add config settings to load only parts desired
-- empty cage shall reset timers
--LOW PRIORITY:
-- add sound effect variety
-- make better cage graphics
--------------------------------------------------------------------------------
----CONFIG OPTIONS:
--Chances of meat rotting [1-100] Lower number = Greater chance
@ -50,6 +56,18 @@ local GROUND_TIMER = 360 --DEFAULT:360 [6 min]
local POCKET_TIMER = 720 --DEFAULT:720 [12 min]
local STORAGE_TIMER = 720 --DEFAULT:720 [12 min]
--Time For Cage Happenings:
local EATING_TIME = 1200 --DEFAULT: 1200 [20 min]
local DRINKING_TIME = 4 * EATING_TIME --DEFAULT: 4 * EATING_TIME
local STARVATION_LIMIT = EATING_TIME --DEFAULT: EATING_TIME
local THIRST_LIMIT = DRINKING_TIME --DEFAULT: DRINKING_TIME
local GESTATION = DRINKING_TIME + EATING_TIME --DEFAULT: DRINKING_TIME + EATING_TIME
-- --Rabbit:
-- local GESTATION_RABBIT = 3600 --DEFAULT: 3600
-- local MAX_LITTER_SIZE_RABBIT = 2 --DEFAULT: 2
-- --Rat:
-- local GESTATION_RAT = 3600 --DEFAULT: 3600
-- local MAX_LITTER_SIZE_RAT = 4 --DEFAULT: 4
--------------------------------ANIMALS-----------------------------------------
----Cow:
@ -78,36 +96,84 @@ mobs:register_mob("my_mobs:cow", {
},
on_rightclick = function(self, clicker)
if self.milked then
minetest.sound_play("Mudchute_cow_1", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
do return end
else
minetest.sound_play("milk_splash", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
end
tool = clicker:get_wielded_item():get_name()
if tool == "bucket:bucket_empty" then
if self.milked then
minetest.sound_play("Mudchute_cow_1", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
do return end
else
minetest.sound_play("milk_splash", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
end
clicker:get_inventory():remove_item("main", "bucket:bucket_empty")
clicker:get_inventory():add_item("main", "my_mobs:milk_bucket")
if math.random(1,2) > 1 then self.milked = true end
elseif tool == "vessels:glass_bottle" then
if self.milked then
minetest.sound_play("Mudchute_cow_1", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
do return end
else
minetest.sound_play("milk_splash", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
end
clicker:get_inventory():remove_item("main", "vessels:glass_bottle")
clicker:get_inventory():add_item("main", "my_mobs:milk_bottle_glass")
if math.random(1,3) > 2 then self.milked = true end
elseif tool == "vessels:drinking_glass" then
if self.milked then
minetest.sound_play("Mudchute_cow_1", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
do return end
else
minetest.sound_play("milk_splash", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
end
clicker:get_inventory():remove_item("main", "vessles:drinking_glass")
clicker:get_inventory():add_item("main", "my_mobs:milk_glass_cup")
if math.random(1,4) > 3 then self.milked = true end
elseif tool == "vessels:steel_bottle" then
if self.milked then
minetest.sound_play("Mudchute_cow_1", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
do return end
else
minetest.sound_play("milk_splash", {
object = self.object,
gain = 1.0, -- default
max_hear_distance = 32, -- default
loop = false,
})
end
clicker:get_inventory():remove_item("main", "vessels:steel_bottle")
clicker:get_inventory():add_item("main", "my_mobs:milk_bottle_steel")
if math.random(1,3) > 2 then self.milked = true end
@ -278,7 +344,7 @@ function spoil_meat( inv, title, chance, warn, owner )
for j=1,qt do
if math.random(1,100) > chance then
rotted = rotted +1
minetest.chat_send_player( "singleplayer", ""..rotted)
-- minetest.chat_send_player( "singleplayer", ""..rotted)
end -- if by chance
end -- end count rotten portion of stack
if rotted ~= 0 then
@ -308,7 +374,9 @@ end -- spoil_meat func
--Rot Stored Meat
if not minetest.get_modpath("homedecor") then
minetest.register_abm({
nodenames = { "default:chest", "default:chest_locked", },
nodenames = { "default:chest", "default:chest_locked",
"my_mobs:cage_empty", "my_mobs:cage_rat", "my_mobs:cage_rabbit",
},
interval = STORAGE_TIMER, -- (operation interval)
chance = 1, -- (chance of trigger is 1.0/this)
action = function(pos, node)
@ -343,7 +411,8 @@ else
"homedecor:kitchen_cabinet", "homedecor:kitchen_cabinet_half",
"homedecor:kitchen_cabinet_with_sink", "homedecor:nightstand_oak_one_drawer",
"homedecor:nightstand_oak_two_drawers", "homedecor:nightstand_mahogany_one_drawer",
"homedecor:nightstand_mahogany_two_drawers",
"homedecor:nightstand_mahogany_two_drawers",
"my_mobs:cage_empty", "my_mobs:cage_rat", "my_mobs:cage_rabbit",
},
interval = STORAGE_TIMER, -- (operation interval)
chance = 1, -- (chance of trigger is 1.0/this)
@ -463,4 +532,339 @@ minetest.register_abm({
end -- func
})
--------------------------------------CAGES-------------------------------------
minetest.register_node("my_mobs:cage_empty", {
description = "Rodent Cage",
-- drawtype = "normal",
drawtype = "glasslike",
---- drawtype = "allfaces_optional",
---- drawtype = "allfaces",
-- tiles = {"my_mobs_cage_top.png", "my_mobs_cage_bottom.png", "my_mobs_cage_empty_side.png",
-- "my_mobs_cage_empty_side.png", "my_mobs_cage_empty_side.png", "my_mobs_cage_empty_side.png"},
tiles = {"my_mobs_cage_empty.png"},
paramtype2 = "facedir",
sunlight_propagates = true,
-- light_source = 1,
groups = {snappy=2,cracky=2,oddly_breakable_by_hand=2},
legacy_facedir_simple = true,
sounds = {},
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"size[8,9;]"..
"list[current_name;drink;5,1;1,1;]"..
"list[current_name;feed;2,2;1,1;]"..
"list[current_name;house;3,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
)
meta:set_string("infotext", "Cage")
local inv = meta:get_inventory()
inv:set_size("house", 2*2)
inv:set_size("feed",1)
inv:set_size("drink",1)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("house") then
return false
elseif not inv:is_empty("feed") then
return false
elseif not inv:is_empty("drink") then
return false
end
return true
end,
})
minetest.register_craft({
output = 'my_mobs:cage_empty',
recipe = {
{'group:wood', 'group:wood', 'group:wood'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'group:wood', 'group:wood', 'group:wood'},
}
})
minetest.register_node("my_mobs:cage_rat", {
description = "Rodent Cage",
drawtype = "glasslike",
tiles = {"my_mobs_cage_rat.png"},
paramtype2 = "facedir",
sunlight_propagates = true,
drop = "my_mobs:cage_empty",
groups = {snappy=2,cracky=2,oddly_breakable_by_hand=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = {},
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"size[8,9;]"..
"list[current_name;drink;5,1;1,1;]"..
"list[current_name;feed;2,2;1,1;]"..
"list[current_name;house;3,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
)
meta:set_string("infotext", "Rat Cage");
local inv = meta:get_inventory()
inv:set_size("house", 2*2)
inv:set_size("feed",1)
inv:set_size("drink",1)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("house") then
return false
elseif not inv:is_empty("feed") then
return false
elseif not inv:is_empty("drink") then
return false
end
return true
end,
})
minetest.register_node("my_mobs:cage_rabbit", {
description = "Rodent Cage",
drawtype = "glasslike",
tiles = {"my_mobs_cage_rabbit.png"},
paramtype2 = "facedir",
sunlight_propagates = true,
drop = "my_mobs:cage_empty",
groups = {snappy=2,cracky=2,oddly_breakable_by_hand=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = {},
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"size[8,9;]"..
"list[current_name;drink;5,1;1,1;]"..
"list[current_name;feed;2,2;1,1;]"..
"list[current_name;house;3,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
)
meta:set_string("infotext", "Rat Cage");
local inv = meta:get_inventory()
inv:set_size("house", 2*2)
inv:set_size("feed",1)
inv:set_size("drink",1)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("house") then
return false
elseif not inv:is_empty("feed") then
return false
elseif not inv:is_empty("drink") then
return false
end
return true
end,
})
minetest.register_abm({
nodenames = {"my_mobs:cage_empty"},
interval = 1.0,
chance = 1,
action = function(pos, node)
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
if inv:contains_item("house", "my_mobs:rabbit") then
hacky_swap_node(pos,"my_mobs:cage_rabbit")
elseif inv:contains_item("house", "mobs:rat") then
hacky_swap_node(pos,"my_mobs:cage_rat")
-- else --DOESNT WORK
-- for i, name in ipairs({
-- "breeding_totaltime",
-- "breeding_time",
-- "eating_totaltime",
-- "eating_time",
-- "drinking_totaltime",
-- "drinking_time"
-- }) do
-- if not meta:get_string(name) == "" then
-- meta:set_float(name, 0.0)
-- end -- if name needs reset
-- end -- for do
end -- swap or set ifs
end,
})
minetest.register_abm({
nodenames = {"my_mobs:cage_rabbit","my_mobs:cage_rat"},
interval = 1.0,
chance = 1,
action = function(pos, node)
local meta = minetest.env:get_meta(pos)
for i, name in ipairs({
"breeding_totaltime",
"breeding_time",
"eating_totaltime",
"eating_time",
"drinking_totaltime",
"drinking_time"
}) do
if meta:get_string(name) == "" then
meta:set_float(name, 0.0)
end
-- minetest.chat_send_player( "singleplayer", name.." "..meta:get_float(name)) --BARF
end
local inv = meta:get_inventory()
local occupant = nil
if inv:contains_item("house", "my_mobs:rabbit") then
occupant = "my_mobs:rabbit"
elseif inv:contains_item("house", "mobs:rat") then
occupant = "mobs:rat"
else -- no occupant
hacky_swap_node(pos,"my_mobs:cage_empty")
end -- if animal occupant
if occupant then
-- minetest.chat_send_player( "singleplayer", occupant) --BARF
--Drinking:
if meta:get_float("drinking_time") < meta:get_float("drinking_totaltime") then -- comsuming drink
if inv:contains_item("drink", "bucket:bucket_water") then -- drink hasn't been removed
meta:set_float("drinking_time", meta:get_float("drinking_time") + 1)
else -- drink has been removed early
meta:set_float("drinking_totaltime", 0.0)
end -- cheating attempt if
elseif meta:get_float("drinking_totaltime") > 0.0 then -- consumed the drink
meta:set_float("drinking_totaltime", 0.0)
if inv:contains_item("drink", "bucket:bucket_water") then -- drink available
inv:remove_item("drink", "bucket:bucket_water")
inv:add_item("drink", "bucket:bucket_empty")
meta:set_float("drinking_time", 0.0)
-- else -- drink was removed early kill them all for punishment
-- for i=1,inv:get_size("house") do
-- local item = inv:get_stack("house", i)
-- if item:get_name() == "my_mobs:rabbit" then
-- item:replace({name = "my_mobs:meat_rotten", count = item:get_count(), wear=0, metadata=""})
-- inv:set_stack("house", i, item)
-- end -- if dead animal exists here
-- end -- for each inventory slot
end -- if there was drink
elseif meta:get_float("drinking_time") > 0.0 then -- dying of thirst
if inv:contains_item("drink", "bucket:bucket_water") then -- saved just in time
meta:set_float("drinking_totaltime", DRINKING_TIME)
if meta:get_float("drinking_time") > meta:get_float("drinking_totaltime") then -- THIRST_TIME > DRINKING_TIME [non default]
inv:remove_item("drink", "bucket:bucket_water")
inv:add_item("drink", "bucket:bucket_empty")
meta:set_float("drinking_time", meta:get_float("drinking_time") - meta:get_float("drinking_totaltime") )
meta:set_float("drinking_totaltime", 0.0 )
end -- Drink if Thirsty
else
if meta:get_float("drinking_time") < THIRST_LIMIT then
meta:set_float("drinking_time", meta:get_float("drinking_time") + 1)
else -- died of thirst
for i=1,inv:get_size("house") do
local item = inv:get_stack("house", i)
if item:get_name() == occupant then
item:replace({name = "my_mobs:meat_rotten", count = item:get_count(), wear=0, metadata=""})
inv:set_stack("house", i, item)
end -- if dead animal exists here
end -- for each inventory slot
meta:set_float("drinking_time", 0.0)
meta:set_float("drinking_totaltime", 0.0)
-- meta:set_float("eating_time", 0.0)
-- meta:set_float("eating_totaltime", 0.0)
end -- if starvation limit
end -- if food became availible
else -- not yet drinking -- both timers == 0.0
if inv:contains_item("drink", "bucket:bucket_water") then -- start drinking
meta:set_float("drinking_totaltime", DRINKING_TIME)
else -- start thirsting
meta:set_float("drinking_time", meta:get_float("drinking_time") + 1)
end -- if drink available
end -- drinking
--Eating:
if meta:get_float("eating_time") < meta:get_float("eating_totaltime") then -- comsuming food
if inv:contains_item("feed", "default:apple") then -- food hasn't been removed
meta:set_float("eating_time", meta:get_float("eating_time") + 1)
else -- food has been removed early
meta:set_float("eating_totaltime", 0.0)
end -- cheating attempt if
elseif meta:get_float("eating_totaltime") > 0.0 then -- consumed the food
meta:set_float("eating_totaltime", 0.0)
if inv:contains_item("feed", "default:apple") then
inv:remove_item("feed", "default:apple")
meta:set_float("eating_time", 0.0)
-- else -- food was removed early kill them all for punishment
-- for i=1,inv:get_size("house") do
-- local item = inv:get_stack("house", i)
-- if item:get_name() == "my_mobs:rabbit" then
-- item:replace({name = "my_mobs:meat_rotten", count = item:get_count(), wear=0, metadata=""})
-- inv:set_stack("house", i, item)
-- end -- if starved animal exists here
-- end -- for each inventory slot
end -- if there was food
elseif meta:get_float("eating_time") > 0.0 then -- starving
if inv:contains_item("feed", "default:apple") then -- saved just in time
meta:set_float("eating_totaltime", EATING_TIME)
if meta:get_float("eating_time") > meta:get_float("eating_totaltime") then -- STARVING_TIME > EATING_TIME [non default]
inv:remove_item("feed", "default:apple")
meta:set_float("eating_time", meta:get_float("eating_time") - meta:get_float("eating_totaltime") )
meta:set_float("eating_totaltime", 0.0)
end -- Eat if Starving
else
if meta:get_float("eating_time") < STARVATION_LIMIT then
meta:set_float("eating_time", meta:get_float("eating_time") + 1)
else -- starved
for i=1,inv:get_size("house") do
local item = inv:get_stack("house", i)
if item:get_name() == occupant then
item:replace({name = "my_mobs:meat_rotten", count = item:get_count(), wear=0, metadata=""})
inv:set_stack("house", i, item)
end -- if starved animal exists here
end -- for each inventory slot
meta:set_float("eating_time", 0.0)
meta:set_float("eating_totaltime", 0.0)
-- meta:set_float("drinking_time", 0.0)
-- meta:set_float("drinking_totaltime", 0.0)
end -- if starvation limit
end -- if food became availible
else -- not consuming food -- both timers == 0.0
if inv:contains_item("feed", "default:apple") then -- start eating
meta:set_float("eating_totaltime", EATING_TIME)
else -- start starving
meta:set_float("eating_time", meta:get_float("eating_time") + 1)
end -- if food available
end -- consuming food
--Breeding: [CRASHES]
-- if meta:get_float("breeding_time") < meta:get_float("breeding_totaltime") then -- breeding
-- meta:set_float("breeding_time", meta:get_float("breeding_time") + 1)
-- elseif meta:get_float("breeding_totaltime") > 0.0 then -- done breeding
-- local n = MAX_LITTER_SIZE
-- while n > 0 do -- get the largest litter possible
-- if inv:room_for_item("house",occupant.." "..n) then
-- inv:add_item("house", occupant.." "..n)
-- n = 0 -- done try no more
-- else -- n is too big
-- n = n - 1
-- end -- n if
-- meta:set_float("breeding_time", 0.0)
-- meta:set_float("breeding_totaltime", 0.0)
-- end -- n while
-- else -- not breeding yet -- both timers == 0.0
-- if inv:contains_item("house", occupant.." 2") then
-- meta:set_float("breeding_totaltime", GESTATION_RABBIT)
-- end -- couple if
-- end -- breeding if
else -- empty house (redundant)
-- hacky_swap_node(pos,"my_mobs:cage_empty")
end
end,
})
-------------------------------------EOF----------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 901 B

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B