饥荒Mod 开发(九):物品栏排列
饥荒Mod 开发(十一):修改物品堆叠
前面的文章介绍了很多基础知识以及如何制作一个物品,这次制作一把武器,装备之后可以用来攻击怪物。
#先cd 到 工具目录下,然后执行命令
.\autocompiler.exe "C:\WeGameApps\rail_apps\饥荒:单机版(2000013)\mods\pigpetfood"
执行完命令之后在相同目录下会生成两个文件,这两个文件就是贴图文件
下载一张高分辨率的图片,png 格式,32位图片,我下载了个128*128 像素的图片,将图片放在exported/lightsword/lightsword 目录下, 需要自己创建目录
打开Spriter.exe 工具,菜单新建工程,选择目录 mods\pigpetfood\exported\lightsword。然后从工程右上角拖入图片到画布中,然后保存工程到 lightsword.scml, 特别需要注意: 新建一个BUILD 动画,否则装备武器的时候不会有任何的显示。
先参考之前的文章饥荒Mod 开发(四):制作一个物品,先制作一个简答的物品,暂时不具备攻击能力,只要能生成这个物品即可
local assets=
{
Asset("ANIM", "anim/lightsword.zip"), -- 加载动画资源
Asset("ATLAS", "images/inventoryimages/lightsword.xml"), -- 加载图像资源
}
local function fn(Sim)
local inst = CreateEntity() -- 创建一个新的实体
inst.entity:AddTransform() -- 添加变换组件
inst.entity:AddAnimState() -- 添加动画状态组件
MakeInventoryPhysics(inst) -- 为实体添加物理属性
inst:AddComponent("inspectable") -- 添加可检查组件
inst:AddComponent("inventoryitem") -- 添加库存物品组件
--物品放在地上的时候播放idle 动画
inst.AnimState:SetBank("lightsword") -- 设置动画库
inst.AnimState:SetBuild("lightsword") -- 设置动画构建
inst.AnimState:PlayAnimation("idle") -- 播放"idle"动画
inst.components.inventoryitem.atlasname = "images/inventoryimages/lightsword.xml" -- 设置在物品栏的图像
return inst -- 返回创建的实体
end
return Prefab( "common/lightsword", fn, assets) -- 返回一个预制物品,这个预制物品使用了上面定义的
--声明预制物
PrefabFiles = {
"pigpetfood",
"lightsword"
}
--添加光剑武器的描述
GLOBAL.STRINGS.NAMES.LIGHTSWORD = "光剑"
GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.LIGHTSWORD = "这是一把光剑"
GLOBAL.STRINGS.RECIPE_DESC.LIGHTSWORD = "可以发光的光剑"
在lightsword.lua 文件的fn 函数中添加可装备组件。这样鼠标悬浮上就会显示装备,右键点击就可以装备
--添加可装备组件
inst:AddComponent("equippable") -- 添加可装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HANDS
inst.components.equippable:SetOnEquip(function(inst, owner) -- 设置装备时的回调函数
owner.AnimState:OverrideSymbol("swap_object", "lightsword", "lightsword") -- 设置玩家的动画
owner.AnimState:Show("ARM_carry") -- 显示玩家的手臂
owner.AnimState:Hide("ARM_normal") -- 隐藏玩家的手臂
end)
inst.components.equippable:SetOnUnequip(function(inst, owner) -- 设置卸下时的回调函数
owner.AnimState:Hide("ARM_carry") -- 隐藏玩家的手臂
owner.AnimState:Show("ARM_normal") -- 显示玩家的手臂
end)
此时装备的光剑并没有任务的作用,所以需要给武器增加攻击力,攻击范围等等
--添加武器组件
inst:AddComponent("weapon") -- 添加武器组件
inst.components.weapon:SetDamage(1) -- 设置武器的伤害值
inst.components.weapon.hitrange = 10 -- 设置武器的攻击范围
武器每次攻击都会丢失耐久度,耐久度为0 就会报废掉。下面设置了100的耐久度,每次攻击默认会减少1.耐久为0的时候就会消失,也可以不设置耐久,这样武器可以一直使用
-- 添加"finiteuses"组件,这个组件用于表示一个物品的耐久度
inst:AddComponent("finiteuses")
-- 设置物品的最大耐久度为100
inst.components.finiteuses:SetMaxUses(100)
-- 设置物品的当前耐久度为100
inst.components.finiteuses:SetUses(100)
-- 设置当耐久度用完时的回调函数
-- 在这个例子中,当耐久度用完时,物品会被移除
inst.components.finiteuses:SetOnFinished(function (inst)
inst:Remove()
end)
如果有一堆怪物的武器可以触发群体攻击,并且冰冻怪物,触发AOE伤害
inst.components.weapon:SetOnAttack(function (inst, attacker, target)
-- 获取攻击目标的世界坐标
local x, y, z = target.Transform:GetWorldPosition()
-- 在攻击目标周围5个单位的范围内查找所有带有"monster"标签的实体
local entities = TheSim:FindEntities(x, y, z, 5, {"monster"})
-- 计算AOE伤害,等于武器的伤害的200%
local damage = inst.components.weapon:GetDamage(attacker, target) * 2
for _,obj in pairs(entities) do
-- 触发"onareaattackother"事件,该事件在区域攻击其他实体时触发
inst:PushEvent("onareaattackother", {target = obj, weapon = inst})
-- 对除攻击目标外的其他实体造成AOE伤害
if obj ~= target then
obj.components.combat:GetAttacked(inst, damage, inst)
end
-- 如果实体可以被冻结,则增加其冷度
if obj.components.freezable then
obj.components.freezable:AddColdness(1)
end
-- 在实体位置生成随机特效
local fxs = {"icespike_fx_1", "icespike_fx_2","icespike_fx_3","icespike_fx_4"}
SpawnAt(GetRandomItem(fxs), obj)
end
end)
AOE带冰冻效果武器源码