update 1.0.1

master
Noodlemire 2019-12-08 20:48:27 -05:00
parent beffb3f225
commit 6e171fcda6
309 changed files with 414 additions and 293 deletions

View File

@ -1,5 +1,5 @@
-------------------------------------------------------------------------------------------------------------
#Voxel Dungeon
Voxel Dungeon
-------------------------------------------------------------------------------------------------------------
This is a recreation and adaptation of an Android rogue-like game, Pixel Dungeon by Watabou, using Minetest's engine. In particular, it is about exploring and digging into the five layers of the underground, in which access to the next layer is granted only upon summoning and defeating the boss of the current layer. Each of the sections is characterized by distinct terrain, monsters, and new ores. The boss of the final layer will grant the Amulet of Yendor; the player who picks this up will win the game.

16
changelog.txt Normal file
View File

@ -0,0 +1,16 @@
Alpha 1.0.1:
Blobs:
No longer are anchored to entities
All of any one type are tied to the same instance; multiple blobs no longer repeatedly apply their effect when stacked inside of each other
A single blob also only applies its effect once per time frame
The applying of blob effects has been greatly streamlined and causes much less lag than before
New blobs no longer teleport some of themselves to any locations where previous blobs existed.
TL;DR: They actually work now.
Fixed:
Throwable items not being taken from the inventory in survival when thrown
Random level algorithm of weapons and armor causing +3 and +2 equipment to become much more common than intended.
Particles sometimes appearing far farther away from where they're intended to spawn
Visual:
Added some textures of grass, dirt, and cobblestone originating from Sprouted Pixel Dungeon

View File

@ -86,13 +86,19 @@ end
function entitycontrol.isAlive(index)
local ent = entitycontrol.get_entity(index)
if ent and ent:get_pos() then return true end
end
function entitycontrol.getFirstEmptyIndex(index)
index = index or 1
local ent = entitycontrol.get_entity(index)
if index > entitycontrol.count_entities() then
return nil
elseif ent and ent:get_pos() then
elseif entitycontrol.isAlive(index) then
return entitycontrol.getFirstEmptyIndex(index + 1)
else
return index

View File

@ -1,5 +1,5 @@
-------------------------------------------------------------------------------------------------------------
#Voxel Dungeon
Voxel Dungeon
-------------------------------------------------------------------------------------------------------------
This is a recreation and adaptation of an Android rogue-like game, Pixel Dungeon by Watabou, using Minetest's engine. In particular, it is about exploring and digging into the five layers of the underground, in which access to the next layer is granted only upon summoning and defeating the boss of the current layer. Each of the sections is characterized by distinct terrain, monsters, and new ores. The boss of the final layer will grant the Amulet of Yendor; the player who picks this up will win the game.

View File

