Poplulate dungeons with goblins, dungeon masters, and treasure. Fix armor hud

master
Brandon 2015-08-14 23:45:41 -05:00
parent c70940939a
commit 6114a2adb1
32 changed files with 404 additions and 35 deletions

View File

@ -58,3 +58,21 @@ Copyright (C) 2013 BlockMen CC BY-3.0
License of Spider model
Copyright (C) 2013 AspireMint CC BY-SA
goblins_goblin.b3d and goblins_goblin.blend
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) by FreeLikeGNU
http://creativecommons.org/licenses/by-sa/3.0/
above meshes based on character from minetest_game
MirceaKitsune (WTFPL)
https://github.com/minetest/minetest_game/blob/master/mods/default/README.txt#L71
goblins_goblins*.png files and goblins_goblin.xcf file by FreeLikeGNU
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) FreeLikeGNU
http://creativecommons.org/licenses/by-sa/3.0/
Thanks to Napiophelios for the goblin king skin
https://forum.minetest.net/viewtopic.php?f=9&t=13004#p186921
goblins_goblin_king.png
License: Creative Commons CC-BY-SA-3.0 SummerFeilds TP

View File

@ -414,6 +414,6 @@ function default.get_file_contents(filename)
end
function randomChance (percent)
math.randomseed( os.time() )
math.randomseed( os.clock() )
return percent >= math.random(1, 100)
end

View File

