game游戏部分1

news/2024/10/30 15:27:30/
 
参考code3Arena网站中 一部分东西
乃是对于game文件夹游戏过程中一个相对比较详细的叙述
game部分

 


 

整个quake3乃是客户端和这个服务器端运行的,


quake3的这个单人部分,也是仿照的这个多人部分的这个客户端

、和这个服务器端来进行这个运行的

对于quake3服务器部分,要处理者也碰撞检测的东西者也,

、服务器要判断这个游戏的方式,game决胜负的方式,

还有这个对于服务器的这个启动,停止等等的处理者也

以及这个得到了物体等等的东西了者也

 

对于客户端,不断的发送信息和接受信息等等

cgame来处理这个ui,声音,图像的显示等等的处理者也


 

这个game部分主要是这个在单人部分时的ai部分,

专门来处理这个bot在各种游戏类型中的这个处理阶段者也


 

服务器端
包括了quaked脚本的编译,ai部分和游戏逻辑部分的处理了者也!


则是全部的游戏逻辑的处理了者也
触发器逻辑,开门关门,bot的处理都是在服务器端来进行处理的,
分为
单人游戏时刻,加载上了这个bot机器人,来虚拟多人作战时候的这个情况的处理了
的处理,仿照了这个客户端的机器人的处理
和多人联网作战时候的处理


可以把quake3分为服务器端和客户端者也,即使在一台机器上者也 
,也是按照这个服务器与客户端的程序来分别运行,处理的
服务器端进行,bot计算碰撞检测数据要使用者也
 
客户端与服务器都是使用的命令行驱动者也,
服务器端检测有几个客户端,抓包,取包,对于逻辑判断,例如这个多人游戏的胜负,单人游戏的bot处理都是用的这个服务器的程序者也 者也  
<P>在学习quake3源码时, 有必要先从总体上了解 quake
的设计思路和结构。<BR>以下内容主要来自Mi
Abrash对quake的综述(quake1到quake3总体结构变化不大),原文见<A
DOOM采用的是一个对等的网络体系结构(peer-to-peer),其中每个玩家机器运行一致的游戏引擎。这种方式对于只有两个玩家的游戏非常好,但是对于支持多人游戏,即通过Internet网的游戏则非常困难,所以quake采用了不同的网络体系结构。</P>

<P>quake是一个client-server模式的程序,如下图所示:</P>

所有的游戏动作和模拟计算都在服务器上进行,

而所有的输入,输出则放在客户端处理。每个客户端为每一帧处理键盘,鼠标,游戏柄事件,并发送消息给服务器。服务器收到这些消息后,在一个指定的时间片内(帧频率以内)完成计算,并返回处理结果给客户端。客户端在下一帧数据接受之前渲染这些结果。这种方式在单人模式下也是一致的。即服务器和客户端在一个进程内,之间通过memory buffers通信。
在多人模式下,客户端和服务器在不同的进程里,运行在不同的机器上。
client-server模式对于多人游戏是非常有利的,因为它提供了多玩家直接的简单同步机制。甚至在单玩家模式下,

client-server也是有用的,它可以支持更好的调试。
通信对于client-server模式来说,最感兴趣的就是能够通过internet来玩游戏。
quake从一开始就被设计为支持多人游戏,包括通过internet。但是通过internet通信要比在通过LAN通信有更多的通信延迟,甚至数据报丢失。</P>

在早期,quake采用了可靠的数据传输方式。在这种方式中,数据包发送出去后,必须得到对方确认的消息,如果没有收到确认消息,则整个游戏将停止直到重发成功。为了减少消息发送的数量,客户端应该只发送那些会导致游戏状态改变的消息。当然如果客户端发生改变游戏状态的消息,但是没有发送给服务器,则累计一定时间后,整个游戏世界的状态都将是不正确的

<P>可靠的数据传输方式的问题是如果数据包丢弃了,它需要花很长的时间去等待,然后重发。如果服务器到客户端 ping的时间为 200ms,则一个丢弃的数据包会导致几个200ms的时间延迟。 </P>

