定义一个名为`ai_dead`的类,继承自`ai_base`类。这个类用于处理游戏中ai在死亡状态下的行为逻辑。以下是对代码的具体解释:
1. **引入基类**:
- 使用`require`函数引入`ai_base`类,作为基础类。
2. **定义`ai_dead`类**:
- 使用`class`关键字定义了`ai_dead`类,并继承自`base`(即`ai_base`)。
3. **构造函数 (`ctor`)**:
- 构造函数接受一个`entity`参数,并设置`_type`属性为`eatype_dead`,表示死亡的行为。
4. **`isvalid` 方法**:
- 这个方法用于验证ai是否应该处于死亡状态。它首先调用基类的`isvalid`方法,然后检查实体是否死亡。
5. **`onenter` 方法**:
- - 当ai组件进入激活状态时执行。如果基类的`onenter`方法返回`true`,则执行以下操作:
- - 重置`_fadeout`和`_slowmotion`标志。
- - 检查并重置玩家的自动普通攻击状态。
- - 隐藏实体的称号节点。
- - 检查并重置玩家的超级模式状态。
- - 检查并重置骑乘状态。
- - 如果实体不是宠物或技能类型,播放死亡动作列表。
- - 锁定实体动画。
- - 处理同步rpc和发送死亡命令。
- - 处理玩家死亡后的界面逻辑,如复活界面和宠物状态。
- - 清理死亡实体的仇恨列表和战斗时间。
6. **`onleave` 方法**: 当ai组件离开激活状态时执行。如果基类的`onleave`方法返回`true`,则解锁实体动画。
7. **`onlogic` 方法**: 逻辑更新方法。如果基类的`onlogic`方法返回`true`,则根据时间间隔处理死亡逻辑,如淡出效果、实体销毁等。
8. **创建组件函数**: `create_component`函数用于创建`ai_dead`类的新实例,传入一个实体和一个优先级。
代码中的一些关键点:
- - `isdead()`:检查实体是否死亡。
- - `showtitlenode()`:显示或隐藏实体的称号节点。
- - `supermode()`:处理玩家的超级模式。
- - `onridemode()`:处理玩家的骑乘模式。
- - `playactionlist()`:播放一系列动作。
- - `lockani()`:锁定实体的动画。
- - `show()`:控制实体的显示与隐藏。
- - `destory()`:销毁实体。
- - `canrelease()`:检查实体是否可以释放。
`onenter` 方法的逻辑流程:
- - 调用基类的`onenter`方法,如果返回`true`,则继续。
- - 重置相关动画和攻击状态。
- - 隐藏称号节点。
- - 检查并重置超级模式和骑乘状态。
- - 播放死亡动作列表并锁定动画。
- - 发送死亡同步命令和处理复活界面逻辑。
- - 清理仇恨列表和战斗时间。
`onlogic` 方法中,根据时间间隔处理死亡后的逻辑,如:
- - 如果实体存活时间超过4秒,并且可以释放,则销毁实体。
- - 如果实体存活时间超过2秒,并且可以释放,则开始淡出效果。
整体而言,`ai_dead`类的目的是在ai实体死亡时,提供一套标准的行为和逻辑处理,确保游戏内死亡状态的表现和交互符合预期。
local require = require
local base = require("logic/entity/ai/ai_base").ai_base;
------------------------------------------------------
ai_dead = class("ai_dead", base);
function ai_dead:ctor(entity)
self._type = eatype_dead;
end
function ai_dead:isvalid()
if not base.isvalid(self) then return false; end
return self._entity:isdead();
end
function ai_dead:onenter()
if base.onenter(self) then
self._fadeout = false;
self._slowmotion= false;
local logic = game_get_logic();
if logic then
local player = logic:getplayer();
if player and player:gethero() then
local hero = player:gethero();
if hero then
if hero._autonormalattack then
if hero._guid == self._entity._guid then
hero._preautonormalattack = false;
hero._autonormalattack = false;
elseif self._entity._selected == self._entity._guid then
hero._preautonormalattack = false;
hero._autonormalattack = false;
elseif hero._follow then
if hero._follow._guid == self._entity._guid then
hero._preautonormalattack = false;
hero._autonormalattack = false;
end
end
end
end
end
end
self._entity:showtitlenode(false);
if self._entity:getentitytype() == eet_player then
--清神兵状态
if self._entity._supermode.valid then
local hero = game_get_player_hero()
if self._entity:isplayer() then
self._entity:supermode(false)
else
self._entity:onsupermode(false)
end
end
if self._entity:isplayer() then
g_game_context:resetleadmode()
local animation = g_game_context:getselectweaponmaxanimation()
if animation then
g_game_context:onstuntanimationchangehandler(animation,false)
end
end
--清骑乘
local world = game_get_world()
if world and not world._syncrpc then
if self._entity:isonride() then
self._entity:onridemode(false, true)
end
end
if self._entity._diyskill then
self._entity._diyskill:onreset();
end
end
if self._entity:getentitytype() ~= eet_pet and self._entity:getentitytype() ~= eet_skill then
local alist = {}
table.insert(alist, {actionname = db_common.engine.defaultdeadaction, actlooptimes = 1})
table.insert(alist, {actionname = db_common.engine.defaultdeadloopaction, actlooptimes = -1})
self._entity:playactionlist(alist, 1);
end
self._entity:lockani(true);
local logic = game_get_logic();
if logic then
local world = logic:getworld();
if world then
local syncrpc = world._syncrpc;
if not syncrpc then
-- send cmd
local entity = self._entity;
if entity and entity:getentitytype() == eet_monster and entity._spawnid > 0 then
local weaponid = g_game_context:isinsupermode() and 1 or 0
local damagerank = g_game_context:getmapcopydamagerank()
local args = { spawnpointid = entity._spawnid , pos = entity._curpos, weaponid = weaponid, damagerank = damagerank}
sbean.sync_privatemap_kill(args)
end
local hero = game_get_player_hero()
if hero then
hero:removesummoned();
end
end
end
end
if self._entity:getentitytype() == eet_player then
if logic then
local player = logic:getplayer()
local hero = nil
if player then
hero = player:gethero()
end
local logic = game_get_logic();
local world = logic:getworld()
local petcount = player:getpetcount()
for i = 1,tonumber(petcount) do
local pet = player:getpet(i)
pet:ondead()
end
if g_db.db_get_is_open_revive_ui() then
if hero._guid == self._entity._guid then
if hero._killerid and hero._killerid < 0 then
--天雷复活界面
local killerid = math.abs(hero._killerid);
local guid = string.split(hero._guid, "|")
local playerid = tonumber(guid[2])
if killerid == playerid then
g_ui_mgr:openui(euiid_playerrevive)
g_ui_mgr:refreshui(euiid_playerrevive, true)
end
else
g_logic:openreviveui()
end
--log("euiid_playerrevive")
local mercenarycount = player:getmercenarycount();
for i = 1,tonumber(mercenarycount) do
local mercenary = player:getmercenary(i)
mercenary:ondead()
end
end
else
if hero._guid == self._entity._guid and (game_get_map_type() == g_arena_solo or game_get_map_type() == g_taoist) then
g_game_context:setautofight(false)
local mercenarycount = player:getmercenarycount();
for i = 1,tonumber(mercenarycount) do
local mercenary = player:getmercenary(i)
if not mercenary:isdead() then
local camera = logic:getmaincamera()
hero:detachcamera()
mercenary:attachcamera(camera);
camera:updatepos(mercenary._curpose);
break;
end
end
end
end
if world and not world._syncrpc then
self._entity:clshorseai();
end
end
end
if self._entity._forceattacktarget then
self._entity._forceattacktarget = nil;
end
if self._entity:getentitytype() == eet_mercenary then
self._entity._deadtimeline = g_get_gmttime(game_get_time())
if logic then
local player = logic:getplayer()
local hero = nil
if player then
hero = player:gethero()
end
local logic = game_get_logic();
local world = logic:getworld()
if world._fightmap then
if hero:isdead() and (game_get_map_type() == g_arena_solo or game_get_map_type() == g_taoist) then
local guid1 = string.split(hero._guid, "_")
local guid2 = string.split(self._entity._guid, "_")
if tonumber(guid1[2]) == tonumber(guid2[3]) then
local mercenarycount = player:getmercenarycount();
for i = 1,tonumber(mercenarycount) do
local mercenary = player:getmercenary(i)
if not mercenary:isdead() then
local camera = logic:getmaincamera()
self._entity:detachcamera()
mercenary:attachcamera(camera);
camera:updatepos(mercenary._curpose);
break;
end
end
end
end
end
end
self._entity:clsenmities();
end
if self._entity:getentitytype() == eet_player or self._entity:getentitytype() == eet_mercenary then
self._entity:clearfighttime();
end
if self._entity:getentitytype() ~= eet_player and self._entity:getentitytype() ~= eet_mercenary then
--self._entity:sethittable(false);
end
if self._entity:getentitytype() == eet_pet then
local world = game_get_world();
local player = game_get_player()
if world and not world._syncrpc then
if self._entity._hoster then
local curfightsp = self._entity._hoster:getfightsp()
self._entity._hoster:updatefightspcanying(curfightsp - 1)
local index = player:getpetidx(self._entity._guid)
if index > 0 then
player:rmvpet(index)
end
end
end
end
return true;
end
return false;
end
function ai_dead:onleave()
if base.onleave(self) then
self._entity:lockani(false);
return true;
end
return false;
end
function ai_dead:onlogic(dtick)
if base.onlogic(self, dtick) then
if dtick > 0 then
if self._timetick > 4000 then
if self._entity:canrelease() then
self._entity:destory()
end
elseif self._timetick > 2000 then
if self._entity:canrelease() then
if not self._fadeout then
self._fadeout = true;
self._entity:show(false, true, 2000);
end
end
end
if self._entity:getentitytype() == eet_pet or self._entity:getentitytype() == eet_skill then
if self._entity:canrelease() then
self._entity:destory()
end
end
end
return true;
end
return false;
end
function create_component(entity, priority)
return ai_dead.new(entity, priority);
end
发表评论