arong 发表于 2024-6-7 22:37:07

当使用nut去编写怪物ai时

早在1~2年前就准备不用官方自带的ai来让怪物进行行动,不过奈何当时技术有限没有深入下去,只是草草
预留了几个文件来确定怪物ai和思路。最近有时间写东西的时候重新写然后把怪物ai底层逻辑按照官方ai原本的意思复写出来了。


本质上其实是ap附加,然后ap执行经过字符串拼接后的函数名称。按照特定的逻辑进行执行后模拟的ai
当然除了一些细致的问题外,整体上是完全可以套用这一套nut的ai,本意是可以直接照抄官方的lua ai
除此之外还可以额外扩展其他的nut类ai,因为后面版本的怪物多了相当多的设定,也就要相当多的扩展判断。
(nut版本的ai是支持怪物的标签,和韧性条判断,此外ai还支持单独的堆栈存储器操作。)
sq_RunScript("monster/ai_nut/ai_value.nut");
sq_RunScript("monster/ai_nut/ai_def.nut");
//gal_AIPattern_GetTarget(obj)
//AI_isNotStay(obj)
//AI_isStay(obj)
//AI_checkRandomIsPresent(v)
//gal_AIPattern_isTargetArea(obj,frontX,backX,upY,downY)
//gal_AIPattern_isInCoolTime(obj,id)
//gal_AIPattern_GetVar(obj,stringName)
//gal_AIPattern_SetVar(obj,stringName,value)
//gal_AIPattern_getHpRate(obj)
//gal_AIPattern_getHp(obj)
//gal_AIPattern_GetAttackIndex(obj)
//gal_AIPattern_isNetralizeState(obj)
//gal_AIPattern_GetAIThinkOffset(obj)
//gal_AIPattern_SetAIThinkOffset(obj,v)
//gal_AIPattern_TargetIsBack(obj)
//gal_AIPattern_getRandom(minv,maxv)
//gal_AIPattern_GetTarget(obj)
//gal_AIPattern_getTargetXPos(obj) //Y or Z
//gal_AIPattern_getXPos(obj) //Y or Z
//gal_AIPattern_getToughnessEnegryValue(obj) //獲得韌性條
//gal_AIPattern_isLockToughness(obj)
//gal_AIPattern_getLimitToughnessValue(obj)
//this is sample File
//將函數后的1000改成怪物在lst的id即可調用。為函數體進行拼接完成
//選擇目標 是生物
function gal_AINutPattern_SelectTargetType_1000(target)
{
if (target.isObjectType(OBJECTTYPE_ACTIVE))
return true;
return false;
}
//不使用優先目標
function gal_AINutPattern_IsFristTarget_1000(target)
{
return null;
}
//技能cd,返回值
function gal_AINutPattern_MonsterCoolTime_1000(ids)
{
local coolVector = [
10000,
10001,
15002,
15003,
30004,
20005,
30006,
20007,
60008,
120009,
10,
60011,
30012];
return coolVector;
}
//技能初始cd,返回值
function gal_AINutPattern_InitMonsterCoolTime_1000(ids)
{
local coolVector = [
3000,
3001,
5002,
5003,
10004,
15005,
5006,
40007,
08,
60009,
10,
30011,
15012];
return coolVector;
}
//gal_forceSetStateSendPacket(obj,attackIndex)
//怪物ai主邏輯思路
function gal_AINutPattern_Action_1000(obj)
{
if (AI_isNotStay(obj))
return -1;
return -1;
local target = gal_AIPattern_GetTarget(obj);
//堆棧器
if (gal_AIPattern_GetVar(obj,0) == 0)
{
gal_AIPattern_SetVar(obj,0,1)
return 34;
//bakal skasa incoming effect
}
if (gal_AIPattern_isTargetArea(obj,800,100,200,200))
{
if (!gal_AIPattern_isInCoolTime(obj,0))
{
//gal_forceSetStateSendPacket(obj,55);
return 0;//set 0 attack action
}
}
if (gal_AIPattern_isTargetArea(obj,800,100,200,200))
{
if (!gal_AIPattern_isInCoolTime(obj,1))
{
gal_forceSetStateSendPacket(obj,155);//免控狀態設定
return -1;
}
}
return -1;
}
//思考間隔
function gal_AINutPattern_ThinkTerm_1000(obj)
{
return 300;
}
//目標選擇間隔
function gal_AINutPattern_DestingTerm_422215(obj)
{
return 1000;
}
//視野
function gal_AINutPattern_MonsterSight_1000(obj)
{
return 10000;
}
最后实现效果倒是和ai写的没什么两样,但是台服的ai实在是太狗屎了,所以必须要改变的……
不过这样有很多的思路都不需要act去参与,比如怪物开场动画,怪物分成了多阶段。完完全全可以由
ai来进行处理(因为支持了存储器操作了。可以把阶段和开场动画flag存进存储器里)
https://www.bilibili.com/video/BV1jM411o7Bp/?vd_source=b607a3e5384ea9d7b12ac837b1ce01fe
怪物ai是拿nut写的。当然只是测试使用。

