找回密码
 register

QQ登录

只需一步,快速开始

查看: 1602|回复: 0

天龙八部AI脚本分析

[复制链接]

天龙八部AI脚本分析

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:103
  • 打卡月天数:26
  • 打卡总奖励:102
  • 最近打卡:2025-01-29 07:46:26
Waylee

主题

0

回帖

1万

积分

仙帝

积分
13019
Waylee 2021-8-10 19:16 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
一个高效简洁AI脚本系统的实现
-陈瑶文
怪物脚本示例
;红熊王见到人就扑上来砍一定几率对玩家释放烈爪狂击(588)和震地攻击(562),血少于50%时释放兽王怒吼603后沿固定路线逃跑,逃跑时挨打不会停不会还手;
[common]
[commonend]
;注意物理攻击技能优先级应该比远程技能优先级高
[skill]
0:if(AIS_IsCanSkill(0)=1){AIS_ToSkill(0);AIS_SetTimes(-1);AIS_SetPRI(30);};如果能使用0号技能则释放次数不限普通攻击
1:if(AIS_GetAIState()=SATTACK&AIS_Rand()<30&AIS_IsCanSkill(588)=1){AIS_ToSkill(588);AIS_SetTimes(-1);AIS_SetPRI(32);};在攻击状态30%的机率释放588号技能(烈爪狂击)次数不限
2:if(AIS_GetAIState()=SATTACK&AIS_Rand()<20&AIS_IsCanSkill(562)=1){AIS_ToSkill(562);AIS_SetTimes(5);AIS_SetPRI(33);};在攻击状态20%的机率释放562号技能(震地攻击)次数5
3:if(AIS_GetAIState()=SATTACK&AIS_GetHP()<50&AIS_IsCanSkill(603)=1){AIS_ToSkill(603);AIS_SetTimes(1);AIS_SetPRI(39);};在血少于一半后释放兽王怒吼603次数1
4:if(AIS_GetHP()<50){AIS_ToSpeak(66,2);AIS_SetBaseAIType(1,2,15);AIS_SetPatrolID(0);AIS_StartPatrol();AIS_SetTimes(1);AIS_SetPRI(37);}
[skillend]
[beskill]
[beskillend]
[damage]
[damageend]

分段结构(一)
脚本按状态配置各个脚本
在AI逻辑里由状态逻辑调用脚本段
common段各个状态都有可能调用的脚本段
其余段一般都对应某个状态或者只是一个名字便于调用方索引。
分段结构(二)
每个段里面可配几个“条件节点-执行动作”对
条件节点包含一个或多个条件表达式的OR/AND形式
执行动作列表里包含一几个要执行的动作
条件表达式以及执行动作可调用的方法是有限的预配置的AI脚本系统接口
每个“条件节点-执行动作”对有个数字序号以及可配置的优先级最多执行次数。

脚本预处理
对每一段调用一个段解析
每个段里面每一行构造一个“条件节点-执行动作”对。
一个段里面的“条件节点-执行动作”对按优先级构造列表。条件节点中的条件表达式以及OR/AND操作符构造一颗条件树
条件树其实是一颗中缀表达式二叉树
脚本调用
当怪物的AI调用脚本时先根据状态其实只是标
识值参数找到对应段。
取出该段的“条件节点-执行动作”对列表。
挨个取出条件节点的条件树求值如果为TRUE则判断该节点还能执行几次如果不能执行了那么跳过要不执行对应的动作列表。执行完后设置还可执行次数。
条件树求值
沿着最深左子树向上
如果左子节点加上父节点的操作符可以断定为TRUE则继续上行
否则走右子节点重复第一步。
AIS接口

INT AIS_GetBuffState( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetAIState( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetHP( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetMP( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_Rand( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetEBuffState( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetEMP( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetEHP( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetEMenPai( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetELevel( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_IsCanSpeak( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_IsHasEnemy( const Obj_Character *pChar, INT param0, INT param1, INT param2 );
INT AIS_GetESex( const Obj_Character *pChar, INT param0, INT param1, INT param2 );



注册AIS接口函数
typedef INT (*PLAISFunc)( const Obj_Character *pChar, INT param0, INT param1,
INT param2 );
#define REGISTERAISFUNC(funcname) {#funcname,PLAISFunc(funcname)},
struct AISFuncMap
{
CHAR* funcname;
PLAISFunc Func;
};
AISFuncMap g_AISFuncTable[] =
{
REGISTERAISFUNC(AIS_GetBuffState)
REGISTERAISFUNC(AIS_GetAIState)
REGISTERAISFUNC(AIS_GetHP)
REGISTERAISFUNC(AIS_GetMP)
//…..省略
};


您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-31 03:42 , Processed in 0.099221 second(s), 8 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表