@ -20,10 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
--]]
voxeldungeon.blobs = {}
--voxeldungeon.blobs.blob_instances = {}
voxeldungeon.blobs.registered_blobs = {}
local TIMESCALE = 2
local TIMESCALE = 1
local function expandUpon(posses, spreadcondition)
local newposses = voxeldungeon.smartVectorTable()
@ -32,13 +31,15 @@ local function expandUpon(posses, spreadcondition)
local p = posses.getVector(i)
local a = posses.getValue(i)
for _, n in pairs(voxeldungeon.utils.NEIGHBORS7) do
local newpos = vector.add(p, n)
if spreadcondition(newpos) then
if not posses.get(newpos) and not newposses.get(newpos) then
newposses.set(newpos, 0)
elseif posses.get(newpos) then
newposses.set(newpos, posses.get(newpos))
if a > 0 then
for _, n in pairs(voxeldungeon.utils.NEIGHBORS7) do
local newpos = vector.add(p, n)
if spreadcondition(newpos) then
if not posses.get(newpos) and not newposses.get(newpos) then
newposses.set(newpos, 0)
elseif posses.get(newpos) then
newposses.set(newpos, posses.get(newpos))
end
end
end
end
@ -47,115 +48,148 @@ local function expandUpon(posses, spreadcondition)
return newposses
end
function voxeldungeon.blobs.register(nme, spreadcondition, effect)
local name = "voxeldungeon:blob_"..nme
function voxeldungeon.blobs.register(name, spreadcondition, effect)
name = "voxeldungeon:blob_"..name
minetest.register_entity(name,
{
physical = false,
--textures = {"voxeldungeon_blank.png"},
collisionbox = {0, 0, 0, 0, 0, 0},
voxeldungeon.blobs.registered_blobs[name] = {}
local blob = voxeldungeon.blobs.registered_blobs[name]
blob.posses = voxeldungeon.smartVectorTable()
blob.offload = voxeldungeon.smartVectorTable()
blob.volume = 0
blob.timer = TIMESCALE
posses = voxeldungeon.smartVectorTable(),
offload = voxeldungeon.smartVectorTable(),
volume = 1000,
offvolume = 1000,
timer = TIMESCALE,
blob.on_step = function(dtime)
if blob.timer > 0 then
blob.timer = blob.timer - dtime
return
end
on_activate = function(self)
end,
on_step = function(self, dtime)
if self.timer > 0 then
self.timer = self.timer - dtime
return
end
self.timer = TIMESCALE
blob.timer = TIMESCALE
if self.volume > 0 then
self.volume = 0
if blob.volume > 0 then
blob.volume = 0
self._evolve(self)
blob.evolve()
local temp = self.offload
self.offload = self.posses
self.posses = temp
local temp = blob.offload
blob.offload = blob.posses
blob.posses = temp
self.offvolume = self.volume
else
self.object:remove()
return
end
end,
for i = 1, blob.posses.size() do
local p = blob.posses.getVector(i)
local v = blob.posses.getValue(i)
_evolve = function(self)
if not self.posses.get(self.object:get_pos()) then return end
local objs = {}
if self.offvolume / self.posses.size() >= 5 then
self.posses = expandUpon(self.posses, spreadcondition)
end
for _, player in ipairs(minetest.get_connected_players()) do
local pos = vector.round(player:get_pos())
for i = 1, self.posses.size() do
local p = self.posses.getVector(i)
local a = self.posses.getValue(i)
if vector.equals(pos, p) then
table.insert(objs, player)
end
end
if spreadcondition(p) then
local count = 1
local sum = a or 0
for e = 1, entitycontrol.count_entities() do
local entity = entitycontrol.get_entity(e)
for _, n in pairs(voxeldungeon.utils.NEIGHBORS6) do
local neighbor = vector.add(p, n)
if not voxeldungeon.utils.solid(neighbor) then
sum = sum + (self.posses.get(neighbor) or 0)
count = count + 1
if entitycontrol.isAlive(e) then
local pos = vector.round(entity:get_pos())
if vector.equals(pos, p) then
table.insert(objs, entity)
end
end
local value = 0
if sum >= count then
value = math.floor(sum / count) - 1
end
self.offload.set(p, value)
self.volume = self.volume + value
effect(p, value)
else
self.offload.del(p)
end
effect(blob, p, v, objs)
end
end,
end
end
_seed = function(self, amount)
self.volume = amount
self.offvolume = self.volume
self.posses.set(self.object:get_pos(), self.volume)
end,
})
voxeldungeon.blobs.registered_blobs[name] = minetest.registered_entities[name]
blob.evolve = function()
blob.offload = expandUpon(blob.posses, spreadcondition)
for i = 1, blob.offload.size() do
local p = blob.offload.getVector(i)
if spreadcondition(p) then
local count = 1
local sum = blob.posses.getValue(i) or 0
for _, n in pairs(voxeldungeon.utils.NEIGHBORS6) do
local neighbor = vector.add(p, n)
if not voxeldungeon.utils.solid(neighbor) then
sum = sum + (blob.posses.get(neighbor) or 0)
count = count + 1
end
end
local value = 0
if sum >= count then
value = math.floor(sum / count) - 1
end
blob.offload.set(p, value)
blob.volume = blob.volume + value
else
blob.offload.del(p)
end
end
end
blob.seed = function(pos, amount)
blob.volume = blob.volume + amount
blob.posses.set(pos, amount)
end
minetest.register_globalstep(blob.on_step)
end
function voxeldungeon.blobs.seed(nme, pos, amount)
local name = "voxeldungeon:blob_"..nme
function voxeldungeon.blobs.seed(name, pos, amount)
name = "voxeldungeon:blob_"..name
pos = vector.round(pos)
local obj = minetest.add_entity(pos, name)
if obj then
local blob = obj:get_luaentity()
blob._seed(blob, amount)
end
voxeldungeon.blobs.registered_blobs[name].seed(pos, amount)
end
voxeldungeon.blobs.register("toxicgas", function(pos)
return not voxeldungeon.utils.solid(pos)
end, function(pos, amount)
local objs = minetest.get_objects_inside_radius(pos, 1)
for _, obj in pairs(objs) do
obj:set_hp(obj:get_hp() - 1)
voxeldungeon.blobs.register("fire",
function(pos)
local node = minetest.get_node_or_nil(pos)
return true--node and minetest.get_item_group(node.name, "flammable") >= 1
end,
function(blob, pos, amount, objs)
for _, obj in ipairs(objs) do
if obj:is_player() then
obj:set_hp(obj:get_hp() - 2)
else
voxeldungeon.mobs.damage(obj, 2, "fire")
end
end
voxeldungeon.particles.factory("flame", pos, 1, TIMESCALE)
end
if math.random(5) == 1 then
voxeldungeon.particles.burst("toxic", pos, 1)
)
voxeldungeon.blobs.register("toxicgas",
function(pos)
return not voxeldungeon.utils.solid(pos)
end,
function(blob, pos, amount, objs)
for _, obj in ipairs(objs) do
if obj:is_player() then
obj:set_hp(obj:get_hp() - voxeldungeon.utils.getChapter(pos))
else
voxeldungeon.mobs.damage(obj, voxeldungeon.utils.getChapter(pos), "toxic gas")
end
end
if voxeldungeon.utils.randomDecimal(blob.posses.size() / (blob.posses.size() + 2)) <= 1/3 then
voxeldungeon.particles.burst("toxic", pos, 1)
end
end
end)
)

