饥荒Mod

modmain.lua

lua 复制代码
PrefabFiles = {
	"rock_avocado_fruit_bomb",
    "fig_light",
}
local MAX_RANGE = 5
local BASE_DAMAGE = 20
local DAMAGE_PER_ROCK_AVOCADO = 200
local RANGE_PER_ROCK_AVOCADO = 1
local BASE_RANGE = 1
local FILL_AMOUNT = 0.06
local BASE_FILL = 0.01
local function OnFilled(inst, filler)
    if inst.components.fueled:GetPercent() >= 1 then
        if filler and filler.components.talker then
            filler.components.talker:Say("塞不下了")
        end
        return false
    end
    
    local current_percent = inst.components.fueled:GetPercent()
    local new_percent = math.min(1, current_percent + FILL_AMOUNT)
    inst.components.fueled:SetPercent(new_percent)
    
    local added_rocks = math.floor((new_percent - BASE_FILL) / FILL_AMOUNT + 0.5)
    inst.damage:set(BASE_DAMAGE + added_rocks * DAMAGE_PER_ROCK_AVOCADO)
    inst.range:set(math.min(BASE_RANGE + added_rocks * RANGE_PER_ROCK_AVOCADO, MAX_RANGE))
    
    
    return true
end
AddSimPostInit(function()
    local old_ADDFUEL_fn = GLOBAL.ACTIONS.ADDFUEL.fn  -- 保存原版动作函数

    GLOBAL.ACTIONS.ADDFUEL.fn = function(act)
        local target = act.target
        local item = act.invobject
        -- 仅当目标是你的特殊物品时进行拦截
        if target and target:HasTag("rock_avocado_device") then
            -- 检查燃料是否是岩石果
            if not item or item.prefab ~= "rock_avocado_fruit" then
                -- 拒绝并提示
                if act.doer and act.doer.components.talker then
                    act.doer.components.talker:Say("只能用石果装填!")
                end
                return true
            end
            -- 是岩石果,交给原版动作处理燃料添加
            if not OnFilled(target,act.doer) then
                return true
            end
            return old_ADDFUEL_fn(act)
        end
        
        -- 不是你的特殊物品,完全交给原版动作
        return old_ADDFUEL_fn(act)
    end
    AddRecipe2("goldnugget",--黄金
        {
            Ingredient("rock_avocado_fruit_ripe", 2),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("petals",  -- 花瓣
        {
            Ingredient("rock_avocado_fruit_ripe", 1),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("cutreeds",  -- 芦苇
        {
            Ingredient("rock_avocado_fruit_ripe", 1),
            Ingredient("cutgrass", 1),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("pigskin",  -- 猪皮
        {
            Ingredient("rock_avocado_fruit_ripe", 5),
            Ingredient("papyrus", 1),
            Ingredient("meat", 1),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("manrabbit_tail",  -- 兔毛
        {
            Ingredient("rock_avocado_fruit_ripe", 5),
            Ingredient("rope", 2),
            Ingredient("fig", 2),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("armorsnurtleshell",  -- 蜗牛壳
        {
            Ingredient("rock_avocado_fruit_ripe", 30),
            Ingredient("rope", 2),
            Ingredient("fig", 3),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("moonglass",--月光玻璃
        {
            Ingredient("rock_avocado_fruit_ripe", 7),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("marble",--大理石
        {
            Ingredient("rock_avocado_fruit_ripe", 6),
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("redgem",--红宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 15),
            Ingredient("goldnugget", 1)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("bluegem",--蓝宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 15),
            Ingredient("goldnugget", 1)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("greengem",--绿宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 30),
            Ingredient("fig", 2),
            Ingredient("goldnugget", 3)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("orangegem",--橙宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 30),
            Ingredient("fig", 2),
            Ingredient("goldnugget", 3)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("yellowgem",--黄宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 30),
            Ingredient("fig", 2),
            Ingredient("goldnugget", 3)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("thulecite",--铥矿
        {
            Ingredient("rock_avocado_fruit_ripe", 10),
            Ingredient("fig", 1),
            Ingredient("goldnugget", 2)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("glommerfuel",--史莱姆粘液
        {
            Ingredient("rock_avocado_fruit_ripe", 3),
            Ingredient("fig", 1)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("tallbirdegg",--高脚鸟蛋
        {
            Ingredient("rock_avocado_fruit_ripe", 10),
            Ingredient("fig", 1),
            Ingredient("bird_egg", 1)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
    AddRecipe2("opalpreciousgem",--彩虹宝石
        {
            Ingredient("rock_avocado_fruit_ripe", 60),
            Ingredient("fig", 3),
            Ingredient("flint", 1)
        },
        GLOBAL.TECH.NONE,
        {
        },
        {"REFINE"}
    )
end)
local fuel_config = {
    {
        name = "lightbulb",
    },
    {
        name = "rock_avocado_fruit_ripe",
    },
    {
        name = "fig",
    },
}

-- 爆炸伤害和范围配置
local LIGHTBULB_EXPLOSIVE_CONFIG = {
    explosivedamage = 150,      -- 爆炸伤害(与火药相同)
    explosiveburn = false,       -- 是否产生火焰
    explosivebuildingdamage = 1,-- 对建筑的伤害系数
    explosiveplayerdamage = 0.5,  -- 对玩家的伤害系数
    explosivephysicsdamage = 1, -- 对物理实体的伤害系数
    explosiverange = 2,         -- 爆炸范围
    explosiveflashrange = 5,    -- 闪光范围
    explosiveflashdmg = 0,      -- 闪光伤害
    explosiveflashdmgmod = 0,   -- 闪光伤害系数
    explosiveflashimmune = {},  -- 免疫闪光的标签
}

for _, fuel_item in ipairs(fuel_config) do
    AddPrefabPostInit(fuel_item.name, function(inst)
        if not GLOBAL.TheWorld.ismastersim then
            return inst
        end
        
        -- 添加燃料组件
        if not inst.components.fuel then
            inst:AddComponent("fuel")
        end
        
        -- 确保有声音发射器(用于播放声音)
        if not inst.SoundEmitter then
            inst.entity:AddSoundEmitter()
        end
        
        -- 添加爆炸组件
        if not inst.components.explosive then
            inst:AddComponent("explosive")
            inst.components.explosive:SetOnExplodeFn(function(inst, target)
                -- 使用正确的爆炸预制体:火药爆炸效果
                local pos = inst:GetPosition()
                local explode = GLOBAL.SpawnPrefab("gunpowder_explode")  -- 修正:使用火药爆炸预制体
                if explode then
                    explode.Transform:SetPosition(pos.x, pos.y, pos.z)
                end
                
                -- 爆炸伤害
                local x, y, z = inst.Transform:GetWorldPosition()
                local ents = GLOBAL.TheSim:FindEntities(x, y, z, 
                    LIGHTBULB_EXPLOSIVE_CONFIG.explosiverange, 
                    nil, 
                    {"INLIMBO", "playerghost"}
                )
                
                for _, ent in ipairs(ents) do
                    if ent ~= inst and ent:IsValid() then
                        -- 对生物造成伤害
                        if ent.components.health and not ent.components.health:IsDead() then
                            ent.components.health:DoFireDamage(LIGHTBULB_EXPLOSIVE_CONFIG.explosivedamage)
                        end
                        
                        -- 点燃可燃烧物体
                        if ent.components.burnable and not ent.components.fueled then
                            ent.components.burnable:Ignite()
                        end
                    end
                end
                
                -- 移除荧光果
                inst:Remove()
            end)
            
            inst.components.explosive.explosivedamage = LIGHTBULB_EXPLOSIVE_CONFIG.explosivedamage
        end
        
        -- 修改燃烧组件(如果存在)
        if not inst.components.burnable then
            inst:AddComponent("burnable")
        end
        
        -- 设置燃烧属性
        inst.components.burnable:SetOnIgniteFn(function(inst)
            -- 点燃时的效果
            if inst.SoundEmitter then
                inst.SoundEmitter:PlaySound("dontstarve/common/blackpowder_fuse_LP", "hiss")
            end
        end)
        
        inst.components.burnable:SetOnExtinguishFn(function(inst)
            -- 熄灭时的效果
            if inst.SoundEmitter then
                inst.SoundEmitter:KillSound("hiss")
            end
        end)
        
        inst.components.burnable:SetOnBurntFn(function(inst)
            -- 烧毁时触发爆炸
            if inst.components.explosive then
                inst.components.explosive:OnBurnt()
            end
        end)
        
        inst.components.burnable.canlight = true
        inst.components.burnable.fuelvalue = TUNING.SMALL_FUEL
        inst.components.burnable:SetBurnTime(1) -- 燃烧时间很短,立即爆炸
        
        -- 添加火焰传播组件(可选)
        if not inst.components.propagator then
            inst:AddComponent("propagator")
            inst.components.propagator.spreads = true
            inst.components.propagator.damagerange = LIGHTBULB_EXPLOSIVE_CONFIG.explosiverange
            inst.components.propagator.damage = LIGHTBULB_EXPLOSIVE_CONFIG.explosivedamage
        end
        
        -- 确保在物品栏中不会被点燃
        inst:ListenForEvent("onputininventory", function(inst)
            if inst.components.burnable and inst.components.burnable:IsBurning() then
                inst.components.burnable:Extinguish()
            end
        end)
        
        -- 确保放在地上时可以点燃
        inst:ListenForEvent("ondropped", function(inst)
            if inst.components.burnable then
                inst.components.burnable.canlight = true
            end
        end)
    end)
end

local fuel1_config = {
    {
        name = "rock_avocado_fruit",
    },
}

-- 石化范围配置
local PETRIFY_CONFIG = {
    petrify_range = 8,          -- 石化范围(8个地皮单位)
}

-- 需要石化的生物列表
local PETRIFY_MOBS = {
    {name="pigman",dl="meat",gl=20},         -- 猪人
    {name="spider",dl="monstermeat",gl=20},         -- 蜘蛛
    {name="spider_warrior",dl="monstermeat",gl=20}, -- 蜘蛛战士
    {name="spider_dropper",dl="monstermeat",gl=20}, -- 喷吐蜘蛛
    {name="spider_spitter",dl="monstermeat",gl=20}, -- 洞穴蜘蛛
    {name="spider_hider",dl="monstermeat",gl=20},   -- 潜伏蜘蛛
    {name="bunnyman",dl="carrot",gl=20},       -- 兔人
    {name="merm",dl="pondfish",gl=20},           -- 鱼人
    {name="mermguard",dl="pondfish",gl=20},      -- 鱼人守卫
    {name="hound",dl="houndstooth",gl=20},          -- 猎狗
    {name="firehound",dl="houndstooth",gl=20},      -- 火猎狗
    {name="icehound",dl="houndstooth",gl=20},       -- 冰猎狗
    {name="rabbit",dl="carrot",gl=5},         -- 兔子
    {name="grassgekko",dl="cutgrass",gl=20},     -- 草壁虎
    {name="beefalo",dl="meat",gl=40},        -- 牛
    {name="powder_monkey",dl="cave_banana",gl=20},  -- 码头猴子(更正为powder_monkey)
    {name="monkey",dl="cave_banana",gl=20},         -- 普通猴子
    {name="monkey_poison",dl="cave_banana",gl=20},  -- 洞穴猴子
    {name="slurper",dl="monstermeat",gl=20},        -- 缀食者(更正为slurper)
    {name="rocky",dl="rocks",gl=20},          -- 石龙虾
}

-- 检查实体是否在陆地上
local function IsOnLand(ent)
    if not ent then return false end
    
    local x, y, z = ent.Transform:GetWorldPosition()
    
    -- 检查是否在海洋上(使用地图API)
    local map = GLOBAL.TheWorld.Map
    if map and map.IsOceanAtPoint then
        return not map:IsOceanAtPoint(x, y, z, false)
    end
    
    -- 如果无法检查地图,默认返回true(在爆炸事件中通常世界已加载)
    return true
end

-- 检查是否是目标生物
local function IsTargetMob(ent)
    if not ent or not ent.prefab then
        return false
    end
    
    -- 检查是否是蜘蛛女王(特殊处理)
    if ent.prefab == "spiderqueen" then
        return "spiderqueen"
    end
    
    -- 检查是否是目标生物类型
    for _, mob1 in ipairs(PETRIFY_MOBS) do
        if ent.prefab == mob1.name then
            return "petrify"
        end
    end
    
    -- 检查生物相关组件和标签
    if ent.components and ent.components.health and not ent:HasTag("player") then
        -- 检查是否是生物类型
        if ent:HasTag("monster") or ent:HasTag("animal") or ent:HasTag("insect") then
            -- 排除玩家和宠物
            if not ent:HasTag("player") and not ent:HasTag("companion") then
                return "petrify"
            end
        end
    end
    
    return false
end

-- 石化生物的函数
local function PetrifyMob(mob)
    if not mob then
        return nil
    end
    
    local x, y, z = mob.Transform:GetWorldPosition()
    
    -- 先播放石化效果
    local fx = GLOBAL.SpawnPrefab("small_puff")
    if fx then
        fx.Transform:SetPosition(x, y, z)
    end
    
    -- 播放石化声音
    if mob.SoundEmitter then
        mob.SoundEmitter:PlaySound("dontstarve/creatures/together/antlion/sfx/ground_break")
    end
    
    -- 生成石化树
    local petrified_tree = GLOBAL.SpawnPrefab("rock_petrified_tree_tall")
    if petrified_tree then
        petrified_tree.Transform:SetPosition(x, y, z)
        
        -- 确保石化树不会被点燃
        if petrified_tree.components.burnable then
            petrified_tree.components.burnable.canlight = false
        end
    end
    
    for _, mob1 in ipairs(PETRIFY_MOBS) do
        if mob.prefab == mob1.name then
            if mob1.dl then
                if math.random(100)<=mob1.gl then
                    local spiderhat = GLOBAL.SpawnPrefab(mob1.dl)
                    if spiderhat then
                        -- 设置掉落物位置(在爆炸中心周围随机分布)
                        local offset_x = (math.random() - 0.5) * 2  -- -1到1之间
                        local offset_z = (math.random() - 0.5) * 2  -- -1到1之间
                        spiderhat.Transform:SetPosition(x + offset_x, y, z + offset_z)
                    end
                end
            end
            break
        end
    end
    -- 移除原生物
    mob:Remove()
    
    return petrified_tree
end

-- 将蜘蛛女王替换为护士蜘蛛
local function ReplaceSpiderQueen(spiderqueen)
    if not spiderqueen or not spiderqueen:IsValid() or spiderqueen.prefab ~= "spiderqueen" then
        return nil
    end
    
    local x, y, z = spiderqueen.Transform:GetWorldPosition()
    
    -- 播放效果
    local fx = GLOBAL.SpawnPrefab("small_puff")
    if fx then
        fx.Transform:SetPosition(x, y, z)
    end
    
    -- 播放声音
    if spiderqueen.SoundEmitter then
        spiderqueen.SoundEmitter:PlaySound("dontstarve/creatures/spiderqueen/scream")
    end
    
    -- 生成护士蜘蛛
    local nurse_spider = GLOBAL.SpawnPrefab("spider_healer")
    if nurse_spider then
        nurse_spider.Transform:SetPosition(x, y, z)
        
        -- 设置护士蜘蛛的属性
        if nurse_spider.components.health then
            nurse_spider.components.health:SetPercent(1.0)  -- 满血
        end
    end
    local spidereggsack = GLOBAL.SpawnPrefab("spidereggsack")
    if spidereggsack then
        -- 设置掉落物位置(在爆炸中心周围随机分布)
        local offset_x = (math.random() - 0.5) * 2  -- -1到1之间
        local offset_z = (math.random() - 0.5) * 2  -- -1到1之间
        spidereggsack.Transform:SetPosition(x + offset_x, y, z + offset_z)
    end
    if math.random(100)<=5 then
        local spiderhat = GLOBAL.SpawnPrefab("spiderhat")
        if spiderhat then
            -- 设置掉落物位置(在爆炸中心周围随机分布)
            local offset_x = (math.random() - 0.5) * 2  -- -1到1之间
            local offset_z = (math.random() - 0.5) * 2  -- -1到1之间
            spiderhat.Transform:SetPosition(x + offset_x, y, z + offset_z)
        end
    end
    -- 移除蜘蛛女王
    spiderqueen:Remove()
    
    return nurse_spider
end

for _, fuel_item in ipairs(fuel1_config) do
    AddPrefabPostInit(fuel_item.name, function(inst)
        if not GLOBAL.TheWorld.ismastersim then
            return inst
        end
        
        -- 添加燃料组件
        if not inst.components.fuel then
            inst:AddComponent("fuel")
        end
        --inst.components.fuel.fuelvalue = GLOBAL.TUNING.SMALL_FUEL
        --inst.components.fuel.fueltype = "SGBOMB"
        -- 确保有声音发射器(用于播放声音)
        if not inst.SoundEmitter then
            inst.entity:AddSoundEmitter()
        end
        
        -- 添加爆炸组件,但设置伤害为0
        if not inst.components.explosive then
            inst:AddComponent("explosive")
            
            -- 确保爆炸伤害为0
            inst.components.explosive.explosivedamage = 0
            inst.components.explosive.explosiveburn = false
            inst.components.explosive.explosivebuildingdamage = 0
            inst.components.explosive.explosiveplayerdamage = 0
            inst.components.explosive.explosivephysicsdamage = 0
            inst.components.explosive:SetOnExplodeFn(function(inst, target)
                -- 播放火药爆炸效果(但没有伤害)
                local pos = inst:GetPosition()
                local explode = GLOBAL.SpawnPrefab("gunpowder_explode")
                if explode then
                    explode.Transform:SetPosition(pos.x, pos.y, pos.z)
                end
                
                -- 石化或替换周围的生物
                local x, y, z = inst.Transform:GetWorldPosition()
                local ents = GLOBAL.TheSim:FindEntities(x, y, z, 
                    PETRIFY_CONFIG.petrify_range, 
                    nil, -- 不筛选任何标签,检查所有实体
                    {"INLIMBO", "playerghost", "player", "companion", "abigail"} -- 排除玩家、鬼魂、宠物等
                )
                
                for _, ent in ipairs(ents) do
                    if ent ~= inst and ent:IsValid() then
                        -- 检查是否在陆地上
                        if IsOnLand(ent) then
                            -- 检查是否是目标生物
                            local mob_type = IsTargetMob(ent)
                            
                            if mob_type == "spiderqueen" then
                                -- 替换蜘蛛女王为护士蜘蛛
                                ReplaceSpiderQueen(ent)
                            elseif mob_type == "petrify" then
                                PetrifyMob(ent)
                            end
                        end
                    end
                end
                
                -- 移除荧光果
                inst:Remove()
            end)
        end
        
        -- 修改燃烧组件(如果存在)
        if not inst.components.burnable then
            inst:AddComponent("burnable")
        end
        
        -- 设置燃烧属性
        inst.components.burnable:SetOnIgniteFn(function(inst)
            -- 点燃时的效果
            if inst.SoundEmitter then
                inst.SoundEmitter:PlaySound("dontstarve/common/blackpowder_fuse_LP", "hiss")
            end
            inst.components.burnable:SetBurningFX("campfirefire", GLOBAL.Vector3(0, 0.5, 0), "fire")
        end)
        
        inst.components.burnable:SetOnExtinguishFn(function(inst)
            -- 熄灭时的效果
            if inst.SoundEmitter then
                inst.SoundEmitter:KillSound("hiss")
            end
        end)
        
        inst.components.burnable:SetOnBurntFn(function(inst)
            -- 烧毁时触发爆炸
            if inst.components.explosive then
                inst.components.explosive:OnBurnt()
            end
        end)
        
        inst.components.burnable.canlight = true
        inst.components.burnable.fuelvalue = GLOBAL.TUNING.SMALL_FUEL
        inst.components.burnable:SetBurnTime(2) -- 燃烧2秒后爆炸
        
        -- 移除火焰传播组件
        if inst.components.propagator then
            inst.components.propagator:StopSpreading()
            inst:RemoveComponent("propagator")
        end
        
        -- 确保在物品栏中不会被点燃
        inst:ListenForEvent("onputininventory", function(inst)
            if inst.components.burnable and inst.components.burnable:IsBurning() then
                inst.components.burnable:Extinguish()
            end
        end)
        
        -- 确保放在地上时可以点燃
        inst:ListenForEvent("ondropped", function(inst)
            if inst.components.burnable then
                inst.components.burnable.canlight = true
            end
        end)
    end)
end
























local STRINGS = GLOBAL.STRINGS
STRINGS.NAMES.ROCK_AVOCADO_FRUIT_BOMB = "石果炸弹"
STRINGS.RECIPE_DESC.ROCK_AVOCADO_FRUIT_BOMB = "一种易爆物品?"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.ROCK_AVOCADO_FRUIT_BOMB = "接下来会很疯狂!"
STRINGS.NAMES.FIG_LIGHT = "无花果灯"
STRINGS.RECIPE_DESC.FIG_LIGHT = "新型的植物融合技术"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.FIG_LIGHT = "一盏由无花果制成的灯,但它会腐烂......"
-- local demons = AddRecipe(
-- 	"demons", 
-- 	{
-- 	GLOBAL.Ingredient("houndstooth",2),  --犬牙
-- 	GLOBAL.Ingredient("goldnugget",3),  --黄金
-- 	GLOBAL.Ingredient("nightsword",1),},  --一个影刀
-- 	milimtab,
-- 	GLOBAL.TECH.NONE,
-- 	nil,nil,nil,nil,"milimonlytag",
-- 	"images/inventoryimages/demons.xml",
-- 	"demons.tex"
-- 	)
AddSimPostInit(function()
    AddRecipe2("fig_light",
        {
            Ingredient("lightbulb", 6),
            Ingredient("fig", 1)
        },
        GLOBAL.TECH.SCIENCE_ONE,  -- 科技等级
        {
            atlas = "images/inventoryimages/fig_light.xml",
            image = "fig_light.tex",
        },
        {"WEAPONS"}  -- 制作栏标签
    )
    AddRecipe2("rock_avocado_fruit_bomb",
        {
            Ingredient("rock_avocado_fruit", 5),
            Ingredient("fig", 1)
        },
        GLOBAL.TECH.SCIENCE_ONE,  -- 科技等级
        {
            atlas = "images/inventoryimages/rock_avocado_fruit_bomb.xml",
            image = "rock_avocado_fruit_bomb.tex",
        },
        {"WEAPONS"}  -- 制作栏标签
    )
end)
-- 	AddRecipe(
-- 	"nightsword", 
-- 	{
-- 	GLOBAL.Ingredient(GLOBAL.CHARACTER_INGREDIENT.HEALTH,5),
-- 	GLOBAL.Ingredient("milimstaff",1,"images/inventoryimages/milimstaff.xml"), 
-- 	GLOBAL.Ingredient("nitre",2),},
-- 	milimtab,
-- 	GLOBAL.TECH.NONE,
-- 	nil,nil,nil,nil,"milimonlytag",
-- 	nil,
-- 	nil
-- 	)
    -- local fight_tab = "FIGHT"

    -- -- 使用正确的 AddRecipe2 格式
    -- AddRecipe2("rock_avocado_fruit_bomb",
    --     {
    --         Ingredient("rock_avocado_fruit", 1),
    --         Ingredient("fig", 1)
    --     },
    --     GLOBAL.TECH.SCIENCE_ONE,
    --     {
    --         atlas = "images/inventoryimages/rock_avocado_fruit_bomb.xml",  -- 注意路径
    --         image = "rock_avocado_fruit_bomb.tex",
    --         product = "rock_avocado_fruit_bomb",
    --         numtogive = 1,
    --         -- 移除 builder_location 参数,使用正确的制作栏
    --     },
    --     {fight_tab}  -- 指定制作栏:武器栏
    -- )

fig_light.lua

lua 复制代码
local assets = {
    Asset("ANIM", "anim/fig_light.zip"),
    Asset("ANIM", "anim/swap_fig_light.zip"),
    Asset("ATLAS", "images/inventoryimages/fig_light.xml"),
    Asset("IMAGE", "images/inventoryimages/fig_light.tex"),
}

local function OnEquip(inst, owner)
    inst.Light:Enable(true)
    owner.AnimState:OverrideSymbol("swap_object", "swap_fig_light", "swap_fig_light")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")
end

local function OnUnequip(inst, owner)
    inst.Light:Enable(false)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("fig_light")
    inst.AnimState:SetBuild("fig_light")
    inst.AnimState:PlayAnimation("idle", true)

    inst.entity:AddLight()
    inst.Light:SetRadius(10)
    inst.Light:SetIntensity(0.8)
    inst.Light:SetFalloff(0.5)
    inst.Light:SetColour(255/255, 200/255, 100/255)
    inst.Light:Enable(false)

    inst:AddTag("fig_light")
    inst:AddTag("light_source")

    if not TheWorld.ismastersim then
        return inst
    end

    inst.entity:SetPristine()

    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.imagename = "fig_light"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/fig_light.xml"

    inst.components.inventoryitem:SetOnDroppedFn(function(inst)
        inst.Light:Enable(true)
    end)
    inst.components.inventoryitem:SetOnPutInInventoryFn(function(inst)
        inst.Light:Enable(false)
    end)

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip(OnEquip)
    inst.components.equippable:SetOnUnequip(OnUnequip)
    inst:AddComponent("weapon")
	--inst.components.weapon:SetOnAttack(onattack)
    inst.components.weapon:SetDamage(1)
	--damage=90
    -- ========== 保鲜组件(标准写法) ==========
    inst:AddComponent("perishable")
    inst.components.perishable:SetPerishTime(TUNING.PERISH_SUPERSLOW*0.25)  -- 约20天
    inst.components.perishable:StartPerishing()
    inst.components.perishable:SetOnPerishFn(function(inst)
        local spoiled = SpawnPrefab("spoiled_food")
        if spoiled then
            local x, y, z = inst.Transform:GetWorldPosition()
            spoiled.Transform:SetPosition(x, y, z)
        end
        inst:Remove()
    end)
    inst.components.perishable.prefers_to_freshen = true  -- 冰箱保鲜

    -- ========== ★ 关键:添加edible组件,强制显示新鲜度边框 ★ ==========
    inst:AddComponent("edible")
    inst.components.edible.foodtype = "GENERIC"
    inst.components.edible.hungervalue = 0
    inst.components.edible.healthvalue = 0
    inst.components.edible.sanityvalue = 0
    inst.components.edible.ismeat = false
    inst.components.edible:SetOnEatenFn(function() end)  -- 什么也不做
    inst:AddTag("inedible")      -- 防止被自动食用
    inst:AddTag("not_eatable")   -- 额外的保护

    -- 不可修复
    inst.repairvalue = 0

    return inst
end

return Prefab("fig_light", fn, assets)

rock_avocado_fruit_bomb.lua

lua 复制代码
local GLOBAL = _G
print("石果炸弹装载中")
-- 定义常量
local BOMB_PREFAB = "rock_avocado_fruit_bomb"
local MAX_RANGE = 5
local BASE_DAMAGE = 20
local DAMAGE_PER_ROCK_AVOCADO = 200
local RANGE_PER_ROCK_AVOCADO = 1
local BASE_RANGE = 1
local FILL_AMOUNT = 0.06
local BASE_FILL = 0.01
local FUSE_TIME = 6

-- 预制物定义
local assets = {
    Asset("ANIM", "anim/rock_avocado_fruit_bomb.zip"),
    Asset("ANIM", "anim/swap_rock_avocado_fruit_bomb.zip"),

    Asset("ATLAS", "images/inventoryimages/rock_avocado_fruit_bomb.xml"),
    Asset("IMAGE", "images/inventoryimages/rock_avocado_fruit_bomb.tex"),
}

-- 本地函数


local function OnIgnite(inst)
    inst:AddTag("exploding")
    inst.SoundEmitter:PlaySound("dontstarve/common/blackpowder_fuse_LP", "fuse")
    if inst.AnimState then
        inst.AnimState:PlayAnimation("burn", false)  -- 播放burn动画,true表示循环播放
    end
    inst:DoTaskInTime(FUSE_TIME, function(inst)
        if inst:IsValid() then
            local explode = SpawnPrefab("explode_small")
            local pos = inst:GetPosition()
            explode.Transform:SetPosition(pos.x, pos.y, pos.z)
            
            local damage = inst.damage:value()
            local range = inst.range:value()
            
            local x, y, z = inst.Transform:GetWorldPosition()
            local ents = TheSim:FindEntities(x, y, z, range * 3)
            
            for _, ent in ipairs(ents) do
                if ent ~= inst and ent:IsValid() then
                    if ent.components.combat ~= nil then
                        ent.components.combat:GetAttacked(inst, damage, inst)
                    end
                    
                    if ent.components.burnable ~= nil and not ent.components.burnable:IsBurning() then
                        if not ent:HasTag("player") then
                            ent.components.burnable:Ignite()
                        end
                    end
                end
            end
			local rg=inst.range:value()
			if rg>=3 then
				local sinkhole = SpawnPrefab("antlion_sinkhole")
				if sinkhole then
					-- 设置世界坐标(饥荒Transform组件使用x, y, z,其中y是垂直高度)
					sinkhole.Transform:SetPosition(x, y, z)
					
					-- 可选:强制唤醒并初始化(部分地形预制体需要)
					sinkhole:PushEvent("ms_forceprefab")
				end
			end
            for i=1,math.ceil(inst.damage:value()/100),1 do
				local rocks = GLOBAL.SpawnPrefab("rocks")
				if rocks then
					-- 设置掉落物位置(在爆炸中心周围随机分布)
					local offset_x = (math.random() - 0.5) * 4*rg  -- -1到1之间
					local offset_z = (math.random() - 0.5) * 4*rg  -- -1到1之间
					rocks.Transform:SetPosition(x + offset_x, y, z + offset_z)
				end
			end
            inst:Remove()
        end
    end)
end

local function OnSave(inst, data)
    data.damage = inst.damage:value()
    data.range = inst.range:value()
    data.percent = inst.components.fueled:GetPercent()
end

local function OnLoad(inst, data)
    if data then
        inst.damage:set(data.damage or BASE_DAMAGE)
        inst.range:set(data.range or BASE_RANGE)
        if data.percent then
            inst.components.fueled:SetPercent(data.percent)
        end
    end
end

local function OnPutInInventory(inst, owner)
    if owner and owner.components.inventoryitem then
        owner.components.inventoryitem:ChangeImageName(inst.prefab)
    end
end

-- 炸弹使用组件
local function bomb_fn()
    local inst = CreateEntity()
    
    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddNetwork()
    
    MakeInventoryPhysics(inst)
    
    inst.AnimState:SetBank("rock_avocado_fruit_bomb")
    inst.AnimState:SetBuild("rock_avocado_fruit_bomb")
    inst.AnimState:PlayAnimation("idle")
    
    inst:AddTag("bomb")
    inst:AddTag("explosive")
    
    inst.damage = net_ushortint(inst.GUID, "rock_avocado_fruit_bomb.damage", "damagedirty")
    inst.range = net_ushortint(inst.GUID, "rock_avocado_fruit_bomb.range", "rangedirty")
    
    inst.entity:SetPristine()
    
    if not TheWorld.ismastersim then
        return inst
    end
    
    inst.damage:set(BASE_DAMAGE)
    inst.range:set(BASE_RANGE)
    
    inst:AddComponent("inspectable")
    
    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.imagename = "rock_avocado_fruit_bomb"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/rock_avocado_fruit_bomb.xml"
    inst.components.inventoryitem:SetOnPutInInventoryFn(OnPutInInventory)
    
    inst:AddComponent("named")
    
	inst:AddTag("rock_avocado_device")
    inst:AddComponent("fueled")
    inst.components.fueled:InitializeFuelLevel(100)
    inst.components.fueled:SetPercent(BASE_FILL)
    inst.components.fueled:SetDepletedFn(nil)

	-- 设置应该接受哪些燃料
	inst.components.fueled.accepting = true
    

    inst:AddComponent("burnable")
    inst.components.burnable:SetOnIgniteFn(OnIgnite)
    inst.components.burnable.canlight = true
    inst.components.burnable.fxprefab = nil
    
    -- inst:AddComponent("stackable")
    -- inst.components.stackable.maxsize = 1
    
    inst.OnSave = OnSave
    inst.OnLoad = OnLoad
    
    return inst
end

print("石果炸弹装载完毕")
return Prefab("common/inventory/"..BOMB_PREFAB, bomb_fn, assets)
相关推荐
foxsen_xia1 小时前
Kamailio通过Lua写路由
开发语言·lua·信息与通信
燃于AC之乐1 小时前
深入解剖STL set/multiset:接口使用与核心特性详解
开发语言·c++·stl·面试题·set·multiset
REDcker1 小时前
Paho MQTT C 开发者快速入门
c语言·开发语言·mqtt
Jack_David1 小时前
kafka_2.13-4.1.1集群安装
java·分布式·kafka
破烂pan1 小时前
Python 实现 HTTP Client 的常见方式
开发语言·python·http
HAPPY酷1 小时前
C++ 高性能消息服务器实战:融合线程、异步与回调的三大核心设计
java·服务器·c++
愿你天黑有灯下雨有伞1 小时前
Spring Boot 整合 Kafka:生产环境标准配置与最佳实践
java·kafka
宁酱醇1 小时前
ORACLE 练习1
java·开发语言
HAPPY酷1 小时前
现代 C++ 并发服务器的核心模式
服务器·开发语言·c++