现在,quake仅仅使用可靠数据传输方式来传输一些关键信息,如分数,等级变化等。对于当前游戏状态,如玩家位置,物品位置等,它只在一定时间间隔发送,而不是这些数据一变化就广播这些数据给所有相关的客户端。并且这些信息的发送并不要求确认报文。即采用的是发出去后不管的原则。 延迟
client-server模式潜在地带来了玩家动作大的延迟,如按下跳跃键,玩家就可以看到结果,比如他的视角变成了天空。这个动作先得发送给Server, 然后再返回。 在LAN中, 这个延迟非常接近no time,而在internet中,则会有几百ms的延迟。长延迟导致游戏非常的难玩。这个问题带了了一种可能性:即在客户端和服务端都运行一些游戏逻辑,

这样客户端可以提高响应速度。
快速的响应大部分时间都能工作的很好,但是对于客户端的模拟计算则存在一些严重的问题。首先它使得通信和游戏逻辑变得非常复杂,因为不是只有一个在服务器上的中心模拟器,而是有一打或更多的模拟器需要同步。&nbsp;

这样就是要求客户端模拟器在有冲突产生的时候,有一个机制来判断哪些决策是对的,

然后回滚其他的模拟器中的一些动作。非常地糟糕,这是一个不可避免的悖论,如一个玩家发射了一个火箭,然后看到它击中了对手并且导致对手死亡,但是过了一会他发现对手奇迹般地复活了。然后
quake也存在一些延迟,但是它不会产生上述情景。 服务器
quake服务器维护着游戏的时间和状态,执行对象的移动,物理计算,和怪物AI。对于服务器方面来说,大部分感兴趣的是数据驱动模型。世界的描述是通过对象的位置和类型,墙的位置,还有存储在数据库中的相关信息来体现的。对象和怪物的行为都是通过编程实现的,通过内建的解释器,

Quake-C控制。

quake服务器是由数据库驱动的,玩家不仅可以增加新的世界场景,还可以创建新的游戏元素,如能自动锁定目标的高级火箭筒,
自动导航的飞机等,这些都不需要写一行的C或汇编代码。这种灵活性不仅使得quake成为一个开发性的平台,而且可以让更多的人参与到游戏的开发中(不需要重新编译代码)。甚至我们可以在quake服务器运行中增加新的世界场景和quake c程序。

客户端<BR>服务器和通信层是quake关键部分, 但是客户端才是玩家直接面对的,

客户端实现了一个3D引擎。客户端处理键盘,鼠标,游戏手柄,声音混合,和2D画图如菜单,工具栏,消息栏等,这些不是复杂的部分。真正的创造性的是3D引擎。
 
而不是DOOM的2.5D),采用光照提高了图像逼真度,更精确的像素绘制。当然quake3D在性能上也是独一无二的。

和服务器一样, 3D引擎也是数据驱动的, quake的数据主要分成两类
quake 3D引擎的挑战主要是两个方面:支持所有角度3D观察( :the world和the entities。
每个场景都包含一些墙的几何体,门,和一些需要画到这些表面的纹理(bitmaps)。quake引擎内存存储了三角形mesh 玩家的纹理, 怪物和其他可移动的对象,即entities。

最早,我们计划是在一个渲染通道中完成这些显示工作。
但是考虑到大量的墙,怪物和成百的多边形在一个通道中渲染效率比较低。现在已经采用了不同的方式来做并行渲染了。
世界被存储在一个BSP树的数据结构中。
BSP树非常的容易理解,这里就不列出细节了,后面有专门针对BSP的解释。对于quake来说,


在服务器端和客户端,


对于服务器的上面的entity,还有这个
在服务器端的对于所有的物体的逻辑处理,例如物体的平移,旋转,缩放,消失以后
物体消失后把物体加入到了重生队列,来进行重生的处理了


加载服务器端的这个game.vm文件 
编译,来执行服务器端的处理


这个套接字的处理了


玩家的状态
对于玩家与服务器之间,
连接
掉线,

游戏开始时
在多人游戏过程中,联网进行对战时候
服务器与玩家之间的命令者也
下载,


阅读park,文件包的处理了
,直接连接了这个东西的处理了者也

// fills in a table of entity numbers with entities that have bounding boxes
// that intersect the given area.  It is possible for a non-axial bmodel
// to be returned that doesn't actually intersect the area on an exact
// test.
// returns the number of pointers filled in
// The world entity is never returned in this list.

对于这个怎么来处理的者也!

这个cd号的处理,比较了者也
这个开始下载了,这个对于下载的处理了者也
显示ip地址,
还有比较这个下载是不是完成了,
开始下载,比较下载完成了是否
得到了这个ping的处理了者也

分析这个服务器是何种类型

case AS_LOCAL :
server = &cls.localServers[0];
max = cls.numlocalservers;
break;

case AS_MPLAYER :
server = &cls.mplayerServers[0];
max = cls.nummplayerservers;
break;
case AS_GLOBAL :
server = &cls.globalServers[0];
max = cls.numglobalservers;
break;

case AS_FAVORITES :
server = &cls.favoriteServers[0];
max = cls.numfavoriteservers;
break;
对于各种联网情况的处理了,这个乃是各种情况了者也

如果不能够拼通地址,算了
创建了服务器的虚拟机文件



加载地图文件
// find the current mapname
info = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ];
mapname = Info_ValueForKey( info, "mapname" );
Com_sprintf( cl.mapname, sizeof( cl.mapname ), "maps/%s.bsp", mapname );

