Skip to content

Commit

Permalink
Merge pull request #2 from MihailRis/health
Browse files Browse the repository at this point in the history
Add health system
  • Loading branch information
MihailRis authored Dec 1, 2024
2 parents 83c3380 + 147bb0b commit 3ea3f6d
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 28 deletions.
2 changes: 1 addition & 1 deletion layouts/health_bar.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<container size="520,36" gravity="bottom-center" margin="0,0,0,70">
<container size="520,36" gravity="bottom-center" margin="0,0,0,70" z-index="-2">
<image id="hp_0" src="gui/health_point" size="32"/>
<image id="hp_1" src="gui/health_point" size="32" pos="24,0"/>
<image id="hp_2" src="gui/health_point" size="32" pos="48,0"/>
Expand Down
19 changes: 19 additions & 0 deletions layouts/health_bar.xml.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
local survival_hud = require "survival_hud"
local gamemodes = require "gamemodes"

function survival_hud.set_health(health)
for i=1,10 do
local img = "gui/health_point"
if i * 2 - 1 == health then
img = "gui/health_point_half"
elseif i * 2 > health then
img = "gui/health_point_off"
end
document["hp_"..tostring(i - 1)].src = img
end
end

function on_open()
local health = gamemodes.get_player_health(hud.get_player())
survival_hud.set_health(health.get_health())
end
9 changes: 9 additions & 0 deletions modules/gamemodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ local gamemodes = {
players = {}
}

function gamemodes.get_player_health(playerid)
local entity = entities.get(player.get_entity(playerid))
return entity:get_component("base_survival:health")
end


function gamemodes.set(playerid, name)
local gamemode = gamemodes.get(playerid)
if name == "developer" then
Expand All @@ -28,6 +34,7 @@ function gamemodes.set(playerid, name)
player.set_noclip(playerid, false)
end
gamemode.current = name
events.emit("base_survival:gamemodes.set", playerid, name)
end

function gamemodes.exists(name)
Expand All @@ -39,6 +46,8 @@ function gamemodes.get(playerid)
gamemodes.players[playerid] = {
current=player.is_infinite_items(playerid)
and "developer" or "survival"}
events.emit("base_survival:gamemodes.set", playerid,
gamemodes.players[playerid].current)
end
return gamemodes.players[playerid]
end
Expand Down
2 changes: 2 additions & 0 deletions modules/survival_hud.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
local survival_hud = {}
return survival_hud
71 changes: 68 additions & 3 deletions scripts/components/health.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,76 @@
local health = ARGS.health or ARGS.max_health or SAVED_DATA.health
local max_health = ARGS.max_health or SAVED_DATA.max_health
local gamemodes = require "gamemodes"
local base_util = require "base:util"

local health = SAVED_DATA.health or ARGS.health or ARGS.max_health or 20
local max_health = SAVED_DATA.max_health or ARGS.max_health or 20

health = math.ceil(health)

local fall_timer = 0.0

local immortal
local spawnpoint
local invid

function set_player(pid)
local gamemode = gamemodes.get(pid).current
immortal = gamemode ~= "survival"
spawnpoint = {player.get_spawnpoint(pid)}
invid = player.get_inventory(pid)
end

function get_health()
return health
return health or 15
end

function set_health(value)
health = math.min(math.max(0, value), max_health)
events.emit("base_survival:health.set", entity, health)
end

function die()
set_health(max_health)
if invid then
local pos = entity.transform:get_pos()
local size = inventory.size(invid)
for i=0,size-1 do
local itemid, count = inventory.get(invid, i)
if itemid ~= 0 then
base_util.drop(pos, itemid, count).rigidbody:set_vel(vec3.spherical_rand(5.0))
inventory.set(invid, i, 0)
end
end
end
if spawnpoint then
entity.transform:set_pos(spawnpoint)
end
events.emit("base_survival:death", entity)
end

function damage(points)
if immortal then
return
end
set_health(health - points)
if health == 0 then
die()
end
end

