代码来源于“易宁”大佬的分享,仅供学习,不要直接复制粘贴。

原帖链接:http://bbs.3dmgame.com/thread-3859071-1-1.html


  1
  2.私家军(用火药种私家军,可装备盔甲、帽子,需要支付工资)
  3
  4	MT管理器打开游戏目录/assets/DLC0002/scripts/prefabs/gunpowder.lua文件,在inst:AddComponent("inspectable")的下一行插入以下内容:
  5
  6local function itemtest(inst, item, slot)
  7	if item.prefab == "armorgrass" or item.prefab == "armorwood" or item.prefab == "armormarble" or item.prefab == "armor_sanity" or item.prefab == "armorruins" or item.prefab == "footballhat" or item.prefab == "ruinshat" or item.prefab == "beefalohat" or item.prefab == "featherhat" or item.prefab == "goldnugget" then
  8	   return true
  9	end
 10	return false
 11end
 12local slotpos = { Vector3(0,32+4,0), Vector3(0,-(32+4),0), Vector3(0,-(64+32+8+4),0)}
 13local widgetbuttoninfo = {
 14	text = "Go",
 15	position = Vector3(0, -165, 0),
 16	fn = function(inst)
 17	  if inst:HasTag("mercenary") then
 18		 if inst.components.container:Has("goldnugget", 20) then inst:AddTag("cango") end
 19		 inst.components.container:Close(GetPlayer())
 20		 GetPlayer().SoundEmitter:PlaySound("dontstarve/HUD/research_available")
 21		 inst.AnimState:Hide("HAT")
 22		 inst.AnimState:Hide("HAT_HAIR")
 23		 inst.AnimState:Show("HAIR_NOHAT")
 24		 inst.AnimState:Show("HAIR")
 25		 inst.AnimState:ClearOverrideSymbol("swap_body")
 26		 for k,v in pairs(inst.components.container.slots) do
 27			 if v.prefab == "footballhat" or v.prefab == "ruinshat" or v.prefab == "beefalohat" or v.prefab == "featherhat" then
 28				inst.AnimState:Show("HAT")
 29				inst.AnimState:Show("HAT_HAIR")
 30				inst.AnimState:Hide("HAIR_NOHAT")
 31				inst.AnimState:Hide("HAIR")
 32			 end
 33			 if v and v.prefab == "armorgrass" then
 34				inst.AnimState:OverrideSymbol("swap_body", "armor_grass", "swap_body")
 35				inst:ListenForEvent("attacked", function(inst, data)
 36					inst.components.health:DoDelta(15)
 37				end )
 38			 end
 39			 if v and v.prefab == "armorwood" then
 40				inst.AnimState:OverrideSymbol("swap_body", "armor_wood", "swap_body")
 41				inst:ListenForEvent("attacked", function(inst, data)
 42					inst.components.health:DoDelta(20)
 43				end )
 44			 end
 45			 if v and v.prefab == "armormarble" then
 46				inst.AnimState:OverrideSymbol("swap_body", "armor_marble", "swap_body")
 47				inst:ListenForEvent("attacked", function(inst, data)
 48					inst.components.health:DoDelta(25)
 49				end )
 50			 end
 51			 if v and v.prefab == "armor_sanity" then
 52				inst.AnimState:OverrideSymbol("swap_body", "armor_sanity", "swap_body")
 53				inst:ListenForEvent("attacked", function(inst, data)
 54					inst.components.health:DoDelta(30)
 55				end )
 56			 end
 57			 if v and v.prefab == "armorruins" then
 58				inst.AnimState:OverrideSymbol("swap_body", "armor_ruins", "swap_body")
 59				inst:ListenForEvent("attacked", function(inst, data)
 60					inst.components.health:DoDelta(35)
 61				end )
 62			 end
 63			 if v and v.prefab == "footballhat" then
 64				inst.AnimState:OverrideSymbol("swap_hat", "hat_football", "swap_hat")
 65			 end
 66			 if v and v.prefab == "ruinshat" then
 67				inst.AnimState:OverrideSymbol("swap_hat", "hat_ruins", "swap_hat")
 68			 end
 69			 if v and v.prefab == "beefalohat" then
 70				inst.AnimState:OverrideSymbol("swap_hat", "hat_beefalo", "swap_hat")
 71			 end
 72			 if v and v.prefab == "featherhat" then
 73				inst.AnimState:OverrideSymbol("swap_hat", "hat_feather", "swap_hat")
 74			 end
 75		 end
 76	  end
 77	end }
 78	inst:AddComponent("container")
 79	inst.components.container.widgetbuttoninfo = widgetbuttoninfo
 80	inst.components.container:SetNumSlots(#slotpos)
 81	inst.components.container.widgetslotpos = slotpos
 82	inst.components.container.widgetpos = Vector3(0,180,0)
 83	inst.components.container.side_align_tip = 160
 84	inst.components.container.canbeopened = false
 85	inst.components.container.itemtestfn = itemtest
 86	inst.components.container.onopenfn = function(inst) inst:RemoveTag("cango") end
 87local items = { SWORD = "swap_spear" }
 88local function EquipItem(inst, item)
 89	if item then
 90	   inst.AnimState:OverrideSymbol("swap_object", item, item)
 91	   inst.AnimState:Show("ARM_carry") 
 92	   inst.AnimState:Hide("ARM_normal")
 93	end
 94end
 95	inst.items = items
 96	inst.equipfn = EquipItem
 97	EquipItem(inst)
 98local function OnDeploy (inst, pt)
 99  if GetPlayer().components.inventory:Has("goldnugget", 100) then 
100	GetPlayer().components.inventory:ConsumeByName("goldnugget", 100)
101	local mercenary = SpawnPrefab("gunpowder")
102	mercenary.Transform:SetPosition(pt.x, pt.y, pt.z)
103	mercenary.AnimState:SetBank("wilson")
104	mercenary.AnimState:SetBuild("wilson")
105	mercenary.AnimState:PlayAnimation("idle")
106	mercenary.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")
107	mercenary.AnimState:Show("ARM_carry") 
108	mercenary.AnimState:Hide("ARM_normal")
109	mercenary.Transform:SetFourFaced()
110	local shadow = mercenary.entity:AddDynamicShadow()
111	shadow:SetSize( 1.3, .6 )
112	MakeCharacterPhysics(mercenary, 75, .5)
113	local minimap = mercenary.entity:AddMiniMapEntity()
114	minimap:SetIcon( "researchlab.png" )
115	mercenary:AddTag("mercenary")
116	mercenary:AddComponent("locomotor")
117	mercenary.components.locomotor.walkspeed = 8
118	mercenary.components.locomotor.runspeed = 15
119	mercenary:SetStateGraph("SGshadowwaxwell")
120	mercenary:RemoveComponent("stackable")
121	mercenary:RemoveComponent("explosive")
122	mercenary:RemoveComponent("inventoryitem")
123	mercenary:RemoveComponent("burnable")
124	mercenary:RemoveComponent("propagator")
125	mercenary:RemoveComponent("deployable")
126	mercenary:RemoveComponent("bait")
127	mercenary:RemoveTag("molebait")
128	mercenary:AddComponent("follower")
129	mercenary:AddComponent("inventory")
130	mercenary.components.container.canbeopened = true
131	mercenary:AddComponent("combat")
132	mercenary.components.combat.hiteffectsymbol = "torso"
133	mercenary.components.combat:SetDefaultDamage(50)
134	mercenary.components.combat:SetRange(2, 3)
135	mercenary.components.combat:SetAttackPeriod(0.5)
136	mercenary.components.combat:SetRetargetFunction(2, function(mercenary)
137		if not mercenary.components.health:IsDead() then
138			return FindEntity(mercenary, 25, function(guy)
139				if guy.components.health and not guy.components.health:IsDead() then
140				   return guy.components.combat.target == GetPlayer() or GetPlayer().components.combat.target == guy or guy:HasTag("monster")
141				end
142			end)
143		end
144	end )
145	mercenary.components.combat:SetKeepTargetFunction(function(mercenary, target) return target and target:IsValid() end )
146	mercenary:AddComponent("health")
147	mercenary.components.health:SetMaxHealth(1500)
148	mercenary.components.health.nofadeout = true
149	mercenary:DoPeriodicTask(1, function(mercenary)
150	  if mercenary:HasTag("cango") then
151		if not mercenary.components.container:Has("goldnugget", 20) then
152		   mercenary.AnimState:SetBloomEffectHandle("")
153		   mercenary.components.locomotor:Stop()
154		   mercenary:SetBrain(nil)
155		   mercenary.components.follower:SetLeader(nil)
156		else
157		   mercenary.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
158		   local brain = require "brains/abigailbrain"
159		   mercenary:SetBrain(brain)
160		   mercenary:RestartBrain()
161		   mercenary.components.follower:SetLeader(GetPlayer())
162		end
163	  else
164		 mercenary.AnimState:SetBloomEffectHandle("")
165		 mercenary.components.locomotor:Stop()
166		 mercenary:SetBrain(nil)
167		 mercenary.components.follower:SetLeader(nil)
168	  end
169	end )
170	mercenary:DoPeriodicTask(480, function(mercenary)
171		if mercenary.components.container:Has("goldnugget", 20) then
172		   mercenary.components.container:ConsumeByName("goldnugget", 20)
173		   mercenary.components.health:DoDelta(500)
174		end
175	end )
176	mercenary:AddComponent( "playerprox" )
177	mercenary.components.playerprox:SetDist(3,5)
178	mercenary.components.playerprox:SetOnPlayerNear(function(mercenary)
179		mercenary.components.locomotor.walkspeed = 1
180		mercenary.components.locomotor.runspeed = 2
181	end )
182	mercenary.components.playerprox:SetOnPlayerFar(function(mercenary)
183		mercenary.components.locomotor.walkspeed = 8
184		mercenary.components.locomotor.runspeed = 15
185	end )
186  end
187	inst.components.stackable:Get():Remove()
188end
189	inst:AddComponent("deployable")
190	inst.components.deployable.ondeploy = OnDeploy
191local function onsave(inst, data)
192	if inst:HasTag("mercenary") then
193		data.mercenary = true
194	end
195	if inst:HasTag("cango") then
196		data.cango = true
197	end
198end
199local function onload(inst, data)
200  if data and data.mercenary then
201	inst.AnimState:SetBank("wilson")
202	inst.AnimState:SetBuild("wilson")
203	inst.AnimState:PlayAnimation("idle")
204	inst.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")
205	inst.AnimState:Show("ARM_carry") 
206	inst.AnimState:Hide("ARM_normal")
207	inst.Transform:SetFourFaced()
208	local shadow = inst.entity:AddDynamicShadow()
209	shadow:SetSize( 1.3, .6 )
210	MakeCharacterPhysics(inst, 75, .5)
211	local minimap = inst.entity:AddMiniMapEntity()
212	minimap:SetIcon( "researchlab.png" )
213	inst:AddTag("mercenary")
214	inst:AddComponent("locomotor")
215	inst.components.locomotor.walkspeed = 8
216	inst.components.locomotor.runspeed = 15
217	inst:SetStateGraph("SGshadowwaxwell")
218	inst:RemoveComponent("stackable")
219	inst:RemoveComponent("explosive")
220	inst:RemoveComponent("inventoryitem")
221	inst:RemoveComponent("burnable")
222	inst:RemoveComponent("propagator")
223	inst:RemoveComponent("deployable")
224	inst:RemoveComponent("bait")
225	inst:RemoveTag("molebait")
226	inst:AddComponent("follower")
227	inst:AddComponent("inventory")
228	inst.components.container.canbeopened = true
229	inst:AddComponent("combat")
230	inst.components.combat.hiteffectsymbol = "torso"
231	inst.components.combat:SetDefaultDamage(50)
232	inst.components.combat:SetRange(2, 3)
233	inst.components.combat:SetAttackPeriod(0.5)
234	inst.components.combat:SetRetargetFunction(2, function(inst)
235		if not inst.components.health:IsDead() then
236			return FindEntity(inst, 25, function(guy)
237				if guy.components.health and not guy.components.health:IsDead() then
238				   return guy.components.combat.target == GetPlayer() or GetPlayer().components.combat.target == guy or guy:HasTag("monster")
239				end
240			end)
241		end
242	end )
243	inst.components.combat:SetKeepTargetFunction(function(inst, target) return target and target:IsValid() end )
244	inst:AddComponent("health")
245	inst.components.health:SetMaxHealth(1500)
246	inst.components.health.nofadeout = true
247	inst:DoPeriodicTask(1, function(inst)
248	  if inst:HasTag("cango") then
249		if not inst.components.container:Has("goldnugget", 20) then
250		   inst.AnimState:SetBloomEffectHandle("")
251		   inst.components.locomotor:Stop()
252		   inst:SetBrain(nil)
253		   inst.components.follower:SetLeader(nil)
254		else
255		   inst.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
256		   local brain = require "brains/abigailbrain"
257		   inst:SetBrain(brain)
258		   inst:RestartBrain()
259		   inst.components.follower:SetLeader(GetPlayer())
260		end
261	  else
262		 inst.AnimState:SetBloomEffectHandle("")
263		 inst.components.locomotor:Stop()
264		 inst:SetBrain(nil)
265		 inst.components.follower:SetLeader(nil)
266	  end
267	end )
268	inst:DoPeriodicTask(480, function(inst)
269		if inst.components.container:Has("goldnugget", 20) then
270		   inst.components.container:ConsumeByName("goldnugget", 20)
271		   inst.components.health:DoDelta(500)
272		end
273	end )
274	inst:AddComponent( "playerprox" )
275	inst.components.playerprox:SetDist(3,5)
276	inst.components.playerprox:SetOnPlayerNear(function(inst)
277		inst.components.locomotor.walkspeed = 1
278		inst.components.locomotor.runspeed = 2
279	end )
280	inst.components.playerprox:SetOnPlayerFar(function(inst)
281		inst.components.locomotor.walkspeed = 8
282		inst.components.locomotor.runspeed = 15
283	end )
284	inst.AnimState:Hide("HAT")
285	inst.AnimState:Hide("HAT_HAIR")
286	inst.AnimState:Show("HAIR_NOHAT")
287	inst.AnimState:Show("HAIR")
288	inst.AnimState:ClearOverrideSymbol("swap_body")
289	for k,v in pairs(inst.components.container.slots) do
290		if v.prefab == "footballhat" or v.prefab == "ruinshat" or v.prefab == "beefalohat" or v.prefab == "featherhat" then
291		   inst.AnimState:Show("HAT")
292		   inst.AnimState:Show("HAT_HAIR")
293		   inst.AnimState:Hide("HAIR_NOHAT")
294		   inst.AnimState:Hide("HAIR")
295		end
296		if v and v.prefab == "armorgrass" then
297		   inst.AnimState:OverrideSymbol("swap_body", "armor_grass", "swap_body")
298		   inst:ListenForEvent("attacked", function(inst, data)
299			   inst.components.health:DoDelta(15)
300		   end )
301		end
302		if v and v.prefab == "armorwood" then
303		   inst.AnimState:OverrideSymbol("swap_body", "armor_wood", "swap_body")
304		   inst:ListenForEvent("attacked", function(inst, data)
305			   inst.components.health:DoDelta(20)
306		   end )
307		end
308		if v and v.prefab == "armormarble" then
309		   inst.AnimState:OverrideSymbol("swap_body", "armor_marble", "swap_body")
310		   inst:ListenForEvent("attacked", function(inst, data)
311			   inst.components.health:DoDelta(25)
312		   end )
313		end
314		if v and v.prefab == "armor_sanity" then
315		   inst.AnimState:OverrideSymbol("swap_body", "armor_sanity", "swap_body")
316		   inst:ListenForEvent("attacked", function(inst, data)
317			   inst.components.health:DoDelta(30)
318		   end )
319		end
320		if v and v.prefab == "armorruins" then
321		   inst.AnimState:OverrideSymbol("swap_body", "armor_ruins", "swap_body")
322		   inst:ListenForEvent("attacked", function(inst, data)
323			   inst.components.health:DoDelta(35)
324		   end )
325		end
326		if v and v.prefab == "footballhat" then
327		   inst.AnimState:OverrideSymbol("swap_hat", "hat_football", "swap_hat")
328		end
329		if v and v.prefab == "ruinshat" then
330		   inst.AnimState:OverrideSymbol("swap_hat", "hat_ruins", "swap_hat")
331		end
332		if v and v.prefab == "beefalohat" then
333		   inst.AnimState:OverrideSymbol("swap_hat", "hat_beefalo", "swap_hat")
334		end
335		if v and v.prefab == "featherhat" then
336		   inst.AnimState:OverrideSymbol("swap_hat", "hat_feather", "swap_hat")
337		end
338	end
339  end
340  if data and data.cango then
341	 inst:AddTag("cango")
342  end
343end
344	inst.OnSave = onsave
345	inst.OnLoad = onload
346
347	即可在身上有100个黄金时,用火药种私家军,将花费100个黄金,身上黄金数不足时不会种出来。鼠标左键点击他可打开格子,放入至少20个黄金后,点Go按钮,会跟随你打仗。追上他用鼠标左键再次点击,可让他停在原地,想让他继续跟随,就再点Go按钮即可。私家军士兵每天的工资是20个黄金,自动从他身上的黄金中扣除(并同时回补三分之一的血),如果他身上的黄金数不足20个时,将罢工,请及时续费。如果私家军的格子中有盔甲、帽子,点Go按钮会自动装备。装备盔甲可提高私家军的防御力,按防御力由低到高排序为草盔甲、木盔甲、大理石盔甲、夜魔盔甲、远古盔甲。装备帽子只起到装饰作用,可装备的帽子有猪皮帽、远古帽、牛毛帽、羽毛帽。不要在他的格子里放2个盔甲或2个帽子,他只会选择1个装备。私家军在小地图上显示为科学机器的图标,可以方便地找到他们的位置。火药在科学选项(画着原子)下,用1个烂鸡蛋、1个木炭、1个硝石制造