加载上了这个bsp文件,

地图文件的加载,来进行这个碰撞检测的处理了


当一个服务器游戏启动的话
或者是这个重生的话,那么通知所有的客户端,发信息

// send the data to all relevent clients
发信息给了所有的客户端了者也
// do not always send server info to all clients



套接字和这个网络传输
初始化这个ip地址,
找到了internet上的
客户端连接


处理ip
过滤这个ip数据包

信息内容
//message types
#define MSG_NEWLEADER 1 //new leader
#define MSG_ENTERGAME 2 //enter game message
#define MSG_HELP 3 //help someone
#define MSG_ACCOMPANY 4 //accompany someone
#define MSG_DEFENDKEYAREA 5 //defend a key area
#define MSG_RUSHBASE 6 //everyone rush to base
#define MSG_GETFLAG 7 //get the enemy flag
#define MSG_STARTTEAMLEADERSHIP 8 //someone wants to become the team leader
#define MSG_STOPTEAMLEADERSHIP 9 //someone wants to stop being the team leader
#define MSG_WHOISTEAMLAEDER 10 //who is the team leader
#define MSG_WAIT 11 //wait for someone
#define MSG_WHATAREYOUDOING 12 //what are you doing?
#define MSG_JOINSUBTEAM 13 //join a sub-team
#define MSG_LEAVESUBTEAM 14 //leave a sub-team
#define MSG_CREATENEWFORMATION 15 //create a new formation
#define MSG_FORMATIONPOSITION 16 //tell someone his/her position in a formation
#define MSG_FORMATIONSPACE 17 //set the formation intervening space
#define MSG_DOFORMATION 18 //form a known formation
#define MSG_DISMISS 19 //dismiss commanded team mates
#define MSG_CAMP 20 //camp somewhere
#define MSG_CHECKPOINT 21 //remember a check point
#define MSG_PATROL 22 //patrol between certain keypoints
#define MSG_LEADTHEWAY 23 //lead the way
#define MSG_GETITEM 24 //get an item
#define MSG_KILL 25 //kill someone
#define MSG_WHEREAREYOU 26 //where is someone
#define MSG_RETURNFLAG 27 //return the flag
#define MSG_WHATISMYCOMMAND 28 //ask the team leader what to do
#define MSG_WHICHTEAM 29 //ask which team a bot is in
#define MSG_TASKPREFERENCE 30 //tell your teamplay task preference
#define MSG_ATTACKENEMYBASE 31 //attack the enemy base
#define MSG_HARVEST 32 //go harvest
#define MSG_SUICIDE 33 //order to suicide
//
#define MSG_ME 100
#define MSG_EVERYONE 101
#define MSG_MULTIPLENAMES 102
#define MSG_NAME 103
#define MSG_PATROLKEYAREA 104
#define MSG_MINUTES 105
#define MSG_SECONDS 106
#define MSG_FOREVER 107
#define MSG_FORALONGTIME 108
#define MSG_FORAWHILE 109
//
#define MSG_CHATALL 200
#define MSG_CHATTEAM 201
#define MSG_CHATTELL 202
//
#define MSG_CTF 300 //ctf message

//command sub types
#define ST_SOMEWHERE 0
#define ST_NEARITEM 1
#define ST_ADDRESSED 2
#define ST_METER 4
#define ST_FEET 8
#define ST_TIME 16
#define ST_HERE 32
#define ST_THERE 64
#define ST_I 128
#define ST_MORE 256
#define ST_BACK 512
#define ST_REVERSE 1024
#define ST_SOMEONE 2048
#define ST_GOTFLAG 4096
#define ST_CAPTUREDFLAG 8192
#define ST_RETURNEDFLAG 16384
#define ST_TEAM 32768
#define ST_1FCTFGOTFLAG 65535
//ctf task preferences
#define ST_DEFENDER 1
#define ST_ATTACKER 2
#define ST_ROAMER 4


