Dateien nach "/" hochladen
This commit is contained in:
7
ai.lua
7
ai.lua
@@ -113,12 +113,15 @@ local function try_fire(self_ent, target_pos)
|
|||||||
local cd = weapon == "plasma" and SHOOT_COOLDOWN_PLASMA or SHOOT_COOLDOWN_BULLET
|
local cd = weapon == "plasma" and SHOOT_COOLDOWN_PLASMA or SHOOT_COOLDOWN_BULLET
|
||||||
if (now - (self_ent._ai_last_shot or 0)) < cd then return false end
|
if (now - (self_ent._ai_last_shot or 0)) < cd then return false end
|
||||||
|
|
||||||
-- Spider ammo check
|
-- Ammo check per weapon type
|
||||||
if weapon == "plasma" then
|
if weapon == "plasma" then
|
||||||
local ammo = self_ent._spider_ammo or SPIDER_AMMO_MAX
|
local ammo = self_ent._spider_ammo or SPIDER_AMMO_MAX
|
||||||
if ammo < SPIDER_AMMO_MIN_TO_FIRE then return false end
|
if ammo < SPIDER_AMMO_MIN_TO_FIRE then return false end
|
||||||
-- Consume ammo
|
|
||||||
self_ent._spider_ammo = math.max(0, ammo - SPIDER_AMMO_COST)
|
self_ent._spider_ammo = math.max(0, ammo - SPIDER_AMMO_COST)
|
||||||
|
elseif weapon == "bullet" then
|
||||||
|
local ammo = self_ent._fang_ammo or FANG_AMMO_MAX
|
||||||
|
if ammo < FANG_AMMO_MIN_TO_FIRE then return false end
|
||||||
|
self_ent._fang_ammo = math.max(0, ammo - FANG_AMMO_COST)
|
||||||
end
|
end
|
||||||
|
|
||||||
local my_pos = self_ent.object:get_pos()
|
local my_pos = self_ent.object:get_pos()
|
||||||
|
|||||||
90
init.lua
90
init.lua
@@ -14,12 +14,20 @@ dofile(modpath .. "/mecha_controller.lua")
|
|||||||
|
|
||||||
local MECH_EXPLOSION_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_explosion_damage")) or 100
|
local MECH_EXPLOSION_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_explosion_damage")) or 100
|
||||||
local MECH_BULLET_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_bullet_damage")) or 10
|
local MECH_BULLET_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_bullet_damage")) or 10
|
||||||
|
|
||||||
|
-- Spider (mech1) ammo config -- plasma cannon, 2 shots max
|
||||||
SPIDER_PLASMA_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_spider_plasma_damage")) or 1000
|
SPIDER_PLASMA_DAMAGE = tonumber(minetest.settings:get("assorted_mecha_spider_plasma_damage")) or 1000
|
||||||
SPIDER_AMMO_MAX = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_max")) or 100
|
SPIDER_AMMO_MAX = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_max")) or 100
|
||||||
SPIDER_AMMO_REGEN = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_regen")) or 2.0
|
SPIDER_AMMO_REGEN = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_regen")) or 2.0
|
||||||
SPIDER_AMMO_COST = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_cost")) or 50
|
SPIDER_AMMO_COST = tonumber(minetest.settings:get("assorted_mecha_spider_ammo_cost")) or 50
|
||||||
SPIDER_AMMO_MIN_TO_FIRE = SPIDER_AMMO_COST
|
SPIDER_AMMO_MIN_TO_FIRE = SPIDER_AMMO_COST
|
||||||
|
|
||||||
|
-- Fang (mech2) ammo config -- rapidfire, 0.1% cost per bullet = 1000 rounds at full
|
||||||
|
FANG_AMMO_MAX = tonumber(minetest.settings:get("assorted_mecha_fang_ammo_max")) or 100
|
||||||
|
FANG_AMMO_REGEN = tonumber(minetest.settings:get("assorted_mecha_fang_ammo_regen")) or 2.0
|
||||||
|
FANG_AMMO_COST = tonumber(minetest.settings:get("assorted_mecha_fang_ammo_cost")) or 0.1
|
||||||
|
FANG_AMMO_MIN_TO_FIRE = 5.0 -- 5% minimum to fire
|
||||||
|
|
||||||
local function apply_mech_scope(player, mech)
|
local function apply_mech_scope(player, mech)
|
||||||
if not player or not mech then return end
|
if not player or not mech then return end
|
||||||
|
|
||||||
@@ -58,23 +66,22 @@ local function ammo_bar_string(ammo_pct)
|
|||||||
return "[" .. bar .. "] " .. math.floor(ammo_pct) .. "%"
|
return "[" .. bar .. "] " .. math.floor(ammo_pct) .. "%"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_ammo_hud(player)
|
-- label: "PLASMA" for spider, "ROUNDS" for fang
|
||||||
|
local function add_ammo_hud(player, label)
|
||||||
if not player then return end
|
if not player then return end
|
||||||
local meta = player:get_meta()
|
local meta = player:get_meta()
|
||||||
|
|
||||||
-- Label
|
|
||||||
local label_id = player:hud_add({
|
local label_id = player:hud_add({
|
||||||
type = "text",
|
type = "text",
|
||||||
position = {x = 0.5, y = 0.88},
|
position = {x = 0.5, y = 0.88},
|
||||||
offset = {x = 0, y = -18},
|
offset = {x = 0, y = -18},
|
||||||
text = "PLASMA",
|
text = label or "AMMO",
|
||||||
alignment = {x = 0, y = 0},
|
alignment = {x = 0, y = 0},
|
||||||
scale = {x = 200, y = 60},
|
scale = {x = 200, y = 60},
|
||||||
number = 0x00FF99,
|
number = 0x00FF99,
|
||||||
})
|
})
|
||||||
meta:set_int("ammo_hud_label", label_id)
|
meta:set_int("ammo_hud_label", label_id)
|
||||||
|
|
||||||
-- Bar + percentage as text
|
|
||||||
local bar_id = player:hud_add({
|
local bar_id = player:hud_add({
|
||||||
type = "text",
|
type = "text",
|
||||||
position = {x = 0.5, y = 0.88},
|
position = {x = 0.5, y = 0.88},
|
||||||
@@ -99,12 +106,14 @@ local function remove_ammo_hud(player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function update_ammo_hud(player, ammo_pct)
|
-- min_to_fire: threshold below which the bar turns red
|
||||||
|
local function update_ammo_hud(player, ammo_pct, min_to_fire)
|
||||||
if not player then return end
|
if not player then return end
|
||||||
local meta = player:get_meta()
|
local meta = player:get_meta()
|
||||||
local bar_id = meta:get_int("ammo_hud_bar")
|
local bar_id = meta:get_int("ammo_hud_bar")
|
||||||
if bar_id and bar_id > 0 then
|
if bar_id and bar_id > 0 then
|
||||||
local color = ammo_pct >= SPIDER_AMMO_MIN_TO_FIRE and 0x00FF99 or 0xFF4444
|
local threshold = min_to_fire or SPIDER_AMMO_MIN_TO_FIRE
|
||||||
|
local color = ammo_pct >= threshold and 0x00FF99 or 0xFF4444
|
||||||
player:hud_change(bar_id, "text", ammo_bar_string(ammo_pct))
|
player:hud_change(bar_id, "text", ammo_bar_string(ammo_pct))
|
||||||
player:hud_change(bar_id, "number", color)
|
player:hud_change(bar_id, "number", color)
|
||||||
end
|
end
|
||||||
@@ -288,9 +297,11 @@ local function register_mech(mech)
|
|||||||
self._mech_stand_anim = mech.stand_animation
|
self._mech_stand_anim = mech.stand_animation
|
||||||
self._mech_head_name = mech.head_name
|
self._mech_head_name = mech.head_name
|
||||||
self._mech_name = mech.name
|
self._mech_name = mech.name
|
||||||
-- Initialize spider ammo (applies to all mechs using head_spider)
|
-- Initialize ammo for armed mechs
|
||||||
if mech.head_name == "assorted_mecha:head_spider" then
|
if mech.head_name == "assorted_mecha:head_spider" then
|
||||||
self._spider_ammo = self._spider_ammo or SPIDER_AMMO_MAX
|
self._spider_ammo = self._spider_ammo or SPIDER_AMMO_MAX
|
||||||
|
elseif mech.head_name == "assorted_mecha:head_2" and mech.name == "mech2" then
|
||||||
|
self._fang_ammo = self._fang_ammo or FANG_AMMO_MAX
|
||||||
end
|
end
|
||||||
-- Initialize AI state (restore from staticdata if available)
|
-- Initialize AI state (restore from staticdata if available)
|
||||||
assorted_mecha_ai_init(self)
|
assorted_mecha_ai_init(self)
|
||||||
@@ -344,7 +355,7 @@ local vel = self.object:get_velocity() or {x=0, y=0, z=0}
|
|||||||
vel.y = vel.y - (dtime * 9.8)
|
vel.y = vel.y - (dtime * 9.8)
|
||||||
self.object:set_velocity(vel)
|
self.object:set_velocity(vel)
|
||||||
|
|
||||||
-- Spider ammo: passive regen (all mechs using head_spider)
|
-- Spider ammo: passive regen
|
||||||
if mech.head_name == "assorted_mecha:head_spider" then
|
if mech.head_name == "assorted_mecha:head_spider" then
|
||||||
if (self._spider_ammo or SPIDER_AMMO_MAX) < SPIDER_AMMO_MAX then
|
if (self._spider_ammo or SPIDER_AMMO_MAX) < SPIDER_AMMO_MAX then
|
||||||
self._spider_ammo = math.min(
|
self._spider_ammo = math.min(
|
||||||
@@ -352,9 +363,21 @@ self.object:set_velocity(vel)
|
|||||||
(self._spider_ammo or 0) + SPIDER_AMMO_REGEN * dtime
|
(self._spider_ammo or 0) + SPIDER_AMMO_REGEN * dtime
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
-- Update HUD for the current driver
|
|
||||||
if self.driver then
|
if self.driver then
|
||||||
update_ammo_hud(self.driver, self._spider_ammo or SPIDER_AMMO_MAX)
|
update_ammo_hud(self.driver, self._spider_ammo or SPIDER_AMMO_MAX, SPIDER_AMMO_MIN_TO_FIRE)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Fang ammo: passive regen
|
||||||
|
if mech.name == "mech2" then
|
||||||
|
if (self._fang_ammo or FANG_AMMO_MAX) < FANG_AMMO_MAX then
|
||||||
|
self._fang_ammo = math.min(
|
||||||
|
FANG_AMMO_MAX,
|
||||||
|
(self._fang_ammo or 0) + FANG_AMMO_REGEN * dtime
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if self.driver then
|
||||||
|
update_ammo_hud(self.driver, self._fang_ammo or FANG_AMMO_MAX, FANG_AMMO_MIN_TO_FIRE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -505,8 +528,8 @@ clicker:set_properties({visual_size = {x=1, y=1, z=1}})
|
|||||||
clicker:hud_set_flags({crosshair = true, wielditem = true})
|
clicker:hud_set_flags({crosshair = true, wielditem = true})
|
||||||
clicker:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
|
clicker:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
|
||||||
clicker:get_meta():set_int("mech_third_person", 0)
|
clicker:get_meta():set_int("mech_third_person", 0)
|
||||||
-- Remove ammo HUD on dismount (spider only)
|
-- Remove ammo HUD on dismount
|
||||||
if mech.head_name == "assorted_mecha:head_spider" then
|
if mech.head_name == "assorted_mecha:head_spider" or mech.name == "mech2" then
|
||||||
remove_ammo_hud(clicker)
|
remove_ammo_hud(clicker)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -540,10 +563,13 @@ clicker:set_properties({visual_size = {x=1, y=1, z=1}})
|
|||||||
-- Scope overlay replaces crosshair; hide ingame crosshair & wielditem
|
-- Scope overlay replaces crosshair; hide ingame crosshair & wielditem
|
||||||
clicker:hud_set_flags({crosshair = false, wielditem = false})
|
clicker:hud_set_flags({crosshair = false, wielditem = false})
|
||||||
clicker:get_meta():set_int("mech_third_person", 0)
|
clicker:get_meta():set_int("mech_third_person", 0)
|
||||||
-- Show ammo HUD on mount (spider only)
|
-- Show ammo HUD on mount
|
||||||
if mech.head_name == "assorted_mecha:head_spider" then
|
if mech.head_name == "assorted_mecha:head_spider" then
|
||||||
add_ammo_hud(clicker)
|
add_ammo_hud(clicker, "PLASMA")
|
||||||
update_ammo_hud(clicker, self._spider_ammo or SPIDER_AMMO_MAX)
|
update_ammo_hud(clicker, self._spider_ammo or SPIDER_AMMO_MAX, SPIDER_AMMO_MIN_TO_FIRE)
|
||||||
|
elseif mech.name == "mech2" then
|
||||||
|
add_ammo_hud(clicker, "ROUNDS")
|
||||||
|
update_ammo_hud(clicker, self._fang_ammo or FANG_AMMO_MAX, FANG_AMMO_MIN_TO_FIRE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@@ -742,11 +768,39 @@ minetest.register_entity("assorted_mecha:head_2", {
|
|||||||
local control = target_player:get_player_control()
|
local control = target_player:get_player_control()
|
||||||
if control.aux1 and not self.is_firing then
|
if control.aux1 and not self.is_firing then
|
||||||
self.is_firing = true
|
self.is_firing = true
|
||||||
|
|
||||||
local function fire_loop()
|
local function fire_loop()
|
||||||
if self.is_firing and target_player then
|
if not self.is_firing or not target_player then return end
|
||||||
spawn_bullets(target_player)
|
|
||||||
minetest.after(0.1, fire_loop)
|
-- Find the mech2 body to read/write fang ammo
|
||||||
|
local mech_ent = nil
|
||||||
|
local hpos = self.object:get_pos()
|
||||||
|
for _, obj in ipairs(minetest.get_objects_inside_radius(hpos, 6)) do
|
||||||
|
if not obj:is_player() then
|
||||||
|
local e = obj:get_luaentity()
|
||||||
|
if e and e.name == "assorted_mecha:mech2" then
|
||||||
|
mech_ent = e
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ammo = mech_ent and (mech_ent._fang_ammo or FANG_AMMO_MAX) or FANG_AMMO_MAX
|
||||||
|
if ammo < FANG_AMMO_MIN_TO_FIRE then
|
||||||
|
-- Dry fire: stop shooting
|
||||||
|
self.is_firing = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
spawn_bullets(target_player)
|
||||||
|
|
||||||
|
-- Consume ammo and update HUD
|
||||||
|
if mech_ent then
|
||||||
|
mech_ent._fang_ammo = math.max(0, ammo - FANG_AMMO_COST)
|
||||||
|
update_ammo_hud(target_player, mech_ent._fang_ammo, FANG_AMMO_MIN_TO_FIRE)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.after(0.1, fire_loop)
|
||||||
end
|
end
|
||||||
fire_loop()
|
fire_loop()
|
||||||
elseif not control.aux1 then
|
elseif not control.aux1 then
|
||||||
|
|||||||
@@ -25,3 +25,13 @@ assorted_mecha_spider_ammo_regen (Spider Plasma Ammo Regen %/s) float 2.0 0.1 10
|
|||||||
# Spider plasma ammo cost per shot (in percent of max ammo).
|
# Spider plasma ammo cost per shot (in percent of max ammo).
|
||||||
# Default: 50 (= 2 shots when full)
|
# Default: 50 (= 2 shots when full)
|
||||||
assorted_mecha_spider_ammo_cost (Spider Plasma Ammo Cost per Shot %) int 50 10 100
|
assorted_mecha_spider_ammo_cost (Spider Plasma Ammo Cost per Shot %) int 50 10 100
|
||||||
|
|
||||||
|
# Fang rapidfire ammo settings
|
||||||
|
# Max ammo pool (percentage-based, always 100)
|
||||||
|
assorted_mecha_fang_ammo_max (Fang Max Ammo) int 100 50 200
|
||||||
|
|
||||||
|
# Fang ammo regen rate in percent per second. Default: 2.0 (~50s full reload)
|
||||||
|
assorted_mecha_fang_ammo_regen (Fang Ammo Regen %/s) float 2.0 0.1 10.0
|
||||||
|
|
||||||
|
# Fang ammo cost per bullet in percent. Default: 0.1 (= 1000 shots at full)
|
||||||
|
assorted_mecha_fang_ammo_cost (Fang Ammo Cost per Bullet %) float 0.1 0.01 5.0
|
||||||
|
|||||||
Reference in New Issue
Block a user