View File

@ -0,0 +1,18 @@
Alpha 1.0.1:
Blobs:
No longer are anchored to entities
All of any one type are tied to the same instance; multiple blobs no longer repeatedly apply their effect when stacked inside of each other
A single blob also only applies its effect once per time frame
The applying of blob effects has been greatly streamlined and causes much less lag than before
New blobs no longer teleport some of themselves to any locations where previous blobs existed.
TL;DR: They actually work now.
Fixed:
Throwable items not being taken from the inventory in survival when thrown
Random level algorithm of weapons and armor causing +3 and +2 equipment to become much more common than intended.
Particles sometimes appearing far farther away from where they're intended to spawn
Punching often dealing no damage to rats.
Visual:
Added some textures of grass, dirt, and cobblestone originating from Sprouted Pixel Dungeon
Toxic particles now spin

View File

@ -1,47 +0,0 @@
--[[
Voxel Dungeon
Copyright (C) 2019 Noodlemire
Pixel Dungeon
Copyright (C) 2012-2015 Oleg Dolya
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
--]]
--A set of methods commonly caused by a variety of mechanics
function voxeldungeon.randomteleport(obj)
for try = 1, 10 do
local p = obj:get_pos()
local testpos =
{
x = p.x + math.random(-100, 100),
y = p.y + 0.5,
z = p.z + math.random(-100, 100)
}
if not minetest.registered_nodes[minetest.get_node(testpos).name].walkable then
obj:set_pos(testpos)
minetest.sound_play("voxeldungeon_teleport",
{
pos = obj:get_pos(),
gain = 1.0,
max_hear_distance = 32,
})
return
end
end
end

View File

