├── .vscode └── extensions.json ├── README.md ├── lesson3 ├── modicon.tex ├── modicon.xml ├── modinfo.lua ├── modmain.lua ├── modworldgenmain.lua └── scripts │ ├── components │ └── ironhand.lua │ └── lf_actions.lua ├── lesson_action ├── modicon.tex ├── modicon.xml ├── modinfo.lua ├── modmain.lua └── scripts │ └── components │ └── ironhand.lua ├── lesson_add_new_recipe ├── anim │ ├── lotus_umbrella.zip │ └── swap_lotus_umbrella.zip ├── images │ ├── craft_samansha_icon.tex │ ├── craft_samansha_icon.xml │ └── inventoryimages │ │ ├── lotus_umbrella.png │ │ ├── lotus_umbrella.tex │ │ └── lotus_umbrella.xml ├── modicon.tex ├── modicon.xml ├── modinfo.lua ├── modmain.lua └── scripts │ └── prefabs │ └── lotus_umbrella.lua ├── lesson_component ├── modicon.tex ├── modicon.xml ├── modinfo.lua ├── modmain.lua ├── modworldgenmain.lua └── scripts │ ├── components │ └── ironhand.lua │ └── lf_actions.lua ├── lesson_network ├── modinfo.lua ├── modmain.lua └── scripts │ └── components │ ├── pho.lua │ └── pho_replica.lua ├── lesson_quick_start_base ├── anim │ ├── lotus_umbrella.zip │ └── swap_lotus_umbrella.zip ├── exported │ ├── lotus_umbrella.png │ └── swap_lotus_umbrella.png ├── images │ └── inventoryimages │ │ ├── lotus_umbrella.png │ │ ├── lotus_umbrella.tex │ │ └── lotus_umbrella.xml ├── modicon.tex ├── modicon.xml ├── modinfo.lua └── modmain.lua └── lesson_quick_start_finish ├── anim ├── lotus_umbrella.zip └── swap_lotus_umbrella.zip ├── exported ├── lotus_umbrella │ ├── lotus_umbrella.scml │ ├── lotus_umbrella.zip │ └── lotus_umbrella │ │ └── lotus_umbrella.png └── swap_lotus_umbrella │ ├── swap_lotus_umbrella.scml │ ├── swap_lotus_umbrella.zip │ └── swap_lotus_umbrella │ └── swap_lotus_umbrella.png ├── images └── inventoryimages │ ├── lotus_umbrella.png │ ├── lotus_umbrella.tex │ └── lotus_umbrella.xml ├── modicon.tex ├── modicon.xml ├── modinfo.lua ├── modmain.lua └── scripts └── prefabs └── lotus_umbrella.lua /.vscode/extensions.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/.vscode/extensions.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dst_mod_tutorial 2 | 3 | Don't Starve Mod Tutorial 饥荒Mod教程,每个lesson都是一个独立的mod,可以直接放入`游戏根目录/mods`使用 4 | 5 | 6 | 文件结构 7 | ``` 8 | dst_mod_tutorial // 9 | ├─ README.md // 10 | └─ lesson3 // 第三期Mod 11 | ├─ modicon.tex // 12 | ├─ modicon.xml // 13 | ├─ modinfo.lua // 14 | ├─ modmain.lua // 主程序文件 15 | ├─ modworldgenmain.lua // 16 | └─ scripts // 17 | ├─ components // 18 | │ └─ ironhand.lua // component定义 19 | └─ lf_actions.lua // 动作相关参数 20 | ``` -------------------------------------------------------------------------------- /lesson3/modicon.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson3/modicon.tex -------------------------------------------------------------------------------- /lesson3/modicon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lesson3/modinfo.lua: -------------------------------------------------------------------------------- 1 | --[[ Copyright © 2015 Ultroman ]] 2 | name = "IronHand" 3 | description = "make you can work without tool" 4 | author = "LongFei" 5 | version = "0.0.1" 6 | 7 | forumthread = "" 8 | api_version = 10 9 | 10 | dst_compatible = true 11 | 12 | dont_starve_compatible = false 13 | reign_of_giants_compatible = false 14 | shipwrecked_compatible = false 15 | 16 | all_clients_require_mod = true 17 | 18 | server_filter_tags = {} 19 | 20 | priority = 0 21 | 22 | icon_atlas = "modicon.xml" 23 | icon = "modicon.tex" 24 | 25 | -------------------------------------------------------------------------------- /lesson3/modmain.lua: -------------------------------------------------------------------------------- 1 | local _G = GLOBAL 2 | local require = _G.require 3 | local pcall = _G.pcall 4 | 5 | -- 为了方便后续添加其它的动作,类似官方代码中的Recipe,将新动作的相关参数都集中存放在一个module中的若干table里 6 | local actions_status,actions_data = pcall(require,"lf_actions") 7 | 8 | -- 这部分的代码是固定的,添加新的动作并不需要改动此处,只需要修改lf_actions.lua文件中的内容 9 | if actions_status then 10 | -- 导入自定义动作 11 | if actions_data.actions then 12 | for _,act in pairs(actions_data.actions) do 13 | -- 首先需要使用AddAction注册新动作,会返回这个动作变量 14 | local action = AddAction(act.id,act.str,act.fn) 15 | -- 会根据actiondata,进一步添加一些动作相关参数比如施放距离和优先级等 16 | if act.actiondata then 17 | for k,data in pairs(act.actiondata) do 18 | action[k] = data 19 | end 20 | end 21 | -- 将这个新动作与SG做绑定,wilson是玩家人物通用的SG,客机玩家还有额外的wilson_client为SG,为了保证客机一致性,都进行绑定 22 | AddStategraphActionHandler("wilson",_G.ActionHandler(action, act.state)) 23 | AddStategraphActionHandler("wilson_client",_G.ActionHandler(action,act.state)) 24 | end 25 | end 26 | 27 | -- 导入动作与组件的绑定 28 | if actions_data.component_actions then 29 | for _,v in pairs(actions_data.component_actions) do 30 | -- 这里定义的testfn,就是在第三期文章中讲到的检测函数,传入参数依所选的场景类型而变化 31 | local testfn = function(...) 32 | -- select是一个基础用法,结合函数传入的不定参数...,这里表示取倒数第二个参数,这个参数不管在哪个场景下,总是默认为actions,倒数第一个则是right 33 | local actions = _G.select(-2,...) 34 | for _,data in pairs(v.tests) do 35 | -- data.testfn是定义在lf_actions中的testfn,是检测是否满足触发条件的函数,只会返回true或false 36 | if data and data.testfn and data.testfn(...) then 37 | data.action = string.upper( data.action ) 38 | -- 如果检测通过,就将该action插入actions序列中 39 | table.insert( actions, _G.ACTIONS[data.action] ) 40 | end 41 | end 42 | end 43 | AddComponentAction(v.type, v.component, testfn) 44 | end 45 | end 46 | end 47 | 48 | -- 为所有玩家添加额外的组件ironhand 49 | AddPrefabPostInitAny(function(inst) 50 | if(inst:HasTag("player")) then 51 | inst:AddComponent("ironhand") 52 | end 53 | end) -------------------------------------------------------------------------------- /lesson3/modworldgenmain.lua: -------------------------------------------------------------------------------- 1 | local GROUND = GLOBAL.GROUND 2 | -------------------------------------------------------------------------------- /lesson3/scripts/components/ironhand.lua: -------------------------------------------------------------------------------- 1 | local DEGREE_1 = 100 2 | local DEGREE_2 = 200 3 | local DEGREE_3 = 500 4 | 5 | 6 | local IronHand = Class(function(self, inst) 7 | self.inst = inst 8 | self.forge_degree = 0 -- 记录熟练度 9 | self.inst:AddTag("ironhand") -- 添加tag方便动作检测 10 | end, 11 | nil, 12 | nil) 13 | 14 | 15 | function IronHand:GetNumWorks() 16 | if(self.forge_degree 2 | 3 | 4 | -------------------------------------------------------------------------------- /lesson_action/modinfo.lua: -------------------------------------------------------------------------------- 1 | name = "Lesson Action" 2 | description = "动作教程Mod" 3 | author = "LongFei" 4 | version = "0.0.1" 5 | 6 | forumthread = "" 7 | api_version = 10 8 | 9 | dst_compatible = true 10 | 11 | dont_starve_compatible = false 12 | reign_of_giants_compatible = false 13 | shipwrecked_compatible = false 14 | 15 | all_clients_require_mod = true 16 | 17 | server_filter_tags = {} 18 | 19 | priority = 0 20 | 21 | icon_atlas = "modicon.xml" 22 | icon = "modicon.tex" 23 | 24 | -------------------------------------------------------------------------------- /lesson_action/modmain.lua: -------------------------------------------------------------------------------- 1 | local _G = GLOBAL 2 | 3 | -- 为所有玩家添加新组件ironhand 4 | AddPrefabPostInitAny(function(inst) 5 | if(inst:HasTag("player")) then 6 | inst:AddComponent("ironhand") 7 | end 8 | end) 9 | 10 | 11 | -- 创建新动作 12 | local act = { 13 | id = "IRONHAND", 14 | -- str的内容会在游戏界面中显示 15 | str = "铁手", 16 | -- action触发时执行的fn 17 | fn = function(act) 18 | if act.doer.components.ironhand ~= nil then 19 | return act.doer.components.ironhand:Work(act.target) 20 | end 21 | return false 22 | end, 23 | state = "dojostleaction" 24 | } 25 | local act_ironhand = AddAction(act.id, act.str, act.fn) 26 | 27 | 28 | -- 添加动作处理器,将动作与人物SG连接,也就是指定触发动作时会进入的state 29 | -- 主客机的两个SG都要添加 30 | -- 这里进入的state是dojostleaction 空手出拳的动作 31 | AddStategraphActionHandler("wilson",_G.ActionHandler(act_ironhand, act.state)) 32 | AddStategraphActionHandler("wilson_client",_G.ActionHandler(act_ironhand,act.state)) 33 | 34 | 35 | -- 设置组件动作,满足特定条件时将动作写入可执行动作表 36 | -- 添加的是一个SCENE动作,对世界地图上任意含有workable组件的物体,比如树、矿石等,都会进入触发检测 37 | -- 触发检测testfn 38 | local cmp_act = { 39 | type = "SCENE", 40 | -- 注意component指的是inst的component,不同type下的inst指代的目标不同,此处的inst是指动作的目标,也就是要砍的树、要挖的矿石等 41 | component = "workable", 42 | -- doer指的是执行动作的角色,也就是玩家 43 | testfn = function (inst, doer, actions, right) 44 | if doer:HasTag("ironhand") then 45 | table.insert(actions, act_ironhand) 46 | end 47 | end 48 | } 49 | AddComponentAction(cmp_act.type, cmp_act.component, cmp_act.testfn) -------------------------------------------------------------------------------- /lesson_action/scripts/components/ironhand.lua: -------------------------------------------------------------------------------- 1 | local T1 = 100 2 | 3 | local IronHand = Class(function(self, inst) 4 | self.inst = inst 5 | self.proficiency = 0 -- 记录熟练度 6 | self.inst:AddTag("ironhand") -- 添加tag方便动作检测 7 | end, 8 | nil, 9 | nil) 10 | 11 | 12 | function IronHand:Work(target) 13 | -- 主要函数,action中调用执行 14 | if target.components.workable ~= nil and 15 | target.components.workable:CanBeWorked() then 16 | target.components.workable:WorkedBy(self.inst, 1) 17 | self:DoHealthDelta() 18 | self:DoProficiencyDelta(1) 19 | return true 20 | end 21 | return false 22 | end 23 | 24 | function IronHand:DoHealthDelta() 25 | if(self.proficiency -------------------------------------------------------------------------------- /lesson_add_new_recipe/images/inventoryimages/lotus_umbrella.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_add_new_recipe/images/inventoryimages/lotus_umbrella.png -------------------------------------------------------------------------------- /lesson_add_new_recipe/images/inventoryimages/lotus_umbrella.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_add_new_recipe/images/inventoryimages/lotus_umbrella.tex -------------------------------------------------------------------------------- /lesson_add_new_recipe/images/inventoryimages/lotus_umbrella.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_add_new_recipe/modicon.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_add_new_recipe/modicon.tex -------------------------------------------------------------------------------- /lesson_add_new_recipe/modicon.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_add_new_recipe/modinfo.lua: -------------------------------------------------------------------------------- 1 | name = "饥荒Mod教程_添加配方" 2 | author = "LongFei" 3 | version = "1.0" 4 | description = "饥荒Mod教程_添加配方\n\n关于新版制作栏下添加配方的全面教程\n\n本教程的美术资源仅供教学使用\n请勿用于自己发布的Mod" 5 | 6 | forumthread = "" 7 | api_version = 10 8 | 9 | dst_compatible = true 10 | all_clients_require_mod = true 11 | -------------------------------------------------------------------------------- /lesson_add_new_recipe/modmain.lua: -------------------------------------------------------------------------------- 1 | PrefabFiles = { 2 | "lotus_umbrella", -- 让Mod加载lotus_umbrella定义文件 3 | } 4 | Assets = { 5 | Asset("ATLAS", "images/craft_samansha_icon.xml"), 6 | } 7 | -- 一些预设置,防止系统报错 8 | env.RECIPETABS = GLOBAL.RECIPETABS 9 | env.TECH = GLOBAL.TECH 10 | env.STRINGS = GLOBAL.STRINGS 11 | 12 | -- 定义一个新的过滤器 13 | local filter_samansha_def = { 14 | name = "SAMANSHA", 15 | atlas = "images/craft_samansha_icon.xml", 16 | image = "craft_samansha_icon.tex", 17 | image_size = 64, 18 | } 19 | 20 | -- 添加自定义过滤器 21 | AddRecipeFilter(filter_samansha_def, 1) 22 | STRINGS.UI.CRAFTING_FILTERS.SAMANSHA ="自定义过滤器" -- 制作栏中显示的名字 23 | 24 | local config = { 25 | atlas = "images/inventoryimages/lotus_umbrella.xml", 26 | } 27 | 28 | AddRecipe2("lotus_umbrella", {Ingredient("cutgrass", 1), Ingredient("twigs", 1)}, TECH.NONE, config, {"SAMANSHA"}) 29 | 30 | -- 将荷叶伞放到「雨具」分类 31 | AddRecipeToFilter("lotus_umbrella","RAIN") 32 | 33 | -- 将斧头移出「工具」分类 34 | RemoveRecipeFromFilter("axe", "TOOLS") 35 | 36 | -- 创建一个角色专属配方,只有可读书的人才能使用 37 | local config2 = { 38 | atlas = "images/inventoryimages/lotus_umbrella.xml", 39 | builder_tag = "reader", 40 | product = "lotus_umbrella", -- 当recipe名不是prefab名时,需要显式指定 41 | } 42 | AddCharacterRecipe("lotus_umbrella_few", {Ingredient("cutgrass", 1)}, TECH.NONE, config2, {"SAMANSHA"}) 43 | 44 | 45 | STRINGS.NAMES.LOTUS_UMBRELLA = "荷叶伞" -- 物体在游戏中显示的名字 46 | STRINGS.CHARACTERS.GENERIC.DESCRIBE.LOTUS_UMBRELLA = "这伞能挡雨吗?" -- 物体的检查描述 47 | STRINGS.RECIPE_DESC.LOTUS_UMBRELLA = "荷叶做的雨伞" -- 物体的制作栏描述 -------------------------------------------------------------------------------- /lesson_add_new_recipe/scripts/prefabs/lotus_umbrella.lua: -------------------------------------------------------------------------------- 1 | -- 加载资源表 2 | local assets = 3 | { 4 | Asset("ANIM", "anim/lotus_umbrella.zip"), 5 | Asset("ANIM", "anim/swap_lotus_umbrella.zip"), 6 | Asset("ATLAS", "images/inventoryimages/lotus_umbrella.xml"), 7 | } 8 | 9 | 10 | -- 装备回调 11 | local function onequip(inst, owner) 12 | owner.AnimState:OverrideSymbol("swap_object", "swap_lotus_umbrella", "swap_lotus_umbrella") -- 以下三句都是设置动画表现的,不会对游戏实际内容产生影响,你可以试试去掉的效果 13 | owner.AnimState:Show("ARM_carry") 14 | owner.AnimState:Hide("ARM_normal") 15 | owner.DynamicShadow:SetSize(1.7, 1) -- 设置阴影大小,你可以仔细观察装备荷叶伞时,人物脚下的阴影变化 16 | inst.components.fueled:StartConsuming() -- 装备之后开始消耗耐久 17 | end 18 | 19 | -- 卸载回调 20 | local function onunequip(inst, owner) 21 | owner.AnimState:Hide("ARM_carry") -- 和上面的装备回调类似,可以试试去掉的结果 22 | owner.AnimState:Show("ARM_normal") 23 | owner.DynamicShadow:SetSize(1.3, 0.6) 24 | inst.components.fueled:StopConsuming() -- 卸载之后停止消耗耐久 25 | end 26 | 27 | -- 耐久度归零回调 28 | local function onperish(inst) 29 | inst:Remove() -- 当耐久度归零时,荷叶伞自动消失 30 | end 31 | 32 | local function fn() 33 | local inst = CreateEntity() -- 创建实体 34 | 35 | inst.entity:AddTransform() -- 添加变换组件 36 | inst.entity:AddAnimState() -- 添加动画组件 37 | inst.entity:AddNetwork() -- 添加网络组件 38 | 39 | MakeInventoryPhysics(inst) -- 添加物理属性 40 | 41 | inst.AnimState:SetBank("lotus_umbrella") -- 设置动画的Bank,也就是动画内容组合 42 | inst.AnimState:SetBuild("lotus_umbrella") -- 设置动画的Build,也就是外表材质 43 | inst.AnimState:PlayAnimation("idle") -- 设置生成时应该播放的动画 44 | 45 | inst:AddTag("nopunch") 46 | inst:AddTag("umbrella") 47 | 48 | inst:AddTag("waterproofer") 49 | ---------------------- 主客机分界代码 ------------------------- 50 | inst.entity:SetPristine() 51 | if not TheWorld.ismastersim then 52 | return inst 53 | end 54 | --------------------------------------------------------------- 55 | 56 | ---------------------- 通用组件 ------------------------- 57 | -- 可检查 58 | inst:AddComponent("inspectable") 59 | -- 可放入物品栏 60 | inst:AddComponent("inventoryitem") 61 | inst.components.inventoryitem.atlasname = "images/inventoryimages/lotus_umbrella.xml" -- 设置物品栏图片文档。官方内置的物体有默认的图片文档,所以不需要设置这一项,但自己额外添加的物体使用自己的图片文档,就应该设置这一项 62 | 63 | -- 可装备 64 | inst:AddComponent("equippable") 65 | inst.components.equippable:SetOnEquip(onequip) -- 设置装备时的回调函数 66 | inst.components.equippable:SetOnUnequip(onunequip) -- 设置卸载时的回调函数 67 | 68 | ---------------------- 核心组件 ------------------------- 69 | --防雨 70 | inst:AddComponent("waterproofer") 71 | inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_HUGE) -- 设置防雨系数 72 | --遮阳 73 | inst:AddComponent("insulator") 74 | inst.components.insulator:SetSummer() -- 设置只能防热 75 | inst.components.insulator:SetInsulation(TUNING.INSULATION_MED) -- 设置防热系数 76 | 77 | 78 | ---------------------- 辅助组件 ------------------------- 79 | inst:AddComponent("fueled") -- 设置可被添加燃料组件,这里实质上就是耐久度。 80 | inst.components.fueled.accepting = true 81 | inst.components.fueled.maxfuel = TUNING.CAMPFIRE_FUEL_MAX --设置雨伞的最大耐久度 82 | inst.components.fueled.fueltype = FUELTYPE.BURNABLE --设置燃料类型,也就是需要特定的燃料才能增加。BURNABLE是默认的燃料类型,木材,干草都可以提供燃料。 83 | inst.components.fueled:SetDepletedFn(onperish) -- 设置燃料用完之后的回调函数,也就是耐久度归零后,这个物体会怎么样处理 84 | inst.components.fueled:InitializeFuelLevel(TUNING.CAMPFIRE_FUEL_MAX) --设置雨伞的初始耐久度 85 | 86 | MakeSmallBurnable(inst, TUNING.SMALL_BURNTIME) -- 系统函数,设置物体可以被点燃 87 | MakeSmallPropagator(inst) -- 系统函数,设置物体可以传播明火 88 | 89 | return inst 90 | end 91 | 92 | return Prefab("lotus_umbrella", fn, assets) -- 这里第一项参数是物体名字,写成路径的形式是为了能够清晰地表达这个物体的分类,common也就是普通物体,inventory表明这是一个可以放在物品栏中使用的物体,最后的lotus_umbrella则是真正的Prefab名。游戏在识别的时候只会识别最后这一段Prefab名,也就是lotus_umbrella。前面的部分只是为了代码可读性,对系统而言并没有什么特别意义 -------------------------------------------------------------------------------- /lesson_component/modicon.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_component/modicon.tex -------------------------------------------------------------------------------- /lesson_component/modicon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lesson_component/modinfo.lua: -------------------------------------------------------------------------------- 1 | name = "Lesson Component" 2 | description = "Component 组件教程" 3 | author = "LongFei" 4 | version = "0.0.1" 5 | 6 | forumthread = "" 7 | api_version = 10 8 | 9 | dst_compatible = true 10 | 11 | dont_starve_compatible = false 12 | reign_of_giants_compatible = false 13 | shipwrecked_compatible = false 14 | 15 | all_clients_require_mod = true 16 | 17 | server_filter_tags = {} 18 | 19 | priority = 0 20 | 21 | icon_atlas = "modicon.xml" 22 | icon = "modicon.tex" 23 | 24 | -------------------------------------------------------------------------------- /lesson_component/modmain.lua: -------------------------------------------------------------------------------- 1 | local _G = GLOBAL 2 | local require = _G.require 3 | local pcall = _G.pcall 4 | 5 | -- 为了方便后续添加其它的动作,类似官方代码中的Recipe,将新动作的相关参数都集中存放在一个module中的若干table里 6 | local actions_status,actions_data = pcall(require,"lf_actions") 7 | 8 | -- 这部分的代码是固定的,添加新的动作并不需要改动此处,只需要修改lf_actions.lua文件中的内容 9 | if actions_status then 10 | -- 导入自定义动作 11 | if actions_data.actions then 12 | for _,act in pairs(actions_data.actions) do 13 | -- 首先需要使用AddAction注册新动作,会返回这个动作变量 14 | local action = AddAction(act.id,act.str,act.fn) 15 | -- 会根据actiondata,进一步添加一些动作相关参数比如施放距离和优先级等 16 | if act.actiondata then 17 | for k,data in pairs(act.actiondata) do 18 | action[k] = data 19 | end 20 | end 21 | -- 将这个新动作与SG做绑定,wilson是玩家人物通用的SG,客机玩家还有额外的wilson_client为SG,为了保证客机一致性,都进行绑定 22 | AddStategraphActionHandler("wilson",_G.ActionHandler(action, act.state)) 23 | AddStategraphActionHandler("wilson_client",_G.ActionHandler(action,act.state)) 24 | end 25 | end 26 | 27 | -- 导入动作与组件的绑定 28 | if actions_data.component_actions then 29 | for _,v in pairs(actions_data.component_actions) do 30 | -- 这里定义的testfn,就是在第三期文章中讲到的检测函数,传入参数依所选的场景类型而变化 31 | local testfn = function(...) 32 | -- select是一个基础用法,结合函数传入的不定参数...,这里表示取倒数第二个参数,这个参数不管在哪个场景下,总是默认为actions,倒数第一个则是right 33 | local actions = _G.select(-2,...) 34 | for _,data in pairs(v.tests) do 35 | -- data.testfn是定义在lf_actions中的testfn,是检测是否满足触发条件的函数,只会返回true或false 36 | if data and data.testfn and data.testfn(...) then 37 | data.action = string.upper( data.action ) 38 | -- 如果检测通过,就将该action插入actions序列中 39 | table.insert( actions, _G.ACTIONS[data.action] ) 40 | end 41 | end 42 | end 43 | AddComponentAction(v.type, v.component, testfn) 44 | end 45 | end 46 | end 47 | 48 | -- 为所有玩家添加额外的组件ironhand 49 | AddPrefabPostInitAny(function(inst) 50 | if(inst:HasTag("player")) then 51 | inst:AddComponent("ironhand") 52 | end 53 | end) -------------------------------------------------------------------------------- /lesson_component/modworldgenmain.lua: -------------------------------------------------------------------------------- 1 | local GROUND = GLOBAL.GROUND 2 | -------------------------------------------------------------------------------- /lesson_component/scripts/components/ironhand.lua: -------------------------------------------------------------------------------- 1 | -- 三个阈值点 2 | local T1 = 100 3 | local T2 = 200 4 | local T3 = 500 5 | 6 | -- 组件定义和初始化 7 | local IronHand = Class(function(self, inst) 8 | self.inst = inst 9 | self.proficiency = 0 -- 熟练度 10 | self.inst:AddTag("ironhand") 11 | end, 12 | nil, 13 | nil) 14 | 15 | -- 计算工作效率,也就是一次动作相当于砍伐几次 16 | function IronHand:GetNumWorks() 17 | if(self.proficiency -------------------------------------------------------------------------------- /lesson_quick_start_base/modicon.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_base/modicon.tex -------------------------------------------------------------------------------- /lesson_quick_start_base/modicon.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_quick_start_base/modinfo.lua: -------------------------------------------------------------------------------- 1 | name = "饥荒Mod入门_脚手架" 2 | author = "LongFei" 3 | version = "V0.0.1 S" 4 | description = "饥荒Mod入门-脚手架,请参照文章完成作业\n\n本教程的美术资源仅供教学使用\n请勿用于自己发布的Mod" 5 | 6 | forumthread = "" 7 | api_version = 10 8 | 9 | dst_compatible = true 10 | all_clients_require_mod = true 11 | 12 | 13 | icon_atlas = "modicon.xml" 14 | icon = "modicon.tex" 15 | -------------------------------------------------------------------------------- /lesson_quick_start_base/modmain.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_base/modmain.lua -------------------------------------------------------------------------------- /lesson_quick_start_finish/anim/lotus_umbrella.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/anim/lotus_umbrella.zip -------------------------------------------------------------------------------- /lesson_quick_start_finish/anim/swap_lotus_umbrella.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/anim/swap_lotus_umbrella.zip -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/lotus_umbrella/lotus_umbrella.scml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/lotus_umbrella/lotus_umbrella.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/exported/lotus_umbrella/lotus_umbrella.zip -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/lotus_umbrella/lotus_umbrella/lotus_umbrella.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/exported/lotus_umbrella/lotus_umbrella/lotus_umbrella.png -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/swap_lotus_umbrella/swap_lotus_umbrella.scml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/swap_lotus_umbrella/swap_lotus_umbrella.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/exported/swap_lotus_umbrella/swap_lotus_umbrella.zip -------------------------------------------------------------------------------- /lesson_quick_start_finish/exported/swap_lotus_umbrella/swap_lotus_umbrella/swap_lotus_umbrella.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/exported/swap_lotus_umbrella/swap_lotus_umbrella/swap_lotus_umbrella.png -------------------------------------------------------------------------------- /lesson_quick_start_finish/images/inventoryimages/lotus_umbrella.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/images/inventoryimages/lotus_umbrella.png -------------------------------------------------------------------------------- /lesson_quick_start_finish/images/inventoryimages/lotus_umbrella.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/images/inventoryimages/lotus_umbrella.tex -------------------------------------------------------------------------------- /lesson_quick_start_finish/images/inventoryimages/lotus_umbrella.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_quick_start_finish/modicon.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/user919lx/dst_mod_tutorial/7e7dfb4cc8d56e26be69e9e7dea071df2c1df55a/lesson_quick_start_finish/modicon.tex -------------------------------------------------------------------------------- /lesson_quick_start_finish/modicon.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_quick_start_finish/modinfo.lua: -------------------------------------------------------------------------------- 1 | name = "饥荒Mod入门_完成" 2 | author = "LongFei" 3 | version = "V0.0.1 F" 4 | description = "饥荒Mod入门-答案,请和自己的作业对比查找问题\n\n本教程的美术资源仅供教学使用\n请勿用于自己发布的Mod" 5 | 6 | forumthread = "" 7 | api_version = 10 8 | 9 | dst_compatible = true 10 | all_clients_require_mod = true 11 | -------------------------------------------------------------------------------- /lesson_quick_start_finish/modmain.lua: -------------------------------------------------------------------------------- 1 | PrefabFiles = { 2 | "lotus_umbrella", -- 让Mod加载lotus_umbrella定义文件 3 | } 4 | 5 | 6 | -- 一些预设置,防止系统报错 7 | env.RECIPETABS = GLOBAL.RECIPETABS 8 | env.TECH = GLOBAL.TECH 9 | 10 | 11 | -- AddRecipe已过期,现在请使用AddRecipe2 12 | -- AddRecipe2是官方提供的MOD API,专门用于Mod环境,参数非常多,和scripts/recipe.lua里的Recipe2一致。 13 | -- Recipe2(name, ingredients, tech, config) 14 | -- 参数说明如下 15 | -- name = prefab名。 16 | -- ingredients = 配方表,用{}框起来,里面每一项配方是一个Ingredient。例子中 17 | -- Ingredient("{prefab_name}", num), 两个参数分别是prefab名和数量 18 | -- 本Mod的例子,可以用一个干草+一个树枝制作 19 | -- tect = 所需科技,TECH.NONE 表明不需要科技,随时都可以制造。 20 | -- config = 其它参数选项,是一个表 21 | -- config: { 22 | -- placer: unknown, 放置物prefab,用于显示一个建筑的临时放置物,在放下建筑后就会消失 23 | -- min_spacing: unknown, 最小间距 24 | -- nounlock: unknown, 是否锁定,锁定时,只能在对应的科技建筑旁建造 25 | -- numtogive: unknown, 给几个制作物 26 | -- builder_tag: unknown, 要求具备的制作者标签。如果人物没有此标签,便无法制作物品,可以用于人物的专属物品。 27 | -- atlas: unknown, 图片文档路径,用于制作栏显示图片 28 | -- image: unknown, 图片文件路径,其实atlas中有包含,不必再填 29 | -- testfn: unknown, 放置时的检测函数,比如有些建筑对地形有特殊要求,可以使用此函数检测 30 | -- product: unknown, 产出物 31 | -- build_mode: unknown, 建造模式,无限制/地上/水上 32 | -- build_distance: unknown, 建造距离, 33 | -- } 34 | 35 | local config = { 36 | atlas = "images/inventoryimages/lotus_umbrella.xml", 37 | } 38 | 39 | AddRecipe2("lotus_umbrella", {Ingredient("cutgrass", 1), Ingredient("twigs", 1)}, TECH.NONE, config) 40 | 41 | env.STRINGS = GLOBAL.STRINGS -- 预设置 42 | STRINGS.NAMES.LOTUS_UMBRELLA = "荷叶伞" -- 物体在游戏中显示的名字 43 | STRINGS.CHARACTERS.GENERIC.DESCRIBE.LOTUS_UMBRELLA = "这伞能挡雨吗?" -- 物体的检查描述 44 | STRINGS.RECIPE_DESC.LOTUS_UMBRELLA = "荷叶做的雨伞" -- 物体的制作栏描述 -------------------------------------------------------------------------------- /lesson_quick_start_finish/scripts/prefabs/lotus_umbrella.lua: -------------------------------------------------------------------------------- 1 | -- 加载资源表 2 | local assets = 3 | { 4 | Asset("ANIM", "anim/lotus_umbrella.zip"), 5 | Asset("ANIM", "anim/swap_lotus_umbrella.zip"), 6 | Asset("ATLAS", "images/inventoryimages/lotus_umbrella.xml"), 7 | } 8 | 9 | 10 | -- 装备回调 11 | local function onequip(inst, owner) 12 | owner.AnimState:OverrideSymbol("swap_object", "swap_lotus_umbrella", "swap_lotus_umbrella") -- 以下三句都是设置动画表现的,不会对游戏实际内容产生影响,你可以试试去掉的效果 13 | owner.AnimState:Show("ARM_carry") 14 | owner.AnimState:Hide("ARM_normal") 15 | owner.DynamicShadow:SetSize(1.7, 1) -- 设置阴影大小,你可以仔细观察装备荷叶伞时,人物脚下的阴影变化 16 | inst.components.fueled:StartConsuming() -- 装备之后开始消耗耐久 17 | end 18 | 19 | -- 卸载回调 20 | local function onunequip(inst, owner) 21 | owner.AnimState:Hide("ARM_carry") -- 和上面的装备回调类似,可以试试去掉的结果 22 | owner.AnimState:Show("ARM_normal") 23 | owner.DynamicShadow:SetSize(1.3, 0.6) 24 | inst.components.fueled:StopConsuming() -- 卸载之后停止消耗耐久 25 | end 26 | 27 | -- 耐久度归零回调 28 | local function onperish(inst) 29 | inst:Remove() -- 当耐久度归零时,荷叶伞自动消失 30 | end 31 | 32 | local function fn() 33 | local inst = CreateEntity() -- 创建实体 34 | 35 | inst.entity:AddTransform() -- 添加变换组件 36 | inst.entity:AddAnimState() -- 添加动画组件 37 | inst.entity:AddNetwork() -- 添加网络组件 38 | 39 | MakeInventoryPhysics(inst) -- 添加物理属性 40 | 41 | inst.AnimState:SetBank("lotus_umbrella") -- 设置动画的Bank,也就是动画内容组合 42 | inst.AnimState:SetBuild("lotus_umbrella") -- 设置动画的Build,也就是外表材质 43 | inst.AnimState:PlayAnimation("idle") -- 设置生成时应该播放的动画 44 | 45 | inst:AddTag("nopunch") 46 | inst:AddTag("umbrella") 47 | 48 | inst:AddTag("waterproofer") 49 | ---------------------- 主客机分界代码 ------------------------- 50 | inst.entity:SetPristine() 51 | if not TheWorld.ismastersim then 52 | return inst 53 | end 54 | --------------------------------------------------------------- 55 | 56 | ---------------------- 通用组件 ------------------------- 57 | -- 可检查 58 | inst:AddComponent("inspectable") 59 | -- 可放入物品栏 60 | inst:AddComponent("inventoryitem") 61 | inst.components.inventoryitem.atlasname = "images/inventoryimages/lotus_umbrella.xml" -- 设置物品栏图片文档。官方内置的物体有默认的图片文档,所以不需要设置这一项,但自己额外添加的物体使用自己的图片文档,就应该设置这一项 62 | 63 | -- 可装备 64 | inst:AddComponent("equippable") 65 | inst.components.equippable:SetOnEquip(onequip) -- 设置装备时的回调函数 66 | inst.components.equippable:SetOnUnequip(onunequip) -- 设置卸载时的回调函数 67 | 68 | ---------------------- 核心组件 ------------------------- 69 | --防雨 70 | inst:AddComponent("waterproofer") 71 | inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_HUGE) -- 设置防雨系数 72 | --遮阳 73 | inst:AddComponent("insulator") 74 | inst.components.insulator:SetSummer() -- 设置只能防热 75 | inst.components.insulator:SetInsulation(TUNING.INSULATION_MED) -- 设置防热系数 76 | 77 | 78 | ---------------------- 辅助组件 ------------------------- 79 | inst:AddComponent("fueled") -- 设置可被添加燃料组件,这里实质上就是耐久度。 80 | inst.components.fueled.accepting = true 81 | inst.components.fueled.maxfuel = TUNING.CAMPFIRE_FUEL_MAX --设置雨伞的最大耐久度 82 | inst.components.fueled.fueltype = FUELTYPE.BURNABLE --设置燃料类型,也就是需要特定的燃料才能增加。BURNABLE是默认的燃料类型,木材,干草都可以提供燃料。 83 | inst.components.fueled:SetDepletedFn(onperish) -- 设置燃料用完之后的回调函数,也就是耐久度归零后,这个物体会怎么样处理 84 | inst.components.fueled:InitializeFuelLevel(TUNING.CAMPFIRE_FUEL_MAX) --设置雨伞的初始耐久度 85 | 86 | MakeSmallBurnable(inst, TUNING.SMALL_BURNTIME) -- 系统函数,设置物体可以被点燃 87 | MakeSmallPropagator(inst) -- 系统函数,设置物体可以传播明火 88 | 89 | return inst 90 | end 91 | 92 | return Prefab("lotus_umbrella", fn, assets) -- 这里第一项参数是物体名字,写成路径的形式是为了能够清晰地表达这个物体的分类,common也就是普通物体,inventory表明这是一个可以放在物品栏中使用的物体,最后的lotus_umbrella则是真正的Prefab名。游戏在识别的时候只会识别最后这一段Prefab名,也就是lotus_umbrella。前面的部分只是为了代码可读性,对系统而言并没有什么特别意义 --------------------------------------------------------------------------------