//word replacement variables
#define THE_ENEMY 7
#define THE_TEAM 7
//team message variables
#define NETNAME 0
#define PLACE 1
#define FLAG 1
#define MESSAGE 2
#define ADDRESSEE 2
#define ITEM 3
#define TEAMMATE 4
#define TEAMNAME 4
#define ENEMY 4
#define KEYAREA 5
#define FORMATION 5
#define POSITION 5
#define NUMBER 5
#define TIME 6
#define NAME 6
#define MORE 6


 

server
游戏过程中的处理
信息处理一下过来后之后这个、
信息先要压缩,到了另一方后,这个解压缩,使用了赫尔曼编码来进行编码的处理等等
时间要进行处理
game逻辑部分的处理,判断这个玩家的伤害情况者也
net方面的情况者也,这个则是玩家的这个端口号

客户端的信息
客户端未连接
客户端开始
客户端命令

客户端思考
客户端结束的一幁
运行客户端

设置这个领导
运行思考
发送得分板的信息给客户端
日志输出
输出
输出错误



 



网络多人交战部分
 quake3网战们可以连接上id的网站,来进行对人游戏,
也可以进行局域网多人对战游戏

typedef struct serverStatus_s
{
char string[BIG_INFO_STRING];
netadr_t address;
int time, startTime;
qboolean pending;
qboolean print;
qboolean retrieved;
} serverStatus_t;
服务器的状态的处理
不断的查找服务器的状态了

网战部分,玩家可以自己在自己的机子上建立了局域网服务器,(这部分未通)

和Internet这个网络部分者也

或者连到id的quake3的服务器多人对战者也。

对于玩家的ip地址首先要进行过滤,查看是否是合适的地址者也,然后给玩家建立一个记录,

1 将玩家的ip值,端口号,ip协议作为数据包的第一部分

2玩家对于服务器的命令,例如申请连接,退出,下载文件等等

3玩家之间在对战时的对话声音数据,通话信息,呼叫防守,等等信息

当然还有发送时的时间,玩家现在执行的的状态(向前走,跳黄河,举枪射击)等等一幁的信息

这三部分组织到一块后,历经赫尔曼编码压缩后

发送到服务器,处理者也

 为了防止玩家作弊,需要先把玩家的数据发到服务器进行逻辑判断正确后,才发数据到客户端,使得显示者也,否则不行


这个客户端和服务器端的处理,怎么来处理的者也!!!一时半会领悟不同了者也!有时候真的呼唤高手了者也!


// if the entire move stays in a solid volume, trace.allsolid will be set,
// trace.startsolid will be set, and trace.fraction will be 0

// if the starting point is in a solid, it will be allowed to move out
// to an open area




如果这个点在这个实体的体内部的话,那么这个allsolid将会设置了,
如果这个trace.startsolid将会设置了,这个trace,fraction这个将会为0了
如果这个开始点在一个实体的内部的话,那么将会挪离到了一个开阔的区域了者也!

得到了这个配置的信息

SV_SetUserinfo: bad index %i\n", index);
设置这个用户的信息的处理了
baseline这个乃是用于了这个创建一个基础信息来处理了者也
Entity baselines are used to compress non-delta messages
to the clients -- only the fields that differ from the
baseline will be transmitted

这个服务器的加载上了这 个game.dll文件来处理了者也

还有这个服务如果是联网作战的时候
那么也要创建衣服地图来相应的来处理这个逻辑的处理了者也
服务器也要进行这个碰撞检测的处理了者也!



服务器传输

第一次发送数据包时,先要发送这个游戏地图名字,和这个游戏类型,夺旗?单挑?死亡竞赛?
等等怎么来处理呢?

  server的数据包中包含了战斗类型如 team,等, 


套接字传输的数据使用赫尔曼编码来进行这个编码者也,到了另一端再进行解码者也
使用客户端嗅探,


客户端与服务器之间的命令包括了下载,等等命令者也
客户端时间与这个服务器端的时间不一致者也,
在服务器端的命令有这个下载命令者也
使用phs可听集,来使得整个的传送数据,减少一半者也