function on_save()
SAVED_DATA.health = health
SAVED_DATA.max_health = max_health
end

function on_grounded(force)
local dmg = 5 * fall_timer * fall_timer - 3
damage(math.max(0, math.floor(dmg)))
end

function on_update(tps)
fall_timer = fall_timer + 1.0 / tps
end

function on_fall()
fall_timer = 0.0
end
18 changes: 17 additions & 1 deletion scripts/hud.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
local gamemodes = require "gamemodes"
local survival_hud = require "survival_hud"

function on_hud_open()
-- hud.open_permanent("base_survival:health_bar")
events.on("base_survival:gamemodes.set", function(playerid, name)
if name == "survival" then
hud.open_permanent("base_survival:health_bar")

local entity = entities.get(player.get_entity(playerid))
local health = entity:get_component("base_survival:health")
survival_hud.set_health(health.get_health())
else
hud.close("base_survival:health_bar")
end
end)
events.on("base_survival:health.set", function(entity, health)
if entity:get_uid() == player.get_entity(hud.get_player()) then
survival_hud.set_health(health)
end
end)

console.add_command("gamemode player:sel=$obj.id name:str=''",
"Set game mode",
Expand Down
40 changes: 17 additions & 23 deletions scripts/world.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,34 @@ local function get_durability(id)
if block.get_model(id) == "X" then
return 0.0
end
local material = block.material(id)
if material == "base:ground" or
material == "base:grass_block" or
material == "base:sand" then
return 0.7
elseif material == "base:glass" then
return 0.4
elseif material == "base:grass" then
return 1.0
end
return 5.0
end

local function get_drop(id, playerid)
local function get_drop(id, pid)
return block.get_picking_item(id), 1
end

local function stop_breaking(target)
events.emit("base_survival:stop_destroy", playerid, target)
events.emit("base_survival:stop_destroy", pid, target)
target.breaking = false
end

function on_player_tick(playerid, tps)
if gamemodes.get(playerid).current ~= "survival" then
function on_player_tick(pid, tps)
local gamemode = gamemodes.get(pid).current
local phealth = gamemodes.get_player_health(pid)
phealth.set_player(pid)

if gamemode ~= "survival" then
return
end
local target = breaking_blocks[playerid]
local target = breaking_blocks[pid]
if not target then
target = {breaking=false}
breaking_blocks[playerid] = target
breaking_blocks[pid] = target
end

if input.is_active("player.destroy") then
local x, y, z = player.get_selected_block(playerid)
local x, y, z = player.get_selected_block(pid)
if target.breaking then
if block.get(x, y, z) ~= target.id or
x ~= target.x or y ~= target.y or z ~= target.z then
Expand All @@ -54,10 +48,10 @@ function on_player_tick(playerid, tps)
target.progress = target.progress + (1.0/tps) * speed
target.tick = target.tick + 1
if target.progress >= 1.0 then
block.destruct(x, y, z, playerid)
block.destruct(x, y, z, pid)
return stop_breaking(target)
end
events.emit("base_survival:progress_destroy", playerid, target)
events.emit("base_survival:progress_destroy", pid, target)
elseif x ~= nil then
target.breaking = true
target.id = block.get(x, y, z)
Expand All @@ -66,17 +60,17 @@ function on_player_tick(playerid, tps)
target.z = z
target.tick = 0
target.progress = 0.0
events.emit("base_survival:start_destroy", playerid, target)
events.emit("base_survival:start_destroy", pid, target)
end
elseif target.wrapper then
stop_breaking(target)
end
end

function on_block_broken(id, x, y, z, playerid)
if gamemodes.get(playerid).current ~= "survival" then
function on_block_broken(id, x, y, z, pid)
if gamemodes.get(pid).current ~= "survival" then
return
end
local dropid, count = get_drop(id, playerid)
local dropid, count = get_drop(id, pid)
base_util.drop({x + 0.5, y + 0.5, z + 0.5}, dropid, count)
end

0 comments on commit 3ea3f6d

Please sign in to comment.