@ -259,19 +259,24 @@ local weaponChances = {
},
}
function voxeldungeon.generator.randomArmor(t)
local tier = t or 1
local arm = voxeldungeon.utils.randomChances(armorChances[tier])
local function randomLevel()
local level = 0
for i = 3, 1, -1 do
if math.random(3 * i) == 1 then
if math.random(math.pow(3, i)) == 1 then
level = i
end
end
return level
end
function voxeldungeon.generator.randomArmor(t)
local tier = t or 1
local arm = voxeldungeon.utils.randomChances(armorChances[tier])
local itemstack = ItemStack({name = arm, count = 1, wear = 0, metadata = ""})
voxeldungeon.tools.setLevelOf(itemstack, level)
voxeldungeon.tools.setLevelOf(itemstack, randomLevel())
return itemstack
end
@ -308,16 +313,9 @@ end
function voxeldungeon.generator.randomWeapon(t)
local tier = t or 1
local wep = voxeldungeon.utils.randomChances(weaponChances[tier])
local level = 0
for i = 3, 1, -1 do
if math.random(3 * i) == 1 then
level = i
end
end
local itemstack = ItemStack({name = wep, count = 1, wear = 0, metadata = ""})
voxeldungeon.tools.setLevelOf(itemstack, level)
voxeldungeon.tools.setLevelOf(itemstack, randomLevel())
return itemstack
end

View File

@ -30,7 +30,6 @@ voxeldungeon.wp = minetest.get_worldpath()..'/'
--Load library files
dofile(mp.."utils.lua")
dofile(mp.."override.lua")
dofile(mp.."commoneffects.lua")
dofile(mp.."smartvectortable.lua")
dofile(mp.."glog.lua")
dofile(mp.."playerhandler.lua")

View File