,也是按照这个服务器与客户端的程序来分别运行,处理的
服务器端进行,bot计算碰撞检测数据要使用者也
客户端进行的是这个图像,图形的显示这也! 
客户端与服务器都是使用的命令行驱动者也,
服务器端检测有几个客户端,抓包,取包,对于逻辑判断,例如这个多人游戏的胜负,单人游戏的bot处理都是用的这个服务器的程序者也 者也  

服务器的一幁与客户端的一幁的交互者也,以前没发现啊 
地图在服务器端啊,可以进行逻辑的计算者也,


 

在quake3之中,为了解决网络延迟,使用了udp协议,我们知道,tcp是根据的阻塞数据保证的数据能够正确的

到达,但是由于网络有问题,延迟了,丢数据报了,又得重新申请数据包,quake3直接udp,数据报出了问题后,

、直接丢了,发新的数据包,不再阻塞了,服务器直接响应,直接处理

对于玩家的机器是什么协议连到服务器的,不知道,按照玩家的协议,服务器组织数据包发到玩家手中去者也

值得注意是,quake也是分区的进行处理。


在游戏中每时每刻都要进行对鼠标,键盘的检测,渲染画面等等,但我们可以往下这样子想

网络对战时:你用鼠标来控制游戏画面中手里拿的枪,按w前进了一步,将前进一步的这个数据命令发到服务器上,

服务器判断你走的地方能不能走的通,一步走多远,发送数据给你,你的机器接到后,如果能走,按服务器的数据

服务器部分在Bsp部分寻找到了叶子部分等等的可见部分的逻辑,我们来处理者也

发送这个数据包loop

检查这个数据包是不是正确的数据包,发送数据包等等





服务器的清除资源
void SV_ClearWorld (void);
// called after the world model has been loaded, before linking any entities

void SV_UnlinkEntity( sharedEntity_t *ent );
// call before removing an entity, and before trying to move one,
// so it doesn't clip against itself

void SV_LinkEntity( sharedEntity_t *ent );
// Needs to be called any time an entity changes origin, mins, maxs,
// or solid.  Automatically unlinks if needed.
// sets ent->v.absmin and ent->v.absmax
// sets ent->leafnums[] for pvs determination even if the entity
// is not solid



对于这个怎么来写这个东西,是在是太难了者也!
服务器初始化的这个初始化所有的bot,还有这个初始化所有的entity,
挪离了entity调用的entity的,处理了者也
Delta encode a client frame onto the network channel


数据包的内容

A normal server packet will look like:

4 sequence number (high bit set if an oversize fragment)
<optional reliable commands>
1 svc_snapshot
4 last client reliable command
4 serverTime                服务器的时间
1 lastframe for delta compression
1 snapFlags                     
1 areaBytes                area的byte的标志
<areabytes>
<playerstate>
<packetentities>
一个正常的服务器的这文件包应该如同以下的形式的处理了者也!
例如1,svc_snapshot等等的处理
4乃是这个服务器的时间的处理了等等
snapFlags这个的标志了者也!

areabyte的这个区域的字节的处理了者也!
碰撞检测的处理了,很多这个怎么来处理的者也,
这个真的不好处理了者也!






// 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;

对于客户端的信息,处理,根据服务器发过来的命令来处理服务器的命令了者也

// write the snapshot
snapshot->snapFlags = clSnap->snapFlags;
snapshot->serverCommandSequence = clSnap->serverCommandNum;
snapshot->ping = clSnap->ping;
snapshot->serverTime = clSnap->serverTime;

server这个寻找这个加载地图者也,寻找这个cluster,者也
对于ai部分,bot的处理者也
服务器的命令者也



 

 

加载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,

//botaas的物体信息了


 

BOTLIB_AAS_INITIALIZED,

BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX,

BOTLIB_AAS_TIME,                           botaas的遍历时间了者也





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,

/*
-----------------------------------------

aibot加载这个角色的处理等等者也

------------------------------------------

*/



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,

/*

-----------------------------

aichat的这个处理等等

------------------------------

*/

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(死亡竞赛)单挑等等的竞赛方式



对应的不同的botAI方式不同了者也

