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)