笔者有幸从同事那边看到一款游戏《饥荒》,玩了下,顿时觉得好玩,丰富的扩展性已经各种精细的制作,深深吸引了我,但是就是时不时的死亡,给我带来了无限的郁闷。。。
作为一名开发者,那当然是要看看游戏文件目录都有些啥。看了看,诶~~居然是lua写的,而且还是明码,没有编译成字节码luac。刚好对lua还算熟悉,于是就想能不能找到死亡的代码,改一下,让自己不要死。顺着这个目的,我开始搜寻代码。看到了主lua,main.lua文件,里面定义了很多东西,看到一个inGamePlay
定义为false,这个应该是定义是否在游戏中的配置,然后顺着找一下inGamePlay
调用的地方。。。
具体找的方法就不赘述了,笔者后来发现是一个health.lua的文件控制了角色是否死亡。
它这里有这个函数:
function Health:SetVal(val, cause)
local old_percent = self:GetPercent()
self.currenthealth = val
if self.currenthealth > self:GetMaxHealth() then
self.currenthealth = self:GetMaxHealth()
end
if self.minhealth and self.currenthealth < self.minhealth then
self.currenthealth = self.minhealth
self.inst:PushEvent("minhealth", { cause = cause })
end
if self.currenthealth < 0 then
self.currenthealth = 0
end
local new_percent = self:GetPercent()
if old_percent > 0 and new_percent <= 0 or self:GetMaxHealth() <= 0 then
self.inst:PushEvent("death", { cause = cause })
GetWorld():PushEvent("entity_death", { inst = self.inst, cause = cause })
if not self.nofadeout then
self.inst:AddTag("NOCLICK")
self.inst.persists = false
self.inst:DoTaskInTime(self.destroytime or 2, destroy)
end
end
end
核心就是后面的一个if判断
if old_percent > 0 and new_percent <= 0 or self:GetMaxHealth() <= 0 then
这个判断控制了是否对当前的实例(inst)发送"death"
事件
一开始尝试想直接把这个self.currenthealth
为0的时候直接改成100,进入游戏发现,我自己是死不了了;但是怪物也都死不了了。。
好吧,这个组件看来是添加到所有有生命的实体上了。。我需要判断当前的实例是否是玩家。
于是带着上面的疑问,我去找创建玩家的代码了。后来发现是一个MakePlayerCharacter
函数创建的。
在这个函数里,我看到下面的代码片段
inst:AddTag("player")
这个应该就是给实例贴上玩家的标签,于是我就直接在health的代码中增加下面的代码:
function Health:SetVal(val, cause)
local old_percent = self:GetPercent()
self.currenthealth = val
if self.currenthealth > self:GetMaxHealth() then
self.currenthealth = self:GetMaxHealth()
end
if self.minhealth and self.currenthealth < self.minhealth then
self.currenthealth = self.minhealth
self.inst:PushEvent("minhealth", { cause = cause })
end
if self.currenthealth < 0 then
self.currenthealth = 0
end
--增加的代码 begin
if self.currenthealth <= 0 then
if self.inst:HasTag("player") then
self.currenthealth = self.maxhealth
end
end
--增加的代码 end
local new_percent = self:GetPercent()
if old_percent > 0 and new_percent <= 0 or self:GetMaxHealth() <= 0 then
self.inst:PushEvent("death", { cause = cause })
GetWorld():PushEvent("entity_death", { inst = self.inst, cause = cause })
if not self.nofadeout then
self.inst:AddTag("NOCLICK")
self.inst.persists = false
self.inst:DoTaskInTime(self.destroytime or 2, destroy)
end
end
end
再打开一下游戏。。。果然不用死啦。。。嘿嘿
在后面的熟悉中,发现可以不用更改源代码,可以直接写一个mod,我于是按着上面的思路写了一个mod:
操作也很简单,BaBa的设置是Call和None,Call的话就是默认不会死,掉血到0就回满血,None的话就是普通的还是会死。玩的时候还可以按F7切换
新手想熟悉游戏,但是又被无数的死搞的郁闷的话可以尝试一下这个mod
:)
最后支持一下正版环节:
增加了支持together的mod,steam订阅地址