/*

------------------------------------------------

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的速度,位置者也

开启了botai,关闭了botai



 

表示机器人移动的各项信息,速度,前进,后退,左转,右转等等

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选择最好的武器者也,对于这个其他的一些操作者也!





botAI判断这个是不是自己一个组的,

一个组的成员聚集在一块,

机器人目标的处理,怎么来处理这个目标呢?





------------------------------------------------

机器人目标activategoal_s

------------------------------------------------

*/

这个活跃的这个目标的处理

这个的开始时间

这个bot一共活动的区域

bot_settings_t settings;

这个bot的设置的处理等等

bot的所有的信息

总共的这个ai要每时每刻

要得到了这个entitybot的状态的处理者也

这个在水里的时间

起点,速度,区域,



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





}



/*

---------------------------------------------------

在游戏开始的时候





botInit初始化

---------------------------------------------------

*/

//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;

 

网络多人交战部分

 

网络多人交战部分
雷神之锤语序玩家连接局域网来进行对战,也可以在互联网上来进行对战
与单人部分的很多代码有相似之处,所以有共性了者也
服务器端和客户端程序的处理了者也

对于玩家的状态
左移,右移,前进,后退,
跳跃,爬行,等等的处理,全部发往了服务器来进行这个逻辑的判断处理了者也


单人的ai部分则不需要加载这个bsp了,直接在本地机器上面来进行了者也

服务器加载这个bsp地图,就有这个碰撞检测的处理了者也
碰撞检测,和这个所有的这个brush的面来进行比较,这样子来判断这个的小家了者也
武器是否打中了玩家了者也
对于这个枪的子弹的判断碰撞检测的处理了者也


这个主要是game部分的多人部分了者也,主要是与人交战的部分,
游戏类型仍然是这个,各种游戏类型的得分不同者也

这个多人游戏,既可以建立了一个局域网的多人战斗,
也可以连接上其他的网上来作战了者也



碰撞检测
游戏中不可避免的就是碰撞检测了,当是这个网络多人联网部分的时候,必须在服务器中来进行这个对于物体的

碰撞检测的处理了者也

对于与这个brush类型的碰撞,相当于与这个包围盒的碰撞检测的处理
由于brush有六七个side面构成的,
那么对于每个side其实就有平面可以生成
那么与这个brush的碰撞,那么就相当于一个点与brush的每个平面,判断是不是相碰撞的问题了


由于quake3使用的bsp场景管理,
加载上了这个bsp地图部分的这个碰撞检测部分的数据,
max,min包装盒的原理,其实乃是这个的,
当一个点在这个最大值和最小值之间的时候,那么表示这个点在这个盒子的里面了者也
如果不在的话,那么表示这个不发生碰撞的者也,
quake3的这个主要是winding和patch碰撞检测,winding这个乃是brush的,只要与构成了
这个brush的side面上的plane平面进行碰撞了者也
因此,主要是使用的pvs遍历,找到了玩家所在的那个protral入口位置,
再找到了这个玩家所在的node节点,再找到了玩家所对的这个face面,来进行玩家这个向量

如果这个side面的类型是这个patch,网格构成的,那么对于这个patch来进行这个碰撞检测的处理了这样

由于这个构成brush这个face面上不仅仅是正方形,还有曲面的patch,网格组成的所以碰撞检测时,要进行对于这个曲面的碰撞者也

这个brush,每一个中都保存了min,max,包围盒,因此是一个天然的包围盒者也,,对于这个的brush面的绘制,和碰撞检测分为了两个部分来进行了者也


关于这个碰撞检测,
(1)关于这个基本场景体的碰撞检测,
 这个主要是使用的这个bsp文件中的特有的特点了者也
 寻找到了leaf,node,再找到了这个
这个对于model的这个碰撞检测等等的处理者也

(2)关于这个model的碰撞
这个model的min,max的这个aabb盒子的最大值和这个最小值
玩家自身是一个包围盒,两个包围盒的碰撞,极为碰撞到了者也

这个quake3处处使用的这个bsp树,者也,场景管理,ai,碰撞检测等等都是利用的这个bsp树者也


当是联网多人游戏时


初始化客户端
初始化客户端的
初始化这个死亡队列
客户端重生
 
初始化所有的玩家
初始化所有的物品entity
初始化时间
 
 在进入到了竞技场后,可以join加入
sepctator分离这个竞技场者也,来进行观战者也

(1)分组作战的共性
一些分组作战时的共同特点者也
 
