Cottage placement refactor and misc

master
francisco athens 2020-07-26 14:05:28 -07:00
parent a246bad96e
commit cf9e69a058
6 changed files with 391 additions and 106 deletions

View File

@ -8,21 +8,25 @@ The MIT License (MIT)
Witches inhabit the land! They are currently in development but, can already:
* Spawn near wood above ground.
* Spawn near wood above ground.
* Witch cottages adapted from Sokomine's basic_houses:
* Witch cottages adapted from Sokomine's basic_houses:
(https://github.com/Sokomine/basic_houses) mod under under MIT license
with permission from author.
Option requires Sokomine's handle_schematics mod (also GPLv3)
https://github.com/Sokomine/handle_schematics
*Have a name and origin location which they will tell player.
Settings provided from settings menu!
*Randomly choose hair color and style
* Some cottages will spawn over a dungeon if they are near the surface
*Randomly choose hat style and hat ornaments
* Have a name and origin location which they will tell player.
*Basic interactivity:
* Randomly choose hair color and style
* Randomly choose hat style and hat ornaments
* Basic interactivity:
will follow player for holding certain items.
one of those items they will request with randomly chosen text, if player right clicks
if player is holding that requested item and right click witch player will receive a reward

View File

@ -38,15 +38,18 @@
-- * cavegen may eat holes into the ground below the house
-- * houses may very seldom overlap
local witches_dungon_cellar_chance = tonumber(minetest.settings:get("witches_dungon_cellar_chance")) or .50
local witches_dungon_cellar_depth = tonumber(minetest.settings:get("witches_dungon_cellar_depth")) or -5
witches.bh = {};
-- generate at max this many houses per mapchunk;
-- Note: This amount will likely only spawn if your mapgen is very flat.
-- Else you will see far less houses.
witches.bh.max_per_mapchunk = 2;
witches.bh.max_per_mapchunk = tonumber(minetest.settings:get("witches_house_max_per_mapchunk")) or 2;
-- how many houses shall be generated on average per mapchunk?
witches.bh.houses_wanted_per_mapchunk = 0.05;
witches.bh.houses_wanted_per_mapchunk = tonumber(minetest.settings:get("witches_houses_wanted_per_mapchunk")) or .05;
-- even if there would not be any house here due to amount of houses
-- generated beeing equal or larger than the amount of houses expected,
@ -59,8 +62,6 @@ witches.bh.mapchunks_processed = 0;
-- how many houses have been generated in these mapchunks?
witches.bh.houses_generated = 0;
-- materials the houses can be made out of
-- allows to reach upper floors
witches.bh.ladder = "default:ladder_wood";
@ -138,9 +139,10 @@ end
--lets see if any dungeons are near
minetest.set_gen_notify("dungeon")
local dungeon_cellar = {
attempts = 1000,
max_depth = -15
chance = tonumber(witches_dungon_cellar_chance), -- chance to try putting cottage over dungeon instead of anywhere else
max_depth = tonumber(witches_dungon_cellar_depth) -- deepest dungeon depth to check
}
local dungeon_list ={}
minetest.register_on_generated(function(minp, maxp, blockseed)
@ -430,7 +432,7 @@ witches.bh.place_ladder = function( p, sizex, sizez, ladder_places, ladder_heigh
vm:set_node_at( {x=res.x, y=height, z=res.z}, ladder_node );
end
if d1 and d1.y and d1.y < p.y-1 then
for height=d1.y,p.y do
for height=d1.y-2,p.y do
vm:set_node_at( {x=res.x, y=height, z=res.z}, {name = "air"} );
vm:set_node_at( {x=res.x, y=height, z=res.z}, ladder_node );
@ -561,20 +563,81 @@ witches.bh.simple_hut_find_place = function( heightmap, minp, maxp, sizex, sizez
-- select a random place - either sizex x sizez or sizez x sizex
--first find a place over a dungeon
local near_dungeon = {};
local attempts = 1
local fails = 0
--if not near_dungeon.x then near_dungeon.x = {} end
--print(dump(dungeon_list))
if dungeon_cellar then
attempts = dungeon_cellar.attempts
--if not near_dungeon.x then near_dungeon.x = {} end
if #dungeon_list >=1 then
for i=1,#dungeon_list do
--print("dungeon list:"..minetest.pos_to_string(dungeon_list[i]))
end
else
--print("no dungeon list!")
end
local chunksize = maxp.x - minp.x + 1;
local c = math.random( 1, #res.places_x + #res.places_z );
--local i = 1;
--local d = 1;
for n=1,attempts do
local c = math.random( 1, #res.places_x + #res.places_z );
local i = 1;
if #dungeon_list >=1 then
--print("there is a list!")
local nearest_dungeon = 10000
--make a list from either of the res
if math.random() <= 0.5 then
for dc=1,#res.places_z do
if res.places_x[dc] and res.places_z[dc] then
for d=1,#dungeon_list do
--local check = {x = res.places_x[dc], y = dungeon_list[d].y, z = res.places_z[dc]}
local check = {x = minp.x+(dc%chunksize)-1, y = dungeon_list[d].y, z=minp.z+math.floor(dc/chunksize)}
local dist = vector.distance(dungeon_list[d], check)
--print("checking for z: "..minetest.pos_to_string(check))
if dist < nearest_dungeon then nearest_dungeon = math.floor(dist) end
if dist <= 2 then
--print("found for z! "..dump(dist))
dungeon_list[d].i = dc
dungeon_list[d].sizex = sizez
dungeon_list[d].sizez = sizex
table.insert(near_dungeon,dungeon_list[d])
end
end
end
end
else
for dc=1,#res.places_x do
if res.places_x[dc] and res.places_z[dc] then
for d=1,#dungeon_list do
--{x=minp.x+(i%chunksize)-1, y=heightmap[ i ], z=minp.z+math.floor(i/chunksize), i=i};
local check = {x = minp.x+(dc%chunksize)-1, y = dungeon_list[d].y, z=minp.z+math.floor(dc/chunksize)}
local dist = vector.distance(dungeon_list[d], check)
--print("checking for x: "..minetest.pos_to_string(check))
if dist < nearest_dungeon then nearest_dungeon = math.floor(dist) end
if dist <= 2 then
--print("found for x! "..dump(dist))
dungeon_list[d].i = dc
dungeon_list[d].sizex = sizex
dungeon_list[d].sizez = sizez
table.insert(near_dungeon,dungeon_list[d])
end
end
end
end
end
print("\n nearest dungeon was "..nearest_dungeon.."\n")
end
if #near_dungeon < 1 and math.random() < (1-dungeon_cellar.chance) then
--print("standard placement")
--print("failed dungeon_list count: " ..#dungeon_list)
--for f=1,#dungeon_list do
-- print("dungeon list:"..minetest.pos_to_string(dungeon_list[f]))
--end
local i = 1
if( c > #res.places_x ) then
i = res.places_z[ c-#res.places_x ];
-- swap x and z due to rotation of 90 or 270 degree
@ -586,38 +649,44 @@ witches.bh.simple_hut_find_place = function( heightmap, minp, maxp, sizex, sizez
i = res.places_x[ c ];
end
local chunksize = maxp.x - minp.x + 1;
-- translate index back into coordinates
local p = {x=minp.x+(i%chunksize)-1, y=heightmap[ i ], z=minp.z+math.floor(i/chunksize), i=i};
--print("standard placement of cottage: "..minetest.pos_to_string(p))
return {p1={x=p.x - sizex, y=p.y, z=p.z - sizez }, p2=p, sizex=sizex, sizez=sizez};
else
if attempts > 1 and n < attempts then
for d=1,#dungeon_list do
local check = {x = p.x, y = dungeon_list[d].y, z = p.z}
-- print(dump(vector.distance(dungeon_list[d], check)))
if vector.distance (dungeon_list[d], check) <= 2 then
table.insert(near_dungeon,dungeon_list[d])
end
end
-- translate index back into coordinates
--local p = {x=minp.x+(i%chunksize)-1, y=heightmap[ i ], z=minp.z+math.floor(i/chunksize), i=i};
--print("near dungeon list: "..dump(near_dungeon))
if #near_dungeon >= 1 then
print("near dungeon list: "..dump(near_dungeon))
local t = minetest.find_node_near(near_dungeon[1],3,"air")
p.x = math.floor(t.x +sizex/2)
p.z = math.floor(t.z +sizez/2)
return {p1={x=p.x - sizex, y=p.y, z=p.z - sizez }, p2=p, sizex=sizex, sizez=sizez, d1=near_dungeon[1]};
else
fails = fails + 1
end
else
--print(tostring(fails+1).." attempts made")
if #near_dungeon >= 1 then
return {p1={x=p.x - sizex, y=p.y, z=p.z - sizez }, p2=p, sizex=sizex, sizez=sizez};
--print("near dungeon count: "..#near_dungeon)
local choice = math.random(1,#near_dungeon)
--print("dungeon found: "..minetest.pos_to_string(near_dungeon[choice]))
local t = minetest.find_node_near(near_dungeon[choice],3,"air")
--local p = {x=minp.x+(i%chunksize)-1, y=heightmap[ t.y ], z=minp.z+math.floor(i/chunksize), i=t.i};
local i = near_dungeon[choice].i
--print("i = "..i)
local p = {
x = math.floor(t.x + (near_dungeon[choice].sizex / 2)),
y = heightmap[ i ],
z = math.floor(t.z + (near_dungeon[choice].sizez / 2)),
i = i,
}
--print(dump(p))
return {p1={x=p.x - sizex, y=p.y, z=p.z - sizez }, p2=p, sizex=sizex, sizez=sizez, d1=near_dungeon[choice]};
else
-- print("dungeon chance: ".. dungeon_cellar.chance.." dungeon_list: "..#dungeon_list)
--for i=1,#dungeon_list do
-- print("dungeon list:"..minetest.pos_to_string(dungeon_list[i]))
-- end
end
end
dungeon_list = {}
end
local build_type = "default"
@ -903,9 +972,9 @@ witches.bh.simple_hut_place_hut_using_vm = function( data, materials, vm, pr )
end
end
--foundation
for dx = p.x-sizex+2, p.x-2 do
for dz = p.z-sizez+2, p.z-2 do
vm:set_node_at( {x=dx,y=p.y-2,z=dz},floor_materials[1]);
for dx = p.x-sizex, p.x do
for dz = p.z-sizez, p.z do
vm:set_node_at( {x=dx,y=p.y-1,z=dz},floor_materials[1]);
end
end
@ -1068,12 +1137,12 @@ witches.bh.simple_hut_place_hut = function( data, materials, pr )
default.grow_new_jungle_tree(v)
end
elseif math.random() < .2 then
minetest.set_node(v,{name = "default:acacia_tree"})
minetest.spawn_tree(v,witches.acacia_tree)
--print("growing tree at "..minetest.pos_to_string(vector.round(v)))
else
minetest.set_node(v,{name = "default:tree"})
minetest.spawn_tree(v,witches.apple_tree)
--print("growing tree at "..minetest.pos_to_string(vector.round(v)))
@ -1144,16 +1213,19 @@ if(not(minetest.get_modpath("mg_villages"))) then
local res = witches.bh.simple_hut_get_size_and_place( heightmap, minp, maxp);
if( res and res.p1 and res.p2
and res.p2.x>=minp.x and res.p2.z>=minp.z
and res.p2.x<=maxp.x and res.p2.z<=maxp.z) then
and res.p2.x<=maxp.x and res.p2.z<=maxp.z) then
handle_schematics.mark_flat_land_as_used(heightmap, minp, maxp,
res.p2.i,
(res.p2.x-res.p1.x),
(res.p2.z-res.p1.z));
table.insert( house_data, res );
houses_placed = houses_placed + 1;
if res.d1 then
print("res.d1 "..minetest.pos_to_string(res.d1))
end
-- print("res.d1 "..minetest.pos_to_string(res.d1))
end
end
end
-- use the same material around the houses in the entire mapchunk

118
init.lua
View File

@ -5,7 +5,7 @@
local path = minetest.get_modpath("witches")
witches = {}
witches.version = "20200725"
witches.version = "20200726"
print("this is Witches "..witches.version)
-- Strips any kind of escape codes (translation, colors) from a string
@ -62,11 +62,12 @@ dofile(path .. "/items.lua")
dofile(path .. "/nodes.lua")
if not handle_schematics then
print("optional handle_schematics not found!\n Witch cottages not available!")
return
else
dofile(path .. "/basic_houses.lua")
print("handle_schematics found! Witch houses enabled!")
print("handle_schematics found! Witch cottages enabled!")
end
print("enter the witches! version: "..witches.version)
@ -76,7 +77,7 @@ local rnd_colors = witches.rnd_colors
local hair_colors = witches.hair_colors
local spawning = {
generic = {
cottage = {
nodes = {"group:wood","default:mossycobble","default:cobble"},
neighbors = {"air","default:chest","doors:wood_witch_a"},
min_light = 5,
@ -90,16 +91,92 @@ local spawning = {
on_spawn = function(self)
local pos = self.object:get_pos()
print(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos)))
end,
end,
},
generic = {
nodes = {"group:wood","default:mossycobble","default:cobble"},
neighbors = {"air","default:chest"},
min_light = 5,
max_light = 15,
interval = 300,
chance = 10,
active_object_count = 1,
min_height = 0,
max_height = 200,
day_toggle = nil,
on_spawn = function(self)
local pos = self.object:get_pos()
print(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos)))
end
}
}
local witch_types = {
generic = {
description = "Wanderling",
lore = "This witch wanders about the land, for what do they seek?",
additional_properties = {
special_follow = {"default:diamond", "default:gold_lump", "default:apple",
"default:blueberries", "default:torch", "default:stick",
"flowers:mushroom_brown","flowers:mushroom_red"},
do_custom_addendum = function(self)
if math.random() < .0005 and minetest.registered_nodes["fireflies:firefly"] then
local pos = self.object:get_pos()
pos.y = pos.y+1
local pos1 = minetest.find_node_near(pos, 3, "air")
minetest.set_node(pos1, {name = "fireflies:firefly"})
--print("setting firefly"..minetest.pos_to_string(pos1))
end
end,
on_spawn_addendum = function(self)
--print(dump(self.drops).."and"..dump(minetest.registered_tools))
if minetest.registered_tools["fireflies:bug_net"] then
local check = 0
for i=1,#self.drops do
if self.drops[i].name == "fireflies:bug_net" then
check = check +1
end
end
if check < 1 then
table.insert(self.drops,1,
{name = "fireflies:bug_net",
chance = 1000, min = 0, max = 1})
table.insert(self.drops,
{name = "fireflies:firefly_bottle",
chance = 100, min = 0, max = 2})
end
end
end
}
},
cottage = {
description = "Eremitant",
lore = "This witch has found a home for themselves, who would bother them?",
additional_properties = {
special_follow = {"default:diamond", "default:gold_lump", "default:apple",
"default:blueberries", "default:torch", "default:stick",
"flowers:mushroom_brown","flowers:mushroom_red"},
},
spawning = spawning.cottage,
}
}
local witch_template = { --your average witch,
description = "Basic Witch",
lore = "This witch has a story yet to be...",
@ -175,15 +252,23 @@ local witch_template = { --your average witch,
},
follow = {
"default:diamond", "default:gold_lump", "default:apple",
"default:blueberries", "default:torch", "default:stick",
"flowers:mushroom_brown","flowers:mushroom_red"
},
additional_properties = {
special_follow = {"default:diamond", "default:gold_lump", "default:apple",
"default:blueberries", "default:torch", "default:stick",
"flowers:mushroom_brown","flowers:mushroom_red"},
},
on_rightclick = function(self,clicker)
witches.quests(self,clicker)
end,
do_custom = function(self)
if self.do_custom_addendum then
self.do_custom_addendum(self)
end
end,
on_spawn = function(self)
--make sure these are baseline on spawn
--self.animation.walk_speed = 30
@ -245,6 +330,16 @@ local witch_template = { --your average witch,
--print(self.secret_name.." has spawned")
--print("self: "..dump(self.follow))
-- print("self properties "..dump(self.object:get_properties()))
--self.follow = {}
if not self.follow or #self.follow < 1 or type(self.follow) == string then
self.follow = {}
table.insert(self.follow,self.special_follow[math.random(#self.special_follow)])
end
if self.on_spawn_addendum then
self.on_spawn_addendum(self)
end
witches.looking_for(self)
end,
@ -282,6 +377,11 @@ function witches.generate(witch_types,witch_template)
mobs:register_egg("witches:witch_"..k, S("@1 Egg",g_template.description),"default_mossycobble.png", 1)
g_template.spawning.name = "witches:witch_"..k --spawn in the name of the key!
mobs:spawn(g_template.spawning)
if g_template.additional_properties then
for x,y in pairs(g_template.additional_properties) do
minetest.registered_entities["witches:witch_"..k][x] = y
end
end
g_template = {}
end
end

View File

@ -5,12 +5,30 @@ local variance = witches.variance
local rnd_color = witches.rnd_color
local rnd_colors = witches.rnd_colors
witches.witch_hair_styles = {"a","b","c","d","e","f","g","h","p"}
witches.witch_hat_styles = {"a_anim","b","c","d","k"}
witches.witch_hair_styles = {"a","b","c","d","e","f","g","h","p"}
witches.witch_hat_styles = {"a_anim","b","c","d","k"}
local hat_bling = {"band","feather","veil"}
local hair_bling = {}
--[[
minetest.register_tool("witches:witch_wand", {
description = "wand",
inventory_image = "witches_witch_wand.png",
tool_capabilities = {
full_punch_interval = 1.2,
max_drop_level=0,
groupcaps={
--cracky = {times={[2]=1.8, [3]=0.90}, uses=25, maxlevel=1},
},
damage_groups = {fleshy=3},
},
sound = {breaks = "default_tool_breaks"},
--groups = {pickaxe = 1}
})
--]]
local function item_set_animation(self, anim, force)
if not self.animation or not anim then return end
@ -74,12 +92,12 @@ for i,v in pairs(witches.witch_hair_styles) do
},
message = "Default message",
on_step = function(self)
on_step = function(self)
if not self.owner or not self.owner:get_luaentity() then
self.object:remove()
else
local owner = self.owner:get_luaentity()
if owner.state == "stand" and self.state ~= "stand" then
self.state = "stand"
item_set_animation(self, "stand")
@ -99,7 +117,7 @@ for i,v in pairs(witches.witch_hair_styles) do
-- local position,rotation = self.owner:get_bone_position(owner_head_bone)
-- self.object:set_attach(self.owner, owner_head_bone, vector.new(0,0,0), rotation)
end
end
end
}
end
@ -112,7 +130,7 @@ end
local witch_hats = {}
for i,v in pairs(witches.witch_hat_styles) do
for i,v in pairs(witches.witch_hat_styles) do
witch_hats[i] = {
initial_properties = {
--physical = true,
@ -125,7 +143,7 @@ for i,v in pairs(witches.witch_hat_styles) do
},
message = "Default message",
on_step = function(self)
if not self.owner or not self.owner:get_luaentity() then
self.object:remove()
else
@ -147,10 +165,10 @@ for i,v in pairs(witches.witch_hat_styles) do
-- local position,rotation = self.owner:get_bone_position(owner_head_bone)
-- self.object:set_attach(self.owner, owner_head_bone, vector.new(0,0,0), rotation)
end
end
end
}
--print("test: ".. string.find("anim", v) )
if string.find(v, "anim") then
if string.find(v, "anim") then
witch_hats[i].animation = {
stand_speed = 1,
@ -184,7 +202,7 @@ witch_tool = {
pointable = false,
collisionbox = {0,0,0,0,0,0},
visual = "wielditem",
visual_size = {x = 0.3, y = 0.3},
wield_item = "default:stick",
--inventory_image = "default_tool_woodpick.png",
@ -194,7 +212,7 @@ witch_tool = {
if not self.owner or not self.owner:get_luaentity() then
self.object:remove()
end
end
end
}
@ -208,7 +226,7 @@ minetest.register_entity("witches:witch_tool",witch_tool)
function witches.attach_hair(self,item)
self.head_bone = "Head"
local item = item or "witches:witch_hair"
local hair = minetest.add_entity(self.object:get_pos(), item)
local hair = minetest.add_entity(self.object:get_pos(), item)
hair:set_attach(self.object, "Head", vector.new(0,4.5,0), vector.new(0,180,0))
local hair_ent = hair:get_luaentity()
if not hair_ent then
@ -216,17 +234,17 @@ function witches.attach_hair(self,item)
end
hair_ent.owner = self.object
--print("HAT: "..dump(hair_ent))
local he_props = hair_ent.object:get_properties()
local he_props = hair_ent.object:get_properties()
--print("he props: "..dump(he_props))
local hair_size = variance(95, 105)
local hair_mods = ""
local hair_bling = hair_bling or {}
if not hair_ent.hair_color then
hair_ent.hair_color = self.hair_color
hair_ent.hair_color = self.hair_color
hair_ent.object:set_texture_mod("^witches_witch_hair_"..hair_ent.hair_color..".png")
end
--[[
self.hair_mods = hair_mods
@ -247,7 +265,7 @@ end
function witches.attach_hat(self,item)
self.head_bone = "Head"
local item = item or "witches:witch_hat"
local hat = minetest.add_entity(self.object:get_pos(), item)
local hat = minetest.add_entity(self.object:get_pos(), item)
hat:set_attach(self.object, "Head", vector.new(0,4.5,0), vector.new(0,180,0))
local hat_ent = hat:get_luaentity()
if not hat_ent then
@ -255,12 +273,12 @@ function witches.attach_hat(self,item)
end
hat_ent.owner = self.object
--print("HAT: "..dump(hat_ent))
local he_props = hat_ent.object:get_properties()
local he_props = hat_ent.object:get_properties()
--print("he props: "..dump(he_props))
local hat_size = variance(90, 120)
local hat_mods = ""
for i,v in pairs(hat_bling) do
if v == "veil" and math.random() < 0.1 then
if v == "veil" and math.random() < 0.1 then
hat_mods = hat_mods.."^witches_witch_hat_"..v..".png"
else
if v ~= "veil" and math.random() < 0.5 then
@ -282,7 +300,7 @@ end
function witches.attach_tool(self,item)
item = item or "witches:witch_tool"
local tool = minetest.add_entity(self.object:get_pos(), item)
local tool = minetest.add_entity(self.object:get_pos(), item)
tool:set_attach(self.object, "Arm_Right", {x=0.3, y=4.0, z=2}, {x=-100, y=225, z=90})
tool:get_luaentity().owner = self.object
end

14
settingtypes.txt Normal file
View File

@ -0,0 +1,14 @@
# chance (1-99) of a witch house spawning over a dungeon instead of anywhere else (requires Sokomines handle_schematics mod!)
witches_dungon_cellar_chance (chance as decimal like .5 of a witch house spawning over a dungeon instead of anywhere else) float .5
# depth (1-20) maximum depth of a dungeon to spawn a witch house over (requires Sokomines handle_schematics mod!)
witches_dungon_cellar_depth (maximum depth 0 to -20 of a dungeon to spawn a witch house over) int -5
#maximum number of houses per mapchunk
witches_house_max_per_mapchunk (maximum number of houses per mapchunk) int 2
#average number of houses to mapchunks over the world
witches_houses_wanted_per_mapchunk (average number of houses to mapchunks over the world) float .05

View File

@ -160,7 +160,7 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
local meta = stack:get_meta()
--boost the stats!
local capabilities = stack:get_tool_capabilities()
local bonuses = {}
for x,y in pairs(capabilities) do
if x == "groupcaps" then
@ -168,10 +168,10 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
--print(dump(a).." is "..dump(b).."\n---")
if b and b.uses then
--print("original uses: "..capabilities.groupcaps[a].uses)
capabilities.groupcaps[a].uses = b.uses + 10
--print("boosted uses: "..capabilities.groupcaps[a].uses)
--print(dump(a).." is now "..dump(b))
end
if b and b.times then
@ -183,7 +183,7 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
-- print("boosted time:".. v )
end
capabilities.groupcaps[a].times[i] = v
end
end
end
end
elseif x == "damage_groups" then
@ -191,7 +191,7 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
--print(dump(a.." = "..capabilities.damage_groups[a]))
capabilities.damage_groups[a] = b + math.random(0,1)
--print(dump(capabilities.damage_groups[a]))
end
end
end
end
meta:set_tool_capabilities(capabilities)
@ -202,7 +202,7 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
"description", S("@1's @2 @3", self.secret_name, tool_adj, org_desc)
)
--minetest.chat_send_player()
local inv = minetest.get_inventory({ type="player", name= pname })
local inv = minetest.get_inventory({ type="player", name= pname })
local reward_text = {}
local reward = {}
for i,_ in pairs(inv:get_lists()) do
@ -231,6 +231,70 @@ function witches.special_gifts(self, pname, drop_chance, max_drops)
end
end
function witches.gift(self, pname, drop_chance_min, drop_chance_max, item_wear )
if not pname then
print("no player defined!")
return
end
if not self.drops then
print("no droplist defined in this mob!")
return
end
local list = {}
local reward_text = {}
local reward_item = {}
local reward = {}
local inv = minetest.get_inventory({ type="player", name= pname })
local pos = self.object:getpos()
pos.y = pos.y + 0.5
drop_chance_min = drop_chance_min or 0
drop_chance_max = drop_chance_max or 100
for i=1,#self.drops do
if self.drops[i].chance <= drop_chance_max and
self.drops[i].chance >= drop_chance_min then
table.insert(list,self.drops[i])
end
end
local item_name = list[math.random(#list)].name
local item_wear = item_wear or math.random(8000,10000)
local stack = ItemStack({name = item_name, wear = item_wear })
local org_desc = minetest.registered_items[item_name].description
local meta = stack:get_meta()
meta:set_string(
"description", S("@1's @2", self.secret_name, org_desc)
)
print("stack meta "..dump(meta))
for i=1,#inv:get_lists() do
--print(i.." = "..dump(v))
if i == "main" and stack and inv:room_for_item(i, stack) then
reward_text = S("You are rewarded with @1",meta:get_string("description"))
--print("generated text: "..reward_text)
reward_item = stack:get_name()
--print("generated:"..stack:get_name())
reward = {r_text = reward_text, r_item = reward_item}
inv:add_item(i,stack)
return reward
else
end
end
reward_text = S("You are rewarded with @1, but you cannot carry it",meta:get_string("description"))
--print("generated text: "..reward_text)
reward_item = stack:get_name()
--print("generated:"..stack:get_name())
reward = {r_text = reward_text, r_item = reward_item}
minetest.add_item(pos, stack)
--print("generated text: "..reward_text)
return reward
end
function witches.attachment_check(self)
if not self.owner or not self.owner:get_luaentity() then
self.object:remove()
@ -280,7 +344,7 @@ end
function witches.found_item(self,clicker)
local item = clicker:get_wielded_item()
if item and item:get_name() == self.item_request.item.name then
local pname = clicker:get_player_name()
if not minetest.settings:get_bool("creative_mode") then
@ -288,27 +352,31 @@ function witches.found_item(self,clicker)
clicker:set_wielded_item(item)
end
if not self.players then
self.players = {}
if not self.players then
self.players = {}
--print("no records")
end
if not self.players[pname] then
self.players[pname] = {}
if not self.players[pname] then
self.players[pname] = {}
--print("no records 2")
end
--print(dump(self.players))
if not self.players[pname].favors then
if not self.players[pname].favors then
self.players[pname] = { favors = 0 }
end
self.players[pname].favors = self.players[pname].favors + 1
local reward = {}
--print(self.secret_name.." has now received 2 favors"..self.players[pname].favors.." from " ..pname)
--if self.players[pname].favors >=3 and math.fmod(18, self.players[pname].favors) == 0 then
if self.players[pname].favors >=3 and math.fmod(18, self.players[pname].favors) == 0 then
reward = witches.special_gifts(self,pname)
else
reward = witches.gift(self,pname)
--print(reward_text)
end
if reward and reward.r_text then
self.players[pname].reward_text = reward.r_text
end
@ -321,6 +389,11 @@ function witches.found_item(self,clicker)
witches.found_item_quest.show_to(self, clicker)
self.item_request = nil
--change the requested item
if self.special_follow then
self.follow = {}
table.insert(self.follow,self.special_follow[math.random(#self.special_follow)])
end
return item
end
@ -332,11 +405,11 @@ function witches.looking_for(self)
self.item_request = {}
end
if not self.item_request.item then
if self.follow then
if self.follow and #self.follow >= 1 then
--print("testing: "..type(self.follow).." "..#self.follow.." "..dump(self.follow).." "..math.random(1,#self.follow))
local item = self.follow[math.random(1,#self.follow)]
--local stack = ItemStack({name = item})
--print("item: "..item)
local find = {name = minetest.registered_items[item].name, desc = minetest.registered_items[item].description, icon = minetest.registered_items[item].inventory_image}
--local meta = item:get_meta()
--print_s(S(dump(desc)))
@ -344,7 +417,11 @@ function witches.looking_for(self)
self.item_request.item = find
return self.item_request
else
if not self.follow or #self.follow < 1 then
table.insert(self.follow,self.special_follow[math.random(#self.special_follow)])
end
end
else
@ -357,7 +434,7 @@ function witches.quests(self, clicker)
local pname = clicker:get_player_name()
--print(pname.." clicked on a witch!")
local item = clicker:get_wielded_item()
local pos = clicker:getpos()
local pos = clicker:getpos()
stop_and_face(self,pos)
--make sure we are looking for an item
@ -374,7 +451,7 @@ function witches.quests(self, clicker)
--print("we are holding a "..dump(item:get_name()))
if item:get_name() ~= self.item_request.item.name then
--create the dialog
--create the dialog
witches.item_request(self,pname)
--we can now show the quest!
witches.find_item_quest.show_to(self, pname)