Merge branch 'master' into 'use_animal_mods'

# Conflicts:
#   init.lua
#   mod.conf
master
Francisco 2022-02-16 02:50:15 +00:00
commit eb141f8746
13 changed files with 1142 additions and 1391 deletions

View File

@ -1,6 +1,6 @@
# [witches] Witches (Mobs Redo addon) [mod] for Minetest # [witches] Witches (Mobs Redo addon) [mod] for Minetest
Witches is copyright 2020 Francisco Athens, Ramona Athens, Damon Athens and Simone Athens Witches is copyright 2022 Francisco Athens, Ramona Athens, Damon Athens and Simone Athens
The MIT License (MIT) The MIT License (MIT)
* code/issue tracking :https://gitlab.com/freelikegnu/witches * code/issue tracking :https://gitlab.com/freelikegnu/witches
@ -13,16 +13,12 @@ Witches inhabit the land! They are currently in development but, can already:
* Witches have magic! They will defend themselves and each other against aggressive players and mobs! * Witches have magic! They will defend themselves and each other against aggressive players and mobs!
* If you are repeatedly helpful to a witch... * If you are repeatedly helpful to a witch something good is likely to happen!
* Witch cottages adapted from Sokomine's basic_houses: * New Witch cottage code with no additional mod requirements!
(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
Settings provided from settings menu!
* If protector (or similar) mod is available and enabled, Witches will no build in these areas!
* Some cottages will spawn over a dungeon if they are near the surface * Some cottages will spawn over a dungeon if they are near the surface
* Have a name and origin location which they will tell player. * Have a name and origin location which they will tell player.
@ -43,8 +39,7 @@ Witches inhabit the land! They are currently in development but, can already:
* Mobs Redo git repository: https://notabug.org/TenPlus1/mobs_redo * Mobs Redo git repository: https://notabug.org/TenPlus1/mobs_redo
## Optional Mods: ## Optional Mods:
* For Witches Cottages: Sokomine's handle_schematics mod (GPLv3) * protector (or similar) - to prevent Witches from placing cottages in protected areas!
* git repository: https://github.com/Sokomine/handle_schematics
* Any mobs from any mobs mod attacking Witches may be turned into a sheep! * Any mobs from any mobs mod attacking Witches may be turned into a sheep!
@ -72,10 +67,6 @@ Witches inhabit the land! They are currently in development but, can already:
* sheep.lua code adapted from mobs_animals by TenPlus1 and authors credited in sheep.lua * sheep.lua code adapted from mobs_animals by TenPlus1 and authors credited in sheep.lua
* Witch houses code adapted from Sokomine's basic_houses
(https://github.com/Sokomine/basic_houses) mod under MIT license
with permission from author.
* Sound files: * Sound files:
witches_magic01.ogg MATRIXXX_ December 28th, 2018 CC-BY 3.0 witches_magic01.ogg MATRIXXX_ December 28th, 2018 CC-BY 3.0
https://freesound.org/people/MATRIXXX_/sounds/455205/ https://freesound.org/people/MATRIXXX_/sounds/455205/

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,7 @@
2022/02/14: Dialog updates
2022/02/13: Debug output can be enabled from game Settings tab > All Settings > Mods > witches
2022/02/12: Witches honor protected nodes ("protector" mod support)
2020/08/10: Testing new cottage building code.
2020/08/06: Fixed witches not registered when handle_schematics is not loaded! D'oh! 2020/08/06: Fixed witches not registered when handle_schematics is not loaded! D'oh!
2020/08/01: Witches have two new wands from Damon and Simone! 2020/08/01: Witches have two new wands from Damon and Simone!
2020/07/31: Witches can turn aggressive mobs into sheep! Witches gain drench spell! 2020/07/31: Witches can turn aggressive mobs into sheep! Witches gain drench spell!

959
cottages.lua Normal file
View File

@ -0,0 +1,959 @@
--this file is copyright (c) 2020 Francisco Athens licensed under the terms of the MIT license
local witches_dungeon_cellar_chance = tonumber(minetest.settings:get("witches_dungeon_cellar_chance")) or .50
local witches_dungeon_cellar_depth = tonumber(minetest.settings:get("witches_dungeon_cellar_depth")) or -5
local function mts(table)
local output = minetest.serialize(table)
return output
end
local function mtpts(table)
local output = minetest.pos_to_string(table)
return output
end
--lets see if any dungeons are near
minetest.set_gen_notify("dungeon")
local dungeon_cellar = {
chance = tonumber(witches_dungeon_cellar_chance), -- chance to try putting cottage over dungeon instead of anywhere else
max_depth = tonumber(witches_dungeon_cellar_depth) -- deepest dungeon depth to check
}
local dungeon_list ={}
minetest.register_on_generated(function(minp, maxp, blockseed)
local dg = minetest.get_mapgen_object("gennotify")
if dg and dg.dungeon and #dg.dungeon > 2 then
for i=1,#dg.dungeon do
if dg.dungeon[i].y >= dungeon_cellar.max_depth then
print("dungeon found: "..minetest.pos_to_string(dg.dungeon[i]))
table.insert(dungeon_list, dg.dungeon[i])
end
end
end
end)
--local vol_vec = {x=5,y=5,z=5}
function witches.grounding(self,vol_vec,required_list,exception_list,replacement_node)
local r_tweak = math.random(-1,1)
local area = vol_vec or {x=math.random(5+r_tweak,9),y=1,z=math.random(5-r_tweak,9)}
local pos = vector.round(self.object:get_pos())
--drop checks below sea level
if pos.y < 0 then return end
--local yaw = self.object:get_yaw()
--print(mts(self.object:get_yaw()))
local pos1 = {x= pos.x-(area.x/2),y=pos.y-area.y ,z= pos.z-(area.z/2)}
local pos2 = {x= pos.x+(area.x/2),y=pos.y, z= pos.z+(area.z/2)}
local ck_pos1 = vector.subtract(pos1,4)
local ck_pos2 = vector.add(pos2,4)
--ck_pos2.y = ck_pos2.y + 12
--print("pos = ".. mtpts(pos))
--print("pos1 = ".. mtpts(pos1))
--print("pos2 = ".. mtpts(pos2))
--test if area is suitable (no air or water)
local rlist = required_list or {"soil","crumbly"}
local elist = exception_list or {"group:stone","group:cracky","group:wood", "group:tree"}
local exceptions = minetest.find_nodes_in_area_under_air(ck_pos1, ck_pos2,elist)
local protected_area = minetest.is_area_protected(ck_pos1, ck_pos2, "", 2)
if #exceptions and #exceptions >= 1 then
witches.debug("exceptions count = "..#exceptions)
return
elseif protected_area then
witches.debug("protected area found at "..mtpts(protected_area))
return
else
witches.debug("SUCCESS!".."pos1 = ".. mtpts(pos1).."pos2 = ".. mtpts(pos2))
local volume = {pos1,pos2}
local ck_volume = {ck_pos1,ck_pos2}
return volume,ck_volume
end
end
local cottage_id = nil
local default_params = {
--plan_size = {x=9, y=7 ,z=9}, --general size not including roof
foundation_nodes = {"default:mossycobble"},
foundation_depth = 3,
porch_nodes = {"default:tree","default:pine_tree","default:acacia_tree"},
porch_size = 2,
first_floor_nodes = {"default:cobble","default:wood","default:pine_wood","default:acacia_wood","default:junglewood"},
second_floor_nodes = {"default:wood","default:pine_wood","default:acacia_wood","default:junglewood"},
gable_nodes = {"default:wood","default:junglewood"},
roof_nodes = {"stairs:stair_wood","stairs:stair_junglewood"},
roof_slabs = {"stairs:slab_wood","stairs:slab_junglewood"},
wall_nodes = {"default:tree","default:pine_tree","default:acacia_tree"},
wall_nodes_ftype = {"wall_wdir"}, --wall_dir, wall_fdir, wall_wdir
wall_height = 3,
window_nodes = {"default:fence_wood","default:fence_pine_wood","default:fence_acacia_wood","default:fence_junglewood"},
window_height = {1,2}, --height min, height max
orient_materials = true,
door_bottom = "doors:door_wood_witch_a";
door_top = "doors:hidden";
root_nodes = {"witches:treeroots"};
builder = "none"
}
function witches.generate_cottage(secret_name,pos1,pos2,params)
local working_parameters = params or default_params -- if there is nothing then initialize with defs
pos1 = vector.round(pos1)
pos2 = vector.round(pos2)
local wp = working_parameters
if params then --get defaults for any missing params
for k,v in default_params do
if not params[k] then
wp[k] = table.copy(default_params[k])
end
end
else wp = table.copy(default_params)
end
local ps = wp.porch_size or math.random(2)
local wall_node = wp.wall_nodes[math.random(#wp.wall_nodes)]
local root_node = wp.root_nodes [math.random(#wp.root_nodes)]
local window_node = wp.window_nodes[math.random(#wp.window_nodes)]
local window_height = wp.window_height[math.random(#wp.window_height)]
--start with basement
--local od = vector.subtract(pos2,pos1)
local lower_corner_nodes = {
{x= pos1.x, y = pos1.y, z = pos1.z},
{x= pos1.x, y = pos1.y, z = pos2.z},
{x= pos2.x, y = pos1.y, z = pos2.z},
{x= pos2.x, y = pos1.y, z = pos1.z},
}
local upper_corner_nodes = {
{x= pos1.x, y = pos2.y, z = pos1.z},
{x= pos1.x, y = pos2.y, z = pos2.z},
{x= pos2.x, y = pos2.y, z = pos2.z},
{x= pos2.x, y = pos2.y, z = pos1.z},
}
local ucn = upper_corner_nodes
for h=1, wp.foundation_depth do
for i=1, #ucn do
local pos = {x=ucn[i].x, y=ucn[i].y-h+1,z=ucn[i].z}
minetest.set_node(pos,{name=wp.foundation_nodes[math.random(#wp.foundation_nodes)]})
end
end
for h=1, wp.foundation_depth do
for i=1, #ucn do
local pos = {x=ucn[i].x, y=ucn[i].y-h+1,z=ucn[i].z}
minetest.set_node(pos,{name=wp.foundation_nodes[math.random(#wp.foundation_nodes)]})
end
end
-- clear the area
local cpos1 = {x = pos1.x-ps, y=pos2.y ,z=pos1.z-ps}
local cpos2 = {x = pos2.x+ps, y=pos2.y+13, z=pos2.z+ps}
local carea = vector.subtract(cpos2,cpos1)
for h=1,carea.y+2 do
for i=1, carea.z+1 do
for j=1, carea.x+1 do
local pos = {x=cpos1.x+j-1, y=cpos1.y+h, z=cpos1.z+i-1}
minetest.set_node(pos,{
name="air"
})
end
end
end
-- porch
local prnodes = wp.porch_nodes[math.random(#wp.porch_nodes)]
local ppos1 = {x = pos1.x-ps, y=pos2.y ,z=pos1.z-ps}
local ppos2 = {x = pos2.x+ps, y=pos2.y, z=pos2.z+ps}
local parea = vector.subtract(ppos2,ppos1)
for i=1, parea.z+1 do
for j=1, parea.x+1 do
local pos = {x=ppos1.x+j-1, y=ppos1.y, z=ppos1.z+i-1}
minetest.set_node(pos,{
name=prnodes,
paramtype2="facedir",
param2=5
})
end
end
local pcn = {
{x= pos1.x-ps, y = pos2.y, z = pos1.z-ps},
{x= pos1.x-ps, y = pos2.y, z = pos2.z+ps},
{x= pos2.x+ps, y = pos2.y, z = pos2.z+ps},
{x= pos2.x+ps, y = pos2.y, z = pos1.z-ps},
}
local pcn_height = wp.foundation_depth + 1
for h=1, pcn_height do
for i=1, #pcn do
local pos = {x=pcn[i].x, y=pcn[i].y+2-h,z=pcn[i].z}
minetest.set_node(pos,{name=wall_node})
minetest.set_node({x=pos.x, y=pos.y-1, z=pos.z},{name=root_node})
end
end
local function mr(min,max)
local v = math.random(min,max)
return v
end
local treecn = {
{x= pcn[1].x-ps+mr(-1,1), y = pos2.y-1, z = pcn[1].z-ps+mr(-1,1)},
{x= pcn[2].x-ps+mr(-1,1), y = pos2.y-1, z = pcn[2].z+ps+mr(-1,1)},
{x= pcn[3].x+ps+mr(-1,1), y = pos2.y-1, z = pcn[3].z+ps+mr(-1,1)},
{x= pcn[4].x+ps+mr(-1,1), y = pos2.y-1, z = pcn[4].z-ps+mr(-1,1)},
}
local tree_pos = treecn[math.random(#treecn)]
local root_pos = vector.new(tree_pos)
root_pos.y = root_pos.y-1
minetest.spawn_tree(tree_pos,witches.acacia_tree)
minetest.set_node(root_pos,{name =root_node})
--first floor!
local ffnodes = wp.first_floor_nodes[math.random(#wp.first_floor_nodes)]
local ffpos1 = {x = pos1.x, y=pos2.y ,z=pos1.z}
local ffpos2 = {x = pos2.x, y=pos2.y, z=pos2.z}
local area = vector.subtract(pos2,pos1)
for i=1, area.z+1 do
for j=1, area.x+1 do
local pos = {x=ffpos1.x+j-1, y=ffpos1.y, z=ffpos1.z+i-1}
minetest.set_node(pos,{
name=ffnodes,
paramtype2="facedir",
param2=5
})
end
end
--local wall_node = wp.wall_nodes[math.random(#wp.wall_nodes)]
if math.random() < 0.9 then
--wall corners wood
for h=1, wp.wall_height do
for i=1, #ucn do
if h % 2 == 0 then
local pos = {x=ucn[i].x, y=ucn[i].y+h,z=ucn[i].z}
minetest.set_node(pos,{
name=wall_node,
paramtype2="facedir",
param2=5
})
else
local pos = {x=ucn[i].x, y=ucn[i].y+h,z=ucn[i].z}
minetest.set_node(pos,{
name=wall_node,
paramtype2="facedir",
param2=13
})
end
end
end
else
--wall corners stone
for h=1, wp.wall_height do
for i=1, #ucn do
local pos = {x=ucn[i].x, y=ucn[i].y+h,z=ucn[i].z}
minetest.set_node(pos,{name=wp.foundation_nodes[math.random(#wp.foundation_nodes)]})
end
end
end
--create first floor wall plan!
local wall_plan ={}
for i=1,area.z-1 do --west wall
local pos = {x=ffpos1.x, y=ffpos1.y+1, z=ffpos1.z+i}
local fpos = {x=ffpos1.x, y=ffpos1.y+1, z=ffpos1.z-1}
local dir = vector.direction(fpos,pos) -- the raw dir we can manipulate later
local facedir = minetest.dir_to_facedir(dir) --this facedir
--walldir is for placing tree nodes in wall direction
table.insert(wall_plan, {
pos = pos, dir = dir, facedir = facedir, walldir = 5
})
end
for i=1,area.x-1 do --north wall
local pos = {x=ffpos1.x+i, y=ffpos1.y+1, z=ffpos1.z}
local fpos = {x=ffpos1.x-1, y=ffpos1.y+1, z=ffpos1.z}
local dir = vector.direction(fpos,pos)
local facedir = minetest.dir_to_facedir(dir)
table.insert(wall_plan, {
pos = pos, dir = dir, facedir = facedir, walldir = 13
})
end
for i=1,area.z-1 do --east wall
local pos = {x=ffpos1.x+area.x, y=ffpos1.y+1, z=ffpos1.z+i}
local fpos = {x=ffpos1.x+area.x, y=ffpos1.y+1, z=ffpos1.z-1}
local dir = vector.direction(fpos,pos)
local facedir = minetest.dir_to_facedir(dir)
table.insert(wall_plan, {
pos = pos, dir = dir, facedir = facedir, walldir = 5
})
end
for i=1,area.x-1 do --south wall
local pos = {x=ffpos1.x+i, y=ffpos1.y+1, z=ffpos1.z+area.z}
local fpos = {x=ffpos1.x-1, y=ffpos1.y+1, z=ffpos1.z+area.z}
local dir = vector.direction(fpos,pos)
local facedir = minetest.dir_to_facedir(dir)
table.insert(wall_plan, {
pos = pos, dir = dir, facedir = facedir, walldir = 13
})
end
for h=1, wp.wall_height do
for i=1, #wall_plan do
minetest.set_node(wall_plan[i].pos,{
name=wall_node,
paramtype2 = "facedir",
param2 = wall_plan[i].walldir
})
end
for i=1, #wall_plan do
wall_plan[i].pos.y = wall_plan[i].pos.y+1
end
end
--possible door locations, extra offset data
local p_door_pos = {
w = {x = ffpos1.x, z = ffpos1.z+math.random(2,area.z-2), y = ffpos1.y+1, p ="z", fp={"x",-1}},
n = {x = ffpos1.x+math.random(2,area.x-2), z = ffpos2.z, y = ffpos1.y+1, p ="x", fp={"z",1}},
e = {x = ffpos2.x, z = ffpos1.z+math.random(2,area.z-2), y = ffpos1.y+1, p ="z", fp={"x",1}},
s = {x = ffpos1.x+math.random(2,area.x-2), z = ffpos1.z, y = ffpos1.y+1, p ="x", fp={"z",-1}}
}
local door_pos = {}
local test = 4
for k,v in pairs(p_door_pos) do
if test >= 1 and math.random(test) == 1 then
door_pos[k]=v
test = 0
else
test = test - 1
end
end
--local door_pos= p_door_pos
witches.debug("door: "..mts(door_pos))
for k,v in pairs(door_pos) do
witches.debug(mts(v))
local f_pos1 = vector.new(v)
--get the offsets
f_pos1[v.fp[1] ] = f_pos1[v.fp[1] ] + v.fp[2]
local dir=vector.direction(f_pos1,door_pos[k])
local f_facedir = minetest.dir_to_facedir(dir)
minetest.set_node(v,{
name=wp.door_bottom,
paramtype2 = "facedir",
param2 = f_facedir
})
local door_pos_t = vector.new(v)
door_pos_t.y = door_pos_t.y+1
minetest.set_node(door_pos_t,{
name=wp.door_top,
paramtype2 = "facedir",
param2 = f_facedir
})
--set some torch-like outside the door
local t_pos1 = vector.new(v)
--use fp to get outside
t_pos1[v.fp[1] ]= t_pos1[v.fp[1] ] + (v.fp[2])
--get wallmount param2
local t_dir = vector.direction(t_pos1,v)
local t_wm = minetest.dir_to_wallmounted(t_dir)
t_pos1.y = t_pos1.y + 1
--offset from door
local t_pos2 = vector.new(t_pos1)
t_pos1[v.p] = t_pos1[v.p] - 1
t_pos2[v.p] = t_pos2[v.p] + 1
minetest.bulk_set_node({t_pos1, t_pos2},{
name="default:torch_wall",
--paramtype2 = "facedir",
param2 = t_wm
})
end
--set windows
local window_pos = {w ={},n={},e={},s={}}
local az = math.floor((area.z-2)/2)
local ax = math.floor((area.x-2)/2)
witches.debug("az/ax= "..az.." "..ax)
for i=1, az do
local wz = {x = ffpos1.x, z = ffpos1.z+math.random(2,area.z-2), y = ffpos1.y+2, p= "z", fp = {"x", 1} }
table.insert(window_pos.w,wz)
local ez = {x = ffpos2.x, z = ffpos1.z+math.random(2,area.z-2), y = ffpos1.y+2, p= "z", fp = {"x", -1} }
table.insert(window_pos.e, ez)
end
for i=1, ax do
local nx = {x = ffpos1.x+math.random(2,area.x-2), z = ffpos2.z, y = ffpos1.y+2, p= "x", fp = {"z", -1} }
table.insert(window_pos.n,nx)
local sx = {x = ffpos1.x+math.random(2,area.x-2), z = ffpos1.z, y = ffpos1.y+2, p= "x", fp = {"z", 1} }
table.insert(window_pos.s,sx)
end
witches.debug(mts(window_pos))
for k,v in pairs(door_pos) do
--v is the door pos vector table
for i=v[v.p]+1,v[v.p]-1,-1 do --start with lateral axis (p) pos on either side of door
witches.debug("doorpos "..v.p.." "..i)
for j,_ in ipairs(window_pos[k]) do --we want the vector table value of each
witches.debug("windowpos "..mts(window_pos[k][j]).." vs "..i)
if window_pos[k][j] and i == window_pos[k][j][v.p] then
witches.debug("windowpos "..window_pos[k][j][v.p].." vs "..i)
witches.debug("removing window_pos[k][j][v.p] = ".. mtpts(window_pos[k][j]))
--table.remove(window_pos[k],j)
window_pos[k][j] = nil
end
end
end
end
if window_pos then
for k,_ in pairs(window_pos) do
for _,v in pairs(window_pos[k]) do
for i=1,window_height do
witches.debug("window set: "..mtpts(v))
minetest.set_node({x= v.x, y=v.y-1+i, z=v.z},{
name=window_node
})
end
end
end
end
--set some torch-like inside near window
if window_pos then
for k,_ in pairs(window_pos) do
for _,v in ipairs(window_pos[k]) do
local t_pos1 = vector.new(v)
--use fp to get inside
t_pos1[v.fp[1] ]= t_pos1[v.fp[1] ] + (v.fp[2])
local t_pos2 = vector.new(t_pos1)
--get wallmount param2
local t_dir = vector.direction(t_pos1,v)
local t_wm = minetest.dir_to_wallmounted(t_dir)
t_pos1[v.p] = t_pos1[v.p] - 1
t_pos2[v.p] = t_pos2[v.p] + 1
local ck_pos1 = vector.new(v)
ck_pos1[v.p] = ck_pos1[v.p] - 1
local ck_pos2 = vector.new(v)
ck_pos2[v.p] = ck_pos1[v.p] + 1
if math.random() < .5 then
local ck = minetest.get_node(ck_pos1)
witches.debug("ck: "..ck.name)
if ck.name ~= window_node then
minetest.set_node(t_pos1,{
name="default:torch_wall",
--paramtype2 = "facedir",
param2 = t_wm
})
end
else
local ck = minetest.get_node(ck_pos2)
witches.debug("ck: "..ck.name)
if ck.name ~= window_node then
minetest.set_node(t_pos2,{
name="default:torch_wall",
--paramtype2 = "facedir",
param2 = t_wm
})
end
end
end
end
end
local furnace_pos = {} --gonna need this later!
--place some furniture
if window_pos then
local furniture = {"default:bookshelf","default:chest_locked","beds:bed","default:furnace"}
local f_pos1 ={}
for j in pairs(window_pos) do
for k,v in ipairs(window_pos[j]) do
if furniture and #furniture >= 1 then
f_pos1 = vector.new(v)
f_pos1[v.fp[1] ] = f_pos1[v.fp[1] ]+v.fp[2]
f_pos1.y = f_pos1.y-1
witches.debug("window:"..mtpts(v))
witches.debug("furniture:"..mtpts(f_pos1))
local dir1=vector.direction(f_pos1,v)
local dir2=vector.direction(v,f_pos1)
local f_facedir1 = minetest.dir_to_facedir(dir1)
local f_facedir2 = minetest.dir_to_facedir(dir2)
local f_num = math.random(#furniture)
local f_name = furniture[f_num]
if f_name == "beds:bed" then
local f_pos2 = vector.new(f_pos1)
if math.random()<0.001 then
f_pos2[v.fp[1] ] = f_pos2[v.fp[1] ]+v.fp[2]
else
f_pos2[v.p] = f_pos2[v.p] + v.fp[2] --bed along wall_nodes
dir1=vector.direction(f_pos2,f_pos1)
dir2=vector.direction(f_pos1,f_pos2)
f_facedir1 = minetest.dir_to_facedir(dir1)
f_facedir2 = minetest.dir_to_facedir(dir2)
end
minetest.set_node(f_pos1,{
name=f_name,
paramtype2 = "facedir",
param2 = f_facedir2
})
witches.debug("bed1:"..mtpts(f_pos1))
witches.debug("bed2:"..mtpts(f_pos2))
minetest.set_node(f_pos2,{
name=f_name,
paramtype2 = "facedir",
param2 = f_facedir1
})
elseif f_name == "default:furnace" then
f_pos1[v.fp[1] ] = f_pos1[v.fp[1] ]-v.fp[2]
minetest.set_node(f_pos1,{
name=f_name,
paramtype2 = "facedir",
param2 = f_facedir1
})
furnace_pos = vector.new(f_pos1)
elseif f_name == "default:chest_locked" then
minetest.set_node(f_pos1,{
name=f_name,
paramtype2 = "facedir",
param2 = f_facedir1
})
minetest.registered_nodes[ f_name ].on_construct( f_pos1 );
local meta = minetest.get_meta(f_pos1);
local inv = meta:get_inventory();
meta:set_string("secret_type", "witches_chest")
meta:set_string("secret_name", secret_name)
meta:set_string("owner",secret_name)
meta:set_string("infotext", "Sealed chest of "..secret_name)
if minetest.get_modpath("fireflies") then
inv:add_item( "main", {name = "fireflies:bug_net"})
end
inv:add_item( "main", {name = "default:meselamp"})
if math.random() < 0.50 then
for i=1,math.random(3) do
inv:add_item( "main", {name = "default:diamond"})
end
end
elseif f_name ~="beds:bed" then
minetest.set_node(f_pos1,{
name=f_name,
paramtype2 = "facedir",
param2 = f_facedir1
})
end
table.remove(furniture, f_num)
end
end
end
end
-- second_floor!
local sfnodes = wp.second_floor_nodes[math.random(#wp.second_floor_nodes)]
local sfpos1 = {x = ffpos1.x, y=ffpos2.y+wp.wall_height,z=ffpos1.z}
local sfpos2 = {x = ffpos2.x, y=ffpos2.y+wp.wall_height, z=ffpos2.z}
local sfarea = vector.subtract(sfpos2,sfpos1)
--
for i=1, sfarea.z+1 do
for j=1, sfarea.x+1 do
local pos = {x=sfpos1.x+j-1, y=sfpos1.y+1, z=sfpos1.z+i-1}
minetest.set_node(pos,{
name=sfnodes,
paramtype2="facedir",
param2=5
})
end
end
--
--[[
for h=1, wp.wall_height-1 do
for i=1, #ucn do
local pos = {x=ucn[i].x, y=ucn[i].y+h+1+wp.wall_height,z=ucn[i].z}
minetest.set_node(pos,{name=wp.foundation_nodes[math.random(#wp.foundation_nodes)]})
end
end
--]]
local stovepipe_pos = {}
--gable and roof
--orientation
local rfnum = math.random(#wp.roof_nodes)
local rfnodes = wp.roof_nodes[rfnum]
local rfslabs = wp.roof_slabs[rfnum]
local gbnodes = wp.gable_nodes[rfnum]
local orientations = {{"x","z"},{"z","x"}}
local o = orientations[math.random(#orientations)]
local gbpos1 = vector.new({x = sfpos1.x, y=sfpos2.y+1, z=sfpos1.z})
local gbpos2 = vector.new({x = sfpos2.x, y=sfpos2.y+1, z=sfpos2.z}) --this is going to change while building
local rfpos1 = vector.new({x = sfpos1.x-1, y=sfpos2.y, z=sfpos1.z-1})
local rfpos2 = vector.new({x = sfpos2.x+1, y=sfpos2.y, z=sfpos2.z+1}) --this is going to change while building
local rfarea = vector.subtract(rfpos2,rfpos1)
local gbarea = vector.subtract(gbpos2,gbpos1)
local l_pos = {}
local rfaz = math.floor(rfarea.z/2)
local rfax = math.floor(rfarea.x/2)
if math.random() < 0.5 then
local midpoint = (rfarea.z+1)/2
local gmp = rfarea.z-1
for i=1, midpoint do
for j=1, rfarea.x+1 do
local pos = {x=rfpos1.x+j-1, y=rfpos2.y+1, z=rfpos1.z+i-1}
minetest.set_node(pos,{
name=rfnodes,
paramtype2="facedir",
param2=0
})
--print("mp "..midpoint)
--both gables are made at the same time
for g=1, gmp do
local gpos = {x=gbpos1.x, y=rfpos2.y+2, z=gbpos1.z+gmp-g}
local gpos2 = {x=gbpos1.x+gbarea.x, y=rfpos2.y+2, z=gbpos1.z+gmp-g}
minetest.bulk_set_node({gpos,gpos2},{
name=gbnodes,
paramtype2="facedir",
param2=0
})
end
end
--transform coords for each step from outer dimension toward midpoint
gmp = gmp -2
gbpos1.z = gbpos1.z+1
rfpos2.y = rfpos2.y+1
end
rfpos2 = vector.new({x = sfpos2.x+1, y=sfpos2.y, z=sfpos2.z+1})--reset rfpos2 for other side of roof
rfarea = vector.subtract(rfpos2,rfpos1)
local rfamid = math.floor((rfarea.z+1)/2)
for i=rfarea.z+1,rfamid+1,-1 do
for j=1, rfarea.x+1 do
local pos = {x=rfpos1.x+j-1, y=rfpos2.y+1, z=rfpos1.z+i-1}
minetest.set_node(pos,{
name=rfnodes,
paramtype2="facedir",
param2=2
})
end
rfpos2.y=rfpos2.y+1
end
if rfarea.z % 2 == 0 then
for j=1, rfarea.x+1 do
local pos = {x=rfpos1.x+j-1, y=rfpos2.y, z=rfpos1.z+(rfarea.z/2)}
minetest.set_node(pos,{
name=rfslabs
})
end
-- p is positional axis along which it is made
-- fp is the facing axis and direction inward
local wpos1 = {x=rfpos1.x+1, y=rfpos2.y-2, z=rfpos1.z+(rfaz), p="z", fp={"x",1}}
table.insert(l_pos,wpos1)
local wpos2 = {x=rfpos1.x+rfarea.x-1, y=rfpos2.y-2, z=rfpos1.z+(rfaz), p="z", fp={"x",-1}}
table.insert(l_pos,wpos2)
minetest.bulk_set_node({wpos1,wpos2},{
name=wp.window_nodes[1]
})
else
local wpos1 = {x=rfpos1.x+1, y=rfpos2.y-2, z=rfpos1.z+(rfaz)+1, p="z", fp={"x",1}}
table.insert(l_pos,wpos1)
local wpos2 = {x=rfpos1.x+1, y=rfpos2.y-2, z=rfpos1.z+(rfaz), p="z", fp={"x",1}}
table.insert(l_pos,wpos2)
local wpos3 = {x=rfpos1.x+rfarea.x-1, y=rfpos2.y-2, z=rfpos1.z+(rfaz)+1, p="z", fp={"x",-1}}
table.insert(l_pos,wpos3)
local wpos4 = {x=rfpos1.x+rfarea.x-1, y=rfpos2.y-2, z=rfpos1.z+(rfaz), p="z", fp={"x",-1}}
table.insert(l_pos,wpos4)
minetest.bulk_set_node({wpos1,wpos2,wpos3,wpos4},{
name=wp.window_nodes[1]
})
end
else --------------------------------------------
local gmp = rfarea.x-1
for j=1, (rfarea.x+1)/2 do
for i=1, rfarea.z+1 do
local pos = {x=rfpos1.x+j-1, y=rfpos2.y+1, z=rfpos1.z+i-1}
minetest.set_node(pos,{
name=rfnodes,
paramtype2="facedir",
param2=1
})
end
for g=1, gmp do
local gpos = {x=gbpos1.x+gmp-g, y=rfpos2.y+2, z=gbpos1.z}
local gpos2 = {x=gbpos1.x+gmp-g, y=rfpos2.y+2, z=gbpos1.z+gbarea.z}
minetest.bulk_set_node({gpos,gpos2},{
name=gbnodes,
paramtype2="facedir",
param2=0
})
end
gmp = gmp -2
gbpos1.x = gbpos1.x+1
rfpos2.y=rfpos2.y+1
end
rfpos2 = vector.new({x = sfpos2.x+1, y=sfpos2.y, z=sfpos2.z+1})--reset rfpos2 for other side of roof
rfarea = vector.subtract(rfpos2,rfpos1)
local rfamid = math.floor((rfarea.x+1)/2)
for j=rfarea.x+1, rfamid+1,-1 do
for i=1,rfarea.z+1 do
local pos = {x=rfpos1.x+j-1, y=rfpos2.y+1, z=rfpos1.z+i-1}
minetest.set_node(pos,{
name=rfnodes,
paramtype2="facedir",
param2=3
})
end
rfpos2.y=rfpos2.y+1
end
if rfarea.x % 2 == 0 then
for i=1,rfarea.z+1 do
local pos = {x=rfpos1.x+(rfarea.x/2), y=rfpos2.y, z=rfpos1.z+i-1}
minetest.set_node(pos,{
name=rfslabs
})
end
local wpos1 = {x=rfpos1.x+(rfax), y=rfpos2.y-2, z=rfpos1.z+1, p="x", fp={"z",1}}
table.insert(l_pos,wpos1)
local wpos2 = {x=rfpos1.x+(rfax), y=rfpos2.y-2, z=rfpos1.z+rfarea.z-1, p="x", fp={"z",-1}}
table.insert(l_pos,wpos2)
minetest.bulk_set_node({wpos1,wpos2},{
name=wp.window_nodes[1]
})
else
local wpos1 = {x=rfpos1.x+(rfax), y=rfpos2.y-2, z=rfpos1.z+1, p="x", fp={"z",1}}
table.insert(l_pos,wpos1)
local wpos2 = {x=rfpos1.x+(rfax)+1, y=rfpos2.y-2, z=rfpos1.z+1, p="x", fp={"z",1}}
table.insert(l_pos,wpos2)
local wpos3 = {x=rfpos1.x+(rfax), y=rfpos2.y-2, z=rfpos1.z+rfarea.z-1, p="x", fp={"z",-1}}
table.insert(l_pos,wpos3)
local wpos4 = {x=rfpos1.x+(rfax)+1, y=rfpos2.y-2, z=rfpos1.z+rfarea.z-1, p="x", fp={"z",-1}}
table.insert(l_pos,wpos4)
minetest.bulk_set_node({wpos1,wpos2,wpos3,wpos4},{
name=wp.window_nodes[1]
})
end
end
witches.debug("ladder l_pos: "..mts(l_pos))
--extend the stovepipe
if furnace_pos and furnace_pos.x then
--print("furnace pos: "..mtpts(furnace_pos))
local stovepipe = (rfpos2.y - furnace_pos.y) + 1
--print(rfpos2.y.." "..furnace_pos.y.." "..stovepipe)
stovepipe_pos = vector.new(furnace_pos)
for i=1, stovepipe do
stovepipe_pos.y = stovepipe_pos.y + 1
minetest.set_node(stovepipe_pos,{
name="default:cobble"
})
end
end
--drop a ladder from the center of the gable, avoiding any doors or windows
witches.debug("door: ".. mts(door_pos))
if door_pos and l_pos then
for _,d in pairs(door_pos) do
for k,l in pairs(l_pos) do
if l.x == d.x and l.z == d.z then
table.remove(l_pos,k)
end
end
end
end
if window_pos and l_pos then
for v,_ in pairs(window_pos) do
for _,w in ipairs(window_pos[v]) do
for k,l in pairs(l_pos) do
witches.debug("possible window before check: ".. mtpts(w))
witches.debug("possible ladder before check: ".. mtpts(l))
if math.ceil(l.x) == w.x and math.ceil(l.z) == w.z then
witches.debug("removing".. mtpts(l_pos[k]))
table.remove(l_pos,k)
end
end
end
end
end
witches.debug("possible ladder: ".. mts(l_pos))
if l_pos and #l_pos >= 1 then
local lpn = math.random(#l_pos)
local lpc = l_pos[lpn]
local ladder_length = lpc.y - 1 - ffpos1.y
local fpos = vector.new(lpc)
fpos[ lpc.fp[1] ] = fpos[ lpc.fp[1] ] + lpc.fp[2]
--print("ladder: "..mtpts(l_pos))
--print("ladder f: "..mtpts(fpos))
local dir1=vector.direction(fpos,lpc)
local dir1_wm = minetest.dir_to_wallmounted(dir1)
witches.debug("ladder chosen: ".. mts(lpc))
lpc[ lpc.fp[1] ] = lpc[ lpc.fp[1] ] + lpc.fp[2]
--l_pos.y = l_pos.y-1
for i=1, ladder_length do
lpc.y = lpc.y-1
minetest.set_node(lpc,{
name= "default:ladder_wood",
param2 = dir1_wm
})
end
witches.debug("ladder: "..mtpts(lpc))
else
local loftpos1 = {x= sfpos1.x+2, y = sfpos1.y+1, z=sfpos1.z+1}
local loftpos2 = {x= sfpos2.x-2, y = sfpos1.y+1, z=sfpos2.z-1}
local loftarea = vector.subtract(loftpos2,loftpos1)
witches.debug(dump(loftpos1))
witches.debug(dump(loftpos2))
witches.debug(dump(loftarea))
for i=1, loftarea.z+1 do
for j=1, loftarea.x+1 do
local pos = {x= loftpos1.x-1 + j, y = loftpos1.y, z = loftpos1.z-1 + i}
witches.debug(mts(pos))
minetest.set_node(pos, {name = "air"})
end
end
end
--[[
for i=1, sfarea.z+1 do
for j=1, sfarea.x+1 do
local pos = {x=sfpos1.x+j-1, y=sfpos1.y+1, z=sfpos1.z+i-1}
minetest.set_node(pos,{
name=wp.second_floor_nodes[math.random(#wp.second_floor_nodes)]
})
end
end
for h=1, wp.wall_height-1 do
for i=1, #ucn do
local pos = {x=ucn[i].x, y=ucn[i].y+h+1+wp.wall_height,z=ucn[i].z}
minetest.set_node(pos,{name=wp.foundation_nodes[math.random(#wp.foundation_nodes)]})
end
end
--]]
local c_area1 = vector.new(ppos1)
local c_area2 =vector.new(ppos2)
if stovepipe_pos and stovepipe_pos.y then
c_area2.y = stovepipe_pos.y
else
c_area2.y = c_area2.y + 12
end
local cottage_area = {c_area1,c_area2}
local cottage_va = VoxelArea:new{MinEdge = c_area1, MaxEdge = c_area2}
--print(mts(VoxelArea))
return cottage_area
end
--- build the cottage in a defined area
local function place_cottage(cottage_id, pos1,pos2)
if not cottage_id then
return
end
end

View File

@ -1,6 +1,6 @@
default default
mobs mobs
handle_schematics? protector?
fireflies? fireflies?
mobs_monster? mobs_monster?
doors? doors?

View File

@ -5,7 +5,7 @@
local path = minetest.get_modpath("witches") local path = minetest.get_modpath("witches")
witches = {} witches = {}
witches.version = "20200806" witches.version = "20220214"
print("This is Witches "..witches.version.."!") print("This is Witches "..witches.version.."!")
-- Strips any kind of escape codes (translation, colors) from a string -- Strips any kind of escape codes (translation, colors) from a string
@ -41,12 +41,20 @@ local function print_s(input)
end end
local S = minetest.get_translator("witches") local S = minetest.get_translator("witches")
local settings = minetest.settings
function witches.debug(input)
local witches_debug = settings:get_bool("witches_debug")
if witches_debug then
print_s(input)
end
end
local witches_version = witches.version local witches_version = witches.version
if mobs.version then if mobs.version then
if tonumber(mobs.version) >= tonumber(20200516) then if tonumber(mobs.version) >= tonumber(20200516) then
print_s(S("Mobs Redo 20200516 or greater found!")) print_s(S("Mobs Redo 20200516 or greater found! ("..mobs.version..")"))
else else
print_s(S("You should find a more recent version of Mobs Redo!")) print_s(S("You should find a more recent version of Mobs Redo!"))
print_s(S("https://notabug.org/TenPlus1/mobs_redo")) print_s(S("https://notabug.org/TenPlus1/mobs_redo"))
@ -81,15 +89,9 @@ end
dofile(path .. "/magic.lua") dofile(path .. "/magic.lua")
if not minetest.get_modpath("handle_schematics") then dofile(path .. "/cottages.lua")
print("optional handle_schematics not found!\n Witch cottages not available!") witches.cottages = true
--dofile(path .. "/cottages.lua")
else
dofile(path .. "/basic_houses.lua")
print("handle_schematics found! Witch cottages enabled!")
end
dofile(path .. "/witches.lua") dofile(path .. "/witches.lua")
@ -111,7 +113,7 @@ function witches.generate(witch_types,witch_template)
g_template[x] = g_type[x] g_template[x] = g_type[x]
end end
print_s("Registering the "..g_template.description..": witches:witch_"..k) witches.debug("Registering the "..g_template.description..": witches:witch_"..k)
if g_template.lore then print_s(" "..g_template.lore) end if g_template.lore then print_s(" "..g_template.lore) end
--print_s("resulting template: " ..dump(g_template)) --print_s("resulting template: " ..dump(g_template))
mobs:register_mob("witches:witch_"..k, g_template) mobs:register_mob("witches:witch_"..k, g_template)

View File

@ -54,7 +54,7 @@ minetest.register_entity("witches:witch_tool_wand_sp",witch_tool_wand_sp)
minetest.register_tool("witches:witch_wand_btb", { minetest.register_tool("witches:witch_wand_btb", {
description = "Better Thank Bacon!", description = "Better Than Bacon!",
inventory_image = "witches_wand_better_than_bacon.png", inventory_image = "witches_wand_better_than_bacon.png",
tool_capabilities = { tool_capabilities = {
full_punch_interval = 1.2, full_punch_interval = 1.2,

View File

@ -1,4 +1,6 @@
name = witches name = witches
descriptions = adds witches descriptions = adds witches and their cottages
depends = default, mobs depends = default, mobs
optional_depends = handle_schematics, animalia, mobs_animal
optional_depends = protector, animalia, mobs_animal

View File

@ -132,4 +132,61 @@ function witches.flower_patch(pos)
end end
end end
minetest.register_node("witches:treeroots", {
description = S("tree roots"),
drawtype = "liquid",
tiles = {{backface_culling = false, name= "default_tree.png"},{backface_culling = false, name= "default_tree.png"}},
--alpha = 220,
paramtype = "light",
walkable = true,
pointable = true,
diggable = true,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 0,
liquidtype = "source",
liquid_alternative_flowing = "witches:treeroots_growing",
liquid_alternative_source = "witches:treeroots",
liquid_viscosity = 9,
-- Not renewable to avoid horizontal spread of water sources in sloping
-- rivers that can cause water to overflow riverbanks and cause floods.
-- River water source is instead made renewable by the 'force renew'
-- option used in the 'bucket' mod by the river water bucket.
liquid_renewable = false,
liquid_range = 1,
post_effect_color = {a = 200, r = 5, g = 5, b = 0},
groups = {liquid = 3, cools_lava = 1, tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
--sounds = default.node_sound_water_defaults(),
})
minetest.register_node("witches:treeroots_growing", {
description = S("Tree Roots"),
drawtype = "flowingliquid",
tiles = {{backface_culling = false, name= "default_tree.png"}},
special_tiles = {{backface_culling = false, name= "default_tree.png"},{backface_culling = false, name= "default_tree.png"}},
--alpha = 220,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = true,
pointable = false,
diggable = true,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 0,
liquidtype = "flowing",
liquid_alternative_flowing = "witches:treeroots_growing",
liquid_alternative_source = "witches:treeroots",
liquid_viscosity = 9,
liquid_renewable = false,
liquid_range = 1,
post_effect_color = {a = 200, r = 5, g = 5, b = 0},
groups = { liquid = 3, not_in_creative_inventory = 1,
cools_lava = 1,tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
--sounds = default.node_sound_water_defaults(),
})

View File

@ -1,4 +1,7 @@
# debug mode
witches_debug (enable debug) bool false
#maximum number of houses per mapchunk #maximum number of houses per mapchunk
witches_house_max_per_mapchunk (maximum number of houses per mapchunk) int 2 witches_house_max_per_mapchunk (maximum number of houses per mapchunk) int 2
@ -6,11 +9,12 @@ witches_house_max_per_mapchunk (maximum number of houses per mapchunk) int 2
witches_houses_wanted_per_mapchunk (average number of houses to mapchunks over the world) float .05 witches_houses_wanted_per_mapchunk (average number of houses to mapchunks over the world) float .05
# chance (1-99) of a witch house spawning over a dungeon instead of anywhere else (requires Sokomines handle_schematics mod!) # chance (1-99) of a witch house spawning over a dungeon instead of anywhere else
witches_dungeon_cellar_chance (chance as decimal like .5 of a witch house spawning over a dungeon instead of anywhere else) float .5 witches_dungeon_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!) # depth (1-20) maximum depth of a dungeon to spawn a witch house over
witches_dungeon_cellar_depth (maximum depth 0 to -20 of a dungeon to spawn a witch house over) int -5 witches_dungeon_cellar_depth (maximum depth 0 to -20 of a dungeon to spawn a witch house over) int -5

3
ui.lua
View File

@ -10,13 +10,14 @@ witches.find_item_quest = {}
witches.found_item_quest = {} witches.found_item_quest = {}
--local item_request = witches.generate_name(witches.quest_dialogs, {"item_request"}) --local item_request = witches.generate_name(witches.quest_dialogs, {"item_request"})
function witches.find_item_quest.get_formspec(self,name) function witches.find_item_quest.get_formspec(self,name)
-- retrieve the thing -- retrieve the thing
--local quest_item = witches.looking_for(self) --local quest_item = witches.looking_for(self)
local text = "" local text = ""
if self.item_request.text and type(self.item_request.text) == "table" then if self.item_request.text and type(self.item_request.text) == "table" then
local intro = self.item_request.text.intro local intro = self.item_request.text.intro
local request = self.item_request.text.request local request = "\n"..self.item_request.text.request
text = S("@1 @2",intro,request) text = S("@1 @2",intro,request)
--print(text) --print(text)

View File

@ -11,45 +11,60 @@ witches.name_parts_male = {
syllablesStart = "Aer, Al, Am, An, Ar, Arm, Arth, B, Bal, Bar, Be, Bel, Ber, Bok, Bor, Bran, Breg, Bren, Brod, Cam, Chal, Cham, Ch, Cuth, Dag, Daim, Dair, Del, Dr, Dur, Duv, Ear, Elen, Er, Erel, Erem, Fal, Ful, Gal, G, Get, Gil, Gor, Grin, Gun, H, Hal, Han, Har, Hath, Hett, Hur, Iss, Khel, K, Kor, Lel, Lor, M, Mal, Man, Mard, N, Ol, Radh, Rag, Relg, Rh, Run, Sam, Tarr, T, Tor, Tul, Tur, Ul, Ulf, Unr, Ur, Urth, Yar, Z, Zan, Zer", syllablesStart = "Aer, Al, Am, An, Ar, Arm, Arth, B, Bal, Bar, Be, Bel, Ber, Bok, Bor, Bran, Breg, Bren, Brod, Cam, Chal, Cham, Ch, Cuth, Dag, Daim, Dair, Del, Dr, Dur, Duv, Ear, Elen, Er, Erel, Erem, Fal, Ful, Gal, G, Get, Gil, Gor, Grin, Gun, H, Hal, Han, Har, Hath, Hett, Hur, Iss, Khel, K, Kor, Lel, Lor, M, Mal, Man, Mard, N, Ol, Radh, Rag, Relg, Rh, Run, Sam, Tarr, T, Tor, Tul, Tur, Ul, Ulf, Unr, Ur, Urth, Yar, Z, Zan, Zer",
syllablesMiddle = "de, do, dra, du, duna, ga, go, hara, kaltho, la, latha, le, ma, nari, ra, re, rego, ro, rodda, romi, rui, sa, to, ya, zila", syllablesMiddle = "de, do, dra, du, duna, ga, go, hara, kaltho, la, latha, le, ma, nari, ra, re, rego, ro, rodda, romi, rui, sa, to, ya, zila",
syllablesEnd = "bar, bers, blek, chak, chik, dan, dar, das, dig, dil, din, dir, dor, dur, fang, fast, gar, gas, gen, gorn, grim, gund, had, hek, hell, hir, hor, kan, kath, khad, kor, lach, lar, ldil, ldir, leg, len, lin, mas, mnir, ndil, ndur, neg, nik, ntir, rab, rach, rain, rak, ran, rand, rath, rek, rig, rim, rin, rion, sin, sta, stir, sus, tar, thad, thel, tir, von, vor, yon, zor", syllablesEnd = "bar, bers, blek, chak, chik, dan, dar, das, dig, dil, din, dir, dor, dur, fang, fast, gar, gas, gen, gorn, grim, gund, had, hek, hell, hir, hor, kan, kath, khad, kor, lach, lar, ldil, ldir, leg, len, lin, mas, mnir, ndil, ndur, neg, nik, ntir, rab, rach, rain, rak, ran, rand, rath, rek, rig, rim, rin, rion, sin, sta, stir, sus, tar, thad, thel, tir, von, vor, yon, zor",
syllablesTown = "mar, ton, veil, Loch, del, Pass, Hillock, shire, nia, ing",
} }
witches.name_parts_female = { witches.name_parts_female = {
syllablesStart = "Ad, Aer, Ar, Bel, Bet, Beth, Ce'N, Cyr, Eilin, El, Em, Emel, G, Gl, Glor, Is, Isl, Iv, Lay, Lis, May, Ner, Pol, Por, Sal, Sil, Vel, Vor, X, Xan, Xer, Yv, Zub", syllablesStart = "Ad, Aer, Ar, Bel, Bet, Beth, Ce'N, Cyr, Eilin, El, Em, Emel, G, Gl, Glor, Is, Isl, Iv, Lay, Lis, May, Ner, Pol, Por, Sal, Sil, Vel, Vor, X, Xan, Xer, Yv, Zub",
syllablesMiddle = "bre, da, dhe, ga, lda, le, lra, mi, ra, ri, ria, re, se, ya", syllablesMiddle = "bre, da, dhe, ga, lda, le, lra, mi, ra, ri, ria, re, se, ya",
syllablesEnd = "ba, beth, da, kira, laith, lle, ma, mina, mira, na, nn, nne, nor, ra, rin, ssra, ta, th, tha, thra, tira, tta, vea, vena, we, wen, wyn", syllablesEnd = "ba, beth, da, kira, laith, lle, ma, mina, mira, na, nn, nne, nor, ra, rin, ssra, ta, th, tha, thra, tira, tta, vea, vena, we, wen, wyn",
syllablesTown = "maer, tine, veila, Loch, dael, Pass, Hillock, shire, mia, aeng",
} }
witches.words_desc = { witches.words_desc = {
tool_adj = S("shiny, polished, favorite, beloved, cherished, sharpened"), tool_adj = S("shiny, polished, favorite, beloved, cherished, sharpened, enhanced"),
titles = S("artificer, librarian, logician, sorcerant, thaumaturgist, polymorphist, elementalist, hedge, herbologist, arcanologist, tutor, historian, mendicant, restorationist"), titles = S("artificer, librarian, logician, sorcerant, thaumaturgist, polymorphist, elementalist, hedge, herbologist, arcanologist, tutor, historian, mendicant, restorationist"),
} }
local function quest_dialogs(self) local function quest_dialogs(self)
local thing = self.item_request.item.desc
local thing_l = string.lower(self.item_request.item.desc)
local dialogs = { local dialogs = {
intro = { intro = {
S("Hello, @1, I am @2, @3 of @4! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale), S("Hello, @1, I am @2, @3 of @4! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale),
S("Just one minute, @1! @2, @3 of @4 seeks your assistance! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale), S("Just one minute, @1! @2, @3 of @4 seeks your assistance! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale),
S("If you are indeed @1, perhaps you and I, @2, @3 of @4 can help each other! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale), S("If you are indeed @1, perhaps you and I, @2, @3 of @4 can help each other! ", self.speaking_to,self.secret_name,self.secret_title,self.secret_locale),
S("Being a long way from @1, can be confusing. I'm known as @2 the @3! ", self.secret_locale,self.secret_name,self.secret_title),
S("You look as though you could be from @1, but I'm sure we have not yet met. I am @2 the @3! ", self.secret_locale,self.secret_name,self.secret_title),
},
having_met = {
S("Well, @1, I have yet to return to @2. Can you help me? ", self.speaking_to,self.secret_locale),
S("@1, do you have any intention of helping me? ", self.speaking_to),
S("There are some matters that still need my attention, @1. ", self.speaking_to),
S("I have been so busy in my search for materials, @1. ", self.speaking_to),
S("It's just that the @1 is so difficult to procure, @2! ", thing_l, self.speaking_to),
S("Great @1!, Where could that be found, @2?!? ", thing_l, self.speaking_to)
}, },
item_request = { item_request = {
S("I've been looking all over for the @1! ",self.item_request.item.desc), S("A @1, just one will do! ", thing_l),
S("I seem to have misplaced the @1! ",self.item_request.item.desc), S("I've been looking all over for the @1! ",thing_l),
S("Would you happen to have some number of @1? ",self.item_request.item.desc), S("I seem to have misplaced the @1! ",thing_l),
S("Would you kindly retrieve for me the @1? ",self.item_request.item.desc), S("Would you happen to have some number of @1? ",thing_l),
S("Might you please return with the @1? ",self.item_request.item.desc), S("Would you kindly retrieve for me the @1? ",thing_l),
S("Do you know I seek only the @1? ",self.item_request.item.desc), S("Might you please return with the @1? ",thing_l),
S("Have you but some number of @1? ",self.item_request.item.desc), S("Do you know I seek only the @1? ",thing_l),
S("Why must my task require the @1? ",self.item_request.item.desc), S("Have you but some number of @1? ",thing_l),
S("Is it so difficult to find the @1? ",self.item_request.item.desc), S("Why must my task require the @1? ",thing_l),
S("Wherefor about this land art the @1? ",self.item_request.item.desc), S("Is it so difficult to find the @1? ",thing_l),
S("Must there be but a few of the @1 about? ",self.item_request.item.desc), S("Wherefor about this land art the @1? ",thing_l),
S("Could I trouble you for some kind of @1? ",self.item_request.item.desc), S("Must not there be but a few of the @1 about? ",thing_l),
S("The @1 would make my collection complete! ",self.item_request.item.desc), S("Could I trouble you for some kind of @1? ",thing_l),
S("I sense the @1 are not far away...",self.item_request.item.desc), S("The @1 would make my collection complete! ",thing_l),
S("Certainly the @1 is not as rare as a blood moon! ",self.item_request.item.desc), S("I sense the @1 are not far away...",thing_l),
S("You look like you know where to find the @1! ",self.item_request.item.desc) S("Certainly the @1 is not as rare as a blood moon! ",thing_l),
S("You look like you know where to find the @1! ",thing_l)
} }
} }
--print(dump(dialogs)) --print(dump(dialogs))
@ -234,11 +249,11 @@ end
function witches.gift(self, pname, drop_chance_min, drop_chance_max, item_wear ) function witches.gift(self, pname, drop_chance_min, drop_chance_max, item_wear )
if not pname then if not pname then
print("no player defined!") witches.debug("no player defined!")
return return
end end
if not self.drops then if not self.drops then
print("no droplist defined in this mob!") witches.debug("no droplist defined in this mob!")
return return
end end
local list = {} local list = {}
@ -355,7 +370,7 @@ function witches.claim_witches_chest(self)
-- if sn then print(sn) end -- if sn then print(sn) end
local o = meta:get_string("owner") local o = meta:get_string("owner")
if o and sn and sn == o then if o and sn and sn == o then
print("unbound chest: "..sn) witches.debug("unbound chest: "..sn)
meta:set_string("owner", self.secret_name) meta:set_string("owner", self.secret_name)
meta:set_string("infotext", self.secret_name.."'s sealed chest of ".. sn) meta:set_string("infotext", self.secret_name.."'s sealed chest of ".. sn)
@ -400,8 +415,29 @@ function witches.item_request(self,name)
--we need text for the quest! --we need text for the quest!
-- print("generating") -- print("generating")
local dialog_list = quest_dialogs(self) local dialog_list = quest_dialogs(self)
local dli_num = math.random(1,#dialog_list.intro) if not self.players then self.players = {} end
local intro_text = dialog_list.intro[dli_num] if not self.players[name] then
self.players[name] = {}
--if not self.players.met or #self.players.met < 1 or type(self.players.met) == string then
--table.insert(self.players_met, self.secret_name)
end
local intro_text = ""
if not self.players[name].met then
--print(dump(self.players[name]))
--print( "We don't know "..name.."!")
local dli_num = math.random(1,#dialog_list.intro)
intro_text = dialog_list.intro[dli_num]
self.players[name] = {met = math.floor(os.time())}
else
--print(dump(self.players.met))
--print( "We first met "..name.." ".. os.time() - self.players[name].met.." seconds ago")
local dli_num = math.random(1,#dialog_list.having_met)
intro_text = dialog_list.having_met[dli_num]
end
--print(intro_text) --print(intro_text)
local quest_item = self.item_request.item.desc local quest_item = self.item_request.item.desc
@ -523,7 +559,7 @@ function witches.quests(self, clicker)
if var1 == var2 then if var1 == var2 then
self.dev_mode = pname self.dev_mode = pname
print("dev mode active for: "..pname) witches.debug("dev mode active for: "..pname)
end end
--print("we are holding a "..dump(item:get_name())) --print("we are holding a "..dump(item:get_name()))

View File

@ -17,7 +17,7 @@ local spawning = {
day_toggle = nil, day_toggle = nil,
on_spawn = function(self) on_spawn = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
print(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos))) witches.debug(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos)))
end, end,
}, },
@ -34,7 +34,7 @@ local spawning = {
day_toggle = nil, day_toggle = nil,
on_spawn = function(self) on_spawn = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
print(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos))) witches.debug(self.secret_name.." spawned at ".. minetest.pos_to_string(vector.round(pos)))
end end
@ -57,13 +57,14 @@ witches.witch_types = {
local pos = self.object:get_pos() local pos = self.object:get_pos()
if pos then if pos then
pos.y = pos.y+1 pos.y = pos.y+1
local pos1 = minetest.find_node_near(pos, 3, "air") local pos1 = minetest.find_node_near(pos, 3, "air")
if pos1 then if pos1 then
minetest.set_node(pos1, {name = "fireflies:firefly"}) minetest.set_node(pos1, {name = "fireflies:firefly"})
--print("setting firefly"..minetest.pos_to_string(pos1)) --print("setting firefly"..minetest.pos_to_string(pos1))
end end
end end
end end
end, end,
on_spawn_addendum = function(self) on_spawn_addendum = function(self)
@ -82,6 +83,22 @@ witches.witch_types = {
"default:blueberries", "default:torch", "default:stick", "default:blueberries", "default:torch", "default:stick",
"flowers:mushroom_brown","flowers:mushroom_red"}, "flowers:mushroom_brown","flowers:mushroom_red"},
do_custom_addendum = function(self) do_custom_addendum = function(self)
if witches.cottages then
if not self.built_house and math.random() < 0.01 then
local volume = witches.grounding(self)
if volume then
witches.debug("volume passed: "..dump(volume))
local pos = self.object:get_pos()
pos.y = pos.y+3
self.object:set_pos(pos)
self.built_house = pos
witches.generate_cottage(self.secret_name,volume[1],volume[2])
end
end
end
end, end,
on_spawn_addendum = function(self) on_spawn_addendum = function(self)
witches.claim_witches_chest(self) witches.claim_witches_chest(self)
@ -90,6 +107,7 @@ witches.witch_types = {
spawning = spawning.cottage, spawning = spawning.cottage,
} }
} }
witches.witch_template = { --your average witch, witches.witch_template = { --your average witch,
description = "Basic Witch", description = "Basic Witch",
lore = "This witch has a story yet to be...", lore = "This witch has a story yet to be...",
@ -113,7 +131,7 @@ witches.witch_template = { --your average witch,
"witches_clothes.png" "witches_clothes.png"
}, },
--blood_texture = "witches_blood.png", --blood_texture = "witches_blood.png",
collisionbox = {-0.25, 0, -.25, 0.25, 2, 0.25}, collisionbox = {-0.2, 0, -.2, 0.2, 1.9, 0.2},
drawtype = "front", drawtype = "front",
makes_footstep_sound = true, makes_footstep_sound = true,
sounds = { sounds = {
@ -272,13 +290,17 @@ witches.witch_template = { --your average witch,
self.secret_title = witches.generate_text(witches.words_desc, {"titles"}) self.secret_title = witches.generate_text(witches.words_desc, {"titles"})
end end
if not self.secret_locale then if not self.secret_locale then
self.secret_locale = witches.generate_text(witches.name_parts_female, {"syllablesStart","syllablesEnd"}) if math.random(2) == 1 then
self.secret_locale = witches.generate_text(witches.name_parts_female, {"syllablesStart","syllablesEnd","syllablesTown"})
else
self.secret_locale = witches.generate_text(witches.name_parts_male, {"syllablesStart","syllablesEnd","syllablesTown"})
end
end end
--self.item_request.text = witches.generate_name(witches.quest_dialogs, {"item_request"}) --self.item_request.text = witches.generate_name(witches.quest_dialogs, {"item_request"})
--print(self.secret_name.." has spawned") --print(self.secret_name.." has spawned")
--print("self: "..dump(self.follow)) --print("self: "..dump(self.follow))
-- print("self properties "..dump(self.object:get_properties())) --print("self properties "..dump(self.object:get_properties()))
--self.follow = {} --self.follow = {}
if not self.follow or #self.follow < 1 or type(self.follow) == string then if not self.follow or #self.follow < 1 or type(self.follow) == string then
self.follow = {} self.follow = {}