@ -19,39 +19,64 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
--]]
minetest.register_craftitem("voxeldungeon:bomb", {
description = voxeldungeon.utils.itemDescription("Bomb\n \nThis is a relatively small bomb, filled with black powder. Conveniently, its fuse is lit automatically when the bomb is thrown.\n \nRight-click while holding a bomb to throw it."),
inventory_image = "voxeldungeon_item_bomb.png",
on_place = function(itemstack, placer, pointed_thing)
tnt.boom(pointed_thing.above, {radius = 2, damage_radius = 2})
end,
on_secondary_use = function(itemstack, user, pointed_thing)
local function get_pointed_pos(pointed_thing)
if pointed_thing.type == "node" then
return pointed_thing.above
elseif pointed_thing.type == "object" then
return pointed_thing.ref:get_pos()
end
end
function voxeldungeon.register_throwingitem(name, desc, callback, itemdef, entdef)
itemdef = itemdef or {}
entdef = entdef or {}
itemdef.description = voxeldungeon.utils.itemDescription(desc)
itemdef.inventory_image = itemdef.inventory_image or "voxeldungeon_item_"..name..".png"
itemdef.on_place = function(itemstack, placer, pointed_thing)
callback(get_pointed_pos(pointed_thing))
return voxeldungeon.utils.take_item(placer, itemstack)
end
itemdef.on_secondary_use = function(itemstack, user, pointed_thing)
local pos = vector.add(user:get_pos(), {x=0, y=1, z=0})
local offset = vector.multiply(user:get_look_dir(), 2)
local projectile = minetest.add_entity(vector.add(pos, offset), "voxeldungeon:thrown_bomb")
local projectile = minetest.add_entity(vector.add(pos, offset), "voxeldungeon:thrown_"..name)
projectile:set_velocity(vector.multiply(offset, 8))
projectile:set_acceleration({x = 0, y = -12, z = 0})
return voxeldungeon.utils.take_item(user, itemstack)
end
})
minetest.register_entity("voxeldungeon:thrown_bomb", {
initial_properties = {
entdef.initial_properties = {
visual = "sprite",
pointable = false,
textures = {"voxeldungeon_item_bomb.png"},
},
textures = {(itemdef.inventory_image or "voxeldungeon_item_"..name..".png")},
}
on_step = function(self, dtime)
entdef.on_step = function(self, dtime)
local pos = self.object:get_pos()
if voxeldungeon.utils.solid(vector.add(pos, vector.normalize(self.object:get_velocity()))) then
tnt.boom(pos, {radius = 2, damage_radius = 2})
callback(pos)
self.object:remove()
end
end
})
minetest.register_craftitem("voxeldungeon:"..name, itemdef)
minetest.register_entity("voxeldungeon:thrown_"..name, entdef)
end
voxeldungeon.register_throwingitem("bomb", "Bomb\n \nThis is a relatively small bomb, filled with black powder. Conveniently, its fuse is lit automatically when the bomb is thrown.\n \nRight-click while holding a bomb to throw it.", function(pos)
tnt.boom(pos, {radius = 2, damage_radius = 2})
end)
minetest.register_craftitem("voxeldungeon:demonite_lump", {
description = "Demonite Lump",
@ -88,42 +113,9 @@ minetest.register_craftitem("voxeldungeon:gold", {
stack_max = 99999,
})
minetest.register_craftitem("voxeldungeon:honeypot", {
description = voxeldungeon.utils.itemDescription("Honeypot\n \nThis large honeypot is only really lined with honey, instead it houses a giant bee! These sorts of massive bees usually stay in their hives, perhaps the pot is some sort of specialized trapper's cage? The bee seems pretty content inside the pot with its honey, and buzzes at you warily when you look at it.\n \nRight-click while holding a honeypot to throw it."),
inventory_image = "voxeldungeon_item_honeypot.png",
on_place = function(itemstack, placer, pointed_thing)
minetest.add_entity(pointed_thing.above, "voxeldungeon:bee")
end,
on_secondary_use = function(itemstack, user, pointed_thing)
local pos = vector.add(user:get_pos(), {x=0, y=1, z=0})
local offset = vector.multiply(user:get_look_dir(), 2)
local projectile = minetest.add_entity(vector.add(pos, offset), "voxeldungeon:thrown_honeypot")
projectile:set_velocity(vector.multiply(offset, 8))
projectile:set_acceleration({x = 0, y = -12, z = 0})
end
})
minetest.register_entity("voxeldungeon:thrown_honeypot", {
initial_properties = {
visual = "sprite",
pointable = false,
textures = {"voxeldungeon_item_honeypot.png"},
},
on_step = function(self, dtime)
local pos = self.object:get_pos()
if voxeldungeon.utils.solid(vector.add(pos, vector.normalize(self.object:get_velocity()))) then
minetest.add_entity(pos, "voxeldungeon:bee")
self.object:remove()
end
end
})
voxeldungeon.register_throwingitem("honeypot", "Honeypot\n \nThis large honeypot is only really lined with honey, instead it houses a giant bee! These sorts of massive bees usually stay in their hives, perhaps the pot is some sort of specialized trapper's cage? The bee seems pretty content inside the pot with its honey, and buzzes at you warily when you look at it.\n \nRight-click while holding a honeypot to throw it.", function(pos)
minetest.add_entity(pos, "voxeldungeon:bee")
end)
minetest.override_item("default:torch", {
description = voxeldungeon.utils.itemDescription("Torch\n \nIt's an indispensable item in the underground, which is notorious for its poor ambient lighting."),

View File

@ -61,7 +61,7 @@ mobs:register_mob("voxeldungeon:rat", {
damage = 3,
hp_min = 8,
hp_max = 8,
armor = 99,
armor = 100,
collisionbox = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4},
visual = "sprite",
textures = {"voxeldungeon_icon_mob_rat.png"},

View File

@ -24,30 +24,40 @@ voxeldungeon.particles = {}
local registered_particles = {}
local registered_factories = {}
function voxeldungeon.particles.register_particle(name, radius, lifespan, gravity, transformation, drawtype, yscale)
local function randomVel()
return math.random(-1/3, 1/3)
end
function voxeldungeon.particles.register_particle(name, radius, lifespan, gravity, initialize, transformation, drawtype, yscale, frames)
local scale = radius * 0.125
frames = frames or 1
minetest.register_entity("voxeldungeon:particle_"..name,
{
physical = false,
timer = 0,
_timer = 0,
textures = {"voxeldungeon_particle_"..name..".png"},
visual_size =
{
x = scale,
y = scale * (yscale or 1)
initial_properties = {
physical = false,
textures = {"voxeldungeon_particle_"..name..".png"},
visual_size =
{
x = scale,
y = scale * (yscale or 1)
},
collisionbox = {0, 0, 0, 0, 0, 0},
visual = drawtype or "sprite",
spritediv = {x = 1, y = frames}
},
collisionbox = {0, 0, 0, 0, 0, 0},
visual = drawtype or "sprite",
on_activate = function(self, staticdata)
local obj = self.object
obj:setvelocity(
{
x=(math.random(0,60)-30)/45,
y=(math.random(0,60)-30)/45,
z=(math.random(0,60)-30)/45
x = randomVel(),
y = randomVel(),
z = randomVel(),
})
local v = obj:get_velocity()
local ax = v.x
if ax ~= 0 then ax = -ax / math.abs(ax) / lifespan / 2 end
@ -58,13 +68,15 @@ function voxeldungeon.particles.register_particle(name, radius, lifespan, gravit
obj:setacceleration({x=ax, y=ay+gravity, z=az})
obj:setyaw(math.random(0,359)/180*math.pi)
if initialize then initialize(self) end
end,
on_step = function(self, dtime)
transformation(self, lifespan)
if transformation then transformation(self, lifespan) end
self.timer = self.timer+dtime
if self.timer >= lifespan then
self._timer = self._timer+dtime
if self._timer >= lifespan then
self.object:remove()
end
end,
@ -74,8 +86,8 @@ function voxeldungeon.particles.register_particle(name, radius, lifespan, gravit
{
visual_size =
{
x = scale + self.timer * change,
y = scale * (yscale or 1) + self.timer * change
x = scale + self._timer * change,
y = scale * (yscale or 1) + self._timer * change
}
})
end,
@ -84,8 +96,24 @@ end
voxeldungeon.particles.register_particle("poison", 1, 0.6, -1, function(self, lifespan)
local timer = self.timer
voxeldungeon.particles.register_particle("flame", 8, 0.8, 1,
function(self)
local gbyte = math.random(155, 222)
local ghex = voxeldungeon.utils.tohex(gbyte)
self.object:settexturemod("^[colorize:#FF"..ghex.."00")
end,
function(self, lifespan)
self.resize(self, -0.125)
end
)
voxeldungeon.particles.register_particle("grass", 1, 1.2, 1, nil, function(self, lifespan)
self.resize(self, -0.075)
end)
voxeldungeon.particles.register_particle("poison", 1, 0.6, -1, nil, function(self, lifespan)
local timer = self._timer
local sbyte = 150 + (lifespan - timer) / lifespan * 100
local shex = voxeldungeon.utils.tohex(sbyte)
@ -96,24 +124,26 @@ voxeldungeon.particles.register_particle("poison", 1, 0.6, -1, function(self, li
self.resize(self, 0.125)
end)
voxeldungeon.particles.register_particle("grass", 1, 1.2, 1, function(self, lifespan)
self.resize(self, -0.075)
end)
voxeldungeon.particles.register_particle("shaft", 2, 1.2, 0, nil, nil, "upright_sprite", 8)
voxeldungeon.particles.register_particle("shaft", 2, 1.2, 0, function(self, lifespan) end, "upright_sprite", 8)
voxeldungeon.particles.register_particle("toxic", 8, 3, 0,
function(self)
self.object:set_sprite({x = 0, y = 0}, 12, voxeldungeon.utils.randomDecimal(0.4, 0.3), false)
end,
voxeldungeon.particles.register_particle("toxic", 8, 3, 0, function(self, lifespan)
self.resize(self, 0.05)
end)
function(self, lifespan)
self.resize(self, 0.25)
end, "sprite", 1, 12
)
function voxeldungeon.particles.burst(name, pos, amount)
pos = vector.add(pos,
{
x = math.random(-0.5, 0.5),
y = math.random(-0.5, 0.5),
z = math.random(-0.5, 0.5),
x = voxeldungeon.utils.randomDecimal(0.25, -0.25),
y = voxeldungeon.utils.randomDecimal(0.25, -0.25),
z = voxeldungeon.utils.randomDecimal(0.25, -0.25),
})
for i = 1, amount do

View File

@ -161,7 +161,7 @@ end
voxeldungeon.register_plant("fadeleaf", "Fadeleaf\n \nTouching a Fadeleaf will teleport any creature to a random place within 100 blocks.", function(pos, objs)
for i = 1, #objs do
voxeldungeon.randomteleport(objs[i])
voxeldungeon.utils.randomteleport(objs[i])
end
end)

View File

@ -29,7 +29,6 @@ local potion_defs =
voxeldungeon.playerhandler.changeSTR(user, 1)
voxeldungeon.glog.p("Newfound strength surges through your body.", user)
voxeldungeon.tools.updateStrdiffArmor(user)
return voxeldungeon.utils.take_item(user, itemstack)
end
},
{
@ -43,6 +42,14 @@ local potion_defs =
{
name = "liquidflame",
desc = "Liquid Flame",
shatter = function(pos)
--[[for _, n in ipairs(voxeldungeon.utils.NEIGHBORS27) do
local f = vector.add(pos, n)
voxeldungeon.blobs.seed("fire", f, 200)
end--]]
end
},
{
name = "might",
@ -154,36 +161,25 @@ local function default_shatter(pos, color)
end
local function register_potion(name, desc, color, drink, shatter)
minetest.register_entity("voxeldungeon:thrownpotion_"..color, {
initial_properties = {
visual = "sprite",
pointable = false,
textures = {"voxeldungeon_item_potion_"..color..".png"},
},
on_step = function(self, dtime)
if voxeldungeon.utils.solid(vector.add(self.object:get_pos(), vector.normalize(self.object:get_velocity()))) then
if shatter then
shatter(self.object:get_pos())
else
default_shatter(self.object:get_pos(), color)
end
self.object:remove()
end
end
})
minetest.register_craftitem("voxeldungeon:potion_"..name,
{
description = voxeldungeon.utils.itemDescription("Potion of "..desc..
voxeldungeon.register_throwingitem("potion_"..name, "Potion of "..desc..
"\n \nLeft click while holding a potion to drink it."..
"\nRight click while holding a potion to throw it."),
"\nRight click while holding a potion to throw it.",
function(pos)
if shatter then
shatter(pos)
else
default_shatter(pos, color)
end
end,
{
inventory_image = "voxeldungeon_item_potion_"..color..".png",
_cornerLR = "voxeldungeon_icon_potion_"..name..".png",
on_use = drink or function(itemstack, user)
if shatter then
on_use = function(itemstack, user)
if drink then
drink(itemstack, user)
elseif shatter then
shatter(user:get_pos())
else
default_shatter(user:get_pos(), color)
@ -191,25 +187,6 @@ local function register_potion(name, desc, color, drink, shatter)
return voxeldungeon.utils.take_item(user, itemstack)
end,
on_place = function(itemstack, placer, pointed_thing)
if shatter then
shatter(pointed_thing.above)
else
default_shatter(pointed_thing.above, color)
end
return voxeldungeon.utils.take_item(placer, itemstack)
end,
on_secondary_use = function(itemstack, user, pointed_thing)
local pos = vector.add(user:get_pos(), {x=0, y=1, z=0})
local offset = vector.multiply(user:get_look_dir(), 2)
local projectile = minetest.add_entity(vector.add(pos, offset), "voxeldungeon:thrownpotion_"..color)
projectile:set_velocity(vector.multiply(offset, 8))
projectile:set_acceleration({x = 0, y = -12, z = 0})
end,
})
end

View File

@ -111,7 +111,7 @@ local scroll_defs =
desc = "Teleportation\n \nThe spell on this parchment instantly transports the reader to a random location up to 100 blocks away. It can be used to escape a dangerous situation, but an unlucky reader might find himself in an even more dangerous place.",
read = function(itemstack, user, pointed_thing)
voxeldungeon.randomteleport(user)
voxeldungeon.utils.randomteleport(user)
return voxeldungeon.utils.take_item(user, itemstack)
end
},

View File

@ -25,8 +25,6 @@ function voxeldungeon.smartVectorTable()
svt.table = {}
svt.set = function(keyVect, value)
if not keyVect or not value then return end
for _, v in ipairs(svt.table) do
if vector.equals(keyVect, v.k) then
v.v = value
@ -37,6 +35,11 @@ function voxeldungeon.smartVectorTable()
table.insert(svt.table, {k = keyVect, v = value})
end
svt.add = function(keyVect, value)
local old = svt.get(keyVect) or 0
svt.set(keyVect, old + value)
end
svt.del = function(keyVect)
for i, v in ipairs(svt.table) do
if vector.equals(keyVect, v.k) then
@ -57,10 +60,12 @@ function voxeldungeon.smartVectorTable()
end
svt.getVector = function(i)
if not svt.table[i] then return end
return svt.table[i].k
end
svt.getValue = function(i)
if not svt.table[i] then return end
return svt.table[i].v
end
@ -68,6 +73,17 @@ function voxeldungeon.smartVectorTable()
return #svt.table
end
svt.combineWith = function(other)
for i = 1, other.size() do
local k = other.getVector(i)
local v = other.getValue(i)
local old = svt.get(k) or 0
svt.set(k, old + v)
end
end
--[[
svt.iterator = function()
local function SVTiterate(i)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -19,8 +19,27 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
--]]
voxeldungeon.tools = {}
if not minetest.settings:get_bool("creative_mode") then
minetest.override_item("", {
tool_capabilities = {
full_punch_interval = 0.667,
max_drop_level = 0,
groupcaps = {
crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
oddly_breakable_by_hand = {times={[1]=3.50,[2]=2.00,[3]=0.70}, uses=0}
},
damage_groups = {fleshy = 1},
}
})
end
minetest.override_item("default:pick_wood", {
max_drop_level=1
})

View File

@ -87,6 +87,37 @@ voxeldungeon.utils.NEIGHBORS26 =
{x = 1, y = 1, z = 1},
}
voxeldungeon.utils.NEIGHBORS27 =
{
{x = -1, y = -1, z = -1},
{x = 0, y = -1, z = -1},
{x = 1, y = -1, z = -1},
{x = -1, y = 0, z = -1},
{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = -1},
{x = -1, y = 1, z = -1},
{x = 0, y = 1, z = -1},
{x = 1, y = 1, z = -1},
{x = -1, y = -1, z = 0},
{x = 0, y = -1, z = 0},
{x = 1, y = -1, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = 0, z = 0},
{x = 1, y = 0, z = 0},
{x = -1, y = 1, z = 0},
{x = 0, y = 1, z = 0},
{x = 1, y = 1, z = 0},
{x = -1, y = -1, z = 1},
{x = 0, y = -1, z = 1},
{x = 1, y = -1, z = 1},
{x = -1, y = 0, z = 1},
{x = 0, y = 0, z = 1},
{x = 1, y = 0, z = 1},
{x = -1, y = 1, z = 1},
{x = 0, y = 1, z = 1},
{x = 1, y = 1, z = 1},
}
voxeldungeon.utils.surface_valid_ground = {"default:dirt_with_grass", "default:dirt_with_coniferous_litter", "default:dirt_with_rainforest_litter",
@ -226,6 +257,38 @@ function voxeldungeon.utils.randomChances(chanceTable)
end
end
function voxeldungeon.utils.randomDecimal(upper, lower)
upper = upper or 1
lower = lower or 0
return lower + (math.random(0, 10000) / 10000) * (upper - lower)
end
function voxeldungeon.utils.randomteleport(obj)
for try = 1, 10 do
local p = obj:get_pos()
local testpos =
{
x = p.x + math.random(-100, 100),
y = p.y + 0.5,
z = p.z + math.random(-100, 100)
}
if not minetest.registered_nodes[minetest.get_node(testpos).name].walkable then
obj:set_pos(testpos)
minetest.sound_play("voxeldungeon_teleport",
{
pos = obj:get_pos(),
gain = 1.0,
max_hear_distance = 32,
})
return
end
end
end
function voxeldungeon.utils.round(num)
return math.floor(num + .5)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 68 B

View File

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 268 B

View File

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View File

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 258 B

View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 248 B

View File

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 440 B

After

Width:  |  Height:  |  Size: 440 B

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

View File

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

Some files were not shown because too many files have changed in this diff Show More