对于不同的游戏类型,重生方式不同的,
红方的队员死后,重生的时候,要给予玩家一个红队的标志
蓝方的队员死后,要给与玩家的蓝队的标志
不同的队伍的玩家在一块厮杀,经常要便利玩家的组队标志。来判断玩家属于哪一方了
对于队伍,先要选出来一个队长,redleader队长来发命令来进行进攻,防御等等了
 
 
对于组队厮杀,我们需要进行这个对于队友的判断,
例如,当玩分组作战和死亡竞赛时,死亡竞赛无所谓,只要选择一个重生点,复活就是了
 

游戏过程中


控制台命令



更新这个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

圆形伤害,

弧形伤害



伤害力的这个计算,还有包括了除去了盔甲的保护以后的这个的处理了者也



对于这个yawpatch方向上面的伤害的处理

没有铠甲的伤害

圆形的伤害,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,网战和这个局域网作战中

服务器来进行每个玩家的等级得分来进行排序,最后将这个排序的结果发送给了客户端来进行显示了者也

服务器要给所有的这个玩家发送了这个得分板上的信息了者

然后在客户端上来进行显示


http://www.ppmy.cn/news/332861.html

相关文章

QAQ的小游戏

描述 Recently,QAQ fell in love a small game,which simulates browser browsing web pages.It has three kind of operations: 1.BACK&#xff1a; Back to the previous page 2.FORWARD&#xff1a;Go to the next page 3.VISIT URL&#xff1a;Access to the web page Now…

游戏(game)

**问题 B: 游戏(game)** **时间限制: 1 Sec 内存限制: 512 MB** **题目描述** 小R和小D在玩一个游戏。游戏涉及两个序列&#xff0c;序列 A 长度为 N&#xff0c;序列 B 长度为M。游戏共有 M 个回合&#xff0c;小R执先手&#xff0c;小R和小D轮流行动。 初始时游戏分数为 0。在…

你今天玩游戏了吗?游戏道具了解下

【面试题】 某游戏的某促销活动&#xff0c;会向玩家推荐一个道具&#xff0c;同时会得到该道具的折扣券。折扣券无有效期&#xff0c;但购买道具一次后失效。推荐一个新的道具&#xff0c;也会导致旧的折扣券失效。 假设道具推荐、查看、购买行为记录在了下面的“游戏道具记录…

Nim 游戏 、⽯头游戏1、石头游戏2

Nim 游戏 、⽯头游戏1、石头游戏2 文章目录 Nim 游戏 、⽯头游戏1、石头游戏2**一&#xff1a;Nim 游戏****二&#xff1a;⽯头游戏****三、石头游戏2****方法一&#xff1a;DP 函数****方法二&#xff1a;DP table** 一&#xff1a;Nim 游戏 你和你的朋友&#xff0c;两个人一…

这有10款好玩游戏,游戏迷速来围观

1、我飞刀玩得贼6 一款创新玩法的游戏&#xff0c;通过对一大堆飞刀的熟练操控来进行混战&#xff0c;独创的龟缩防御机制&#xff0c;让你能轻松在对手面前秀一把。 2、监狱建筑师 它作为一款优秀的模拟游戏&#xff0c;沿袭了《地下城守护者》、《矮人要塞》以及《主题医院…

从0-1一起学习live555设计思想之二 RTSP交互过程

流媒体服务系列 文章目录 流媒体服务系列前言一、OPTION二、DESCRIBE三、SETUP四、PLAY总结前言 本篇文章通过代码去分析rtsp交互过程与工作原理。由于live555的继承关系太过复杂,所以做了个图简单记录一下与h264文件传输相关的类继承关系。 一、OPTION OPTION比较简单,就…

C语言基础--整型int,长整型long,浮点型double float

本文讲解常见的C语言变量,并举出一些实例 从微软的C语言文档把所有的C语言可定义(就是能用的)截图展示: 还有好几页,不放了,看着都头疼 但是,往往用的最多的,也就是下面的(本篇只讲整数和浮点数) int 整数 整数的定义不用说了吧QAQ int a = 10; //定义一个…

libVLC 调节图像(亮度、对比度、色调、饱和度、伽玛)

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 对于一个视频来说,色彩和画面效果的呈现非常重要。假如你的画面偏暗或偏亮,缺乏层次感,色彩不够丰富或不自然,则需要根据场景和氛围进行调整。 所涉及的重要参数有: 亮度: 是视频画面的明暗程度。调整…