arong 发表于 2024-6-7 22:37:44

//军团本黑龙奈伊则ai重写后,nut式ai写法
function gal_AINutPattern_Action_109014135(obj)
{
//一阶段血量只有1时转二阶段
if (gal_AIPattern_GetVar(obj,1) == 1 && gal_AIPattern_getHp(obj) <= 1)
{
gal_forceSetStateSendPacket(obj,5355);
gal_AIPattern_SetVar(obj,1,2);
//goto 2phase
return -1;
}
//怪物非站立状态下返回
if (AI_isNotStay(obj))
return -1;
local target = gal_AIPattern_GetTarget(obj);
//开场动画,初始化进场动画和 设置当前怪物阶段数为1
if (gal_AIPattern_GetVar(obj,0) == 0)
{
gal_AIPattern_SetVar(obj,0,1);
gal_AIPattern_SetVar(obj,1,1);
gal_forceSetStateSendPacket(obj,6155);
return -1;
//skasa incoming effect
}
//phase 1
if (gal_AIPattern_GetVar(obj,1) == 1)
{
if (gal_AIPattern_isTargetArea(obj,8000,0,2000,2000))
{
commonNagorAIPatternPacketage(obj);
}
}else if (gal_AIPattern_GetVar(obj,1) == 2)//2阶段ai
{
if (gal_AIPattern_isTargetArea(obj,8000,0,2000,2000))
{
if (!gal_AIPattern_isInCoolTime(obj,15))
{
gal_forceSetStateSendPacket(obj,1555);
return -1;
}//this is new
if (!gal_AIPattern_isInCoolTime(obj,23))
{
gal_forceSetStateSendPacket(obj,2355);
return -1;
}//this is new
commonNagorAIPatternPacketage(obj);
}
}
return -1;
}
function commonNagorAIPatternPacketage(obj)
{
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,10))
{
gal_forceSetStateSendPacket(obj,1055);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,9))
{
gal_forceSetStateSendPacket(obj,955);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,54))
{
gal_forceSetStateSendPacket(obj,5455);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,52))
{
gal_forceSetStateSendPacket(obj,5255);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,0))
{
gal_forceSetStateSendPacket(obj,55);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,1))
{
gal_forceSetStateSendPacket(obj,155);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,11))
{
gal_forceSetStateSendPacket(obj,1155);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,16))
{
gal_forceSetStateSendPacket(obj,1655);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,2))
{
gal_forceSetStateSendPacket(obj,255);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,4))
{
gal_forceSetStateSendPacket(obj,455);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,5))
{
gal_forceSetStateSendPacket(obj,555);
return -1;
}
}
if (AI_checkRandomIsPresent(50))
{
if (!gal_AIPattern_isInCoolTime(obj,6))
{
gal_forceSetStateSendPacket(obj,655);
return -1;
}
}
}
确实后面写的挺方便的(最主要热重载特别方便,)。原本怪物自带的action返回值固定为-1,
组队方面确实还没考虑,有不少的东西要额外发个包,不过这种问题后期等需要了再
处理。

arong 发表于 2024-6-7 22:38:17

又新又好

Donaldinoms 发表于 2024-6-7 22:38:43

arong 发表于 2024-6-7 22:38:55

nut这么牛嘛,还可以做ai

arong 发表于 2024-6-7 22:39:36

厉害

arong 发表于 2024-6-7 22:40:19

请问一下花花,能改召唤师老召唤兽的ai吗?

arong 发表于 2024-6-7 22:41:07

厉害

arong 发表于 2024-6-7 22:41:26

问下大佬,有些怪物召唤出来会攻击自己,虽然是队友打不到,怎么修改不攻击玩家,比如真猪召唤出来会追着玩家打,假猪则会正常打敌人,还有就是守护冰的冰刺也是追着玩家打。

arong 发表于 2024-6-7 22:41:53

大佬

arong 发表于 2024-6-7 22:41:59

感谢🙏花神!

arong 发表于 2024-6-7 22:42:41

大佬有啥方法能检测怪物id来执行呢

arong 发表于 2024-6-7 22:43:20

感谢花神分享,有你们的帮助版本变得的越来越好玩和完善

arong 发表于 2024-6-7 22:44:14

花神,请问下字符串是如何拼接并转换为函数执行的呢?
页: [1]
查看完整版本: 当使用nut去编写怪物ai时