@ -21,7 +21,7 @@ HUD_ARMOR_OFFSET = {x = -262, y = -135}
local damage_enabled = minetest.setting_getbool("enable_damage")
hud.show_hunger = minetest.get_modpath("hunger") ~= nil
hud.show_armor = minetest.get_modpath("3d_armor") ~= nil
hud.show_armor = true
if damage_enabled then
hud.register("health", {

View File

@ -2,11 +2,10 @@
function hud.set_armor()
end
if hud.show_armor then
local shields = minetest.get_modpath("shields") ~= nil
local armor_org_func = armor.update_armor
local shields = minetest.get_modpath("shields") ~= nil
local armor_org_func = armor.update_armor
local function get_armor_lvl(def)
local function get_armor_lvl(def)
-- items/protection based display
local lvl = def.level or 0
local max = 63 -- full diamond armor
@ -20,9 +19,9 @@ if hud.show_armor then
end
return tonumber(20 * ret)
end
end
function armor.update_armor(self, player)
function armor.update_armor(self, player)
armor_org_func(self, player)
local name = player:get_player_name()
local def = self.def
@ -31,7 +30,6 @@ if hud.show_armor then
armor_lvl = get_armor_lvl(def[name])
end
hud.change_item(player, "armor", {number = armor_lvl})
end
end
-- Hunger related functions

155
mods/mg/dungeons.lua Executable file
View File

@ -0,0 +1,155 @@
minetest.set_gen_notify("dungeon,temple")
dungeon_chest = {}
table.insert(dungeon_chest, { "default:gold_ingot", 60, 25 })
table.insert(dungeon_chest, { "default:steel_ingot", 68, 35 })
table.insert(dungeon_chest, { "default:mese_crystal", 40, 10})
table.insert(dungeon_chest, { "default:sword_steel", 80, 1 })
table.insert(dungeon_chest, { "default:sword_mese", 20, 1 })
table.insert(dungeon_chest, { "default:sword_diamond", 5, 1 })
table.insert(dungeon_chest, { "default:diamond", 10, 5 })
table.insert(dungeon_chest, { "default:torch", 95, 25 })
table.insert(dungeon_chest, { "default:mese", 15, 4 })
table.insert(dungeon_chest, { "default:diamondblock",10, 4 })
table.insert(dungeon_chest, { "potions:fly3", 50, 1})
table.insert(dungeon_chest, { "potions:bones", 70, 5})
table.insert(dungeon_chest, { "potions:magid_replenish3", 60, 10})
table.insert(dungeon_chest, { "potions:antidote", 80, 10})
table.insert(dungeon_chest, { "farming:bread", 80, 15})
table.insert(dungeon_chest, { "mobs:meat", 80, 5})
table.insert(dungeon_chest, { "bushes:berry_pie_cooked", 90, 5})
table.insert(dungeon_chest, { "3d_armor:helmet_bronze", 70, 1})
table.insert(dungeon_chest, { "3d_armor:helmet_diamond", 20, 1})
table.insert(dungeon_chest, { "3d_armor:chestplate_bronze", 60,1})
table.insert(dungeon_chest, { "3d_armor:leggings_bronze", 65, 1})
table.insert(dungeon_chest, { "3d_armor:boots_bronze", 70, 1})
table.insert(dungeon_chest, { "3d_armor:helmet_mithril", 12, 1})
table.insert(dungeon_chest, { "3d_armor:chestplate_mithril", 12,1})
table.insert(dungeon_chest, { "3d_armor:leggings_mithril", 12, 1})
table.insert(dungeon_chest, { "3d_armor:boots_mithril", 12, 1})
table.insert(dungeon_chest, { "magic:wand_missle",25,1})
d_air = minetest.get_content_id("air")
d_glowblock = minetest.get_content_id("glowcrystals:glowcrystal_ore")
minetest.register_on_generated( function (minp, maxp, blockseed)
local notify = minetest.get_mapgen_object("gennotify")
if notify ~= nil then
if notify.dungeon ~= nil then
--print("Dungeon generated")
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local spawn = {}
local chests = {}
for k,v in ipairs(notify.dungeon) do
--print(minetest.pos_to_string(v))
-- find the size of this room
if v.y < 0 then
local center = {x=v.x,y=v.y,z=v.z}
local ycheck = {x=center.x,y=center.y,z=center.z}
local i = area:indexp(ycheck)
while data[i] == d_air do
ycheck.y = ycheck.y + 1
i = area:indexp(ycheck)
end
ycheck.y = ycheck.y - 1
local height = ( ycheck.y - center.y )
local xcheck = {x=center.x,y=center.y,z=center.z}
local i = area:indexp(xcheck)
while data[i] == d_air do
xcheck.x = xcheck.x + 1
i = area:indexp(xcheck)
end
xcheck.x = xcheck.x - 1
local zcheck = {x=center.x,y=center.y,z=center.z}
local i = area:indexp(zcheck)
while data[i] == d_air do
zcheck.z = zcheck.z + 1
i = area:indexp(zcheck)
end
zcheck.z = zcheck.z - 1
local xsize = ( xcheck.x - center.x )
local zsize = ( zcheck.z - center.z )
if randomChance(75) then
i = area:indexp({x=zcheck.x,y=(zcheck.y+1),z=(zcheck.z+1)})
if data[i] ~= d_air then
data[i] = d_glowblock
end
i = area:indexp({x=(xcheck.x+1),y=(xcheck.y+1),z=xcheck.z})
if data[i] ~= d_air then
data[i] = d_glowblock
end
i = area:indexp({x=(center.x - (xsize+1)),y=(center.y+1),z=zcheck.z})
if data[i] ~= d_air then
data[i] = d_glowblock
end
i = area:indexp({x=center.x,y=(center.y+1),z=(zcheck.z - (zsize+1))})
if data[i] ~= d_air then
data[i] = d_glowblock
end
end
local size = xsize * zsize
math.randomseed(os.clock())
local fillratio = ( math.random(10,16) / 100 )
local numgoblins = ((xsize * 2) * (zsize * 2)) * fillratio
for e=1,numgoblins do
local rx = math.random((center.x-(xsize-1)),(center.x+(xsize-1)))
local rz = math.random((center.z-(zsize-1)),(center.z+(zsize-1)))
local s = {mob="mobs:goblin",pos={x=rx,z=rz,y=(center.y+1)}}
table.insert(spawn,s)
end
if numgoblins > 4 then
local king = { mob = "mobs:goblin_king", pos={x=center.x,y=(center.y+1),z=center.z} }
table.insert(spawn,king)
end
if ( (xsize*2) * (zsize*2) ) > 68 and height > 2 then
-- larger rooms add a chest full of stuff and a DM
local i = area:indexp(center)
table.insert(chests,center)
local d = { mob = "mobs:dungeon_master", pos={x=center.x,y=(center.y+1),z=center.z} }
table.insert(spawn,d)
end
end
end
vm:set_data(data)
vm:calc_lighting()
vm:write_to_map(data)
for _,v in ipairs(spawn) do
mobs:spawn_mob(v.pos,v.mob)
end
for _,cpos in ipairs(chests) do
minetest.place_node(cpos,{name="default:chest"})
local meta = minetest.get_meta( cpos );
local inv = meta:get_inventory();
inv:add_item("main","quests:dungeon_token")
for _,item in ipairs(dungeon_chest) do
if randomChance(item[2]) then
local qty = math.random(1,item[3])
inv:add_item("main", item[1].." "..tostring(qty))
end
end
end
end
if notify.temple ~= nil then
print("Temple generated")
for k,v in ipairs(notify.temple) do
print(minetest.pos_to_string(v))
end
end
end
end)

View File

@ -45,6 +45,7 @@ dofile(mgpath.."/biomes.lua")
dofile(mgpath.."/decorations.lua")
dofile(mgpath.."/villages.lua")
dofile(mgpath.."/fill_chests.lua")
dofile(mgpath.."/dungeons.lua")
minetest.register_on_mapgen_init(function(params)
minetest.set_mapgen_params({

View File

@ -25,6 +25,7 @@ armor = {
armor.def = {
state = 0,
count = 0,
level = 0,
}
armor.update_player_visuals = function(self, player)
@ -97,6 +98,7 @@ armor.set_player_armor = function(self, player)
self.textures[name].armor = armor_texture
self.def[name].state = state
self.def[name].count = items
self.def[name].level = armor_level
self:update_player_visuals(player)
end
@ -198,13 +200,11 @@ minetest.register_on_joinplayer(function(player)
local armor_inv = minetest.create_detached_inventory(name.."_armor",{
on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_stack(listname, index, stack)
-- TODO apply physics
physics.apply_item_physics(player,stack:get_name())
armor:set_player_armor(player)
end,
on_take = function(inv, listname, index, stack, player)
player:get_inventory():set_stack(listname, index, nil)
-- TODO remove applied physics
physics.remove_item_physics(player,stack:get_name())
armor:set_player_armor(player)
end,

View File

@ -14,8 +14,8 @@ function mobs:register_mob(name, def)
textures = def.textures,
makes_footstep_sound = def.makes_footstep_sound,
view_range = def.view_range,
walk_velocity = def.walk_velocity,
run_velocity = def.run_velocity,
walk_velocity = def.walk_velocity or 0,
run_velocity = def.run_velocity or 0,
damage = def.damage,
light_damage = def.light_damage,
water_damage = def.water_damage or 1,
@ -149,12 +149,23 @@ function mobs:register_mob(name, def)
in_fov = function(self,pos)
-- checks if POS is in self's FOV
local yaw = self.object:getyaw()
return true
--[[
local yaw = (self.object:getyaw() * 180 / math.pi)
if self.drawtype == "side" then
yaw = yaw+(math.pi/2)
end
if yaw < 0 then
yaw = 360 - yaw
end
if yaw > 360 then
yaw = yaw - 360
end
print("Yaw: "..tostring(yaw))
print("FOV: "..tostring(self.fov))
local vx = math.sin(yaw)
local vz = math.cos(yaw)
local ds = math.sqrt(vx^2 + vz^2)
@ -162,12 +173,15 @@ function mobs:register_mob(name, def)
local d = { x = vx / ds, z = vz / ds }
local p = { x = pos.x / ps, z = pos.z / ps }
local an = ( d.x * p.x ) + ( d.z * p.z )
print("DS "..tostring(ds))
print("PS "..tostring(ps))
print("D: x="..tostring(d.x)..", z="..tostring(d.z))
print("P: x="..tostring(p.x)..", z="..tostring(p.z))
local a = math.deg( math.acos( an ) )
return true
--[[
local an = ( d.x * p.x ) + ( d.z * p.z )
print("AN: "..tostring(an))
local a = math.deg ( math.acos( an ) )
print("A: "..tostring(a))
if a > ( self.fov / 2 ) then
return false
else
@ -240,21 +254,22 @@ function mobs:register_mob(name, def)
self.object:remove()
end
self.lifetimer = self.lifetimer - dtime
if self.lifetimer <= 0 and not self.tamed and self.type ~= "npc" then
local player_count = 0
for _,obj in ipairs(minetest.get_objects_inside_radius(self.object:getpos(), 10)) do
if obj:is_player() then
player_count = player_count+1
if self.lifetimer ~= false then
self.lifetimer = self.lifetimer - dtime
if self.lifetimer <= 0 and not self.tamed and self.type ~= "npc" then
local player_count = 0
for _,obj in ipairs(minetest.get_objects_inside_radius(self.object:getpos(), 10)) do
if obj:is_player() then
player_count = player_count+1
end
end
if player_count == 0 and self.state ~= "attack" then
minetest.log("action","lifetimer expired, removed mob "..self.name)
self.object:remove()
return
end
end
if player_count == 0 and self.state ~= "attack" then
minetest.log("action","lifetimer expired, removed mob "..self.name)
self.object:remove()
return
end
end
if self.object:getvelocity().y > 0.1 then
local yaw = self.object:getyaw()
if self.drawtype == "side" then
@ -887,6 +902,18 @@ function mobs:spawn_mob(pos,name)
local newHP = mob.hp_min + math.floor( mob.hp_max * distance_rating )
mob.object:set_hp( newHP )
mob.state = "walk" -- make them walk when they spawn so they walk away from their original spawn position
-- vary the walk and run velocity when a mob is spawned so groups of mobs don't clump up so bad
math.randomseed(os.clock())
mob.walk_velocity = mob.walk_velocity - ( mob.walk_velocity * ( math.random(0,12) / 100 ) )
if mob.walk_velocity < 0 then
mob.walk_velocity = 0
end
mob.run_velocity = mob.run_velocity - ( mob.run_velocity * ( math.random(0,12) / 100 ) )
if mob.run_velocity < 0 then
mob.run_velocity = 0
end
return true
end
end

View File

@ -15,6 +15,7 @@ dofile(minetest.get_modpath("mobs").."/monsters/jungle_spider.lua")
dofile(minetest.get_modpath("mobs").."/monsters/stonemonster.lua")
dofile(minetest.get_modpath("mobs").."/monsters/treemonster.lua")
dofile(minetest.get_modpath("mobs").."/monsters/yeti.lua")
dofile(minetest.get_modpath("mobs").."/monsters/goblins.lua")
dofile(minetest.get_modpath("mobs").."/animals/rat.lua")
dofile(minetest.get_modpath("mobs").."/animals/sheep.lua")

Binary file not shown.

View File

@ -45,6 +45,7 @@ mobs:register_mob("mobs:dungeon_master", {
},
jump = true,
step=0.5,
lifetimer = false,
})
mobs:register_spawn("mobs:dungeon_master", {"default:stone"}, 3, -1, 7000, 1, -50)
@ -73,7 +74,7 @@ mobs:register_arrow("mobs:fireball", {
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30 then
minetest.env:set_node(p, {name="fire:basic_flame"})
else
minetest.env:remove_node(p)
--minetest.env:remove_node(p)
end
end
end
@ -89,7 +90,7 @@ mobs:register_arrow("mobs:fireball", {
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30 then
minetest.env:set_node(p, {name="fire:basic_flame"})
else
minetest.env:remove_node(p)
--minetest.env:remove_node(p)
end
end
end

103
mods/mobs/monsters/goblins.lua Executable file
View File

@ -0,0 +1,103 @@
mobs:register_mob("mobs:goblin", {
type = "monster",
hp_min = 5,
hp_max = 15,
exp_min = 5,
exp_max = 20,
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.0,0.35},
visual = "mesh",
mesh = "goblins_goblin.b3d",
textures = {"goblins_goblin_coal1.png"},
visual_size = {x=1, y=1},
makes_footstep_sound = false,
view_range = 4,
walk_velocity = 1,
run_velocity = 2,
damage = 1.5,
drops = { },
armor = 150,
drawtype = "front",
water_damage = 1,
lava_damage = 5,
light_damage = 0,
on_rightclick = nil,
attack_type = "dogfight",
animation = {
speed_normal = 30,
speed_run = 30,
stand_start = 0,
stand_end = 79,
walk_start = 168,
walk_end = 187,
run_start = 168,
run_end = 187,
punch_start = 200,
punch_end = 219,
},
jump = true,
sounds = {
},
step=0.5,
blood_amount = 15,
blood_offset = 0.25,
activity_level=2,
lifetimer = false,
})
mobs:register_mob("mobs:goblin_king", {
type = "monster",
hp_min = 8,
hp_max = 22,
exp_min = 10,
exp_max = 35,
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.0,0.35},
visual = "mesh",
mesh = "goblins_goblin.b3d",
textures = {"goblins_goblin_king.png"},
visual_size = {x=1, y=1},
makes_footstep_sound = false,
view_range = 7,
walk_velocity = 1,
run_velocity = 2.5,
damage = 2,
drops = {
{name = "mobs:goblin_king_crown",
chance = 101,
min = 1,
max = 1,},
},
armor = 150,
drawtype = "front",
water_damage = 1,
lava_damage = 5,
light_damage = 0,
on_rightclick = nil,
attack_type = "dogfight",
animation = {
speed_normal = 30,
speed_run = 30,
stand_start = 0,
stand_end = 79,
walk_start = 168,
walk_end = 187,
run_start = 168,
run_end = 187,
punch_start = 200,
punch_end = 219,
},
jump = true,
sounds = {
},
step=0.5,
blood_amount = 15,
blood_offset = 0.25,
activity_level=2,
lifetimer = false,
})
minetest.register_tool("mobs:goblin_king_crown", {
description = "Goblin King's Crown",
inventory_image = "mobs_inv_goblin_king_crown.png",
groups = {armor_head=10, armor_heal=24, armor_use=50},
wear = 0,
})

View File

@ -168,4 +168,16 @@ local numNPCs = math.random(0,1)
end
end
function mobs.add_spawner(pos,mob,ao,aow)
local r = mobs:spawn_mob(pos,mob)
if r ~= -1 then
local spos = {x=pos.x,y=pos.y-5,z=pos.z}
minetest.set_node(spos,{name="mobs:spawner"})
local meta = minetest.get_meta(spos)
meta:set_string("entity",mob)
meta:set_string("infotext",mob)
meta:set_int("active_objects",ao)
meta:set_int("active_objects_wider",aow)
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

30
mods/quests/dungeon.lua Executable file
View File

@ -0,0 +1,30 @@
minetest.register_craftitem("quests:dungeon_token",{
description = "Dungeon Token",
inventory_image = "quests_dungeon_token.png",
stack_max = 999,
on_use = function(itemstack, user, pointed_thing)
local message = ""
if pointed_thing.type == "node" then
local n = minetest.get_node(pointed_thing.under)
message = user:get_player_name() .. " taps their Dungeon Token loudly on a " .. minetest.registered_nodes[n.name]['description'] .. " to draw your attention to their many dungeon conquests!"
end
if pointed_thing.type == "object" then
if pointed_thing.ref:is_player() then
local n2 = pointed_thing.ref:get_player_name()
message = user:get_player_name() .. " hits " .. n2 .. " with their Dungeon Token to draw your attention to their many dungeon conquests!"
else
message = user:get_player_name() .. " waves their Dungeon Token around in the air to draw your attention to their many dungeon conquests!"
end
end
if pointed_thing.type == "nothing" then
message = user:get_player_name() .. " waves their Dungeon Token around in the air to draw your attention to their many dungeon conquests!"
end
if message ~= "" then
chat.local_chat(user:getpos(),message,25)
end
end,
})

View File

@ -2,4 +2,6 @@
quests = {}
dofile(minetest.get_modpath("quests").."/treasure.lua")
dofile(minetest.get_modpath("quests").."/chest.lua")
dofile(minetest.get_modpath("quests").."/chest.lua")
dofile(minetest.get_modpath("quests").."/markers.lua")
dofile(minetest.get_modpath("quests").."/dungeon.lua")

21
mods/quests/markers.lua Executable file
View File

@ -0,0 +1,21 @@
minetest.register_node( "quests:marker", {
description = "Quest Marker",
tiles = { "quests_marker.png" },
is_ground_content = false,
paramtype = "light",
sunlight_propagates = true,
light_source = 8,
diggable=false,
on_punch = function(pos, node, puncher, pointed_thing)
local m = minetest.get_meta(pos)
local message = m:get_string("message")
local drop = m:get_string("drop")
if message ~= nil then
minetest.chat_send_player(puncher:get_player_name(),message)
end
if drop ~= nil then
default.drop_item(puncher:getpos(),drop)
end
minetest.sound_play("quests_marker_punch",{pos=pos,gain=10,max_hear_distance=50})
end,
})

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B