定义一个名为ai_dead
的类,继承自ai_base
类。这个类用于处理游戏中AI在死亡状态下的行为逻辑。以下是对代码的具体解释:
引入基类:
- 使用
require
函数引入ai_base
类,作为基础类。
- 使用
定义
ai_dead
类:- 使用
class
关键字定义了ai_dead
类,并继承自BASE
(即ai_base
)。
- 使用
**构造函数 (
ctor
)**:- 构造函数接受一个
entity
参数,并设置_type
属性为eAType_DEAD
,表示死亡的行为。
- 构造函数接受一个
IsValid
方法:- 这个方法用于验证AI是否应该处于死亡状态。它首先调用基类的
IsValid
方法,然后检查实体是否死亡。
- 这个方法用于验证AI是否应该处于死亡状态。它首先调用基类的
OnEnter
方法:
- 当AI组件进入激活状态时执行。如果基类的`OnEnter`方法返回`true`,则执行以下操作:
- 重置`_fadeOut`和`_slowMotion`标志。
- 检查并重置玩家的自动普通攻击状态。
- 隐藏实体的称号节点。
- 检查并重置玩家的超级模式状态。
- 检查并重置骑乘状态。
- 如果实体不是宠物或技能类型,播放死亡动作列表。
- 锁定实体动画。
- 处理同步RPC和发送死亡命令。
- 处理玩家死亡后的界面逻辑,如复活界面和宠物状态。
- 清理死亡实体的仇恨列表和战斗时间。
OnLeave
方法: 当AI组件离开激活状态时执行。如果基类的OnLeave
方法返回true
,则解锁实体动画。OnLogic
方法: 逻辑更新方法。如果基类的OnLogic
方法返回true
,则根据时间间隔处理死亡逻辑,如淡出效果、实体销毁等。创建组件函数:
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
版权归原作者 heyuchang666 所有, 如有侵权,请联系我们删除。