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

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



一.私家军(用火药种私家军,可装备盔甲、帽子,需要支付工资)

	用MT管理器打开游戏目录/assets/DLC0002/scripts/prefabs/gunpowder.lua文件,在inst:AddComponent("inspectable")的下一行插入以下内容:

local function itemtest(inst, item, slot)
	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
	   return true
	end
	return false
end
local slotpos = { Vector3(0,32+4,0), Vector3(0,-(32+4),0), Vector3(0,-(64+32+8+4),0)}
local widgetbuttoninfo = {
	text = "Go",
	position = Vector3(0, -165, 0),
	fn = function(inst)
	  if inst:HasTag("mercenary") then
		 if inst.components.container:Has("goldnugget", 20) then inst:AddTag("cango") end
		 inst.components.container:Close(GetPlayer())
		 GetPlayer().SoundEmitter:PlaySound("dontstarve/HUD/research_available")
		 inst.AnimState:Hide("HAT")
		 inst.AnimState:Hide("HAT_HAIR")
		 inst.AnimState:Show("HAIR_NOHAT")
		 inst.AnimState:Show("HAIR")
		 inst.AnimState:ClearOverrideSymbol("swap_body")
		 for k,v in pairs(inst.components.container.slots) do
			 if v.prefab == "footballhat" or v.prefab == "ruinshat" or v.prefab == "beefalohat" or v.prefab == "featherhat" then
				inst.AnimState:Show("HAT")
				inst.AnimState:Show("HAT_HAIR")
				inst.AnimState:Hide("HAIR_NOHAT")
				inst.AnimState:Hide("HAIR")
			 end
			 if v and v.prefab == "armorgrass" then
				inst.AnimState:OverrideSymbol("swap_body", "armor_grass", "swap_body")
				inst:ListenForEvent("attacked", function(inst, data)
					inst.components.health:DoDelta(15)
				end )
			 end
			 if v and v.prefab == "armorwood" then
				inst.AnimState:OverrideSymbol("swap_body", "armor_wood", "swap_body")
				inst:ListenForEvent("attacked", function(inst, data)
					inst.components.health:DoDelta(20)
				end )
			 end
			 if v and v.prefab == "armormarble" then
				inst.AnimState:OverrideSymbol("swap_body", "armor_marble", "swap_body")
				inst:ListenForEvent("attacked", function(inst, data)
					inst.components.health:DoDelta(25)
				end )
			 end
			 if v and v.prefab == "armor_sanity" then
				inst.AnimState:OverrideSymbol("swap_body", "armor_sanity", "swap_body")
				inst:ListenForEvent("attacked", function(inst, data)
					inst.components.health:DoDelta(30)
				end )
			 end
			 if v and v.prefab == "armorruins" then
				inst.AnimState:OverrideSymbol("swap_body", "armor_ruins", "swap_body")
				inst:ListenForEvent("attacked", function(inst, data)
					inst.components.health:DoDelta(35)
				end )
			 end
			 if v and v.prefab == "footballhat" then
				inst.AnimState:OverrideSymbol("swap_hat", "hat_football", "swap_hat")
			 end
			 if v and v.prefab == "ruinshat" then
				inst.AnimState:OverrideSymbol("swap_hat", "hat_ruins", "swap_hat")
			 end
			 if v and v.prefab == "beefalohat" then
				inst.AnimState:OverrideSymbol("swap_hat", "hat_beefalo", "swap_hat")
			 end
			 if v and v.prefab == "featherhat" then
				inst.AnimState:OverrideSymbol("swap_hat", "hat_feather", "swap_hat")
			 end
		 end
	  end
	end }
	inst:AddComponent("container")
	inst.components.container.widgetbuttoninfo = widgetbuttoninfo
	inst.components.container:SetNumSlots(#slotpos)
	inst.components.container.widgetslotpos = slotpos
	inst.components.container.widgetpos = Vector3(0,180,0)
	inst.components.container.side_align_tip = 160
	inst.components.container.canbeopened = false
	inst.components.container.itemtestfn = itemtest
	inst.components.container.onopenfn = function(inst) inst:RemoveTag("cango") end
local items = { SWORD = "swap_spear" }
local function EquipItem(inst, item)
	if item then
	   inst.AnimState:OverrideSymbol("swap_object", item, item)
	   inst.AnimState:Show("ARM_carry") 
	   inst.AnimState:Hide("ARM_normal")
	end
end
	inst.items = items
	inst.equipfn = EquipItem
	EquipItem(inst)
local function OnDeploy (inst, pt)
  if GetPlayer().components.inventory:Has("goldnugget", 100) then 
	GetPlayer().components.inventory:ConsumeByName("goldnugget", 100)
	local mercenary = SpawnPrefab("gunpowder")
	mercenary.Transform:SetPosition(pt.x, pt.y, pt.z)
	mercenary.AnimState:SetBank("wilson")
	mercenary.AnimState:SetBuild("wilson")
	mercenary.AnimState:PlayAnimation("idle")
	mercenary.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")
	mercenary.AnimState:Show("ARM_carry") 
	mercenary.AnimState:Hide("ARM_normal")
	mercenary.Transform:SetFourFaced()
	local shadow = mercenary.entity:AddDynamicShadow()
	shadow:SetSize( 1.3, .6 )
	MakeCharacterPhysics(mercenary, 75, .5)
	local minimap = mercenary.entity:AddMiniMapEntity()
	minimap:SetIcon( "researchlab.png" )
	mercenary:AddTag("mercenary")
	mercenary:AddComponent("locomotor")
	mercenary.components.locomotor.walkspeed = 8
	mercenary.components.locomotor.runspeed = 15
	mercenary:SetStateGraph("SGshadowwaxwell")
	mercenary:RemoveComponent("stackable")
	mercenary:RemoveComponent("explosive")
	mercenary:RemoveComponent("inventoryitem")
	mercenary:RemoveComponent("burnable")
	mercenary:RemoveComponent("propagator")
	mercenary:RemoveComponent("deployable")
	mercenary:RemoveComponent("bait")
	mercenary:RemoveTag("molebait")
	mercenary:AddComponent("follower")
	mercenary:AddComponent("inventory")
	mercenary.components.container.canbeopened = true
	mercenary:AddComponent("combat")
	mercenary.components.combat.hiteffectsymbol = "torso"
	mercenary.components.combat:SetDefaultDamage(50)
	mercenary.components.combat:SetRange(2, 3)
	mercenary.components.combat:SetAttackPeriod(0.5)
	mercenary.components.combat:SetRetargetFunction(2, function(mercenary)
		if not mercenary.components.health:IsDead() then
			return FindEntity(mercenary, 25, function(guy)
				if guy.components.health and not guy.components.health:IsDead() then
				   return guy.components.combat.target == GetPlayer() or GetPlayer().components.combat.target == guy or guy:HasTag("monster")
				end
			end)
		end
	end )
	mercenary.components.combat:SetKeepTargetFunction(function(mercenary, target) return target and target:IsValid() end )
	mercenary:AddComponent("health")
	mercenary.components.health:SetMaxHealth(1500)
	mercenary.components.health.nofadeout = true
	mercenary:DoPeriodicTask(1, function(mercenary)
	  if mercenary:HasTag("cango") then
		if not mercenary.components.container:Has("goldnugget", 20) then
		   mercenary.AnimState:SetBloomEffectHandle("")
		   mercenary.components.locomotor:Stop()
		   mercenary:SetBrain(nil)
		   mercenary.components.follower:SetLeader(nil)
		else
		   mercenary.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
		   local brain = require "brains/abigailbrain"
		   mercenary:SetBrain(brain)
		   mercenary:RestartBrain()
		   mercenary.components.follower:SetLeader(GetPlayer())
		end
	  else
		 mercenary.AnimState:SetBloomEffectHandle("")
		 mercenary.components.locomotor:Stop()
		 mercenary:SetBrain(nil)
		 mercenary.components.follower:SetLeader(nil)
	  end
	end )
	mercenary:DoPeriodicTask(480, function(mercenary)
		if mercenary.components.container:Has("goldnugget", 20) then
		   mercenary.components.container:ConsumeByName("goldnugget", 20)
		   mercenary.components.health:DoDelta(500)
		end
	end )
	mercenary:AddComponent( "playerprox" )
	mercenary.components.playerprox:SetDist(3,5)
	mercenary.components.playerprox:SetOnPlayerNear(function(mercenary)
		mercenary.components.locomotor.walkspeed = 1
		mercenary.components.locomotor.runspeed = 2
	end )
	mercenary.components.playerprox:SetOnPlayerFar(function(mercenary)
		mercenary.components.locomotor.walkspeed = 8
		mercenary.components.locomotor.runspeed = 15
	end )
  end
	inst.components.stackable:Get():Remove()
end
	inst:AddComponent("deployable")
	inst.components.deployable.ondeploy = OnDeploy
local function onsave(inst, data)
	if inst:HasTag("mercenary") then
		data.mercenary = true
	end
	if inst:HasTag("cango") then
		data.cango = true
	end
end
local function onload(inst, data)
  if data and data.mercenary then
	inst.AnimState:SetBank("wilson")
	inst.AnimState:SetBuild("wilson")
	inst.AnimState:PlayAnimation("idle")
	inst.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")
	inst.AnimState:Show("ARM_carry") 
	inst.AnimState:Hide("ARM_normal")
	inst.Transform:SetFourFaced()
	local shadow = inst.entity:AddDynamicShadow()
	shadow:SetSize( 1.3, .6 )
	MakeCharacterPhysics(inst, 75, .5)
	local minimap = inst.entity:AddMiniMapEntity()
	minimap:SetIcon( "researchlab.png" )
	inst:AddTag("mercenary")
	inst:AddComponent("locomotor")
	inst.components.locomotor.walkspeed = 8
	inst.components.locomotor.runspeed = 15
	inst:SetStateGraph("SGshadowwaxwell")
	inst:RemoveComponent("stackable")
	inst:RemoveComponent("explosive")
	inst:RemoveComponent("inventoryitem")
	inst:RemoveComponent("burnable")
	inst:RemoveComponent("propagator")
	inst:RemoveComponent("deployable")
	inst:RemoveComponent("bait")
	inst:RemoveTag("molebait")
	inst:AddComponent("follower")
	inst:AddComponent("inventory")
	inst.components.container.canbeopened = true
	inst:AddComponent("combat")
	inst.components.combat.hiteffectsymbol = "torso"
	inst.components.combat:SetDefaultDamage(50)
	inst.components.combat:SetRange(2, 3)
	inst.components.combat:SetAttackPeriod(0.5)
	inst.components.combat:SetRetargetFunction(2, function(inst)
		if not inst.components.health:IsDead() then
			return FindEntity(inst, 25, function(guy)
				if guy.components.health and not guy.components.health:IsDead() then
				   return guy.components.combat.target == GetPlayer() or GetPlayer().components.combat.target == guy or guy:HasTag("monster")
				end
			end)
		end
	end )
	inst.components.combat:SetKeepTargetFunction(function(inst, target) return target and target:IsValid() end )
	inst:AddComponent("health")
	inst.components.health:SetMaxHealth(1500)
	inst.components.health.nofadeout = true
	inst:DoPeriodicTask(1, function(inst)
	  if inst:HasTag("cango") then
		if not inst.components.container:Has("goldnugget", 20) then
		   inst.AnimState:SetBloomEffectHandle("")
		   inst.components.locomotor:Stop()
		   inst:SetBrain(nil)
		   inst.components.follower:SetLeader(nil)
		else
		   inst.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
		   local brain = require "brains/abigailbrain"
		   inst:SetBrain(brain)
		   inst:RestartBrain()
		   inst.components.follower:SetLeader(GetPlayer())
		end
	  else
		 inst.AnimState:SetBloomEffectHandle("")
		 inst.components.locomotor:Stop()
		 inst:SetBrain(nil)
		 inst.components.follower:SetLeader(nil)
	  end
	end )
	inst:DoPeriodicTask(480, function(inst)
		if inst.components.container:Has("goldnugget", 20) then
		   inst.components.container:ConsumeByName("goldnugget", 20)
		   inst.components.health:DoDelta(500)
		end
	end )
	inst:AddComponent( "playerprox" )
	inst.components.playerprox:SetDist(3,5)
	inst.components.playerprox:SetOnPlayerNear(function(inst)
		inst.components.locomotor.walkspeed = 1
		inst.components.locomotor.runspeed = 2
	end )
	inst.components.playerprox:SetOnPlayerFar(function(inst)
		inst.components.locomotor.walkspeed = 8
		inst.components.locomotor.runspeed = 15
	end )
	inst.AnimState:Hide("HAT")
	inst.AnimState:Hide("HAT_HAIR")
	inst.AnimState:Show("HAIR_NOHAT")
	inst.AnimState:Show("HAIR")
	inst.AnimState:ClearOverrideSymbol("swap_body")
	for k,v in pairs(inst.components.container.slots) do
		if v.prefab == "footballhat" or v.prefab == "ruinshat" or v.prefab == "beefalohat" or v.prefab == "featherhat" then
		   inst.AnimState:Show("HAT")
		   inst.AnimState:Show("HAT_HAIR")
		   inst.AnimState:Hide("HAIR_NOHAT")
		   inst.AnimState:Hide("HAIR")
		end
		if v and v.prefab == "armorgrass" then
		   inst.AnimState:OverrideSymbol("swap_body", "armor_grass", "swap_body")
		   inst:ListenForEvent("attacked", function(inst, data)
			   inst.components.health:DoDelta(15)
		   end )
		end
		if v and v.prefab == "armorwood" then
		   inst.AnimState:OverrideSymbol("swap_body", "armor_wood", "swap_body")
		   inst:ListenForEvent("attacked", function(inst, data)
			   inst.components.health:DoDelta(20)
		   end )
		end
		if v and v.prefab == "armormarble" then
		   inst.AnimState:OverrideSymbol("swap_body", "armor_marble", "swap_body")
		   inst:ListenForEvent("attacked", function(inst, data)
			   inst.components.health:DoDelta(25)
		   end )
		end
		if v and v.prefab == "armor_sanity" then
		   inst.AnimState:OverrideSymbol("swap_body", "armor_sanity", "swap_body")
		   inst:ListenForEvent("attacked", function(inst, data)
			   inst.components.health:DoDelta(30)
		   end )
		end
		if v and v.prefab == "armorruins" then
		   inst.AnimState:OverrideSymbol("swap_body", "armor_ruins", "swap_body")
		   inst:ListenForEvent("attacked", function(inst, data)
			   inst.components.health:DoDelta(35)
		   end )
		end
		if v and v.prefab == "footballhat" then
		   inst.AnimState:OverrideSymbol("swap_hat", "hat_football", "swap_hat")
		end
		if v and v.prefab == "ruinshat" then
		   inst.AnimState:OverrideSymbol("swap_hat", "hat_ruins", "swap_hat")
		end
		if v and v.prefab == "beefalohat" then
		   inst.AnimState:OverrideSymbol("swap_hat", "hat_beefalo", "swap_hat")
		end
		if v and v.prefab == "featherhat" then
		   inst.AnimState:OverrideSymbol("swap_hat", "hat_feather", "swap_hat")
		end
	end
  end
  if data and data.cango then
	 inst:AddTag("cango")
  end
end
	inst.OnSave = onsave
	inst.OnLoad = onload

	即可在身上有100个黄金时,用火药种私家军,将花费100个黄金,身上黄金数不足时不会种出来。鼠标左键点击他可打开格子,放入至少20个黄金后,点Go按钮,会跟随你打仗。追上他用鼠标左键再次点击,可让他停在原地,想让他继续跟随,就再点Go按钮即可。私家军士兵每天的工资是20个黄金,自动从他身上的黄金中扣除(并同时回补三分之一的血),如果他身上的黄金数不足20个时,将罢工,请及时续费。如果私家军的格子中有盔甲、帽子,点Go按钮会自动装备。装备盔甲可提高私家军的防御力,按防御力由低到高排序为草盔甲、木盔甲、大理石盔甲、夜魔盔甲、远古盔甲。装备帽子只起到装饰作用,可装备的帽子有猪皮帽、远古帽、牛毛帽、羽毛帽。不要在他的格子里放2个盔甲或2个帽子,他只会选择1个装备。私家军在小地图上显示为科学机器的图标,可以方便地找到他们的位置。火药在科学选项(画着原子)下,用1个烂鸡蛋、1个木炭、1个硝石制造