整个quake3乃是客户端和这个服务器端运行的,
quake3的这个单人部分,也是仿照的这个多人部分的这个客户端
、和这个服务器端来进行这个运行的
对于quake3服务器部分,要处理者也碰撞检测的东西者也,
、服务器要判断这个游戏的方式,game决胜负的方式,
还有这个对于服务器的这个启动,停止等等的处理者也
以及这个得到了物体等等的东西了者也
对于客户端,不断的发送信息和接受信息等等
cgame来处理这个ui,声音,图像的显示等等的处理者也
这个game部分主要是这个在单人部分时的ai部分,
专门来处理这个bot在各种游戏类型中的这个处理阶段者也
,也是按照这个服务器与客户端的程序来分别运行,处理的
服务器端进行,bot计算碰撞检测数据要使用者也
客户端与服务器都是使用的命令行驱动者也,
服务器端检测有几个客户端,抓包,取包,对于逻辑判断,例如这个多人游戏的胜负,单人游戏的bot处理都是用的这个服务器的程序者也 者也
网战部分,玩家可以自己在自己的机子上建立了局域网服务器,(这部分未通)
和Internet这个网络部分者也
或者连到id的quake3的服务器多人对战者也。
对于玩家的ip地址首先要进行过滤,查看是否是合适的地址者也,然后给玩家建立一个记录,
1 将玩家的ip值,端口号,ip协议作为数据包的第一部分
2玩家对于服务器的命令,例如申请连接,退出,下载文件等等
3玩家之间在对战时的对话声音数据,通话信息,呼叫防守,等等信息
当然还有发送时的时间,玩家现在执行的的状态(向前走,跳黄河,举枪射击)等等一幁的信息
这三部分组织到一块后,历经赫尔曼编码压缩后
发送到服务器,处理者也
为了防止玩家作弊,需要先把玩家的数据发到服务器进行逻辑判断正确后,才发数据到客户端,使得显示者也,否则不行
这个客户端和服务器端的处理,怎么来处理的者也!!!一时半会领悟不同了者也!有时候真的呼唤高手了者也!
这个服务器的加载上了这 个game.dll文件来处理了者也
服务器端进行,bot计算碰撞检测数据要使用者也
客户端进行的是这个图像,图形的显示这也!
客户端与服务器都是使用的命令行驱动者也,
服务器端检测有几个客户端,抓包,取包,对于逻辑判断,例如这个多人游戏的胜负,单人游戏的bot处理都是用的这个服务器的程序者也 者也
地图在服务器端啊,可以进行逻辑的计算者也,
在quake3之中,为了解决网络延迟,使用了udp协议,我们知道,tcp是根据的阻塞数据保证的数据能够正确的
到达,但是由于网络有问题,延迟了,丢数据报了,又得重新申请数据包,quake3直接udp,数据报出了问题后,
、直接丢了,发新的数据包,不再阻塞了,服务器直接响应,直接处理
对于玩家的机器是什么协议连到服务器的,不知道,按照玩家的协议,服务器组织数据包发到玩家手中去者也
值得注意是,quake也是分区的进行处理。
在游戏中每时每刻都要进行对鼠标,键盘的检测,渲染画面等等,但我们可以往下这样子想
网络对战时:你用鼠标来控制游戏画面中手里拿的枪,按w前进了一步,将前进一步的这个数据命令发到服务器上,
服务器判断你走的地方能不能走的通,一步走多远,发送数据给你,你的机器接到后,如果能走,按服务器的数据
服务器部分在Bsp部分寻找到了叶子部分等等的可见部分的逻辑,我们来处理者也
发送这个数据包loop
检查这个数据包是不是正确的数据包,发送数据包等等
// first 12 bytes of the data are always:
long serverId;
long messageAcknowledge;
long reliableAcknowledge;
typedef struct
{
GR_CONTEXT context;
uint64_t game_id;
uint64_t match;
uint64_t player_id;
GR_PLAYER_TOKEN token;
grank_status_t grank_status;
grank_status_t final_status; // status to set after cleanup
uint32_t grank; // global rank
char name[32];
} ranked_player_t;
加载arena文件
,通常是用来加载游戏时候的这个txt文件了者也
如下所示
{
map "mrcq3t2" //地图的名字
bots "visor tankjr" //bot的名字,哪一个bot被加入了者也
longname "Mutually Assured Destruction"
fraglimit "15"
type "single"
再根据这个地图的名字加载对应地图的bsp文件,aas文件
当然可以再控制台中输入sv_pure 0以后,再输入map 地图名,即可打开在quake3游戏下面的
base/maps中的地图了
对于cm碰撞检测,也是从bsp这里面
逻辑部分的解析bsp文件中的这个entity的属性,根据寻找这个玩家的playStart点,来进行玩家的重生了
bsp文件中存储的这个触发器,来进行这个触发器逻辑的处理了
当游戏开始前,玩家在菜单之中可以选择这个bot数量,距离哪一个bot加入到了游戏之中了
或者bot的多少者也,具体到了选择的那个bot,不然就按照游戏的默认设置来进行者也!在游戏的运行中也可以进行这个bot值的设置者也!
/*
------------------------------------------------------------
游戏开始的时候
---------------------------------------------------------
*/
初始化game
G_RegisterCvars();
得到了配置文件中关于游戏配置的一些信息
记录这个cvar这个变量者也
更新这个cvar这个变量的值者也
cvar里面包括了这个最大的客户端数目,游戏名字,游戏类型等等,密码,ip号码
记录这个cvar的值者也
G_ProcessIPBans();
G_InitMemory();
typedef enum {
TAG_FREE,
TAG_GENERAL,
TAG_BOTLIB,
TAG_RENDERER,
TAG_SMALL,
TAG_STATIC
} memtag_t;
内存的标志了者也
初始化这个内存,
动态,值得一提的是加上了debug阶段,判断内存消耗多少者也。
定义这个堆栈池的大小者也
这个game_mem如果这个分配的内存大于这个堆栈的存储空间的话,那么输出这个错误的信息者也
mem内存的分配处理者也
分配内存
--- low memory ----
server vm
server clipmap
---mark---
renderer initialization (shaders, etc)
UI vm
cgame vm
renderer map
renderer models
---free---
temp file loading
--- high memory ---
初始化游戏开始的时间
初始化游戏日志
初始化这个world区域者也
初始化这个死亡重生队列
InitBodyQue();
ClearRegisteredItems();
G_SpawnEntitiesFromString();
// general initialization
G_FindTeams();
// make sure we have flags for CTF, etc
if( g_gametype.integer >= GT_TEAM ) {
G_CheckTeamItems();
}
SaveRegisteredItems();
增加这个竞技场队员,
挪离了这个竞技场中的失败者
调整这个竞技场中的得分
挪离这个竞技场中的得胜者
检查是不是到了这个限制的时间了者也
检查是不是到了退出竞技场的规则了
void InitClientPersistant (gclient_t *client);
void InitClientResp (gclient_t *client);
void InitBodyQue (void);
游戏类型
/*
-------------------------------
(1)死亡竞赛时,
---------------------------------
*/
死亡竞赛乃是在一定的时间里面,(当然时间你可以自己选定了)
(限制的人数等等)
死亡竞赛的规则最最简单了,,kill and killed !见人杀人就行了
谁干掉的人最多,谁就是第一的
对于团队死亡竞赛,整个团队的成员会一起合作摧毁对方的团队,
每一个团队成员获得这个击杀数会加到了团队的总的击杀数上。
首先达到了最大击杀数的团队赢得比赛。对死亡竞赛和团队死亡竞赛的处理完全没有什么区别。
机器人目标,见人就杀,
(2)夺旗模式,
Capture the Flag
A tried and true strategy for Capture the Flag is to have a solid defense, a solid offense,
and then one or more floaters to roam the middle of the map.
The floaters will be in a position to serve as a first line of defense for the home base as well as
a kind of bodyguard force when the flag carrier needs a little protection.
Team Arena's powerups should be doled out according to role: the flag carrier should try
and get the Scout, his protector should have the Guard, someone on defense needs to have
the Ammo Regen, and the Doubler should go to someone else on defense so they can keep the base pest-free.
一个夺旗模式乃是一队士兵进攻,一堆士兵防御
机器人的目标乃是夺旗
双方各有一面旗帜,一方将对方的旗帜拿回到了自己的基地,并且确保自己的旗帜在自己的
基地里面,那么就得分
最后游戏结束时候,哪一方得到的旗帜次数最多,谁就获胜了
如果我们的队有了对方队伍里面的旗帜的话,
如果对方有了我们的旗帜的话,那么就去阻止
clt抓取旗帜的标志,分为状态者也
如果我们去夺取bot的旗帜的话,那么bot将会阻止我们来得到了旗帜者也
当我们夺取旗帜时,这个bot将会冲向了旗帜了
/*
-------------------------------------------------------
(3)分组作战部分的处理
--------------------------------------------
*/
例如一个分组作战的文件格式如下
Filename: Teamname.team
// .team file begins here
teams {
{ "Kreechurs" "ui/assets/kreechurs" "BoB" "Lily" "Vlad" "Infinite" "Prime"}
}
characters {
{ "Callisto/Lily" " BoB " }
{ "Kreecha" " BoB " }
{ "Infinite" " BoB " }
{ "Prime" " BoB " }
{ "Vlad" " BoB " }
}
// Aliases are the link between character name, headmodel, and bot A.I.
aliases {
{ "Kreecha" "BoB" "a" }
{ "Lily" "Callisto/Lily" "d" }
{ "Vlad" "Vlad" "o" }
{ "Infinite" "Infinite" "d" }
{ "Prime" "Prime" "o" }
}
//.team file ends here
分组作战的处理
(1)分组作战的共性
一些分组作战时的共同特点者也
分为红绿两队,进行组队作战,通常你可以离开两队,加入队伍等等操作
给每一个玩家分配下了所属组的名字和皮肤的颜色
如同cs中的恐怖分子和反恐精英一样
case TEAM_BLUE:
case TEAM_RED:
case TEAM_FREE:
case TEAM_SPECTATOR:观战模式,哪一方面都不加入了者也
team分组
初始化组员的数量
初始化组的领导
组队竞赛有时间的限制者也
捡起组
设置这个客户端的视角
选择这个重生点
当分组作战类型为这个ctf分夺旗模式的时候,旗帜被夺去之后,这个旗帜的重生
当自己的旗帜被对方夺去后,自己一方的bot要追逐对方拿到旗帜的那个家伙
如果你偷走了对方的旗帜,恭喜你,你将成为对方所有人的众矢之矢了,所有对方的火箭,武器超你发射,赶紧讨回本队中的插旗的位置,那么就会团队得到了1分了者也!
遇到一个bot,先要判断这个bot是不是跟自己一个组里面,如果不是,恭喜你,要么你干掉对方,要么对方干掉你
如果不是一组的成员的话,那么算了,如果是同一组的成员的话,
那么就传输这些命令者也
其他的组
其他的组的名字
增加组的得分
在相同的一组
设置的标志的状态了者也
/*
------------------------------------------------
当是这个bot单人游戏时候
------------------------------------------------
*/
botlib部分
这个乃是quake3中的机器人的一个处理部分了
包含了游戏时刻的这个机器人的各项的处理了者也
一些乃是机器人的一些说明了
First: Extract all the files (leaving the directory structure in tact).
解压整个文件
Second: In order to use the bot, you must tell Quake3[TM] to look in the new scripts/bots.txt
file for the new bot we added. You cannot extract the bots.txt file (or delete it) from
the original Pak0.pk3 file and expect the bot will work. Besides, if you delete the
bots.txt file in the Pak0.pk3 file, whenever you start or try and join a Pure Server
to play multiplayer gaming, it will report your pak file is smaller or has changed.
That will prevent you from playing on that or any other server that uses a Pure
Server configuration. (Which is most all of the servers)
Third: If you would like to changfe the name of the bot, you can open all the 'c' files in
如果你想要给机器人改名字的话,那么请打开botfiles/bot的目录
Botfiles/Bots directory and replace all instances in all files of RakeThese with
whatever you plan on naming the bot. Once finished, rename the files from
rakethese.xxx to (yourname).xxx --keeping the name of the bot the same as the
what you replaced rakethese with inside the files. -Easy.
Forth: Modify the bots.txt file (you may need to do a search for rakethese) to reflect
-replace rakethese bot name with your new name.
Your Finished... to load the bot simply make a shortcut to quake3 like this:
quake3.exe +set g_botsfile scripts/bots.txt
举例,quake3竞技场中的bot文件
bot.txt文件的内容,
{
name Xaero //这个bot的名字了者也
model xaero //这个bot对应的md3模型
aifile bots/xaero_c.c //ai的脚本文件
arenaLord 1
}
{
name Orbb //bot的名字
model orbb //bot对应的md3模型
aifile bots/orbb_c.c
}
{
name Slash
model slash
aifile bots/slash_c.c
}
{
name Snatch
model snatch
aifile bots/snatch_c.c
}
{
name RakeThese
model rakethese
aifile bots/rakeThese_c.c
}
{
name Sorlag
model sorlag
aifile bots/sorlag_c.c
}
{
name Daemia
model major/daemia
aifile bots/daemia_c.c
}
{
name Uriel
model uriel
aifile bots/uriel_c.c
arenaLord 1
}
botlib运行时刻
加载以上的bot机器人脚本,将
脚本的内存的处理,把脚本中的数据给于了各个部分了者也,例如武器脚本的变量给了这个武器的,
bot脚本的内容,供给了一个bot处理了
机器人里有限状态机的处理,在进行这个徘徊,移动,飞行等等的一个选择了
weapon.c对于这个武器的ai,没子弹了装弹,彻底没有子弹了换枪,
最后没有子弹了换电锯来处理
/*
----------------------------------
机器人的各项状态,在游戏的时候
----------------------------------
*/
// 1.32
G_FS_SEEK,
BOTLIB_SETUP = 200, // ( void );
BOTLIB_SHUTDOWN, // ( void );
BOTLIB_LIBVAR_SET,
BOTLIB_LIBVAR_GET,
BOTLIB_PC_ADD_GLOBAL_DEFINE,
BOTLIB_START_FRAME,
BOTLIB_LOAD_MAP, 加载aas寻路地图
BOTLIB_UPDATENTITY,
BOTLIB_TEST,
BOTLIB_GET_SNAPSHOT_ENTITY, // ( int client, int ent );
BOTLIB_GET_CONSOLE_MESSAGE, // ( int client, char *message, int size );
BOTLIB_USER_COMMAND, // ( int client, usercmd_t *ucmd );
BOTLIB_AAS_ENABLE_ROUTING_AREA = 300,
BOTLIB_AAS_BBOX_AREAS,
BOTLIB_AAS_AREA_INFO,
BOTLIB_AAS_ENTITY_INFO,
//bot的aas的物体信息了
BOTLIB_AAS_INITIALIZED,
BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX,
BOTLIB_AAS_TIME, bot的aas的遍历时间了者也
BOTLIB_AAS_POINT_AREA_NUM, // bot要遍历的区域数目了者也
BOTLIB_AAS_TRACE_AREAS,
BOTLIB_AAS_POINT_CONTENTS, 一个点的内容了者也
BOTLIB_AAS_NEXT_BSP_ENTITY, 下一个entity了
BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY,
BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY,
BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY,
BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY,
BOTLIB_AAS_AREA_REACHABILITY, 到达能力
BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA,
BOTLIB_AAS_SWIMMING, 游泳
BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT,
BOTLIB_EA_SAY = 400,
BOTLIB_EA_SAY_TEAM,
BOTLIB_EA_COMMAND, 命令
//移动ai
可以看到这个跟玩家的基本动作一样的
BOTLIB_EA_ACTION, 行为
BOTLIB_EA_GESTURE,
BOTLIB_EA_TALK, 谈话
BOTLIB_EA_ATTACK, 攻击
BOTLIB_EA_USE, 使用
BOTLIB_EA_RESPAWN, 重生
BOTLIB_EA_CROUCH, 蹲下
BOTLIB_EA_MOVE_UP, 向上移动
BOTLIB_EA_MOVE_DOWN, 向下移动
BOTLIB_EA_MOVE_FORWARD, 向前移动
BOTLIB_EA_MOVE_BACK, 向后移动
BOTLIB_EA_MOVE_LEFT, 向左移动
BOTLIB_EA_MOVE_RIGHT, 向右移动
BOTLIB_EA_SELECT_WEAPON, 选择武器
BOTLIB_EA_JUMP, 跳跃
BOTLIB_EA_DELAYED_JUMP,
BOTLIB_EA_MOVE, 移动
BOTLIB_EA_VIEW,
BOTLIB_EA_END_REGULAR,
BOTLIB_EA_GET_INPUT, 得到输入
BOTLIB_EA_RESET_INPUT,
/*
-----------------------------------------
ai的bot加载这个角色的处理等等者也
------------------------------------------
*/
BOTLIB_AI_LOAD_CHARACTER = 500,
BOTLIB_AI_FREE_CHARACTER,
BOTLIB_AI_CHARACTERISTIC_FLOAT,
BOTLIB_AI_CHARACTERISTIC_BFLOAT,
BOTLIB_AI_CHARACTERISTIC_INTEGER,
BOTLIB_AI_CHARACTERISTIC_BINTEGER,
BOTLIB_AI_CHARACTERISTIC_STRING,
/*
-----------------------------------------
chat的处理等等
-----------------------------------------
*/
BOTLIB_AI_ALLOC_CHAT_STATE, bot分配了谈话状态
BOTLIB_AI_FREE_CHAT_STATE, bot释放了chat的状态了者也
BOTLIB_AI_QUEUE_CONSOLE_MESSAGE,
BOTLIB_AI_REMOVE_CONSOLE_MESSAGE,
BOTLIB_AI_NEXT_CONSOLE_MESSAGE,
BOTLIB_AI_NUM_CONSOLE_MESSAGE,
BOTLIB_AI_INITIAL_CHAT,
BOTLIB_AI_REPLY_CHAT,
BOTLIB_AI_CHAT_LENGTH,
BOTLIB_AI_ENTER_CHAT, 进入谈话了者也
BOTLIB_AI_STRING_CONTAINS,
BOTLIB_AI_FIND_MATCH, 寻找了这个match了者也
BOTLIB_AI_MATCH_VARIABLE,
BOTLIB_AI_UNIFY_WHITE_SPACES,
BOTLIB_AI_REPLACE_SYNONYMS,
BOTLIB_AI_LOAD_CHAT_FILE, 加载了chat的文件了
BOTLIB_AI_SET_CHAT_GENDER,
BOTLIB_AI_SET_CHAT_NAME,
/*
---------------------------------------
ai的目标的处理等等
----------------------------------------
*/
BOTLIB_AI_RESET_GOAL_STATE, 重启目标状态
BOTLIB_AI_RESET_AVOID_GOALS, 重启避免目标了
BOTLIB_AI_PUSH_GOAL, 压入目标
BOTLIB_AI_POP_GOAL, 弹出目标
BOTLIB_AI_EMPTY_GOAL_STACK,
BOTLIB_AI_DUMP_AVOID_GOALS,
BOTLIB_AI_DUMP_GOAL_STACK,
BOTLIB_AI_GOAL_NAME, 目标的名字了者也
BOTLIB_AI_GET_TOP_GOAL, 得到了首要的目标了者也
BOTLIB_AI_GET_SECOND_GOAL,
BOTLIB_AI_CHOOSE_LTG_ITEM,
BOTLIB_AI_CHOOSE_NBG_ITEM,
BOTLIB_AI_TOUCHING_GOAL,
BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE,
BOTLIB_AI_GET_LEVEL_ITEM_GOAL,
BOTLIB_AI_AVOID_GOAL_TIME,
BOTLIB_AI_INIT_LEVEL_ITEMS,
BOTLIB_AI_UPDATE_ENTITY_ITEMS, 更新关卡的item图标了
BOTLIB_AI_LOAD_ITEM_WEIGHTS, 加载图标的权重了
BOTLIB_AI_FREE_ITEM_WEIGHTS,
BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC,
BOTLIB_AI_ALLOC_GOAL_STATE,
BOTLIB_AI_FREE_GOAL_STATE,
/*
-----------------------------------
ai的移动的状态的处理等等
---------------------------------
*/
BOTLIB_AI_RESET_MOVE_STATE,重启ai的移动状态了者也
BOTLIB_AI_MOVE_TO_GOAL,
BOTLIB_AI_MOVE_IN_DIRECTION,
BOTLIB_AI_RESET_AVOID_REACH,
BOTLIB_AI_RESET_LAST_AVOID_REACH,
BOTLIB_AI_REACHABILITY_AREA,
BOTLIB_AI_MOVEMENT_VIEW_TARGET,
BOTLIB_AI_ALLOC_MOVE_STATE,
BOTLIB_AI_FREE_MOVE_STATE,
BOTLIB_AI_INIT_MOVE_STATE,
/*
----------------
weapon ai 武器的ai处理
----------------
*/
BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON,
BOTLIB_AI_GET_WEAPON_INFO,
BOTLIB_AI_LOAD_WEAPON_WEIGHTS,
BOTLIB_AI_ALLOC_WEAPON_STATE,
BOTLIB_AI_FREE_WEAPON_STATE,
BOTLIB_AI_RESET_WEAPON_STATE,
/*
-----------------------------
ai的chat的这个处理等等
------------------------------
*/
BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION,
BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC,
BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC,
BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL,
BOTLIB_AI_GET_MAP_LOCATION_GOAL,
BOTLIB_AI_NUM_INITIAL_CHATS,
BOTLIB_AI_GET_CHAT_MESSAGE,
BOTLIB_AI_REMOVE_FROM_AVOID_GOALS,
BOTLIB_AI_PREDICT_VISIBLE_POSITION,
/*
---------------------------------------
bot机器人用来进行path寻径的函数处理者也
----------------------------------------
*/
BOTLIB_AI_SET_AVOID_GOAL_TIME,
BOTLIB_AI_ADD_AVOID_SPOT,
BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL,
BOTLIB_AAS_PREDICT_ROUTE,
BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX,
bot脚本的加载与这个编译脚本的处理等等
BOTLIB_PC_LOAD_SOURCE,
BOTLIB_PC_FREE_SOURCE,
BOTLIB_PC_READ_TOKEN,
BOTLIB_PC_SOURCE_FILE_AND_LINE
}
void trap_EA_Say(int client, char *str);
void trap_EA_SayTeam(int client, char *str);
void trap_EA_Command(int client, char *command);
void trap_EA_Action(int client, int action);
void trap_EA_Gesture(int client);
void trap_EA_Talk(int client);
void trap_EA_Attack(int client);
void trap_EA_Use(int client);
void trap_EA_Respawn(int client);
void trap_EA_Crouch(int client);
void trap_EA_MoveUp(int client);
void trap_EA_MoveDown(int client);
void trap_EA_MoveForward(int client);
void trap_EA_MoveBack(int client);
void trap_EA_MoveLeft(int client);
void trap_EA_MoveRight(int client);
void trap_EA_SelectWeapon(int client, int weapon);
void trap_EA_Jump(int client);
void trap_EA_DelayedJump(int client);
void trap_EA_Move(int client, vec3_t dir, float speed);
void trap_EA_View(int client, vec3_t viewangles);
void trap_EA_EndRegular(int client, float thinktime);
void trap_EA_GetInput(int client, float thinktime, void /* struct bot_input_s */ *input);
void trap_EA_ResetInput(int client);
int trap_BotLoadCharacter(char *charfile, float skill);
void trap_BotFreeCharacter(int character);
float trap_Characteristic_Float(int character, int index);
float trap_Characteristic_BFloat(int character, int index, float min, float max);
int trap_Characteristic_Integer(int character, int index);
int trap_Characteristic_BInteger(int character, int index, int min, int max);
void trap_Characteristic_String(int character, int index, char *buf, int size);
int trap_BotAllocChatState(void);
void trap_BotFreeChatState(int handle);
void trap_BotQueueConsoleMessage(int chatstate, int type, char *message);
void trap_BotRemoveConsoleMessage(int chatstate, int handle);
int trap_BotNextConsoleMessage(int chatstate, void /* struct bot_consolemessage_s */ *cm);
int trap_BotNumConsoleMessages(int chatstate);
void trap_BotInitialChat(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
int trap_BotNumInitialChats(int chatstate, char *type);
int trap_BotReplyChat(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
int trap_BotChatLength(int chatstate);
void trap_BotEnterChat(int chatstate, int client, int sendto);
void trap_BotGetChatMessage(int chatstate, char *buf, int size);
int trap_StringContains(char *str1, char *str2, int casesensitive);
int trap_BotFindMatch(char *str, void /* struct bot_match_s */ *match, unsigned long int context);
void trap_BotMatchVariable(void /* struct bot_match_s */ *match, int variable, char *buf, int size);
void trap_UnifyWhiteSpaces(char *string);
void trap_BotReplaceSynonyms(char *string, unsigned long int context);
int trap_BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
void trap_BotSetChatGender(int chatstate, int gender);
void trap_BotSetChatName(int chatstate, char *name, int client);
void trap_BotResetGoalState(int goalstate);
void trap_BotRemoveFromAvoidGoals(int goalstate, int number);
void trap_BotResetAvoidGoals(int goalstate);
void trap_BotPushGoal(int goalstate, void /* struct bot_goal_s */ *goal);
void trap_BotPopGoal(int goalstate);
void trap_BotEmptyGoalStack(int goalstate);
void trap_BotDumpAvoidGoals(int goalstate);
void trap_BotDumpGoalStack(int goalstate);
void trap_BotGoalName(int number, char *name, int size);
int trap_BotGetTopGoal(int goalstate, void /* struct bot_goal_s */ *goal);
int trap_BotGetSecondGoal(int goalstate, void /* struct bot_goal_s */ *goal);
int trap_BotChooseLTGItem(int goalstate, vec3_t origin, int *inventory, int travelflags);
int trap_BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags, void /* struct bot_goal_s */ *ltg, float maxtime);
int trap_BotTouchingGoal(vec3_t origin, void /* struct bot_goal_s */ *goal);
int trap_BotItemGoalInVisButNotVisible(int viewer, vec3_t eye, vec3_t viewangles, void /* struct bot_goal_s */ *goal);
int trap_BotGetNextCampSpotGoal(int num, void /* struct bot_goal_s */ *goal);
int trap_BotGetMapLocationGoal(char *name, void /* struct bot_goal_s */ *goal);
int trap_BotGetLevelItemGoal(int index, char *classname, void /* struct bot_goal_s */ *goal);
float trap_BotAvoidGoalTime(int goalstate, int number);
void trap_BotSetAvoidGoalTime(int goalstate, int number, float avoidtime);
void trap_BotInitLevelItems(void);
void trap_BotUpdateEntityItems(void);
int trap_BotLoadItemWeights(int goalstate, char *filename);
void trap_BotFreeItemWeights(int goalstate);
void trap_BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child);
void trap_BotSaveGoalFuzzyLogic(int goalstate, char *filename);
void trap_BotMutateGoalFuzzyLogic(int goalstate, float range);
int trap_BotAllocGoalState(int state);
void trap_BotFreeGoalState(int handle);
void trap_BotResetMoveState(int movestate);
void trap_BotMoveToGoal(void /* struct bot_moveresult_s */ *result, int movestate, void /* struct bot_goal_s */ *goal, int travelflags);
int trap_BotMoveInDirection(int movestate, vec3_t dir, float speed, int type);
void trap_BotResetAvoidReach(int movestate);
void trap_BotResetLastAvoidReach(int movestate);
int trap_BotReachabilityArea(vec3_t origin, int testground);
int trap_BotMovementViewTarget(int movestate, void /* struct bot_goal_s */ *goal, int
travelflags, float lookahead, vec3_t target);
int trap_BotPredictVisiblePosition(vec3_t origin, int areanum, void /* struct bot_goal_s */ *goal, int travelflags, vec3_t target);
int trap_BotAllocMoveState(void);
void trap_BotFreeMoveState(int handle);
void trap_BotInitMoveState(int handle, void /* struct bot_initmove_s */ *initmove);
void trap_BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type);
int trap_BotChooseBestFightWeapon(int weaponstate, int *inventory);
void trap_BotGetWeaponInfo(int weaponstate, int weapon, void /* struct weaponinfo_s */ *weaponinfo);
int trap_BotLoadWeaponWeights(int weaponstate, char *filename);
int trap_BotAllocWeaponState(void);
void trap_BotFreeWeaponState(int weaponstate);
void trap_BotResetWeaponState(int weaponstate);
int trap_GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);
void trap_SnapVector( float *v );
enum {
BC_NULL,
BC_FOLLOW ,跟随
BC_HELP, 帮助
BC_GET, 得到
BC_PATROL,入口
BC_CAMP,
BC_HUNT,
BC_DISMISS,
BC_REPORT, 报告
BC_POINT,
BC_GETFLAG,得到标志
BC_DEFENDBASE防御基地
} botCommandId;
这个目标的处理了这个的判断,这个乃是对于机器人目标的处理了
压入到了目标的堆栈,来处理这个的了
机器人的第二目标,机器人的第一目标的处理
加载武器的权重
机器人的跑跳,向左移动,向右移动,跑跳,等等的处理了
这个机器人的逻辑大致上是有限状态机的模式了
见到人就打,没人的时候,遍历,寻找area的这个
我认为area就是brush的逻辑上的一个名称了者也
从这个area里面寻找到了这个边edge路径了者也
以下是机器人移动时的这个结构体
typedef struct bsp_trace_s
{
qboolean allsolid; // if true, plane is not valid
//判断机器人是否碰撞到了实体了呢?
qboolean startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
cplane_t plane; // surface normal at impact
float exp_dist; // expanded plane distance
int sidenum; // number of the brush side hit
bsp_surface_t surface; // hit surface
int contents; // contents on other side of surface hit
int ent; // number of entity hit
} bsp_trace_t;
//
*/
脚本编译分为开始,结束,编译过程中
脚本部分也属于这个预处理阶段的部分者也
使用脚本来生成机器人的名字,对应的模型文件,武器的杀伤力
然后引擎在运行的时候,加载上了这个数值,字符来进行这个武器和bot的数值的处理了
武器ai脚本举例
#include "inv.h"
#define W_GAUNTLET 10
#define W_SHOTGUN 40
#define W_MACHINEGUN 20
#define W_GRENADELAUNCHER 40
#define W_ROCKETLAUNCHER 80
#define W_RAILGUN 270
#define W_BFG10K 95
#define W_LIGHTNING 80
#define W_PLASMAGUN 75
#define W_GRAPPLE 15
武器的权重值者也
这个乃是bot的选择武器的权重,不同的bot选择武器的权重不同,这样子有利于形成不同的bot了
举例,rakethese_w.c武器权重文件
//initial health/armor states
#define FS_HEALTH 2
#define FS_ARMOR 2
//initial weapon weights
#define W_SHOTGUN 50
#define W_MACHINEGUN 70
#define W_GRENADELAUNCHER 40
#define W_ROCKETLAUNCHER 120
#define W_RAILGUN 285
#define W_BFG10K 130
#define W_LIGHTNING 80
#define W_PLASMAGUN 80
//initial powerup weights初始化权重
#define W_TELEPORTER 40
#define W_MEDKIT 40
#define W_QUAD 80
#define W_ENVIRO 40
#define W_HASTE 40
#define W_INVISIBILITY 80
#define W_REGEN 40
#define W_FLIGHT 40
标志权重了者也
//flag weight
#define FLAG_WEIGHT
这个乃是这个机器人的chat谈话文件,也就是在单人游戏中左上方显示出来的谈话内容了
================================
chat "rakethese"
{
//the teamplay.h file is included for all kinds of teamplay chats
#include "teamplay.h"
//======================================================
//======================================================
//进入游戏后的状态了
type "game_enter" //initiated when the bot enters the game
{
"Greetings Mortal!";
"Hiho... where's Dark Mistress???";
"I like it foul smelly!";
"Grrrr!!";
"rakethese here, ready to rock!";
"", 0, ", I'm going to eat you up and spit you out!";
// 0 = bot name
} //end type
//当游戏退出游戏时的状态
type "game_exit" //initiated when the bot exits the game
{
"My dungeon needs me, I'm outta here";
"This place is too clean for my taste!";
"End of the line.";
"Horned rakethese meeting now... got to go.";
// 0 = bot name
} //end type
type "level_start" //initiated when a new level starts
{
"MMMmmmm, Very foul smelling!.";
"Let's rock!!";
"Like my horns?";
"Time to kill!";
"Horned rakethese returns!";
// 0 = bot name
} //end type
type "level_end" //initiated when a level ends and the bot is not first and not last in the rankings
{
"Damn I was doing so well in the begining.";
"Next TIME!!!!";
"I'll be BACK!";
"Noooo!!!! So close!";
"Hmm... the winner is using bot aim :-)";
"At least I'm not last.";
"damn the lag!!!";
// 0 = bot name
} //end type
type "level_end_victory" //initiated when a level ends and the bot is first in the rankings
{
"I rule all of you!";
"GG";
"Ahhh.... like my dungeon?";
"Yeah yeah";
"Hmmmm is it because I'm a LPB? :-)";
"Being evil has its advantages :-)";
// 0 = bot name
} //end type
type "level_end_lose" //initiated when a level ends and the bot is last in the rankings
{
"I see you 'Heros' have been practicing.";
"Must be because the place is too clean!";
"Not fair.. AGAIN... I said AGAIN!";
"I suck, I suck!";
"Why, why tell me why!";
"Not again!";
// 0 = bot name
} //end type
//======================================================
//======================================================
type "hit_talking" //bot is hit while chat balloon is visible; lecture attacker on poor sportsmanship
{
"Useless!";
"",0 ," you have no Multiplayer ethics!.";
"Tiu!";
"See that smily face? IT MEANS I'M TALKING!!!";
"Damn you ", 0,", Can't you see I'm talking?";
"F U";
//0 = shooter
} //end type
type "hit_nodeath" //bot is hit by an opponent's weapon attack; either praise or insult
{
"Argh!";
"Trying to inflict mortal wound to me?";
"Grrrrr!!!";
"Shit you,", 0,"!";
//0 = shooter
} //end type
type "hit_nokill" //bot hits an opponent but does not kill it
{
"Oi, ", 0, "! Here got some more!";
"Damn... didn't kill you.";
"The Dungeon Keeper won't be happy :-(";
"Damn!";
//0 = opponent
} //end type
//======================================================
//======================================================
type "death_telefrag" //initiated when the bot is killed by a telefrag
{
"Weeellllll... sorry of intruding!";
"Hey my place", 0, "!";
"Ouch... why me????";
":-(";
// 0 = enemy name
} //end type
type "death_cratered" //initiated when the bot is killed by taking "normal" falling damage
{
"SPLOT!!!";
"Hehehe";
"I'm a pankcake :-)";
"Wooohooo";
"Geranimoooooo!!!!";
"I taught I was Superman in carnate";
"Damn I was aiming for you ", 0, "!";
// 0 = enemy name
} //end type
type "death_lava" //initiated when the bot dies in lava
{
"Damn";
"Opps :-)";
"I'm the human torce... NOT! :-)";
"Gee nothing left of me :-)";
"Wooo weeee :-)";
"This is embarrassing!";
// 0 = enemy name
} //end type
type "death_slime" //initiated when the bot dies in slime
{
"Well, it looked pretty :-)";
"My mistake :-)";
"Smells :-)";
"Just like home... except it kills me :-)";
"Just my luck.";
// 0 = enemy name
} //end type
type "death_drown" //initiated when the bot drowns
{
"How much can I drink? Not much I guest :-)";
"I always wondered what is is like to be a snorkel :-)";
"Forgot I ain't a fish :-)";
"Damn... I'm all clean now!";
"Anyone wants sardines?";
"Tuna fish anyone?";
"BURP!!! :-)";
// 0 = enemy name
} //end type
type "death_suicide" //initiated when bot blows self up with a weapon or craters
{
"Woohoo!";
"Dang!";
"What an embrassement!";
"Opps :-)";
"Hehehe";
"I taught I was immortal!!!";
// 0 = enemy name
} //end type
type "death_gauntlet" //initiated when the bot is killed by a gauntlet attack
{
"Shit that is huminating!!!";
"!@@%@^$%#@%^$$%$%";
"Grinded! Damn!";
"Oooiiiii!!!!!!";
"OUCH!!!!";
"I'll get you for that ", 0, "!";
// 0 = enemy name
} //end type
type "death_rail" //initiated when the bot is killed by a rail gun shot
{
"Impressive shot ", 0, "!";
"Argh! I'm poisoned by radiation! ARRRRR!!!!";
"Nice!";
"Ooofff!!!";
// 0 = enemy name
} //end type
type "death_bfg" //initiated when the bot died by a BFG
{
"No fair!";
"Lamer!";
"Learn to AIM!";
"Cheater!!!!!!!";
// 0 = enemy name
} //end type
type "death_insult" //insult initiated when the bot died
{
"I'll be back!!!";
"The rakethese will return!";
"I taught I'm immortal :-)";
"Come back!!!";
":-(";
"You'll be sorry you did that!!";
// 0 = enemy name
} //end type
type "death_praise" //praise initiated when the bot died
{
"Nice frag!";
"Impressive!";
"Gee... who's your teacher!";
"Woohooo... nice one.";
"You wiped me up nicely";
// 0 = enemy name
} //end type
//======================================================
//======================================================
type "kill_rail" //initiated when the bot kills someone with rail gun
{
"Damn I'm GOOD!";
"Bulls eye!";
"Did I do that to you ", 0, "? Well I'm soooo sorry :-)";
"Bang you're dead :-)";
// 0 = enemy name
} //end type
type "kill_gauntlet" //initiated when the bot kills someone with gauntlet
{
"Street Fighter 2 baby :-)";
"Got ta like it baby :-)";
"King Kong Bandi has returned... hohum!";
"Yeah! Humiliation baby!";
"Kiss my fist!";
"Too bad it isn't a chainsaw :-)";
// 0 = enemy name
} //end type
type "kill_telefrag" //initiated when the bot telefragged someone
{
"Ohh... your place?";
"My house!";
"Opps :-)";
"Keep to your own space!";
"Now that was fun!";
// 0 = enemy name
} //end type
type "kill_suicide" //initiated when the player kills self with a weapon of craters
{
"tsk tsk tsk";
"Do you know how to play?";
"Kill others... not yourself!";
"Now I didn't see that coming :-)";
"Awwwww... what a pity :-)";
// 0 = enemy name
} //end type
type "kill_insult" //insult initiated when the bot killed someone
{
"Elvis has left the building!";
"You suck!";
"How you like my dungeon?";
"Wooohoooo!";
"HAHAHAHAHAHA.";
"tsk tsk tsk... come on you can do better ", 0,"!";
// 0 = enemy name
} //end type
type "kill_praise" //praise initiated when the bot killed someone
{
"God I AM GOOD!!!!";
"Rampage time :-)";
"Death becomes tee!";
"I like it baby!";
"Woooo what a pile of gib ", 0,".";
// 0 = enemy name
} //end type
//======================================================
//======================================================
type "random_insult" //insult initiated randomly (just when the bot feels like it)
{
"Wanna visit my dungeon?";
"Beware the Horned rakethese!";
"Nah nah, did you miss me ", 0,"?";
"Winshaft working up all day :-(";
"Damn... lag working up... must be Winshaft's fault :-)";
"I rule all of you!";
// 0 = name of randomly chosen player
// 1 = bot name
} //end type
type "random_misc" //miscellanous chats initiated randomly
{
"I like it foul and stenched!";
"Slime is my fav drink :-)";
"Huh... no knights in shining armour to kill here????";
"Gee... I miss my smoking steps :-(";
"blah blah blah blah :-)";
"Hmmm.... ", 1," sucks big time :-)";
"Did you know I don't wear underpants :-?;
"Dang... can't I use my good old trusty rakethese blade? :-)";
// 0 = name of randomly chosen player
// 1 = bot name
} //end type
} //end rakethese chat
===============================
#include "chars.h"
skill 1
{
CHARACTERISTIC_NAME "rakethese"
CHARACTERISTIC_GENDER "male"
CHARACTERISTIC_ATTACK_SKILL 0.35
CHARACTERISTIC_WEAPONWEIGHTS "bots/rakethese_w.c"
CHARACTERISTIC_AIM_SKILL 0.25
CHARACTERISTIC_AIM_ACCURACY 0.25
CHARACTERISTIC_VIEW_FACTOR 0.45
CHARACTERISTIC_VIEW_MAXCHANGE 90
CHARACTERISTIC_REACTIONTIME 2.5
CHARACTERISTIC_CHAT_FILE "bots/rakethese_t.c"
CHARACTERISTIC_CHAT_NAME "rakethese"
CHARACTERISTIC_CHAT_CPM 400
CHARACTERISTIC_CHAT_INSULT 0.9
CHARACTERISTIC_CHAT_MISC 0.9
CHARACTERISTIC_CHAT_STARTENDLEVEL 0.9
CHARACTERISTIC_CHAT_ENTEREXITGAME 0.9
CHARACTERISTIC_CHAT_KILL 0.9
CHARACTERISTIC_CHAT_DEATH 0.9
CHARACTERISTIC_CHAT_ENEMYSUICIDE 0.9
CHARACTERISTIC_CHAT_HITTALKING 0.9
CHARACTERISTIC_CHAT_HITNODEATH 0.9
CHARACTERISTIC_CHAT_HITNOKILL 0.9
CHARACTERISTIC_CHAT_RANDOM 0.9
CHARACTERISTIC_CHAT_REPLY 0.9
CHARACTERISTIC_CROUCHER 0.3
CHARACTERISTIC_JUMPER 0.9
CHARACTERISTIC_WEAPONJUMPING 0.5
CHARACTERISTIC_GRAPPLE_USER 0.0
CHARACTERISTIC_ITEMWEIGHTS "bots/rakethese_i.c"
CHARACTERISTIC_AGGRESSION 0.95
CHARACTERISTIC_SELFPRESERVATION 0.55
CHARACTERISTIC_VENGEFULNESS 0.95
CHARACTERISTIC_CAMPER 0.0
CHARACTERISTIC_EASY_FRAGGER 0.5
CHARACTERISTIC_ALERTNESS 0.5
}
skill 4
{
CHARACTERISTIC_NAME "rakethese"
CHARACTERISTIC_GENDER "male"
CHARACTERISTIC_ATTACK_SKILL 0.75
CHARACTERISTIC_WEAPONWEIGHTS "bots/rakethese_w.c"
CHARACTERISTIC_AIM_SKILL 0.45
CHARACTERISTIC_AIM_ACCURACY 0.45
CHARACTERISTIC_VIEW_FACTOR 0.45
CHARACTERISTIC_VIEW_MAXCHANGE 120
CHARACTERISTIC_REACTIONTIME 2.5
CHARACTERISTIC_CHAT_FILE "bots/rakethese_t.c"
CHARACTERISTIC_CHAT_NAME "rakethese"
CHARACTERISTIC_CHAT_CPM 400
CHARACTERISTIC_CHAT_INSULT 0.8
CHARACTERISTIC_CHAT_MISC 0.8
CHARACTERISTIC_CHAT_STARTENDLEVEL 0.8
CHARACTERISTIC_CHAT_ENTEREXITGAME 0.8
CHARACTERISTIC_CHAT_KILL 0.8
CHARACTERISTIC_CHAT_DEATH 0.8
CHARACTERISTIC_CHAT_ENEMYSUICIDE 0.8
CHARACTERISTIC_CHAT_HITTALKING 0.8
CHARACTERISTIC_CHAT_HITNODEATH 0.8
CHARACTERISTIC_CHAT_HITNOKILL 0.8
CHARACTERISTIC_CHAT_RANDOM 0.8
CHARACTERISTIC_CHAT_REPLY 0.8
CHARACTERISTIC_CROUCHER 0.5
CHARACTERISTIC_JUMPER 0.9
CHARACTERISTIC_WEAPONJUMPING 0.5
CHARACTERISTIC_GRAPPLE_USER 0.05
CHARACTERISTIC_ITEMWEIGHTS "bots/rakethese_i.c"
CHARACTERISTIC_AGGRESSION 0.9
CHARACTERISTIC_SELFPRESERVATION 0.45
CHARACTERISTIC_VENGEFULNESS 0.9
CHARACTERISTIC_CAMPER 0.25
CHARACTERISTIC_EASY_FRAGGER 0.5
CHARACTERISTIC_ALERTNESS 0.5
}
skill 5
{
CHARACTERISTIC_NAME "rakethese"
CHARACTERISTIC_GENDER "male"
CHARACTERISTIC_ATTACK_SKILL 1.0
CHARACTERISTIC_WEAPONWEIGHTS "bots/rakethese_w.c"
CHARACTERISTIC_AIM_SKILL 0.8
CHARACTERISTIC_AIM_ACCURACY 0.8
CHARACTERISTIC_VIEW_FACTOR 0.8
CHARACTERISTIC_VIEW_MAXCHANGE 360
CHARACTERISTIC_REACTIONTIME 1.0
CHARACTERISTIC_CHAT_FILE "bots/rakethese_t.c"//bot的chat文件为路径
CHARACTERISTIC_CHAT_NAME "rakethese"
CHARACTERISTIC_CHAT_CPM 400
CHARACTERISTIC_CHAT_INSULT 0.7
CHARACTERISTIC_CHAT_MISC 0.7
CHARACTERISTIC_CHAT_STARTENDLEVEL 0.7
CHARACTERISTIC_CHAT_ENTEREXITGAME 0.7
CHARACTERISTIC_CHAT_KILL 0.7
CHARACTERISTIC_CHAT_DEATH 0.7
CHARACTERISTIC_CHAT_ENEMYSUICIDE 0.7
CHARACTERISTIC_CHAT_HITTALKING 0.7
CHARACTERISTIC_CHAT_HITNODEATH 0.7
CHARACTERISTIC_CHAT_HITNOKILL 0.7
CHARACTERISTIC_CHAT_RANDOM 0.7
CHARACTERISTIC_CHAT_REPLY 0.7
CHARACTERISTIC_CROUCHER 0.0
CHARACTERISTIC_JUMPER 0.9
CHARACTERISTIC_WEAPONJUMPING 0.5
CHARACTERISTIC_GRAPPLE_USER 0.5
CHARACTERISTIC_ITEMWEIGHTS "bots/rakethese_i.c"
//机器人的item权重了
CHARACTERISTIC_AGGRESSION 0.95
CHARACTERISTIC_SELFPRESERVATION 0.95
CHARACTERISTIC_VENGEFULNESS 0.95
CHARACTERISTIC_CAMPER 0.5
CHARACTERISTIC_AIM_ACCURACY_MACHINEGUN 0.7
CHARACTERISTIC_AIM_ACCURACY_SHOTGUN 1.0
CHARACTERISTIC_AIM_ACCURACY_ROCKETLAUNCHER 1.0
CHARACTERISTIC_AIM_ACCURACY_GRENADELAUNCHER 1.0
CHARACTERISTIC_AIM_ACCURACY_LIGHTNING 1.0
CHARACTERISTIC_AIM_ACCURACY_PLASMAGUN 1.0
CHARACTERISTIC_AIM_ACCURACY_RAILGUN 1.0
CHARACTERISTIC_AIM_ACCURACY_BFG10K 1.0
CHARACTERISTIC_AIM_SKILL_ROCKETLAUNCHER 1.0
CHARACTERISTIC_AIM_SKILL_GRENADELAUNCHER 1.0
CHARACTERISTIC_AIM_SKILL_PLASMAGUN 1.0
CHARACTERISTIC_AIM_SKILL_BFG10K 1.0
CHARACTERISTIC_FIRETHROTTLE 1.0
CHARACTERISTIC_EASY_FRAGGER 1.0
CHARACTERISTIC_ALERTNESS 1.0
}
当然每一个bot对应的声音不同,例如死亡dealth1,2,3pilled 1,2,3种死法了者也!
初始化这个武器的这个权重系数这个者也!
对于这个值的处理等等
对于这个词元的对应的处理者也
item标志
iteminfo "item_health"
{
name "25 Health"
model "models/powerups/health/medium_cross.md3"
modelindex MODELINDEX_HEALTH
type ITEM_HEALTH
index INVENTORY_HEALTH
respawntime 30
mins {-15,-15,-15}
maxs {15,15,15}
} //end iteminfo
对于这个aas脚本
和这个bot的脚本的处理者也
还有这个bot的脚本的处理者
bot的脚本摘录
2
机器人的脚本
机器人的动画部分的定义
sex m
// first frame, num frames, looping frames, frames per second
0 30 0 20 // BOTH_DEATH1
29 1 0 20 // BOTH_DEAD1
30 30 0 20 // BOTH_DEATH2
59 1 0 20 // BOTH_DEAD2
60 30 0 20 // BOTH_DEATH3
89 1 0 20 // BOTH_DEAD3
90 40 0 20 // TORSO_GESTURE
130 6 0 15 // TORSO_ATTACK (MUST NOT CHANGE -- hand animation is synced to this)
136 6 0 15 // TORSO_ATTACK2 (MUST NOT CHANGE -- hand animation is synced to this)
142 5 0 20 // TORSO_DROP (MUST NOT CHANGE -- hand animation is synced to this)
147 4 0 20 // TORSO_RAISE (MUST NOT CHANGE -- hand animation is synced to this)
151 1 0 15 // TORSO_STAND
152 1 0 15 // TORSO_STAND2
153 8 8 20 // LEGS_WALKCR
161 12 12 20 // LEGS_WALK
173 8 8 18 // LEGS_RUN
181 10 10 20 // LEGS_BACK
191 10 10 15 // LEGS_SWIM
201 7 0 15 // LEGS_JUMP
208 2 0 15 // LEGS_LAND
210 8 0 15 // LEGS_JUMPB
218 1 0 15 // LEGS_LANDB
219 10 10 15 // LEGS_IDLE
229 10 10 15 // LEGS_IDLECR
239 7 7 15 // LEGS_TURN
脚本的编译
加载这些脚本,主要包括,bot的脚本,武器的脚本了
将bot的脚本来绑定到了bot身上了者也
武器的脚本绑定到了武器上了
对于脚本的处理者也,将这些脚本增加到了这个堆栈上了者也
AddScriptToStack( const char *filename )
LoadScriptFile
void ParseFromMemory (char *buffer, int size)
分析这个脚本的缓存的处理者也
GetToken (qboolean crossline)
{
对于脚本,quake3居然能够找到了这个错误在哪一行那一列的处理
id的这个编译器居然还使用了这个多线程来进行这个的处理了者也
编译脚本
当前文件的数目,这个不是编译一个文件的者也
编译出了错误的话,那么输出了这个错误信息了者也
输出了这个警告了者
脚本居然关联了这么多的这个类型,还有这个事件的处理了
类型的定义了者也,还有对于entity的处理了
对于gamesave的处理了者也
对于变量的处理了
脚本对象的处理了
还有对于这个事件定义的处理了
bot的这个加载武器的权重者也
对于这个bot存在这个move ai移动的ai处理者也
不光是要加载bot的脚本,还要加载武器的脚本
对于脚本加载,
调试,错误出在了哪一行程序了者也
对于武器,要加载武器的脚本文件了者也
这个有这个武器的名字,杀伤类型等等者也
对于脚本绑定到了物体的名字的赋予
从脚本中得到了数据值,等等要实现这些
武器的ai脚本的处理者也
对于这个bot的状态等等,例如对于广播给其他的组员来进行这个广播了者也
对于这个bot的识别敌人者也,寻路在这个aas文件中的处理者也
对于这个aas中对于这个entity的处理者也
这个entity的更新处理者也,
对于game文件中的这个area竞技场文件这个来进行这个map的名字还有这个bot的数量,名字者也
对于从脚本中得到了这个变量的值,字符串的值,还有得到了这个字符的值者也
ai开始
加载ai地图
设置这个客户端
开始bot的 ai
包括启用bot的这个
测试这个aas地图
ai停止
客户端ai停止
游戏开始后
点击菜单可以添加bot,移除bot者也,当第一次玩家出现时,这个玩家
游戏类型,有CLT夺旗模式,deathmath(死亡竞赛)单挑等等的竞赛方式
对应的不同的bot的AI方式不同了者也
/*
------------------------------------------------
bot的信息者也
--------------------------------------------------------------
*/
机器人的信息的遍历处理
对于bot来说,要进行这个相互之间发送信息,例如我们打开了雷神竞技场后会发现
这个不断出现的窗口上面的信息的处理了
将bot的处理单独的独立出来了者也
这个bot的信息的处理者也
the bg (both games)
这个bot的共性者也
初始化bot的数目
得到了这个bot的信息
得到了bot的名字者也
检查这个bot的重生
//
// g_bot.c
void G_RemoveQueuedBotBegin( int clientNum );
qboolean G_BotConnect( int clientNum, qboolean restart );
void Svcmd_AddBot_f( void );
void Svcmd_BotList_f( void );
void BotInterbreedEndMatch( void );
游戏过程中的这个bot的处理
对于bot的这个避免障碍,这个者也
初始化bot的速度,位置者也
开启了bot的ai,关闭了bot的ai
表示机器人移动的各项信息,速度,前进,后退,左转,右转等等
quake3的机器人速度特别的快,
当然,也比较的笨,特别适合我这种菜鸟级选手,当一大批bot聚在一块的时候
,我一火箭弹直接轰过去,直接轰死一大片,看着血雾,特爽!
bot具有四种ai,move ai,武器ai,决定到什么区域类型,采用什么运动方式者也
对了,在不同的区域,这个行走方式不同,这个走的方式就不一样者也,操作方式的不通者也
这个组员的这个chat交谈
启动这个群体ai,例如跟随,分离,
bot去跟随某人,等等
typedef struct {
vec3_t forward, right, up;
float frametime;
int msec;
qboolean walking;
qboolean groundPlane;
trace_t groundTrace;
float impactSpeed;
vec3_t previous_origin;
vec3_t previous_velocity;
int previous_waterlevel;
} pml_t;
火箭跳的处理,
平移跳,
旋转跳
等等的一些处理了者也
ai的命令
这个bot发给了bot的命令了者也
//组员帮助
case LTG_TEAMHELP:
//组员
LTG_TEAMACCOMPANY:
//夺取标志
case LTG_GETFLAG:
//基地
case LTG_RUSHBASE:
//返回标志
LTG_RETURNFLAG:
#ifdef MISSIONPACK
LTG_ATTACKENEMYBASE:
LTG_HARVEST:
LTG_DEFENDKEYAREA:
LTG_GETITEM:
LTG_KILL:
LTG_CAMP:
LTG_CAMPORDER:
LTG_PATROL:
说话ai
voiceCommand
这个quake3游戏中左上方,这个组员的各种信息,说出的话者也
说话时候的命令,例如命令组员去夺取标志
命令所有的组员来进行防守,给所有的组员发送了命令来进行防守的
机器人的这个说话命令
BotVoiceChatCommand
voiceCommands这个语音的命令有这个
{VOICECHAT_GETFLAG, BotVoiceChat_GetFlag},
{VOICECHAT_OFFENSE, BotVoiceChat_Offense },
{VOICECHAT_DEFEND, BotVoiceChat_Defend },
{VOICECHAT_DEFENDFLAG, BotVoiceChat_DefendFlag },
{VOICECHAT_PATROL, BotVoiceChat_Patrol },
{VOICECHAT_CAMP, BotVoiceChat_Camp },
{VOICECHAT_FOLLOWME, BotVoiceChat_FollowMe },
{VOICECHAT_FOLLOWFLAGCARRIER, BotVoiceChat_FollowFlagCarrier },
{VOICECHAT_RETURNFLAG, BotVoiceChat_ReturnFlag },
{VOICECHAT_STARTLEADER, BotVoiceChat_StartLeader },
{VOICECHAT_STOPLEADER, BotVoiceChat_StopLeader },
{VOICECHAT_WHOISLEADER, BotVoiceChat_WhoIsLeader },
{VOICECHAT_WANTONDEFENSE, BotVoiceChat_WantOnDefense },
{VOICECHAT_WANTONOFFENSE, BotVoiceChat_WantOnOffense },
{NULL, BotVoiceChat_Dummy}
bot_state bot的状态
bot在分组作战时的这个逻辑部分的处理等等
game
分组作战时候的这个bot AI
说话,发信息给组员,夺取标志,例如旗帜
告诉组员去防御 oOffense
记住上一个命令者也
保护标志
告诉组员进行巡逻
宿营
一些函数的处理
follow me,跟着我
FollowFlagCarrier跟着这个携带标志的人
返回标志
开始领导
停止领导
谁是领导
WantOnDefense
WantOnOffense
在相同的一组吗?
检查掉落的图标
检查这个攻击
/*
----------------------------------------
bot行走
----------------------------------------
*/
从aas文件里面寻径了者也
typedef struct bot_waypoint_s
{
int inuse;
char name[32];
bot_goal_t goal;
struct bot_waypoint_s *next, *prev;
} bot_waypoint_t;
这个机器人的行走的点的处理
/*
---------------------------------------
bot的碰撞检测,
避免障碍
-----------------------------------------
*/
对于这个bot的这个每时每刻来测试这个的起点,终点
跟这个叶子起点是不是相碰等等的处理者也
/*
----------------------------------------------
botWeapon AI bot的这个武器ai
----------------------------------------------
*/
对于bot选择武器,bot选择最好的武器者也,对于这个其他的一些操作者也!
bot的AI判断这个是不是自己一个组的,
一个组的成员聚集在一块,
机器人目标的处理,怎么来处理这个目标呢?
------------------------------------------------
机器人目标activategoal_s
------------------------------------------------
*/
这个活跃的这个目标的处理
这个的开始时间
这个bot一共活动的区域
bot_settings_t settings;
这个bot的设置的处理等等
bot的所有的信息
总共的这个ai要每时每刻
要得到了这个entity,bot的状态的处理者也
这个在水里的时间
起点,速度,区域,
int lastgoal_decisionmaker;
int lastgoal_ltgtype;
int lastgoal_teammate;
int ms; //move state of the bot
int gs; //goal state of the bot
int cs; //chat state of the bot
int ws; //weapon state of the bot
//
这个移动的状态的处理等等
/*
---------------------------------------
BotChangeViewAngle
--------------------------------------
*/
这个bot的改变了这个视角的处理等等
这个转弯的时候,我想用的着了这个的处理了
if (bs->enemy >= 0) {
factor = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_FACTOR, 0.01f, 1);
maxchange = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_MAXCHANGE, 1, 1800);
}
这里是什么意思的啊?我就是不大明白了者也
还要处理这个bot的输入啊,针对于bot的行为,来显示出来这个bot现在的这个动作来了者也
前移,右移,等等
void BotUpdateInput(bot_state_t *bs, int time, int elapsed_time) {
bot居然还要进行这个的处理?真的没有想到了这个者也
RemoveColorEscapeSequences
}
/*
---------------------------------------------------
在游戏开始的时候
bot的Init初始化
---------------------------------------------------
*/
//retrieve the current client state
BotAI_GetClientState( client, &bs->cur_ps );
trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
这个似乎还有这个消息的队列了者也! }
//load the bot character
加载上了这个bot角色的脚本文件的处理等等
//copy the settings得到了这个bot的这个设置了者也
//allocate a weapon state
分配了这个武器的状态的变量处理者也
游戏结束时,这个bot释放了各种ai情况了
trap_BotFreeMoveState(bs->ms);
//free the goal state`
trap_BotFreeGoalState(bs->gs);
//free the chat file
trap_BotFreeChatState(bs->cs);
//free the weapon weights
trap_BotFreeWeaponState(bs->ws);
//free the bot character
trap_BotFreeCharacter(bs->character);
//
count = client->damage_blood + client->damage_armor;
网络多人交战部分
游戏过程中
控制台命令
更新这个bot的状态,例如寻路
有限状态机等等的处理,
//bot settings
typedef struct bot_settings_s
{
char characterfile[MAX_FILEPATH];
float skill;
char team[MAX_FILEPATH];
} bot_settings_t;
死亡竞赛开始后,要遍历的状态有这个以下
/*
--------------------------------------------
武器的处理,射击对方的家伙
---------------------------------------------
*/
武器的信息,
武器的状态包括了
没有子弹,重装子弹,换武器,得到了武器,等等
例如,以下为一个武器的信息
"model2" .md3 model to also draw
"height" amplitude of bob (32 default)
"speed" seconds to complete a bob cycle (4 default)
"phase" the 0.0 to 1.0 offset in the cycle to start at
"dmg" damage to inflict when blocked (2 default)
"color" constantLight color
"light" constantLight radius
(发射速度,偏移的角度等等,子弹的数目者也,还有武器的名字)
返回伤害,还有计算散弹枪等等对于其他的处理等等者也!
武器开火时,如果弹药不是无限的,那么减少这个弹药的值者也
武器重装时,我们检查这个弹药的值者也,如果这个武器的弹药完了,那么就重装时间到了
对于组队厮杀,我们需要进行这个对于队友的判断,
如果同队的战友,算了,如果不是,干掉,射击
在服务器端来判定这个武器是否接近了,打中了这个玩家
武器的发射的各种函数等等的处理者也
导弹爆炸
导弹反弹
导弹接近我
接近我的触发器
武器准确度的射击
计算这个枪口点
如果武器开火的话,那么
开始这个Kamikate
运行这个导弹
手枪射击
掷弹筒射击
火箭筒射击
牛大强射击
钉子枪射击
bfg枪的射击
/*
--------------------------------------------
轨迹线弹道
----------------------------------------
*/
武器开火之后,除了要发出武器特有的这个声音,投影(客户端部分显示的)
在服务器端进行武器的这个子弹的弹道计算,
子弹风暴中的这个狙击枪的这个子弹,不知道是怎么做的
各种枪支的子弹的轨迹线不同,例如手榴弹,乃是一条抛物线,
离子枪,闪电的轨迹为这个直线,
对应的伤害也不同的
武器的轨道的处理,还有对于武器的其他的处理等等
typedef enum {
TR_STATIONARY,
TR_INTERPOLATE,
TR_LINEAR, //线性
TR_LINEAR_STOP,
TR_SINE,
TR_GRAVITY
} trType_t;
弹道的轨道有几种方式等等,类型
持续的时间等等,
子弹的位置者也
三角形
这个水中的子弹的轨迹的处理
子弹在飞行过程中有这个飞行轨迹弹道的计算的处理等等
bolt->clipmask = MASK_SHOT;
bolt->s.pos.trType = TR_ACCEL;
bolt->s.pos.trDuration = 500;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;
VectorCopy( start, bolt->s.pos.trBase );开始位置了者也
VectorScale( dir, 50, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta );
VectorCopy (start, bolt->r.currentOrigin);
return bolt;
shot枪的弹道管道了者也
根据公式
s = u*t + .5*a*t^2来进行计算这个弹道了
物理计算公式的处理等等
/*
================
BG_EvaluateTrajectoryDelta
For determining velocity at a given time
================
*/
void BG_EvaluateTrajectoryDelta
(const trajectory_t *tr,
int atTime,vec3_t result ){
float deltaTime;
float phase;
vec3_t dir;
switch( tr->trType ) {
case TR_STATIONARY:
case TR_INTERPOLATE:
VectorClear( result );
break;
case TR_LINEAR:
VectorCopy( tr->trDelta, result );
break;
case TR_SINE:
deltaTime = ( atTime - tr->trTime ) /
(float) tr->trDuration;
phase = cos( deltaTime * M_PI * 2 );
phase *= 0.5;
VectorScale( tr->trDelta, phase, result );
break;
case TR_LINEAR_STOP:
if ( atTime > tr->trTime + tr->trDuration ) {
VectorClear( result );
return;
}
VectorCopy( tr->trDelta, result );
break;
case TR_GRAVITY:
deltaTime = ( atTime - tr->trTime ) * 0.001;
VectorCopy( tr->trDelta, result );
result[2] -= DEFAULT_GRAVITY * deltaTime;
break;
case TR_ACCEL:
// time since missile fired in seconds
deltaTime = ( atTime - tr->trTime ) * 0.001;
// Turn magnitude of acceleration into a vector
VectorCopy(tr->trDelta,dir);
VectorNormalize (dir);
VectorScale (dir, tr->trDuration, dir);
// u + t * a = v
VectorMA (tr->trDelta, deltaTime, dir, result);
break;
default:
Com_Error( ERR_DROP,
"BG_EvaluateTrajectoryDelta:
unknown trType: %i",
tr->trTime );
break;
}
}
-------------------------------------------------
*/
伤害分几种情况者也
DAMAGE_RADIUS damage was indirect (from a nearby explosion)
DAMAGE_NO_ARMOR armor does not protect from this damage
DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles
DAMAGE_NO_PROTECTION kills godmode, armor, everything
============
伤害的类型的处理
一些命令
targ entity that is being damaged
inflictor entity that is causing the damage
attacker entity that caused the inflictor to damage targ
example: targ=monster, inflictor=rocket, attacker=player
dir direction of the attack for knockback
point point at which the damage is being inflicted, used for headshots
damage amount of damage being inflicted
knockback force to be applied against targ as a result of the damage
inflictor, attacker, dir, and point can be NULL for environmental effects
dflags these flags are used to control how T_Damage works
DAMAGE_RADIUS damage was indirect (from a nearby explosion)
DAMAGE_NO_ARMOR armor does not protect from this damage
DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles
DAMAGE_NO_PROTECTION kills godmode, armor, everything
圆形伤害,
弧形伤害
伤害力的这个计算,还有包括了除去了盔甲的保护以后的这个的处理了者也
对于这个yaw和patch方向上面的伤害的处理
没有铠甲的伤害
圆形的伤害,void CopyToBodyQue( gentity_t *ent );
void respawn (gentity_t *ent);
void BeginIntermission (void);
弧形的伤害,如果这个超过了这个伤害的包围盒的最大距离,那么拉到,
如果在这个伤害的距离之内的话,那么根据这个points = damage * ( 1.0 - dist / radius );
公式来计算这个伤害的系数者也
我的天啊,要对于眼前的物体一个一个的遍历,看哪一个与枪支射出的子弹相交了,
然后与这个子弹发生碰撞了者也
各种武器造成的伤害不同了者也
例如火箭一出手,直接把人轰成了碎片了,血雾了者也
但是手枪打的话,几百法子弹打不死了一个boss了者也
当然玩家死的方式不至一种,例如这个,从高台上掉下来
(我就经常干这种事情,从天上就掉下去)
/*
-------------------------------------------------------
死亡情况
-------------------------------------------------------
*/
//从高空中掉下去的伤害,这个的伤害,例如子弹风暴中,经常一脚敌人踹下去,
quake3中的从天上掉下来
当然,子弹风暴中的这个伤害比较的特多了,天上掉下来的,电死的,甚至直升飞机的螺旋桨锯死的,
遇到了岩浆,被烫死的
遇到了毒液,打过quake系列和虚幻竞技场3的人知道,蓝色的毒液,乃是一点点的把人给毒死的
水中的伤害,你在水里潜水时候的,时间太长了的话,那么缺氧而死等等
还有被重物压死的情况
武器打死的情况
子弹打死,手雷炸死,
火箭轰死,机枪扫死
电锯锯死,
等等各种死亡的情况的处理等等
从入口掉了下来,
杀死的玩家扔下了自己的武器了者也
如果客户端的武器不是机关枪或者地雷枪,那么就不放下者也,或者他们死前还握着这个枪支,
还有死亡以后玩家这个掉下了不掉下则个物品的情况的处理
这个乃是对于玩家的各种情况下的掉下不掉下物品的处理
/*
--------------------------------------------------------------
打死了玩家后,把玩家加入到了这个重生队列
------------------------------------------------
*/
当打死一个机器人后,重生队列里面了者也,比如一个火箭筒轰死好几个ai机器人,
然后就把这个几个机器人加入到了重生队列里面了,
在游戏过程中的这个游戏的遍历情况
bot死掉,加入死亡重生队列
重生
当玩家死去后,要复活的,死去的玩家被保存到了一个队列里面
挨个复活者也
选择重生的地点来重生的,
对于不同的游戏类型,重生方式不同的,
例如,当玩分组作战和死亡竞赛时,死亡竞赛无所谓,只要选择一个重生点,复活就是了
对于组团作战,则是要分组,红队?绿队?重生的时候先要判断来判断这个在哪一个队里面?
不同点的处理者也
死亡竞赛的这个重生点乃是从bsp文件存储中的这个deadmath点处存储的者也
一共有四种重生点的选择方法,在一个点上重生,相邻的点上重生,随机点上重生,
随机点出生者也,这个挨个的随机点重生了,
在第二个点出生者也,距离当前的随机点最远的一个随机点出生
这个是为了防止别的玩家来进行在同一个地点,老实狙杀别的玩家的
重生以后,选择随机点位置,出生,
重生时发出重生的声音,
分配给玩家一把武器,初始化武器,
比如quake3乃是一把机关枪,200发子弹,相当的厉害,
这个quake3涉及的武器算是比较的平衡型比较的好,武器威力大的,发射速度就慢
例如火箭,给的弹药也少,就10发,但是机关枪,200发子弹
武器射速快的,但是伤害就小,例如机关枪,
/*
----------------------------------------------------------------
计算得分信息
-----------------------------------------------------------------
*/
先要计算这个玩家得分的大小等级
(例如死亡竞赛中,干掉的敌人数目,谁最多呢?)
打中玩家后要增加得分
死亡竞赛的的分班分数信息
由服务器来进行这个的计算处理了
计算出来得分信息以后,传送到了客户端来进行显示出来了
对于不同的游戏方式,这个最终的得分不同者也,
组队夺标志,乃是这个夺下标志就是这个得分了,
/*
------------------------------------------
得分板
-------------------------------------
*/
这个得分似乎要发送回给了玩家的客户端了
在internet,网战和这个局域网作战中
服务器来进行每个玩家的等级得分来进行排序,最后将这个排序的结果发送给了客户端来进行显示了者也
服务器要给所有的这个玩家发送了这个得分板上的信息了者
然后在客户端上来进行显示