bot: refactor and clean up old code

fix: crash when saving old format pwf on hlds
bot: moved sdk headers to separate submodule
nav: improved unstuck and avoidance (thanks @commandcobra7) code
bot: use correct path slashes depending on platform for all data
cfg: removed simplified chines' translation, as it's too outdated
This commit is contained in:
jeefo 2023-05-12 20:00:06 +03:00
commit 7b58d51973
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
42 changed files with 365 additions and 3805 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "ext/crlib"]
path = ext/crlib
url = https://github.com/yapb/crlib
[submodule "ext/linkage"]
path = ext/linkage
url = https://github.com/yapb/linkage

View file

@ -1,826 +0,0 @@
;
; @package: YaPB
; @version: 4.3
; @author: YaPB Project
; @filename: chs_lang.cfg
;
; Configuration file contains Simplified Chinese translation for bots menus and messages.
;
[ORIGINAL]
\yMain Menu\w
1. Control Bots
2. Features
3. Fill Server
4. End Round
0. Exit
[TRANSLATED]
\yYaPB 主菜单\w
1. YaPB 控制
2. 特性
3. 填充服务器
4. 结束本局
0. 退出
[ORIGINAL]
\yBots Features\w
1. Weapon Mode Menu
2. Waypoint Menu
3. Select Personality
4. Toggle Debug Mode
5. Command Menu
0. Exit
[TRANSLATED]
\yYaPB 特性\w
1. 武器模式菜单
2. 路点菜单
3. 选择个性
4. 切换调试模式
5. 命令菜单
0. 退出
[ORIGINAL]
\yBots Control Menu\w
1. Add a Bot, Quick
2. Add a Bot, Specified
3. Remove Random Bot
4. Remove All Bots
5. Remove Bot Menu
0. Exit
[TRANSLATED]
\yYaPB 控制菜单\w
1. 快速添加一个 bot
2. 添加一个特定的 bot
3. 随机删除一个 bot
4. 删除所有 bot
5. 删除 bot 菜单
0. 退出
[ORIGINAL]
\yBots Weapon Mode\w
1. Knives only
2. Pistols only
3. Shotguns only
4. Machine Guns only
5. Rifles only
6. Sniper Weapons only
7. All Weapons
0. Exit
[TRANSLATED]
\yBots 武器模式\w
1. 只用刀
2. 只用手枪
3. 只用霰弹枪
4. 只用机枪
5. 只用步枪
6. 只用狙击枪
7. 所有武器
0. 退出
[ORIGINAL]
\yBots Personality\w
1. Random
2. Normal
3. Aggressive
4. Defensive
0. Exit
[TRANSLATED]
\yYaPB 个性\w
1. 随机
2. 正常
3. 进攻型
4. 防守型
0. 退出
[ORIGINAL]
\yBots Difficulty Level\w
1. Newbie
2. Average
3. Normal
4. Professional
5. Godlike
0. Exit
[TRANSLATED]
\yYaPB 技能\w
1. 新手
2. 一般
3. 高级
4. 专业
5. 作弊者
0. 退出
[ORIGINAL]
\ySelect a team\w
1. Terrorist Force
2. Counter-Terrorist Force
5. Auto-select
0. Exit
[TRANSLATED]
\y选择一个队伍\w
1. 恐怖分子
2. 反恐精英
5. 自动选择
0. 退出
[ORIGINAL]
\ySelect an appearance\w
1. Phoenix Connexion
2. L337 Krew
3. Arctic Avengers
4. Guerilla Warfare
5. Auto-select
0. Exit
[TRANSLATED]
\y选择一个外观\w
1. Phoenix Connexion
2. L337 Krew
3. Arctic Avengers
4. Guerilla Warfare
5. 自动选择
0. 退出
[ORIGINAL]
\ySelect an appearance\w
1. Seal Team 6 (DEVGRU)
2. German GSG-9
3. UK SAS
4. French GIGN
5. Auto-select
0. Exit
[TRANSLATED]
\y选择一个外观\w
1. Seal Team 6 (DEVGRU)
2. German GSG-9
3. UK SAS
4. French GIGN
5. 自动选择
0. 退出
[ORIGINAL]
\yWaypoint Operations (Page 1)\w
1. Show/Hide waypoints
2. Cache waypoint
3. Create path
4. Delete path
5. Add waypoint
6. Delete waypoint
7. Set Autopath Distance
8. Set Radius
9. Next...
0. Exit
[TRANSLATED]
\y路点菜单 (第 1 页)\w
1. 显示/隐藏路点
2. 缓存路点
3. 建立路径
4. 删除路径
5. 添加路点
6. 删除路点
7. 设置自动路径距离
8. 设置路点作用范围
9. 下一页...
0. 退出
[ORIGINAL]
\yWaypoint Operations (Page 2)\w
1. Waypoint stats
2. Autowaypoint on/off
3. Set flags
4. Save waypoints
5. Save without checking
6. Load waypoints
7. Check waypoints
8. Noclip cheat on/off
9. Previous...
0. Exit
[TRANSLATED]
\y路点菜单 (第 2 页)\w
1. 路点统计
2. 自动放置路点开/关
3. 设置路点属性
4. 保存路点
5. 不检查保存路点
6. 读取路点
7. 检查路点
8. 穿墙模式开/关
9. 上一页...
0. 退出
[ORIGINAL]
\yWaypoint Radius\w
1. SetRadius 0
2. SetRadius 8
3. SetRadius 16
4. SetRadius 32
5. SetRadius 48
6. SetRadius 64
7. SetRadius 80
8. SetRadius 96
9. SetRadius 128
0. Exit
[TRANSLATED]
\y路点作用范围\w
1. 0
2. 8
3. 16
4. 32
5. 48
6. 64
7. 80
8. 96
9. 128
0. 退出
[ORIGINAL]
\yWaypoint Type\w
1. Normal
\r2. Terrorist Important
3. Counter-Terrorist Important
\w4. Block with hostage / Ladder
\y5. Rescue Zone
\w6. Camping
7. Camp End
\r8. Map Goal
\w9. Jump
0. Exit
[TRANSLATED]
\y路点类型\w
1. 正常
\r2. 恐怖分子重要点
3. 反恐精英重要点
\w4. 人质无法通过/梯子
\y5. 人质解救点
\w6. 守卫点
7. 守卫结束角度
\r8. 地图目标点
\w9. 跳跃点
0. 退出
[ORIGINAL]
\yWaypoint Flags\w
\yAdd waypoint flag:\w
1. Block with Hostage
2. Terrorists Specific
3. CTs Specific
4. Use Elevator
\yDelete waypoint flag:\w
5. Block with Hostage
6. Terrorists Specific
7. CTs Specific
8. Use Elevator
0. Exit
[TRANSLATED]
\y路点属性\w
\y添加路点属性:\w
1. 人质无法通过
2. 恐怖分子
3. 反恐精英
4. 使用电梯
\y删除路点属性:\w
5. 人质无法通过
6. 恐怖分子
7. 反恐精英
8. 使用电梯
0. 退出
[ORIGINAL]
\yBot Command Menu\w
1. Make Double Jump
2. Finish Double Jump
3. Drop the C4 Bomb
4. Drop the Weapon
0. Exit
[TRANSLATED]
\yBot 命令菜单\w
1. 双跳跃
2. 双跳跃结束
3. 扔掉炸弹
4. 扔掉枪
0. 退出
[ORIGINAL]
\yAutoPath Distance\w
1. Distance 0
2. Distance 100
3. Distance 130
4. Distance 160
5. Distance 190
6. Distance 220
7. Distance 250 (Default)
0. Exit
[TRANSLATED]
\y自动路径距离\w
1. 0
2. 100
3. 130
4. 160
5. 190
6. 220
7. 250 (默认)
0. 退出
[ORIGINAL]
\yCreate Path (Choose Direction)\w
1. Outgoing Path
2. Incoming Path
3. Bidirectional (Both Ways)
0. Exit
[TRANSLATED]
\y建立路径 (选择方向)\w
1. 向外
2. 向内
3. 双向
0. 退出
[ORIGINAL]
Map not waypointed. Can't Create Bot
[TRANSLATED]
没有路点。不能建立 bot
[ORIGINAL]
Waypoints has been changed. Load waypoints again...
[TRANSLATED]
路点已经改变。需要重新读取路点...
[ORIGINAL]
Invalid skill given. Using random skill.
[TRANSLATED]
输入了不正确的技能值。使用随机技能。
[ORIGINAL]
Connecting Bot...
[TRANSLATED]
正在连接 Bot...
[ORIGINAL]
Fill Server with %s bots...
[TRANSLATED]
用 %s bot 来填充服务器...
[ORIGINAL]
Bots are removed from server.
[TRANSLATED]
Bot 已被从服务器删除。
[ORIGINAL]
Bot '%s' kicked
[TRANSLATED]
Bot '%s' 已被删除。
[ORIGINAL]
\yBots Remove Menu (%d/4):\w
%s
%s 0. Back
[TRANSLATED]
\y删除 bot (%d/4):\w
%s
%s 0. 退出
[ORIGINAL]
%s\d %1.1d. Not a Bot\w
[TRANSLATED]
%s\d %1.1d. 不是 Bot\w
[ORIGINAL]
9. More...
[TRANSLATED]
9. 更多...
[ORIGINAL]
All Bots died !
[TRANSLATED]
所有的 bot 已被删除。
[ORIGINAL]
%s weapon mode selected
[TRANSLATED]
%s 武器模式已被选定。
[ORIGINAL]
ERROR: FindPath Source Invalid->%d
[TRANSLATED]
错误: 寻找路径源不正确->%d
[ORIGINAL]
ERROR: FindPath Destination Invalid->%d
[TRANSLATED]
错误: 寻找路径目标不正确->%d
[ORIGINAL]
Denied path creation from %d to %d (path already exists)
[TRANSLATED]
无法建立从 %d 到 %d 的路径 (路径已存在)
[ORIGINAL]
Path added from %d to %d
[TRANSLATED]
从 %d 到 %d 的路径已添加
[ORIGINAL]
This is not Camping Waypoint
[TRANSLATED]
没有守卫路点
[ORIGINAL]
Waypoint number out of range (Valid range From 0 to %d)
[TRANSLATED]
路点编号超出范围 (合法的范围从 0 到 %d)
[ORIGINAL]
Cannot connect waypoint to itself
[TRANSLATED]
无法将路点与自身连接
[ORIGINAL]
Waypoint %d connected with invalid Waypoint Nr. %d!
[TRANSLATED]
路点 %d 与非法的路点 %d 连接!
[ORIGINAL]
Waypoint %d isn't connected with any other Waypoint!
[TRANSLATED]
路点 %d 没有和其它任何路点连接!
[ORIGINAL]
Waypoint %d pathnumber differs from index!
[TRANSLATED]
路点 %d 路径编号不等于索引号!
[ORIGINAL]
Waypoint %d Camp-Endposition not set!
[TRANSLATED]
路点 %d 守卫结束角度没有设定!
[ORIGINAL]
You didn't set a Rescue Point!
[TRANSLATED]
你没有设置一个人质解救点!
[ORIGINAL]
You didn't set any Terrorist Important Point!
[TRANSLATED]
你没有设置一个 T 重要路点!
[ORIGINAL]
You didn't set any CT Important Point!
[TRANSLATED]
你没有设置一个 CT 重要路点!
[ORIGINAL]
You didn't set any Goal Point!
[TRANSLATED]
你没有设置一个目标点!
[ORIGINAL]
Path broken from Waypoint Nr. 0 to Waypoint Nr. %d!
[TRANSLATED]
从路点 #0 到路点 #%d 的路径损坏!
[ORIGINAL]
Path broken from Waypoint Nr. %d to Waypoint Nr. 0!
[TRANSLATED]
从路点 #%d 到路点 #%0 的路径损坏!
[ORIGINAL]
Choose weapon from 1 to 7 range
[TRANSLATED]
选择武器,范围从 1 到 7
[ORIGINAL]
All dead bots will vote for map #%d
[TRANSLATED]
所有的死亡的 bot 将会投地图 #%d 的票
[ORIGINAL]
Bot %s executing command %s
[TRANSLATED]
Bot %s 正在执行命令 %s
[ORIGINAL]
Player is NOT Bot!
[TRANSLATED]
玩家不是一个 bot!
[ORIGINAL]
Waypoint Editing Enabled
[TRANSLATED]
路点编辑已打开
[ORIGINAL]
Waypoint Editing Disabled
[TRANSLATED]
路点编辑已关闭
[ORIGINAL]
Noclip Cheat Enabled
[TRANSLATED]
穿墙模式已打开
[ORIGINAL]
Waypoints are Disabled
[TRANSLATED]
路点已关闭
[ORIGINAL]
Waypoints are Enabled
[TRANSLATED]
路点已打开
[ORIGINAL]
Noclip Cheat Disabled
[TRANSLATED]
穿墙模式已关闭
[ORIGINAL]
Showing Direction to Waypoint #%d
[TRANSLATED]
显示到路点 #%d 的方向
[ORIGINAL]
Waypoints Saved
[TRANSLATED]
路点已保存
[ORIGINAL]
Waypoints loaded
[TRANSLATED]
路点已读取
[ORIGINAL]
Nodes work Fine
[TRANSLATED]
路点没有错误
[ORIGINAL]
Waypoint Nr. %d now cached
[TRANSLATED]
路点 #%d 已被缓存
[ORIGINAL]
Player '%s' teleported to waypoint #%d (x:%d, y:%d, z:%d)
[TRANSLATED]
玩家 '%s' 已被传送到路点 #%d (x:%d, y:%d, z:%d)
[ORIGINAL]
Experience tab saved
[TRANSLATED]
经验已保存
[ORIGINAL]
Experience Enabled
[TRANSLATED]
经验已打开
[ORIGINAL]
Experience Disabled
[TRANSLATED]
经验已关闭
[ORIGINAL]
Command not supported on dedicated server
[TRANSLATED]
此命令无法在独立的服务器上使用
[ORIGINAL]
Waypoint not saved
There are errors, see console
[TRANSLATED]
路点没有被保存
有错误,详见控制台
[ORIGINAL]
There are errors, see console
[TRANSLATED]
有错误,详见控制台
[ORIGINAL]
You're dead, and have no access to this menu
[TRANSLATED]
你已死亡,不能使用此菜单
[ORIGINAL]
AutoPath disabled
[TRANSLATED]
自动路径已关闭
[ORIGINAL]
AutoPath maximum distance set to %f
[TRANSLATED]
最大自动路径距离已被设为 %f
[ORIGINAL]
Unable to find nearest waypoint in 50 units
[TRANSLATED]
在最近的 50 单位内无法找到一个路点
[ORIGINAL]
Unable to find destination waypoint
[TRANSLATED]
无法找到目标路点
[ORIGINAL]
Unable to connect waypoint with itself
[TRANSLATED]
无法将路点与自身连接
[ORIGINAL]
There is already no path on this waypoint
[TRANSLATED]
此路点已经没有路径
[ORIGINAL]
Cached waypoint cleared (nearby point not found in 50 units range)
[TRANSLATED]
缓存的路点已清除 (在 50 单位的范围内没有找到路点)
[ORIGINAL]
Waypoint #%d has been put into memory
[TRANSLATED]
路点 #%d 已被放入内存
[ORIGINAL]
Maximum players reached (%d/%d). Unable to create Bot.
[TRANSLATED]
最大的玩家数目已达到 (%d/%d)。无法添加 bot。

@ -1 +1 @@
Subproject commit 95405e93fcdad85586103c843a20f8cb5985ae94
Subproject commit aee96574220a0e8e6fe5e84431cc184be4e05130

View file

@ -1,881 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef CONST_H
#define CONST_H
//
// Constants shared by the engine and dlls
// This header file included by engine files and DLL files.
// Most came from server.h
#define INTERFACE_VERSION 140
// Dot products for view cone checking
#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
#define FCVAR_ARCHIVE (1 << 0) // set to cause it to be saved to vars.rc
#define FCVAR_USERINFO (1 << 1) // changes the client's info string
#define FCVAR_SERVER (1 << 2) // notifies players when changed
#define FCVAR_EXTDLL (1 << 3) // defined by external DLL
#define FCVAR_CLIENTDLL (1 << 4) // defined by the client dll
#define FCVAR_PROTECTED (1 << 5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
#define FCVAR_SPONLY (1 << 6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1 << 7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1 << 8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
// edict->flags
#define FL_FLY (1 << 0) // Changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1 << 1) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define FL_CONVEYOR (1 << 2)
#define FL_CLIENT (1 << 3)
#define FL_INWATER (1 << 4)
#define FL_MONSTER (1 << 5)
#define FL_GODMODE (1 << 6)
#define FL_NOTARGET (1 << 7)
#define FL_SKIPLOCALHOST (1 << 8) // Don't send entity to local host, it's predicting this entity itself
#define FL_ONGROUND (1 << 9) // At rest / on the ground
#define FL_PARTIALGROUND (1 << 10) // not all corners are valid
#define FL_WATERJUMP (1 << 11) // player jumping out of water
#define FL_FROZEN (1 << 12) // Player is frozen for 3rd person camera
#define FL_FAKECLIENT (1 << 13) // JAC: fake client, simulated server side; don't send network messages to them
#define FL_DUCKING (1 << 14) // Player flag -- Player is fully crouched
#define FL_FLOAT (1 << 15) // Apply floating force to this entity when in water
#define FL_GRAPHED (1 << 16) // worldgraph has this ent listed as something that blocks a connection
// UNDONE: Do we need these?
#define FL_IMMUNE_WATER (1 << 17)
#define FL_IMMUNE_SLIME (1 << 18)
#define FL_IMMUNE_LAVA (1 << 19)
#define FL_PROXY (1 << 20) // This is a spectator proxy
#define FL_ALWAYSTHINK (1 << 21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path)
#define FL_BASEVELOCITY (1 << 22) // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_MONSTERCLIP (1 << 23) // Only collide in with monsters who have FL_MONSTERCLIP set
#define FL_ONTRAIN (1 << 24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_WORLDBRUSH (1 << 25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_SPECTATOR (1 << 26) // This client is a spectator, don't run touch functions, etc.
#define FL_CUSTOMENTITY (1 << 29) // This is a custom entity
#define FL_KILLME (1 << 30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time
#define FL_DORMANT (1 << 31) // Entity is dormant, no updates to client
// Goes into globalvars_t.trace_flags
#define FTRACE_SIMPLEBOX (1 << 0) // Traceline with a simple box
// walkmove modes
#define WALKMOVE_NORMAL 0 // normal walkmove
#define WALKMOVE_WORLDONLY 1 // doesn't hit ANY entities, no matter what the solid type
#define WALKMOVE_CHECKONLY 2 // move, but don't touch triggers
// edict->movetype values
#define MOVETYPE_NONE 0 // never moves
#define MOVETYPE_WALK 3 // Player only - moving on the ground
#define MOVETYPE_STEP 4 // gravity, special edge handling -- monsters use this
#define MOVETYPE_FLY 5 // No gravity, but still collides with stuff
#define MOVETYPE_TOSS 6 // gravity/collisions
#define MOVETYPE_PUSH 7 // no clip to world, push and crush
#define MOVETYPE_NOCLIP 8 // No gravity, no collisions, still do velocity/avelocity
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
#define MOVETYPE_BOUNCE 10 // Just like Toss, but reflect velocity when contacting surfaces
#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity
#define MOVETYPE_FOLLOW 12 // track movement of aiment
#define MOVETYPE_PUSHSTEP 13 // BSP model that needs physics/world collisions (uses nearest hull for world collision)
// edict->solid values
// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves
// SOLID only effects OTHER entities colliding with this one when they move - UGH!
#define SOLID_NOT 0 // no interaction with other objects
#define SOLID_TRIGGER 1 // touch on edge, but not blocking
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
// edict->deadflag values
#define DEAD_NO 0 // alive
#define DEAD_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground
#define DEAD_DEAD 2 // dead. lying still.
#define DEAD_RESPAWNABLE 3
#define DEAD_DISCARDBODY 4
#define DAMAGE_NO 0
#define DAMAGE_YES 1
#define DAMAGE_AIM 2
// entity effects
#define EF_BRIGHTFIELD 1 // swirling cloud of particles
#define EF_MUZZLEFLASH 2 // single frame ELIGHT on entity attachment 0
#define EF_BRIGHTLIGHT 4 // DLIGHT centered at entity origin
#define EF_DIMLIGHT 8 // player flashlight
#define EF_INVLIGHT 16 // get lighting from ceiling
#define EF_NOINTERP 32 // don't interpolate the next frame
#define EF_LIGHT 64 // rocket flare glow sprite
#define EF_NODRAW 128 // don't draw entity
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
//
// temp entity events
//
#define TE_BEAMPOINTS 0 // beam effect between two points
// coord coord coord (start position)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMENTPOINT 1 // beam effect between point and entity
// short (start entity)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_GUNSHOT 2 // particle effect plus ricochet sound
// coord coord coord (position)
#define TE_EXPLOSION 3 // additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
// byte (flags)
//
// The Explosion effect has some flags to control performance/aesthetic features:
#define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
#define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
#define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
#define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
#define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
#define TE_TAREXPLOSION 4 // Quake1 "tarbaby" explosion with sound
// coord coord coord (position)
#define TE_SMOKE 5 // alphablend sprite, move vertically 30 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
#define TE_TRACER 6 // tracer effect from point to point
// coord, coord, coord (start)
// coord, coord, coord (end)
#define TE_LIGHTNING 7 // TE_BEAMPOINTS with simplified parameters
// coord, coord, coord (start)
// coord, coord, coord (end)
// byte (life in 0.1's)
// byte (width in 0.1's)
// byte (amplitude in 0.01's)
// short (sprite model index)
#define TE_BEAMENTS 8
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_SPARKS 9 // 8 random tracers with gravity, ricochet sprite
// coord coord coord (position)
#define TE_LAVASPLASH 10 // Quake1 lava splash
// coord coord coord (position)
#define TE_TELEPORT 11 // Quake1 teleport splash
// coord coord coord (position)
#define TE_EXPLOSION2 12 // Quake1 colormaped (base palette) particle explosion with sound
// coord coord coord (position)
// byte (starting color)
// byte (num colors)
#define TE_BSPDECAL 13 // Decal from the .BSP file
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// short (texture index of precached decal texture name)
// short (entity index)
// [optional - only included if previous short is non-zero (not the world)] short (index of model of above entity)
#define TE_IMPLOSION 14 // tracers moving toward a point
// coord, coord, coord (position)
// byte (radius)
// byte (count)
// byte (life in 0.1's)
#define TE_SPRITETRAIL 15 // line of moving glow sprites with gravity, fadeout, and collisions
// coord, coord, coord (start)
// coord, coord, coord (end)
// short (sprite index)
// byte (count)
// byte (life in 0.1's)
// byte (scale in 0.1's)
// byte (velocity along Vector in 10's)
// byte (randomness of velocity in 10's)
#define TE_BEAM 16 // obsolete
#define TE_SPRITE 17 // additive sprite, plays 1 cycle
// coord, coord, coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (brightness)
#define TE_BEAMSPRITE 18 // A beam with a sprite at the end
// coord, coord, coord (start position)
// coord, coord, coord (end position)
// short (beam sprite index)
// short (end sprite index)
#define TE_BEAMTORUS 19 // screen aligned beam ring, expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMDISK 20 // disk that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMCYLINDER 21 // cylinder that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMFOLLOW 22 // create a line of decaying beam segments until entity stops moving
// short (entity:attachment to follow)
// short (sprite index)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte,byte,byte (color)
// byte (brightness)
#define TE_GLOWSPRITE 23
// coord, coord, coord (pos) short (model index) byte (scale / 10)
#define TE_BEAMRING 24 // connect a beam ring to two entities
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_STREAK_SPLASH 25 // oriented shower of tracers
// coord coord coord (start position)
// coord coord coord (direction Vector)
// byte (color)
// short (count)
// short (base speed)
// short (ramdon velocity)
#define TE_BEAMHOSE 26 // obsolete
#define TE_DLIGHT 27 // dynamic light, effect world, minor entity effect
// coord, coord, coord (pos)
// byte (radius in 10's)
// byte byte byte (color)
// byte (brightness)
// byte (life in 10's)
// byte (decay rate in 10's)
#define TE_ELIGHT 28 // point entity light, no world effect
// short (entity:attachment to follow)
// coord coord coord (initial position)
// coord (radius)
// byte byte byte (color)
// byte (life in 0.1's)
// coord (decay rate)
#define TE_TEXTMESSAGE 29
// short 1.2.13 x (-1 = center)
// short 1.2.13 y (-1 = center)
// byte Effect 0 = fade in/fade out
// 1 is flickery credits
// 2 is write out (training room)
// 4 bytes r,g,b,a color1 (text color)
// 4 bytes r,g,b,a color2 (effect color)
// ushort 8.8 fadein time
// ushort 8.8 fadeout time
// ushort 8.8 hold time
// optional ushort 8.8 fxtime (time the highlight lags behing the leading text in effect 2)
// string text message (512 chars max sz string)
#define TE_LINE 30
// coord, coord, coord startpos
// coord, coord, coord endpos
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_BOX 31
// coord, coord, coord boxmins
// coord, coord, coord boxmaxs
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_KILLBEAM 99 // kill all beams attached to entity
// short (entity)
#define TE_LARGEFUNNEL 100
// coord coord coord (funnel position)
// short (sprite index)
// short (flags)
#define TE_BLOODSTREAM 101 // particle spray
// coord coord coord (start position)
// coord coord coord (spray Vector)
// byte (color)
// byte (speed)
#define TE_SHOWLINE 102 // line of particles every 5 units, dies in 30 seconds
// coord coord coord (start position)
// coord coord coord (end position)
#define TE_BLOOD 103 // particle spray
// coord coord coord (start position)
// coord coord coord (spray Vector)
// byte (color)
// byte (speed)
#define TE_DECAL 104 // Decal applied to a brush entity (not the world)
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
// short (entity index)
#define TE_FIZZ 105 // create alpha sprites inside of entity, float upwards
// short (entity)
// short (sprite index)
// byte (density)
#define TE_MODEL 106 // create a moving model that bounces and makes a sound when it hits
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// angle (initial yaw)
// short (model index)
// byte (bounce sound type)
// byte (life in 0.1's)
#define TE_EXPLODEMODEL 107 // spherical shower of models, picks from set
// coord, coord, coord (origin)
// coord (velocity)
// short (model index)
// short (count)
// byte (life in 0.1's)
#define TE_BREAKMODEL 108 // box of models or sprites
// coord, coord, coord (position)
// coord, coord, coord (size)
// coord, coord, coord (velocity)
// byte (random velocity in 10's)
// short (sprite or model index)
// byte (count)
// byte (life in 0.1 secs)
// byte (flags)
#define TE_GUNSHOTDECAL 109 // decal and ricochet sound
// coord, coord, coord (position)
// short (entity index???)
// byte (decal???)
#define TE_SPRITE_SPRAY 110 // spay of alpha sprites
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (sprite index)
// byte (count)
// byte (speed)
// byte (noise)
#define TE_ARMOR_RICOCHET 111 // quick spark sprite, client ricochet sound.
// coord, coord, coord (position)
// byte (scale in 0.1's)
#define TE_PLAYERDECAL 112 // ???
// byte (playerindex)
// coord, coord, coord (position)
// short (entity???)
// byte (decal number???)
// [optional] short (model index???)
#define TE_BUBBLES 113 // create alpha sprites inside of box, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BUBBLETRAIL 114 // create alpha sprites along a line, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BLOODSPRITE 115 // spray of opaque sprite1's that fall, single sprite2 for 1..2 secs (this is a high-priority tent)
// coord, coord, coord (position)
// short (sprite1 index)
// short (sprite2 index)
// byte (color)
// byte (scale)
#define TE_WORLDDECAL 116 // Decal applied to the world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
#define TE_WORLDDECALHIGH 117 // Decal (with texture index > 256) applied to world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
#define TE_DECALHIGH 118 // Same as TE_DECAL, but the texture index was greater than 256
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
// short (entity index)
#define TE_PROJECTILE 119 // Makes a projectile (like a nail) (this is a high-priority tent)
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (modelindex)
// byte (life)
// byte (owner) projectile won't collide with owner (if owner == 0, projectile will hit any client).
#define TE_SPRAY 120 // Throws a shower of sprites or models
// coord, coord, coord (position)
// coord, coord, coord (direction)
// short (modelindex)
// byte (count)
// byte (speed)
// byte (noise)
// byte (rendermode)
#define TE_PLAYERSPRITES 121 // sprites emit from a player's bounding box (ONLY use for players!)
// byte (playernum)
// short (sprite modelindex)
// byte (count)
// byte (variance) (0 = no variance in size) (10 = 10% variance in size)
#define TE_PARTICLEBURST 122 // very similar to lavasplash.
// coord (origin)
// short (radius)
// byte (particle color)
// byte (duration * 10) (will be randomized a bit)
#define TE_FIREFIELD 123 // makes a field of fire.
// coord (origin)
// short (radius) (fire is made in a square around origin. -radius, -radius to radius, radius)
// short (modelindex)
// byte (count)
// byte (flags)
// byte (duration (in seconds) * 10) (will be randomized a bit)
//
// to keep network traffic low, this message has associated flags that fit into a byte:
#define TEFIRE_FLAG_ALLFLOAT 1 // all sprites will drift upwards as they animate
#define TEFIRE_FLAG_SOMEFLOAT 2 // some of the sprites will drift upwards. (50% chance)
#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration.
#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque
#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube.
#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
// byte (entity index of player)
// coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset )
// short (model index)
// short (life * 10 );
#define TE_KILLPLAYERATTACHMENTS 125 // will expire all TENTS attached to a player.
// byte (entity index of player)
#define TE_MULTIGUNSHOT 126 // much more compact shotgun message
// This message is used to make a client approximate a 'spray' of gunfire.
// Any weapon that fires more than one bullet per frame and fires in a bit of a spread is
// a good candidate for MULTIGUNSHOT use. (shotguns)
//
// NOTE: This effect makes the client do traces for each bullet, these client traces ignore
// entities that have studio models.Traces are 4096 long.
//
// coord (origin)
// coord (origin)
// coord (origin)
// coord (direction)
// coord (direction)
// coord (direction)
// coord (x noise * 100)
// coord (y noise * 100)
// byte (count)
// byte (bullethole decal texture index)
#define TE_USERTRACER 127 // larger message than the standard tracer, but allows some customization.
// coord (origin)
// coord (origin)
// coord (origin)
// coord (velocity)
// coord (velocity)
// coord (velocity)
// byte ( life * 10 )
// byte ( color ) this is an index into an array of color vectors in the engine. (0 - )
// byte ( length * 10 )
#define MSG_BROADCAST 0 // unreliable to all
#define MSG_ONE 1 // reliable to one (msg_entity)
#define MSG_ALL 2 // reliable to all
#define MSG_INIT 3 // write to the init string
#define MSG_PVS 4 // Ents in PVS of org
#define MSG_PAS 5 // Ents in PAS of org
#define MSG_PVS_R 6 // Reliable to PVS
#define MSG_PAS_R 7 // Reliable to PAS
#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram ( could be dropped )
#define MSG_SPEC 9 // Sends to all spectator proxies
// contents of a spot in the world
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
#define CONTENTS_SLIME -4
#define CONTENTS_LAVA -5
#define CONTENTS_SKY -6
#define CONTENTS_LADDER -16
#define CONTENT_FLYFIELD -17
#define CONTENT_GRAVITY_FLYFIELD -18
#define CONTENT_FOG -19
#define CONTENT_EMPTY -1
#define CONTENT_SOLID -2
#define CONTENT_WATER -3
#define CONTENT_SLIME -4
#define CONTENT_LAVA -5
#define CONTENT_SKY -6
// channels
#define CHAN_AUTO 0
#define CHAN_WEAPON 1
#define CHAN_VOICE 2
#define CHAN_ITEM 3
#define CHAN_BODY 4
#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area
#define CHAN_STATIC 6 // allocate channel from the static area
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network
#define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END).
// attenuation values
#define ATTN_NONE 0.0f
#define ATTN_NORM 0.8f
#define ATTN_IDLE 2f
#define ATTN_STATIC 1.25f
// pitch values
#define PITCH_NORM 100 // non-pitch shifted
#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high
#define PITCH_HIGH 120
// volume values
#define VOL_NORM 1.0
// plats
#define PLAT_LOW_TRIGGER 1
// Trains
#define SF_TRAIN_WAIT_RETRIGGER 1
#define SF_TRAIN_START_ON 4 // Train is initially moving
#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains
// buttons
#define IN_ATTACK (1 << 0)
#define IN_JUMP (1 << 1)
#define IN_DUCK (1 << 2)
#define IN_FORWARD (1 << 3)
#define IN_BACK (1 << 4)
#define IN_USE (1 << 5)
#define IN_CANCEL (1 << 6)
#define IN_LEFT (1 << 7)
#define IN_RIGHT (1 << 8)
#define IN_MOVELEFT (1 << 9)
#define IN_MOVERIGHT (1 << 10)
#define IN_ATTACK2 (1 << 11)
#define IN_RUN (1 << 12)
#define IN_RELOAD (1 << 13)
#define IN_ALT1 (1 << 14)
#define IN_SCORE (1 << 15)
// Break Model Defines
#define BREAK_TYPEMASK 0x4F
#define BREAK_GLASS 0x01
#define BREAK_METAL 0x02
#define BREAK_FLESH 0x04
#define BREAK_WOOD 0x08
#define BREAK_SMOKE 0x10
#define BREAK_TRANS 0x20
#define BREAK_CONCRETE 0x40
#define BREAK_2 0x80
// Colliding temp entity sounds
#define BOUNCE_GLASS BREAK_GLASS
#define BOUNCE_METAL BREAK_METAL
#define BOUNCE_FLESH BREAK_FLESH
#define BOUNCE_WOOD BREAK_WOOD
#define BOUNCE_SHRAP 0x10
#define BOUNCE_SHELL 0x20
#define BOUNCE_CONCRETE BREAK_CONCRETE
#define BOUNCE_SHOTSHELL 0x80
// Temp entity bounce sound types
#define TE_BOUNCE_NULL 0
#define TE_BOUNCE_SHELL 1
#define TE_BOUNCE_SHOTSHELL 2
#define MAX_ENT_LEAFS 48
#define MAX_WEAPON_SLOTS 5 // hud item selection slots
#define MAX_ITEM_TYPES 6 // hud item selection slots
#define MAX_ITEMS 5 // hard coded item types
#define HIDEHUD_WEAPONS (1 << 0)
#define HIDEHUD_FLASHLIGHT (1 << 1)
#define HIDEHUD_ALL (1 << 2)
#define HIDEHUD_HEALTH (1 << 3)
#define MAX_AMMO_TYPES 32 // ???
#define MAX_AMMO_SLOTS 32 // not really slots
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define WEAPON_SUIT 31
#define VERTEXSIZE 7
#define MAXLIGHTMAPS 4
#define NUM_AMBIENTS 4
#define MAX_MAP_HULLS 4
#define MAX_PHYSINFO_STRING 256
#define MAX_PHYSENTS 600
#define MAX_MOVEENTS 64
#define MAX_LIGHTSTYLES 64
#define MAX_LIGHTSTYLEVALUE 256
#define SURF_DRAWTILED 0x20
#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation
#define AMBIENT_SOUND_EVERYWHERE 1
#define AMBIENT_SOUND_SMALLRADIUS 2
#define AMBIENT_SOUND_MEDIUMRADIUS 4
#define AMBIENT_SOUND_LARGERADIUS 8
#define AMBIENT_SOUND_START_SILENT 16
#define AMBIENT_SOUND_NOT_LOOPING 32
#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements
#define SND_SPAWNING (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients
#define SND_STOP (1 << 5) // duplicated in protocol.h stop sound
#define SND_CHANGE_VOL (1 << 6) // duplicated in protocol.h change sound vol
#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch
#define LFO_SQUARE 1
#define LFO_TRIANGLE 2
#define LFO_RANDOM 3
// func_rotating
#define SF_BRUSH_ROTATE_Y_AXIS 0
#define SF_BRUSH_ROTATE_INSTANT 1
#define SF_BRUSH_ROTATE_BACKWARDS 2
#define SF_BRUSH_ROTATE_Z_AXIS 4
#define SF_BRUSH_ROTATE_X_AXIS 8
#define SF_PENDULUM_AUTO_RETURN 16
#define SF_PENDULUM_PASSABLE 32
#define SF_BRUSH_ROTATE_SMALLRADIUS 128
#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256
#define SF_BRUSH_ROTATE_LARGERADIUS 512
#define PUSH_BLOCK_ONLY_X 1
#define PUSH_BLOCK_ONLY_Y 2
#define VEC_HULL_MIN Vector(-16, -16, -36)
#define VEC_HULL_MAX Vector(16, 16, 36)
#define VEC_HUMAN_HULL_MIN Vector(-16, -16, 0)
#define VEC_HUMAN_HULL_MAX Vector(16, 16, 72)
#define VEC_HUMAN_HULL_DUCK Vector(16, 16, 36)
#define VEC_VIEW Vector(0, 0, 28)
#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18)
#define VEC_DUCK_HULL_MAX Vector(16, 16, 18)
#define VEC_DUCK_VIEW Vector(0, 0, 12)
#define SVC_TEMPENTITY 23
#define SVC_CENTERPRINT 26
#define SVC_INTERMISSION 30
#define SVC_CDTRACK 32
#define SVC_WEAPONANIM 35
#define SVC_ROOMTYPE 37
#define SVC_DIRECTOR 51
// triggers
#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger
#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger
#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger
// func breakable
#define SF_BREAK_TRIGGER_ONLY 1 // may only be broken by trigger
#define SF_BREAK_TOUCH 2 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 4 // can be broken by a player standing on it
#define SF_BREAK_CROWBAR 256 // instant break if hit with crowbar
// func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 128
#define SF_LIGHT_START_OFF 1
#define SPAWNFLAG_NOMESSAGE 1
#define SPAWNFLAG_NOTOUCH 1
#define SPAWNFLAG_DROIDONLY 4
#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons)
#define TELE_PLAYER_ONLY 1
#define TELE_SILENT 2
#define SF_TRIG_PUSH_ONCE 1
// Rendering constants
enum {
kRenderNormal, // src
kRenderTransColor, // c*a+dest*(1-a)
kRenderTransTexture, // src*a+dest*(1-a)
kRenderGlow, // src*a+dest -- No Z buffer checks
kRenderTransAlpha, // src*srca+dest*(1-srca)
kRenderTransAdd // src*a+dest
};
enum {
kRenderFxNone = 0,
kRenderFxPulseSlow,
kRenderFxPulseFast,
kRenderFxPulseSlowWide,
kRenderFxPulseFastWide,
kRenderFxFadeSlow,
kRenderFxFadeFast,
kRenderFxSolidSlow,
kRenderFxSolidFast,
kRenderFxStrobeSlow,
kRenderFxStrobeFast,
kRenderFxStrobeFaster,
kRenderFxFlickerSlow,
kRenderFxFlickerFast,
kRenderFxNoDissipation,
kRenderFxDistort, // Distort/scale/translate flicker
kRenderFxHologram, // kRenderFxDistort + distance fade
kRenderFxDeadPlayer, // kRenderAmt is the player index
kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale // Keep this sprite from getting very small (SPRITES only!)
};
typedef enum {
ignore_monsters = 1,
dont_ignore_monsters = 0,
missile = 2
} IGNORE_MONSTERS;
typedef enum {
ignore_glass = 1,
dont_ignore_glass = 0
} IGNORE_GLASS;
typedef enum {
point_hull = 0,
human_hull = 1,
large_hull = 2,
head_hull = 3
} HULL;
typedef enum {
at_notice,
at_console, // same as at_notice, but forces a ConPrintf, not a message box
at_aiconsole, // same as at_console, but only shown if developer level is 2!
at_warning,
at_error,
at_logged // Server print to console ( only in multiplayer games ).
} ALERT_TYPE;
// 4-22-98 JOHN: added for use in pfnClientPrintf
typedef enum {
print_console,
print_center,
print_chat
} PRINT_TYPE;
// For integrity checking of content on clients
typedef enum {
force_exactfile, // File on client must exactly match server's file
force_model_samebounds, // For model files only, the geometry must fit in the same bbox
force_model_specifybounds // For model files only, the geometry must fit in the specified bbox
} FORCE_TYPE;
#endif

View file

@ -1,349 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#pragma once
struct cvar_t {
char *name;
char *string;
int flags;
float value;
cvar_t *next;
};
typedef struct hudtextparms_s {
float x;
float y;
int effect;
uint8_t r1, g1, b1, a1;
uint8_t r2, g2, b2, a2;
float fadeinTime;
float fadeoutTime;
float holdTime;
float fxTime;
int channel;
} hudtextparms_t;
// Returned by TraceLine
typedef struct {
int fAllSolid; // if true, plane is not valid
int fStartSolid; // if true, the initial point was in a solid area
int fInOpen;
int fInWater;
float flFraction; // time completed, 1.0 = didn't hit anything
vec3_t vecEndPos; // final position
float flPlaneDist;
vec3_t vecPlaneNormal; // surface normal at impact
edict_t *pHit; // entity the surface is on
int iHitgroup; // 0 == generic, non zero is specific body part
} TraceResult;
typedef struct usercmd_s {
short lerp_msec; // Interpolation time on client
byte msec; // Duration in ms of command
vec3_t viewangles; // Command view angles.
// intended velocities
float forwardmove; // Forward velocity.
float sidemove; // Sideways velocity.
float upmove; // Upward velocity.
byte lightlevel; // Light level at spot where we are standing.
unsigned short buttons; // Attack buttons
byte impulse; // Impulse command issued.
byte weaponselect; // Current weapon id
// Experimental player impact stuff.
int impact_index;
vec3_t impact_position;
} usercmd_t;
typedef uint32_t CRC32_t;
// Engine hands this to DLLs for functionality callbacks
typedef struct enginefuncs_s {
int (*pfnPrecacheModel) (const char *s);
int (*pfnPrecacheSound) (const char *s);
void (*pfnSetModel) (edict_t *e, const char *m);
int (*pfnModelIndex) (const char *m);
int (*pfnModelFrames) (int modelIndex);
void (*pfnSetSize) (edict_t *e, const float *rgflMin, const float *rgflMax);
void (*pfnChangeLevel) (char *s1, char *s2);
void (*pfnGetSpawnParms) (edict_t *ent);
void (*pfnSaveSpawnParms) (edict_t *ent);
float (*pfnVecToYaw) (const float *rgflVector);
void (*pfnVecToAngles) (const float *rgflVectorIn, float *rgflVectorOut);
void (*pfnMoveToOrigin) (edict_t *ent, const float *pflGoal, float dist, int iMoveType);
void (*pfnChangeYaw) (edict_t *ent);
void (*pfnChangePitch) (edict_t *ent);
edict_t *(*pfnFindEntityByString) (edict_t *pentEdictStartSearchAfter, const char *pszField, const char *pszValue);
int (*pfnGetEntityIllum) (edict_t *pEnt);
edict_t *(*pfnFindEntityInSphere) (edict_t *pentEdictStartSearchAfter, const float *org, float rad);
edict_t *(*pfnFindClientInPVS) (edict_t *ent);
edict_t *(*pfnEntitiesInPVS) (edict_t *pplayer);
void (*pfnMakeVectors) (const float *rgflVector);
void (*pfnAngleVectors) (const float *rgflVector, float *forward, float *right, float *up);
edict_t *(*pfnCreateEntity) ();
void (*pfnRemoveEntity) (edict_t *e);
edict_t *(*pfnCreateNamedEntity) (int className);
void (*pfnMakeStatic) (edict_t *ent);
int (*pfnEntIsOnFloor) (edict_t *e);
int (*pfnDropToFloor) (edict_t *e);
int (*pfnWalkMove) (edict_t *ent, float yaw, float dist, int mode);
void (*pfnSetOrigin) (edict_t *e, const float *rgflOrigin);
void (*pfnEmitSound) (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch);
void (*pfnEmitAmbientSound) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
void (*pfnTraceLine) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceToss) (edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
int (*pfnTraceMonsterHull) (edict_t *ent, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceHull) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceModel) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2);
void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnGetAimVector) (edict_t *ent, float speed, float *rgflReturn);
void (*pfnServerCommand) (char *str);
void (*pfnServerExecute) ();
void (*pfnClientCommand) (edict_t *ent, char const *szFmt, ...);
void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count);
void (*pfnLightStyle) (int style, char *val);
int (*pfnDecalIndex) (const char *name);
int (*pfnPointContents) (const float *rgflVector);
void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
void (*pfnMessageEnd) ();
void (*pfnWriteByte) (int value);
void (*pfnWriteChar) (int value);
void (*pfnWriteShort) (int value);
void (*pfnWriteLong) (int value);
void (*pfnWriteAngle) (float flValue);
void (*pfnWriteCoord) (float flValue);
void (*pfnWriteString) (const char *sz);
void (*pfnWriteEntity) (int value);
void (*pfnCVarRegister) (cvar_t *pCvar);
float (*pfnCVarGetFloat) (const char *szVarName);
const char *(*pfnCVarGetString) (const char *szVarName);
void (*pfnCVarSetFloat) (const char *szVarName, float flValue);
void (*pfnCVarSetString) (const char *szVarName, const char *szValue);
void (*pfnAlertMessage) (ALERT_TYPE atype, const char *szFmt, ...);
void (*pfnEngineFprintf) (void *pfile, char *szFmt, ...);
void *(*pfnPvAllocEntPrivateData) (edict_t *ent, int32_t cb);
void *(*pfnPvEntPrivateData) (edict_t *ent);
void (*pfnFreeEntPrivateData) (edict_t *ent);
const char *(*pfnSzFromIndex) (int stingPtr);
int (*pfnAllocString) (const char *szValue);
struct entvars_s *(*pfnGetVarsOfEnt) (edict_t *ent);
edict_t *(*pfnPEntityOfEntOffset) (int iEntOffset);
int (*pfnEntOffsetOfPEntity) (const edict_t *ent);
int (*pfnIndexOfEdict) (const edict_t *ent);
edict_t *(*pfnPEntityOfEntIndex) (int entIndex);
edict_t *(*pfnFindEntityByVars) (struct entvars_s *pvars);
void *(*pfnGetModelPtr) (edict_t *ent);
int (*pfnRegUserMsg) (const char *pszName, int iSize);
void (*pfnAnimationAutomove) (const edict_t *ent, float flTime);
void (*pfnGetBonePosition) (const edict_t *ent, int iBone, float *rgflOrigin, float *rgflAngles);
uint32_t (*pfnFunctionFromName) (const char *pName);
const char *(*pfnNameForFunction) (uint32_t function);
void (*pfnClientPrintf) (edict_t *ent, PRINT_TYPE ptype, const char *szMsg); // JOHN: engine callbacks so game DLL can print messages to individual clients
void (*pfnServerPrint) (const char *szMsg);
const char *(*pfnCmd_Args) (); // these 3 added
const char *(*pfnCmd_Argv) (int argc); // so game DLL can easily
int (*pfnCmd_Argc) (); // access client 'cmd' strings
void (*pfnGetAttachment) (const edict_t *ent, int iAttachment, float *rgflOrigin, float *rgflAngles);
void (*pfnCRC32_Init) (CRC32_t *pulCRC);
void (*pfnCRC32_ProcessBuffer) (CRC32_t *pulCRC, void *p, int len);
void (*pfnCRC32_ProcessByte) (CRC32_t *pulCRC, uint8_t ch);
CRC32_t (*pfnCRC32_Final) (CRC32_t pulCRC);
int32_t (*pfnRandomLong) (int32_t lLow, int32_t lHigh);
float (*pfnRandomFloat) (float flLow, float flHigh);
void (*pfnSetView) (const edict_t *client, const edict_t *pViewent);
float (*pfnTime) ();
void (*pfnCrosshairAngle) (const edict_t *client, float pitch, float yaw);
uint8_t *(*pfnLoadFileForMe) (char const *szFilename, int *pLength);
void (*pfnFreeFile) (void *buffer);
void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection
int (*pfnCompareFileTime) (char *filename1, char *filename2, int *compare);
void (*pfnGetGameDir) (char *szGetGameDir);
void (*pfnCvar_RegisterVariable) (cvar_t *variable);
void (*pfnFadeClientVolume) (const edict_t *ent, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
void (*pfnSetClientMaxspeed) (const edict_t *ent, float fNewMaxspeed);
edict_t *(*pfnCreateFakeClient) (const char *netname); // returns nullptr if fake client can't be created
void (*pfnRunPlayerMove) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, uint16_t buttons, uint8_t impulse, uint8_t msec);
int (*pfnNumberOfEntities) ();
char *(*pfnGetInfoKeyBuffer) (edict_t *e); // passing in nullptr gets the serverinfo
char *(*pfnInfoKeyValue) (char *infobuffer, char const *key);
void (*pfnSetKeyValue) (char *infobuffer, char *key, char *value);
void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, char const *key, char const *value);
int (*pfnIsMapValid) (char *szFilename);
void (*pfnStaticDecal) (const float *origin, int decalIndex, int entityIndex, int modelIndex);
int (*pfnPrecacheGeneric) (char *s);
int (*pfnGetPlayerUserId) (edict_t *e); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
int (*pfnIsDedicatedServer) (); // is this a dedicated server?
cvar_t *(*pfnCVarGetPointer) (const char *szVarName);
unsigned int (*pfnGetPlayerWONId) (edict_t *e); // returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnInfo_RemoveKey) (char *s, const char *key);
const char *(*pfnGetPhysicsKeyValue) (const edict_t *client, const char *key);
void (*pfnSetPhysicsKeyValue) (const edict_t *client, const char *key, const char *value);
const char *(*pfnGetPhysicsInfoString) (const edict_t *client);
uint16_t (*pfnPrecacheEvent) (int type, const char *psz);
void (*pfnPlaybackEvent) (int flags, const edict_t *pInvoker, uint16_t evIndexOfEntity, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
uint8_t *(*pfnSetFatPVS) (float *org);
uint8_t *(*pfnSetFatPAS) (float *org);
int (*pfnCheckVisibility) (const edict_t *entity, uint8_t *pset);
void (*pfnDeltaSetField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaUnsetField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaAddEncoder) (char *name, void (*conditionalencode) (struct delta_s *pFields, const uint8_t *from, const uint8_t *to));
int (*pfnGetCurrentPlayer) ();
int (*pfnCanSkipPlayer) (const edict_t *player);
int (*pfnDeltaFindField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaSetFieldByIndex) (struct delta_s *pFields, int fieldNumber);
void (*pfnDeltaUnsetFieldByIndex) (struct delta_s *pFields, int fieldNumber);
void (*pfnSetGroupMask) (int mask, int op);
int (*pfnCreateInstancedBaseline) (int classname, struct entity_state_s *baseline);
void (*pfnCvar_DirectSet) (struct cvar_t *var, const char *value);
void (*pfnForceUnmodified) (FORCE_TYPE type, float *mins, float *maxs, const char *szFilename);
void (*pfnGetPlayerStats) (const edict_t *client, int *ping, int *packet_loss);
void (*pfnAddServerCommand) (const char *cmd_name, void (*function) ());
int (*pfnVoice_GetClientListening) (int iReceiver, int iSender);
int (*pfnVoice_SetClientListening) (int iReceiver, int iSender, int bListen);
const char *(*pfnGetPlayerAuthId) (edict_t *e);
struct sequenceEntry_s *(*pfnSequenceGet) (const char *fileName, const char *entryName);
struct sentenceEntry_s *(*pfnSequencePickSentence) (const char *groupName, int pickMethod, int *picked);
int (*pfnGetFileSize) (char *szFilename);
unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath);
int (*pfnIsCareerMatch) ();
int (*pfnGetLocalizedStringLength) (const char *label);
void (*pfnRegisterTutorMessageShown) (int mid);
int (*pfnGetTimesTutorMessageShown) (int mid);
void (*pfnProcessTutorMessageDecayBuffer) (int *buffer, int bufferLength);
void (*pfnConstructTutorMessageDecayBuffer) (int *buffer, int bufferLength);
void (*pfnResetTutorMessageDecayData) ();
void (*pfnQueryClientCVarValue) (const edict_t *player, const char *cvarName);
void (*pfnQueryClientCVarValue2) (const edict_t *player, const char *cvarName, int requestID);
int (*pfnCheckParm) (const char *pchCmdLineToken, char **ppnext);
// edict_t *(*pfnPEntityOfEntIndexAllEntities) (int iEntIndex);
} enginefuncs_t;
// Passed to pfnKeyValue
typedef struct KeyValueData_s {
char *szClassName; // in: entity classname
char const *szKeyName; // in: name of key
char *szValue; // in: value of key
int32_t fHandled; // out: DLL sets to true if key-value pair was understood
} KeyValueData;
typedef struct customization_s customization_t;
typedef struct {
// Initialize/shutdown the game (one-time call after loading of game .dll )
void (*pfnGameInit) ();
int (*pfnSpawn) (edict_t *pent);
void (*pfnThink) (edict_t *pent);
void (*pfnUse) (edict_t *pentUsed, edict_t *pentOther);
void (*pfnTouch) (edict_t *pentTouched, edict_t *pentOther);
void (*pfnBlocked) (edict_t *pentBlocked, edict_t *pentOther);
void (*pfnKeyValue) (edict_t *pentKeyvalue, KeyValueData *pkvd);
void (*pfnSave) (edict_t *pent, struct SAVERESTOREDATA *pSaveData);
int (*pfnRestore) (edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
void (*pfnSetAbsBox) (edict_t *pent);
void (*pfnSaveWriteFields) (SAVERESTOREDATA *, const char *, void *, struct TYPEDESCRIPTION *, int);
void (*pfnSaveReadFields) (SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int);
void (*pfnSaveGlobalState) (SAVERESTOREDATA *);
void (*pfnRestoreGlobalState) (SAVERESTOREDATA *);
void (*pfnResetGlobalState) ();
int (*pfnClientConnect) (edict_t *ent, const char *pszName, const char *pszAddress, char szRejectReason[128]);
void (*pfnClientDisconnect) (edict_t *ent);
void (*pfnClientKill) (edict_t *ent);
void (*pfnClientPutInServer) (edict_t *ent);
void (*pfnClientCommand) (edict_t *ent);
void (*pfnClientUserInfoChanged) (edict_t *ent, char *infobuffer);
void (*pfnServerActivate) (edict_t *edictList, int edictCount, int clientMax);
void (*pfnServerDeactivate) ();
void (*pfnPlayerPreThink) (edict_t *ent);
void (*pfnPlayerPostThink) (edict_t *ent);
void (*pfnStartFrame) ();
void (*pfnParmsNewLevel) ();
void (*pfnParmsChangeLevel) ();
// Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life
const char *(*pfnGetGameDescription) ();
// Notify dll about a player customization.
void (*pfnPlayerCustomization) (edict_t *ent, struct customization_s *pCustom);
// Spectator funcs
void (*pfnSpectatorConnect) (edict_t *ent);
void (*pfnSpectatorDisconnect) (edict_t *ent);
void (*pfnSpectatorThink) (edict_t *ent);
// Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint.
void (*pfnSys_Error) (const char *error_string);
void (*pfnPM_Move) (struct playermove_s *ppmove, int server);
void (*pfnPM_Init) (struct playermove_s *ppmove);
char (*pfnPM_FindTextureType) (char *name);
void (*pfnSetupVisibility) (struct edict_s *pViewEntity, struct edict_s *client, uint8_t **pvs, uint8_t **pas);
void (*pfnUpdateClientData) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
int (*pfnAddToFullPack) (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, uint8_t *pSet);
void (*pfnCreateBaseline) (int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, float *player_mins, float *player_maxs);
void (*pfnRegisterEncoders) ();
int (*pfnGetWeaponData) (struct edict_s *player, struct weapon_data_s *info);
void (*pfnCmdStart) (const edict_t *player, usercmd_t *cmd, unsigned int random_seed);
void (*pfnCmdEnd) (const edict_t *player);
// Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max
// size of the response_buffer, so you must zero it out if you choose not to respond.
int (*pfnConnectionlessPacket) (const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
// Enumerates player hulls. Returns 0 if the hull number doesn't exist, 1 otherwise
int (*pfnGetHullBounds) (int hullnumber, float *mins, float *maxs);
// Create baselines for certain "unplaced" items.
void (*pfnCreateInstancedBaselines) ();
// One of the pfnForceUnmodified files failed the consistency check for the specified player
// Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters )
int (*pfnInconsistentFile) (const struct edict_s *player, const char *szFilename, char *disconnect_message);
// The game .dll should return 1 if lag compensation should be allowed ( could also just set
// the sv_unlag cvar.
// Most games right now should return 0, until client-side weapon prediction code is written
// and tested for them.
int (*pfnAllowLagCompensation) ();
} gamefuncs_t;
typedef struct {
// Called right before the object's memory is freed.
// Calls its destructor.
void (*pfnOnFreeEntPrivateData) (edict_t *pEnt);
void (*pfnGameShutdown) ();
int (*pfnShouldCollide) (edict_t *pentTouched, edict_t *pentOther);
void (*pfnCvarValue) (const edict_t *pEnt, const char *value);
void (*pfnCvarValue2) (const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
} newgamefuncs_t;

View file

@ -1,126 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef EXTDLL_H
#define EXTDLL_H
typedef int func_t; //
typedef float vec_t; // needed before including progdefs.h
typedef vec_t vec2_t[2];
typedef vec_t vec4_t[4];
typedef int qboolean;
typedef unsigned char byte;
#include <crlib/vector.h>
#include <crlib/string.h>
#if defined (CR_ARCH_X64)
using estring_t = int32_t;
#else
using estring_t = uint32_t;
#endif
// idea from regamedll
class string_t final : public cr::DenyCopying {
private:
estring_t offset;
public:
explicit string_t () : offset (0) {}
string_t (int offset) : offset (offset) {}
~string_t () = default;
public:
const char *chars (estring_t shift = 0) const;
public:
operator estring_t () const {
return offset;
}
string_t &operator = (const string_t &rhs) {
offset = rhs.offset;
return *this;
}
};
typedef cr::Vector vec3_t;
typedef struct edict_s edict_t;
#include "const.h"
#include "progdefs.h"
#include "model.h"
typedef struct link_s {
struct link_s *prev, *next;
} link_t;
typedef struct {
vec3_t normal;
float dist;
} plane_t;
struct edict_s {
int free;
int serialnumber;
link_t area; // linked to a division node or leaf
int headnode; // -1 to use normal leaf check
int num_leafs;
short leafnums[MAX_ENT_LEAFS];
float freetime; // sv.time when the object was freed
void *pvPrivateData; // Alloced and freed by engine, used by DLLs
entvars_t v; // C exported fields from progs
};
#include "eiface.h"
extern globalvars_t *globals;
extern enginefuncs_t engfuncs;
extern gamefuncs_t dllapi;
// Use this instead of ALLOC_STRING on constant strings
static inline const char *STRING (estring_t offset) {
return globals->pStringBase + offset;
}
// form fwgs-hlsdk
#if defined (CR_ARCH_X64)
static inline int MAKE_STRING (const char *val) {
long long ptrdiff = val - STRING (0);
if (ptrdiff > INT_MAX || ptrdiff < INT_MIN) {
return engfuncs.pfnAllocString (val);
}
return static_cast <int> (ptrdiff);
}
#else
static inline estring_t MAKE_STRING (const char *str) {
return static_cast <estring_t> (reinterpret_cast <uint64_t> (str) - reinterpret_cast <uint64_t> (globals->pStringBase));
}
#endif
inline const char *string_t::chars (estring_t shift) const {
auto result = STRING (offset);
return cr::strings.isEmpty (result) ? &cr::kNullChar : (result + shift);
}
enum HLBool : int32_t {
HLFalse, HLTrue
};
#endif // EXTDLL_H

View file

@ -1,224 +0,0 @@
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
*
* This file is part of Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
// Simplified version by Wei Mingzhi
#ifndef META_API_H
#define META_API_H
typedef int (*GETENTITYAPI_FN) (gamefuncs_t *pFunctionTable, int interfaceVersion);
typedef int (*GETENTITYAPI2_FN) (gamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GETNEWDLLFUNCTIONS_FN) (newgamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
#define META_INTERFACE_VERSION "5:13"
typedef enum { PT_NEVER = 0, PT_STARTUP, PT_CHANGELEVEL, PT_ANYTIME, PT_ANYPAUSE } PLUG_LOADTIME;
typedef struct {
char const *ifvers;
char const *name;
char const *version;
char const *date;
char const *author;
char const *url;
char const *logtag;
PLUG_LOADTIME loadable;
PLUG_LOADTIME unloadable;
} plugin_info_t;
extern plugin_info_t Plugin_info;
typedef plugin_info_t *plid_t;
#define PLID &Plugin_info
typedef enum { PNL_NULL = 0, PNL_INI_DELETED, PNL_FILE_NEWER, PNL_COMMAND, PNL_CMD_FORCED, PNL_DELAYED, PNL_PLUGIN, PNL_PLG_FORCED, PNL_RELOAD } PL_UNLOAD_REASON;
typedef enum { MRES_UNSET = 0, MRES_IGNORED, MRES_HANDLED, MRES_OVERRIDE, MRES_SUPERCEDE } META_RES;
typedef struct meta_globals_s {
META_RES mres;
META_RES prev_mres;
META_RES status;
void *orig_ret;
void *override_ret;
} meta_globals_t;
extern meta_globals_t *gpMetaGlobals;
#define SET_META_RESULT(result) gpMetaGlobals->mres = result
#define RETURN_META(result) \
{ \
gpMetaGlobals->mres = result; \
return; \
}
#define RETURN_META_VALUE(result, value) \
{ \
gpMetaGlobals->mres = result; \
return (value); \
}
#define META_RESULT_STATUS gpMetaGlobals->status
#define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres
#define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret
#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret
typedef struct {
GETENTITYAPI_FN pfnGetEntityAPI;
GETENTITYAPI_FN pfnGetEntityAPI_Post;
GETENTITYAPI2_FN pfnGetEntityAPI2;
GETENTITYAPI2_FN pfnGetEntityAPI2_Post;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post;
} metamod_funcs_t;
#include "util.h"
// max buffer size for printed messages
#define MAX_LOGMSG_LEN 1024
// for getgameinfo:
typedef enum { GINFO_NAME = 0, GINFO_DESC, GINFO_GAMEDIR, GINFO_DLL_FULLPATH, GINFO_DLL_FILENAME, GINFO_REALDLL_FULLPATH } ginfo_t;
// Meta Utility Function table type.
typedef struct meta_util_funcs_s {
void (*pfnLogConsole) (plid_t plid, const char *szFormat, ...);
void (*pfnLogMessage) (plid_t plid, const char *szFormat, ...);
void (*pfnLogError) (plid_t plid, const char *szFormat, ...);
void (*pfnLogDeveloper) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSay) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, const char *szFormat, ...);
void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, const char *szFormat, va_list ap);
int (*pfnCallGameEntity) (plid_t plid, const char *entStr, entvars_t *pev);
int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size);
const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size);
const char *(*pfnGetPluginPath) (plid_t plid);
const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag);
int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
const char *(*pfnIsQueryingClienCVar_t) (plid_t plid, const edict_t *player);
int (*pfnMakeRequestID) (plid_t plid);
void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, gamefuncs_t **pdll, newgamefuncs_t **pnewdll);
} mutil_funcs_t;
typedef struct {
gamefuncs_t *dllapi_table;
newgamefuncs_t *newapi_table;
} gamedll_funcs_t;
extern gamedll_funcs_t *gpGamedllFuncs;
extern mutil_funcs_t *gpMetaUtilFuncs;
extern metamod_funcs_t gMetaFunctionTable;
#define MDLL_FUNC gpGamedllFuncs->dllapi_table
#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit
#define MDLL_Spawn MDLL_FUNC->pfnSpawn
#define MDLL_Think MDLL_FUNC->pfnThink
#define MDLL_Use MDLL_FUNC->pfnUse
#define MDLL_Touch MDLL_FUNC->pfnTouch
#define MDLL_Blocked MDLL_FUNC->pfnBlocked
#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue
#define MDLL_Save MDLL_FUNC->pfnSave
#define MDLL_Restore MDLL_FUNC->pfnRestore
#define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox
#define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields
#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields
#define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState
#define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState
#define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState
#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect
#define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect
#define MDLL_ClientKill MDLL_FUNC->pfnClientKill
#define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer
#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand
#define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged
#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate
#define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate
#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink
#define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink
#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame
#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel
#define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel
#define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription
#define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization
#define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect
#define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect
#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink
#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error
#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move
#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init
#define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType
#define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility
#define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData
#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack
#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline
#define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders
#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData
#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart
#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd
#define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket
#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds
#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines
#define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile
#define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation
#define MNEW_FUNC gpGamedllFuncs->newapi_table
#define MNEW_OnFreeEntPrivateData MNEW_FUNC->pfnOnFreeEntPrivateData
#define MNEW_GameShutdown MNEW_FUNC->pfnGameShutdown
#define MNEW_ShouldCollide MNEW_FUNC->pfnShouldCollide
#define MNEW_CvarValue MNEW_FUNC->pfnCvarValue
#define MNEW_CvarValue2 MNEW_FUNC->pfnCvarValue2
// convenience macros for metautil functions
#define LOG_CONSOLE (*gpMetaUtilFuncs->pfnLogConsole)
#define LOG_MESSAGE (*gpMetaUtilFuncs->pfnLogMessage)
#define LOG_MMERROR (*gpMetaUtilFuncs->pfnLogError)
#define LOG_DEVELOPER (*gpMetaUtilFuncs->pfnLogDeveloper)
#define CENTER_SAY (*gpMetaUtilFuncs->pfnCenterSay)
#define CENTER_SAY_PARMS (*gpMetaUtilFuncs->pfnCenterSayParms)
#define CENTER_SAY_VARARGS (*gpMetaUtilFuncs->pfnCenterSayVarargs)
#define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity)
#define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID)
#define GET_USER_MSG_NAME (*gpMetaUtilFuncs->pfnGetUserMsgName)
#define GET_PLUGIN_PATH (*gpMetaUtilFuncs->pfnGetPluginPath)
#define GET_GAME_INFO (*gpMetaUtilFuncs->pfnGetGameInfo)
#define LOAD_PLUGIN (*gpMetaUtilFuncs->pfnLoadPlugin)
#define UNLOAD_PLUGIN (*gpMetaUtilFuncs->pfnUnloadPlugin)
#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle)
#define IS_QUERYING_CLIENT_CVAR (*gpMetaUtilFuncs->pfnIsQueryingClienCVar_t)
#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestID)
#define GET_HOOK_TABLES (*gpMetaUtilFuncs->pfnGetHookTables)
#endif

View file

@ -1,229 +0,0 @@
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
*
* This file is part of Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
// Simplified version by Wei Mingzhi
#ifndef METAMOD_H
#define METAMOD_H
typedef enum {
PNL_NULL = 0,
PNL_INI_DELETED,
PNL_FILE_NEWER,
PNL_COMMAND,
PNL_CMD_FORCED,
PNL_DELAYED,
PNL_PLUGIN,
PNL_PLG_FORCED,
PNL_RELOAD
} PL_UNLOAD_REASON;
typedef enum {
MRES_UNSET = 0,
MRES_IGNORED,
MRES_HANDLED,
MRES_OVERRIDE,
MRES_SUPERCEDE
} META_RES;
typedef enum {
PT_NEVER = 0,
PT_STARTUP,
PT_CHANGELEVEL,
PT_ANYTIME,
PT_ANYPAUSE
} PLUG_LOADTIME;
// for getgameinfo:
typedef enum {
GINFO_NAME = 0,
GINFO_DESC,
GINFO_GAMEDIR,
GINFO_DLL_FULLPATH,
GINFO_DLL_FILENAME,
GINFO_REALDLL_FULLPATH
} ginfo_t;
typedef int (*GETENTITYAPI_FN) (gamefuncs_t *pFunctionTable, int interfaceVersion);
typedef int (*GETENTITYAPI2_FN) (gamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GETNEWDLLFUNCTIONS_FN) (newgamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
#define META_INTERFACE_VERSION "5:13"
typedef struct {
char const *ifvers;
char const *name;
char const *version;
char const *date;
char const *author;
char const *url;
char const *logtag;
PLUG_LOADTIME loadable;
PLUG_LOADTIME unloadable;
} plugin_info_t;
extern plugin_info_t Plugin_info;
typedef plugin_info_t *plid_t;
#define PLID &Plugin_info
typedef struct meta_globals_s {
META_RES mres;
META_RES prev_mres;
META_RES status;
void *orig_ret;
void *override_ret;
} meta_globals_t;
extern meta_globals_t *gpMetaGlobals;
#define RETURN_META(result) \
{ \
gpMetaGlobals->mres = result; \
return; \
}
#define RETURN_META_VALUE(result, value) \
{ \
gpMetaGlobals->mres = result; \
return (value); \
}
#define META_RESULT_STATUS gpMetaGlobals->status
#define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres
#define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret
#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret
typedef struct {
GETENTITYAPI_FN pfnGetEntityAPI;
GETENTITYAPI_FN pfnGetEntityAPI_Post;
GETENTITYAPI2_FN pfnGetEntityAPI2;
GETENTITYAPI2_FN pfnGetEntityAPI2_Post;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post;
} metamod_funcs_t;
// max buffer size for printed messages
#define MAX_LOGMSG_LEN 1024
// Meta Utility Function table type.
typedef struct meta_util_funcs_s {
void (*pfnLogConsole) (plid_t plid, const char *szFormat, ...);
void (*pfnLogMessage) (plid_t plid, const char *szFormat, ...);
void (*pfnLogError) (plid_t plid, const char *szFormat, ...);
void (*pfnLogDeveloper) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSay) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, const char *szFormat, ...);
void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, const char *szFormat, va_list ap);
int (*pfnCallGameEntity) (plid_t plid, const char *entStr, entvars_t *pev);
int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size);
const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size);
const char *(*pfnGetPluginPath) (plid_t plid);
const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag);
int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
const char *(*pfnIsQueryingClienCVar_t) (plid_t plid, const edict_t *player);
int (*pfnMakeRequestID) (plid_t plid);
void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, gamefuncs_t **pdll, newgamefuncs_t **pnewdll);
} mutil_funcs_t;
typedef struct {
gamefuncs_t *dllapi_table;
newgamefuncs_t *newapi_table;
} gamedll_funcs_t;
extern gamedll_funcs_t *gpGamedllFuncs;
extern mutil_funcs_t *gpMetaUtilFuncs;
extern metamod_funcs_t gMetaFunctionTable;
#define MDLL_FUNC gpGamedllFuncs->dllapi_table
#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit
#define MDLL_Spawn MDLL_FUNC->pfnSpawn
#define MDLL_Think MDLL_FUNC->pfnThink
#define MDLL_Use MDLL_FUNC->pfnUse
#define MDLL_Touch MDLL_FUNC->pfnTouch
#define MDLL_Blocked MDLL_FUNC->pfnBlocked
#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue
#define MDLL_Save MDLL_FUNC->pfnSave
#define MDLL_Restore MDLL_FUNC->pfnRestore
#define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox
#define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields
#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields
#define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState
#define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState
#define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState
#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect
#define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect
#define MDLL_ClientKill MDLL_FUNC->pfnClientKill
#define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer
#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand
#define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged
#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate
#define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate
#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink
#define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink
#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame
#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel
#define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel
#define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription
#define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization
#define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect
#define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect
#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink
#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error
#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move
#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init
#define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType
#define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility
#define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData
#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack
#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline
#define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders
#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData
#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart
#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd
#define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket
#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds
#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines
#define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile
#define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation
#define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity)
#define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID)
#endif

View file

@ -1,229 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
// stripped down version of com_model.h & pm_info.h
#ifndef MODEL_H
#define MODEL_H
typedef struct mplane_s {
vec3_t normal;
float dist;
byte type; // for fast side tests
byte signbits; // signx + (signy<<1) + (signz<<1)
byte pad[2];
} mplane_t;
typedef struct {
vec3_t position;
} mvertex_t;
typedef struct {
float vecs[2][4]; // [s/t] unit vectors in world space [i][3] is the s/t offset relative to the origin s or t = dot( 3Dpoint, vecs[i] ) + vecs[i][3]
float mipadjust; // mipmap limits for very small surfaces
struct texture_t *texture;
int flags; // sky or slime, no lightmap or 256 subdivision
} mtexinfo_t;
typedef struct mnode_hw_s {
int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current
float minmaxs[6]; // for bounding box culling
struct mnode_s *parent;
mplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
} mnode_hw_t;
typedef struct mnode_s {
int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current
short minmaxs[6]; // for bounding box culling
struct mnode_s *parent;
mplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
} mnode_t;
typedef struct {
byte r, g, b;
} color24;
typedef struct msurface_hw_s {
int visframe; // should be drawn when node is crossed
mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
short texturemins[2];
short extents[2];
int light_s, light_t; // gl lightmap coordinates
struct glpoly_t *polys; // multiple if warped
struct msurface_s *texturechain;
mtexinfo_t *texinfo;
int dlightframe; // last frame the surface was checked by an animated light
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
int lightmaptexturenum;
byte styles[MAXLIGHTMAPS];
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
qboolean cached_dlight; // true if dynamic light in cache
color24 *samples; // note: this is the actual lightmap data for this surface
struct decal_t *pdecals;
} msurface_hw_t;
typedef struct msurface_s {
int visframe; // should be drawn when node is crossed
int dlightframe; // last frame the surface was checked by an animated light
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
struct surfcache_s *cachespots[4]; // surface generation data
short texturemins[2]; // smallest s/t position on the surface.
short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces
mtexinfo_t *texinfo;
byte styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights no one surface can be effected by more than 4 animated lights.
color24 *samples;
struct decal_t *pdecals;
} msurface_t;
typedef struct cache_user_s {
void *data; // extradata
} cache_user_t;
typedef struct hull_s {
struct dclipnode_t *clipnodes;
mplane_t *planes;
int firstclipnode;
int lastclipnode;
vec3_t clip_mins;
vec3_t clip_maxs;
} hull_t;
typedef struct model_s {
char name[64]; // model name
qboolean needload; // bmodels and sprites don't cache normally
int type; // model type
int numframes; // sprite's framecount
byte *mempool; // private mempool (was synctype)
int flags; // hl compatibility
vec3_t mins, maxs; // bounding box at angles '0 0 0'
float radius;
int firstmodelsurface;
int nummodelsurfaces;
int numsubmodels;
struct dmodel_t *submodels; // or studio animations
int numplanes;
mplane_t *planes;
int numleafs; // number of visible leafs, not counting 0
struct mleaf_t *leafs;
int numvertexes;
mvertex_t *vertexes;
int numedges;
struct medge_t *edges;
int numnodes;
mnode_t *nodes;
int numtexinfo;
mtexinfo_t *texinfo;
int numsurfaces;
msurface_t *surfaces;
int numsurfedges;
int *surfedges;
int numclipnodes;
struct dclipnode_t *clipnodes;
int nummarksurfaces;
msurface_t **marksurfaces;
hull_t hulls[MAX_MAP_HULLS];
int numtextures;
texture_t **textures;
byte *visdata;
color24 *lightdata;
char *entities;
cache_user_t cache; // only access through Mod_Extradata
} model_t;
struct lightstyle_t {
int length;
char map[MAX_LIGHTSTYLES];
};
typedef struct physent_s {
char name[32]; // name of model, or "player" or "world".
int player;
vec3_t origin; // model's origin in world coordinates.
struct model_s *model; // only for bsp models
} physent_t;
typedef struct playermove_s {
int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly.
qboolean server; // For debugging, are we running physics code on server side?
qboolean multiplayer; // 1 == multiplayer server
float time; // realtime on host, for reckoning duck timing
float frametime; // Duration of this frame
vec3_t forward, right, up; // Vectors for angles
vec3_t origin; // Movement origin.
vec3_t angles; // Movement view angles.
vec3_t oldangles; // Angles before movement view angles were looked at.
vec3_t velocity; // Current movement direction.
vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge.
vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g.
vec3_t view_ofs; // Our eye position.
float flDuckTime; // Time we started duck
qboolean bInDuck; // In process of ducking or ducked already?
int flTimeStepSound; // Next time we can play a step sound
int iStepLeft;
float flFallVelocity;
vec3_t punchangle;
float flSwimTime;
float flNextPrimaryAttack;
int effects; // MUZZLE FLASH, e.g.
int flags; // FL_ONGROUND, FL_DUCKING, etc.
int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull
float gravity; // Our current gravity and friction.
float friction;
int oldbuttons; // Buttons last usercmd
float waterjumptime; // Amount of time left in jumping out of water cycle.
qboolean dead; // Are we a dead player?
int deadflag;
int spectator; // Should we use spectator physics model?
int movetype; // Our movement type, NOCLIP, WALK, FLY
int onground;
int waterlevel;
int watertype;
int oldwaterlevel;
char sztexturename[256];
char chtexturetype;
float maxspeed;
float clientmaxspeed; // Player specific maxspeed
int iuser1;
int iuser2;
int iuser3;
int iuser4;
float fuser1;
float fuser2;
float fuser3;
float fuser4;
vec3_t vuser1;
vec3_t vuser2;
vec3_t vuser3;
vec3_t vuser4;
int numphysent;
physent_t physents[MAX_PHYSENTS];
} playermove_t;
#endif

View file

@ -1,161 +0,0 @@
/*
physint.h - Server Physics Interface
Copyright (C) 2011 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef PHYSINT_H
#define PHYSINT_H
#define SV_PHYSICS_INTERFACE_VERSION 6
#define STRUCT_FROM_LINK( l, t, m ) ((t *)((byte *)l - (int)&(((t *)0)->m)))
#define EDICT_FROM_AREA( l ) STRUCT_FROM_LINK( l, edict_t, area )
// values that can be returned with pfnServerState
#define SERVER_DEAD 0
#define SERVER_LOADING 1
#define SERVER_ACTIVE 2
// LUMP reading errors
#define LUMP_LOAD_OK 0
#define LUMP_LOAD_COULDNT_OPEN 1
#define LUMP_LOAD_BAD_HEADER 2
#define LUMP_LOAD_BAD_VERSION 3
#define LUMP_LOAD_NO_EXTRADATA 4
#define LUMP_LOAD_INVALID_NUM 5
#define LUMP_LOAD_NOT_EXIST 6
#define LUMP_LOAD_MEM_FAILED 7
#define LUMP_LOAD_CORRUPTED 8
// LUMP saving errors
#define LUMP_SAVE_OK 0
#define LUMP_SAVE_COULDNT_OPEN 1
#define LUMP_SAVE_BAD_HEADER 2
#define LUMP_SAVE_BAD_VERSION 3
#define LUMP_SAVE_NO_EXTRADATA 4
#define LUMP_SAVE_INVALID_NUM 5
#define LUMP_SAVE_ALREADY_EXIST 6
#define LUMP_SAVE_NO_DATA 7
#define LUMP_SAVE_CORRUPTED 8
typedef struct areanode_s {
int axis; // -1 = leaf node
float dist;
struct areanode_s *children[2];
link_t trigger_edicts;
link_t solid_edicts;
link_t portal_edicts;
} areanode_t;
typedef struct server_physics_api_s {
// unlink edict from old position and link onto new
void (*pfnLinkEdict) (edict_t *ent, qboolean touch_triggers);
double (*pfnGetServerTime)(void); // unclamped
double (*pfnGetFrameTime)(void); // unclamped
void *(*pfnGetModel)(int modelindex);
areanode_t *(*pfnGetHeadnode)(void); // AABB tree for all physic entities
int (*pfnServerState)(void);
void (*pfnHost_Error)(const char *error, ...); // cause Host Error
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
struct triangleapi_s *pTriAPI; // draw coliisions etc. Only for local system
// draw debug messages (must be called from DrawOrthoTriangles). Only for local system
int (*pfnDrawConsoleString)(int x, int y, char *string);
void (*pfnDrawSetTextColor)(float r, float g, float b);
void (*pfnDrawConsoleStringLen)(const char *string, int *length, int *height);
void (*Con_NPrintf)(int pos, const char *fmt, ...);
void (*Con_NXPrintf)(struct con_nprint_s *info, const char *fmt, ...);
const char *(*pfnGetLightStyle)(int style); // read custom appreance for selected lightstyle
void (*pfnUpdateFogSettings)(unsigned int packed_fog);
char **(*pfnGetFilesList)(const char *pattern, int *numFiles, int gamedironly);
struct msurface_s *(*pfnTraceSurface)(edict_t *pTextureEntity, const float *v1, const float *v2);
const byte *(*pfnGetTextureData)(unsigned int texnum);
// static allocations
void *(*pfnMemAlloc)(size_t cb, const char *filename, const int fileline);
void (*pfnMemFree)(void *mem, const char *filename, const int fileline);
// trace & contents
int (*pfnMaskPointContents)(const float *pos, int groupmask);
struct trace_t (*pfnTrace)(const float *p0, float *mins, float *maxs, const float *p1, int type, edict_t *e);
struct trace_t (*pfnTraceNoEnts)(const float *p0, float *mins, float *maxs, const float *p1, int type, edict_t *e);
int (*pfnBoxInPVS)(const float *org, const float *boxmins, const float *boxmaxs);
// message handler (missed function to write raw bytes)
void (*pfnWriteBytes)(const byte *bytes, int count);
// BSP lump management
int (*pfnCheckLump)(const char *filename, const int lump, int *lumpsize);
int (*pfnReadLump)(const char *filename, const int lump, void **lumpdata, int *lumpsize);
int (*pfnSaveLump)(const char *filename, const int lump, void *lumpdata, int lumpsize);
// FS tools
int (*pfnSaveFile)(const char *filename, const void *data, int len);
const byte *(*pfnLoadImagePixels)(const char *filename, int *width, int *height);
const char *(*pfnGetModelName)(int modelindex);
} server_physics_api_t;
// physic callbacks
typedef struct physics_interface_s {
int version;
// passed through pfnCreate (0 is attempt to create, -1 is reject)
int (*SV_CreateEntity)(edict_t *pent, const char *szName);
// run custom physics for each entity (return 0 to use built-in engine physic)
int (*SV_PhysicsEntity)(edict_t *pEntity);
// spawn entities with internal mod function e.g. for re-arrange spawn order (0 - use engine parser, 1 - use mod parser)
int (*SV_LoadEntities)(const char *mapname, char *entities);
// update conveyor belt for clients
void (*SV_UpdatePlayerBaseVelocity)(edict_t *ent);
// The game .dll should return 1 if save game should be allowed
int (*SV_AllowSaveGame)(void);
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
// override trigger area checking and touching
int (*SV_TriggerTouch)(edict_t *pent, edict_t *trigger);
// some engine features can be enabled only through this function
unsigned int (*SV_CheckFeatures)(void);
// used for draw debug collisions for custom physic engine etc
void (*DrawDebugTriangles)(void);
// used for draw debug overlay (textured)
void (*DrawNormalTriangles)(void);
// used for draw debug messages (2d mode)
void (*DrawOrthoTriangles)(void);
// tracing entities with SOLID_CUSTOM mode on a server (not used by pmove code)
void (*ClipMoveToEntity)(edict_t *ent, const float *start, float *mins, float *maxs, const float *end, trace_t *trace);
// tracing entities with SOLID_CUSTOM mode on a server (only used by pmove code)
void (*ClipPMoveToEntity)(struct physent_s *pe, const float *start, float *mins, float *maxs, const float *end, struct pmtrace_s *tr);
// called at end the frame of SV_Physics call
void (*SV_EndFrame)(void);
// obsolete
void (*pfnPrepWorldFrame)(void);
// called through save\restore process
void (*pfnCreateEntitiesInRestoreList)(SAVERESTOREDATA *pSaveData, int levelMask, qboolean create_world);
// allocate custom string (e.g. using user implementation of stringtable, not engine strings)
string_t (*pfnAllocString)(const char *szValue);
// make custom string (e.g. using user implementation of stringtable, not engine strings)
string_t (*pfnMakeString)(const char *szValue);
// read custom string (e.g. using user implementation of stringtable, not engine strings)
const char *(*pfnGetString)(string_t iString);
// helper for restore custom decals that have custom message (e.g. Paranoia)
int (*pfnRestoreDecal)(struct decallist_s *entry, edict_t *pEdict, qboolean adjacent);
// handle custom trigger touching for player
void (*PM_PlayerTouch)(struct playermove_s *ppmove, edict_t *client);
// alloc or destroy model custom data (called only for dedicated servers, otherwise using an client version)
void (*Mod_ProcessUserData)(struct model_s *mod, qboolean create, const byte *buffer);
// select BSP-hull for trace with specified mins\maxs
void *(*SV_HullForBsp)(edict_t *ent, const float *mins, const float *maxs, float *offset);
// handle player custom think function
int (*SV_PlayerThink)(edict_t *ent, float frametime, double time);
} physics_interface_t;
#endif//PHYSINT_H

View file

@ -1,213 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#pragma once
typedef struct {
float time;
float frametime;
float force_retouch;
string_t mapname;
string_t startspot;
float deathmatch;
float coop;
float teamplay;
float serverflags;
float found_secrets;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
edict_t *trace_ent;
float trace_inopen;
float trace_inwater;
int trace_hitgroup;
int trace_flags;
int msg_entity;
int cdAudioTrack;
int maxClients;
int maxEntities;
const char *pStringBase;
void *pSaveData;
vec3_t vecLandmarkOffset;
} globalvars_t;
typedef struct entvars_s {
string_t classname;
string_t globalname;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t basevelocity;
vec3_t clbasevelocity; // Base velocity that was passed in to server physics so
// client can predict conveyors correctly. Server zeroes it, so we need to store here, too.
vec3_t movedir;
vec3_t angles; // Model angles
vec3_t avelocity; // angle velocity (degrees per second)
vec3_t punchangle; // auto-decaying view angle adjustment
vec3_t v_angle; // Viewing angle (player only)
// For parametric entities
vec3_t endpos;
vec3_t startpos;
float impacttime;
float starttime;
int fixangle; // 0:nothing, 1:force view angles, 2:add avelocity
float idealpitch;
float pitch_speed;
float ideal_yaw;
float yaw_speed;
int modelindex;
string_t model;
string_t viewmodel; // player's viewmodel
string_t weaponmodel; // what other players see
vec3_t absmin; // BB max translated to world coord
vec3_t absmax; // BB max translated to world coord
vec3_t mins; // local BB min
vec3_t maxs; // local BB max
vec3_t size; // maxs - mins
float ltime;
float nextthink;
int movetype;
int solid;
int skin;
int body; // sub-model selection for studiomodels
int effects;
float gravity; // % of "normal" gravity
float friction; // inverse elasticity of MOVETYPE_BOUNCE
int light_level;
int sequence; // animation sequence
int gaitsequence; // movement animation sequence for player (0 for none)
float frame; // % playback position in animation sequences (0..255)
float animtime; // world time when frame was set
float framerate; // animation playback rate (-8x to 8x)
uint8_t controller[4]; // bone controller setting (0..255)
uint8_t blending[2]; // blending amount between sub-sequences (0..255)
float scale; // sprite rendering scale (0..255)
int rendermode;
float renderamt;
vec3_t rendercolor;
int renderfx;
float health;
float frags;
int weapons; // bit mask for available weapons
float takedamage;
int deadflag;
vec3_t view_ofs; // eye position
int button;
int impulse;
edict_t *chain; // Entity pointer when linked into a linked list
edict_t *dmg_inflictor;
edict_t *enemy;
edict_t *aiment; // entity pointer when MOVETYPE_FOLLOW
edict_t *owner;
edict_t *groundentity;
int spawnflags;
int flags;
int colormap; // lowbyte topcolor, highbyte bottomcolor
int team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
int waterlevel;
int watertype;
string_t target;
string_t targetname;
string_t netname;
string_t message;
float dmg_take;
float dmg_save;
float dmg;
float dmgtime;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
float speed;
float air_finished;
float pain_finished;
float radsuit_finished;
edict_t *pContainingEntity;
int playerclass;
float maxspeed;
float fov;
int weaponanim;
int pushmsec;
int bInDuck;
int flTimeStepSound;
int flSwimTime;
int flDuckTime;
int iStepLeft;
float flFallVelocity;
int gamestate;
int oldbuttons;
int groupinfo;
// For mods
int iuser1;
int iuser2;
int iuser3;
int iuser4;
float fuser1;
float fuser2;
float fuser3;
float fuser4;
vec3_t vuser1;
vec3_t vuser2;
vec3_t vuser3;
vec3_t vuser4;
edict_t *euser1;
edict_t *euser2;
edict_t *euser3;
edict_t *euser4;
} entvars_t;

View file

@ -1,129 +0,0 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef SDKUTIL_H
#define SDKUTIL_H
extern globalvars_t *globals;
extern enginefuncs_t engfuncs;
extern gamefuncs_t dllapi;
// Dot products for view cone checking
#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
typedef enum { ignore_monsters = 1, dont_ignore_monsters = 0, missile = 2 } IGNORE_MONSTERS;
typedef enum { ignore_glass = 1, dont_ignore_glass = 0 } IGNORE_GLASS;
typedef enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 } HULL;
typedef struct hudtextparms_s {
float x;
float y;
int effect;
uint8_t r1, g1, b1, a1;
uint8_t r2, g2, b2, a2;
float fadeinTime;
float fadeoutTime;
float holdTime;
float fxTime;
int channel;
} hudtextparms_t;
#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation
#define AMBIENT_SOUND_EVERYWHERE 1
#define AMBIENT_SOUND_SMALLRADIUS 2
#define AMBIENT_SOUND_MEDIUMRADIUS 4
#define AMBIENT_SOUND_LARGERADIUS 8
#define AMBIENT_SOUND_START_SILENT 16
#define AMBIENT_SOUND_NOT_LOOPING 32
#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements
#define SND_SPAWNING (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients
#define SND_STOP (1 << 5) // duplicated in protocol.h stop sound
#define SND_CHANGE_VOL (1 << 6) // duplicated in protocol.h change sound vol
#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch
#define LFO_SQUARE 1
#define LFO_TRIANGLE 2
#define LFO_RANDOM 3
// func_rotating
#define SF_BRUSH_ROTATE_Y_AXIS 0
#define SF_BRUSH_ROTATE_INSTANT 1
#define SF_BRUSH_ROTATE_BACKWARDS 2
#define SF_BRUSH_ROTATE_Z_AXIS 4
#define SF_BRUSH_ROTATE_X_AXIS 8
#define SF_PENDULUM_AUTO_RETURN 16
#define SF_PENDULUM_PASSABLE 32
#define SF_BRUSH_ROTATE_SMALLRADIUS 128
#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256
#define SF_BRUSH_ROTATE_LARGERADIUS 512
#define PUSH_BLOCK_ONLY_X 1
#define PUSH_BLOCK_ONLY_Y 2
#define VEC_HULL_MIN Vector(-16, -16, -36)
#define VEC_HULL_MAX Vector(16, 16, 36)
#define VEC_HUMAN_HULL_MIN Vector(-16, -16, 0)
#define VEC_HUMAN_HULL_MAX Vector(16, 16, 72)
#define VEC_HUMAN_HULL_DUCK Vector(16, 16, 36)
#define VEC_VIEW Vector(0, 0, 28)
#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18)
#define VEC_DUCK_HULL_MAX Vector(16, 16, 18)
#define VEC_DUCK_VIEW Vector(0, 0, 12)
#define SVC_TEMPENTITY 23
#define SVC_CENTERPRINT 26
#define SVC_INTERMISSION 30
#define SVC_CDTRACK 32
#define SVC_WEAPONANIM 35
#define SVC_ROOMTYPE 37
#define SVC_DIRECTOR 51
// triggers
#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger
#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger
#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger
// func breakable
#define SF_BREAK_TRIGGER_ONLY 1 // may only be broken by trigger
#define SF_BREAK_TOUCH 2 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 4 // can be broken by a player standing on it
#define SF_BREAK_CROWBAR 256 // instant break if hit with crowbar
// func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 128
#define SF_LIGHT_START_OFF 1
#define SPAWNFLAG_NOMESSAGE 1
#define SPAWNFLAG_NOTOUCH 1
#define SPAWNFLAG_DROIDONLY 4
#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons)
#define TELE_PLAYER_ONLY 1
#define TELE_SILENT 2
#define SF_TRIG_PUSH_ONCE 1
#endif

1
ext/linkage Submodule

@ -0,0 +1 @@
Subproject commit a8117ca144f5652974d3eb3210396138a907a980

View file

@ -44,7 +44,7 @@ private:
Array <Array <ChatterItem>> m_chatter {};
Array <BotName> m_botNames {};
Array <Keywords> m_replies {};
Array <ChatKeywords> m_replies {};
SmallArray <WeaponInfo> m_weapons {};
SmallArray <WeaponProp> m_weaponProps {};
@ -170,7 +170,7 @@ public:
}
// get's the replies array
Array <Keywords> &getReplies () {
Array <ChatKeywords> &getReplies () {
return m_replies;
}

View file

@ -90,7 +90,7 @@ public:
private:
const char *allocStr (const char *str) const {
return STRING (engfuncs.pfnAllocString (str));
return string_t::from (engfuncs.pfnAllocString (str));
}
public:
@ -159,7 +159,7 @@ public:
void testModel (const Vector &start, const Vector &end, int hullNumber, edict_t *entToHit, TraceResult *ptr);
// trace line with channel, but allows us to store last traceline bot has fired, saving us some cpu cycles
bool testLineChannel (TraceChannel channel, const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult &result);
//bool testLineChannel (TraceChannel channel, const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult &result);
// test line
void testHull (const Vector &start, const Vector &end, int ignoreFlags, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr);
@ -389,7 +389,7 @@ public:
// prints center message to specified player
template <typename ...Args> void clientPrint (edict_t *ent, const char *fmt, Args &&...args) {
if (isNullEntity (ent)) {
if (isNullEntity (ent) || ent == getLocalEntity ()) {
print (fmt, cr::forward <Args> (args)...);
return;
}
@ -398,7 +398,7 @@ public:
// prints message to client console
template <typename ...Args> void centerPrint (edict_t *ent, const char *fmt, Args &&...args) {
if (isNullEntity (ent)) {
if (isNullEntity (ent) || ent == getLocalEntity ()) {
print (fmt, cr::forward <Args> (args)...);
return;
}
@ -407,7 +407,7 @@ public:
};
// simplify access for console variables
class ConVar final : public DenyCopying {
class ConVar final : public NonCopyable {
public:
cvar_t *ptr;

View file

@ -309,7 +309,7 @@ private:
ThreadPool m_botWorker;
public:
BotThreadWorker () = default;
explicit BotThreadWorker () = default;
~BotThreadWorker () = default;
public:
@ -322,7 +322,7 @@ public:
fn (); // no threads, no fun, just run task in current thread
return;
}
m_botWorker.enqueue (cr::forward <F> (fn));
m_botWorker.enqueue (cr::move (fn));
}
};

View file

@ -51,7 +51,7 @@ public:
// bot heuristic functions for astar planner
class Heuristic final {
public:
using Func = Lambda <float (int, int, int)>;
using Func = float (*) (int, int, int);
public:
// least kills and number of nodes to goal for a team
@ -84,7 +84,7 @@ public:
};
// A* algorithm for bots
class AStarAlgo final : public DenyCopying {
class AStarAlgo final : public NonCopyable {
public:
using HeuristicFn = Heuristic::Func;
@ -137,6 +137,9 @@ public:
m_constructedPath.reserve (getMaxLength ());
m_smoothedPath.reserve (getMaxLength ());
m_constructedPath.shrink ();
m_smoothedPath.shrink ();
}
// set the g heuristic

View file

@ -17,31 +17,54 @@
// simple class for bot internal information
class Product final : public Singleton <Product> {
public:
explicit constexpr Product () = default;
~Product () = default;
public:
struct Build {
StringRef hash { MODULE_COMMIT_COUNT };
StringRef count { MODULE_COMMIT_HASH };
StringRef author { MODULE_AUTHOR };
StringRef machine { MODULE_MACHINE };
StringRef compiler { MODULE_COMPILER };
StringRef id { MODULE_BUILD_ID };
static constexpr StringRef hash { MODULE_COMMIT_COUNT };
static constexpr StringRef count { MODULE_COMMIT_HASH };
static constexpr StringRef author { MODULE_AUTHOR };
static constexpr StringRef machine { MODULE_MACHINE };
static constexpr StringRef compiler { MODULE_COMPILER };
static constexpr StringRef id { MODULE_BUILD_ID };
} build {};
public:
StringRef name { "YaPB" };
StringRef year { &__DATE__[7] };
StringRef author { "YaPB Project" };
StringRef email { "yapb@jeefo.net" };
StringRef url { "https://yapb.jeefo.net/" };
StringRef download { "yapb.jeefo.net" };
StringRef folder { "yapb" };
StringRef logtag { "YB" };
StringRef dtime { __DATE__ " " __TIME__ };
StringRef date { __DATE__ };
StringRef version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
StringRef cmdPri { "yb" };
StringRef cmdSec { "yapb" };
static constexpr StringRef name { "YaPB" };
static constexpr StringRef nameLower { "yapb" };
static constexpr StringRef year { &__DATE__[7] };
static constexpr StringRef author { "YaPB Project" };
static constexpr StringRef email { "yapb@jeefo.net" };
static constexpr StringRef url { "https://yapb.jeefo.net/" };
static constexpr StringRef download { "yapb.jeefo.net" };
static constexpr StringRef logtag { "YB" };
static constexpr StringRef dtime { __DATE__ " " __TIME__ };
static constexpr StringRef date { __DATE__ };
static constexpr StringRef version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
static constexpr StringRef cmdPri { "yb" };
static constexpr StringRef cmdSec { "yapb" };
};
class Folders final : public Singleton <Folders> {
public:
explicit constexpr Folders () = default;
~Folders () = default;
public:
static constexpr StringRef bot { "yapb" };
static constexpr StringRef addons { "addons" };
static constexpr StringRef config { "conf" };
static constexpr StringRef data { "data" };
static constexpr StringRef lang { "lang" };
static constexpr StringRef logs { "logs" };
static constexpr StringRef train { "train" };
static constexpr StringRef graph { "graph" };
static constexpr StringRef podbot { "pwf" };
static constexpr StringRef ebot { "ewp" };
};
// expose product info
CR_EXPOSE_GLOBAL_SINGLETON (Product, product);
CR_EXPOSE_GLOBAL_SINGLETON (Folders, folders);

View file

@ -8,7 +8,7 @@
#pragma once
// storage file magic (podbot)
constexpr char kPodbotMagic[8] = "PODWAY!";
constexpr char kPodbotMagic[8] = { 'P', 'O', 'D', 'W', 'A', 'Y', '!', kNullChar };
constexpr int32_t kStorageMagic = 0x59415042; // storage magic for yapb-data files
constexpr int32_t kStorageMagicUB = 0x544f4255; //support also the fork format (merged back into yapb)

View file

@ -55,7 +55,7 @@ public:
bool isPlayerVIP (edict_t *ent);
// opens config helper
bool openConfig (const char *fileName, const char *errorIfNotExists, MemFile *outFile, bool languageDependant = false);
bool openConfig (StringRef fileName, StringRef errorIfNotExists, MemFile *outFile, bool languageDependant = false);
// nearest player search helper
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);

View file

@ -35,7 +35,7 @@ private:
float m_notifyMsgTimestamp {};
public:
GraphVistable () = default;
explicit GraphVistable () = default;
~GraphVistable () = default;
public:

View file

@ -7,12 +7,12 @@
#pragma once
#include <hlsdk/extdll.h>
#include <hlsdk/metamod.h>
#include <hlsdk/physint.h>
#include <crlib/crlib.h>
#include <linkage/goldsrc.h>
#include <linkage/metamod.h>
#include <linkage/physint.h>
// use all the cr-library
using namespace cr;
@ -405,13 +405,6 @@ CR_DECLARE_SCOPED_ENUM (Visibility,
None = 0
)
// channel for skip traceline
CR_DECLARE_SCOPED_ENUM (TraceChannel,
Enemy = 0,
Body,
Num
)
// frustum sides
CR_DECLARE_SCOPED_ENUM (FrustumSide,
Top = 0,
@ -424,53 +417,54 @@ CR_DECLARE_SCOPED_ENUM (FrustumSide,
)
// some hardcoded desire defines used to override calculated ones
namespace TaskPri {
static constexpr float Normal { 35.0f };
static constexpr float Pause { 36.0f };
static constexpr float Camp { 37.0f };
static constexpr float Spraypaint { 38.0f };
static constexpr float FollowUser { 39.0f };
static constexpr float MoveToPosition { 50.0f };
static constexpr float DefuseBomb { 89.0f };
static constexpr float PlantBomb { 89.0f };
static constexpr float Attack { 90.0f };
static constexpr float SeekCover { 91.0f };
static constexpr float Hide { 92.0f };
static constexpr float Throw { 99.0f };
static constexpr float DoubleJump { 99.0f };
static constexpr float Blind { 100.0f };
static constexpr float ShootBreakable { 100.0f };
static constexpr float EscapeFromBomb { 100.0f };
}
struct TaskPri {
static constexpr auto Normal { 35.0f };
static constexpr auto Pause { 36.0f };
static constexpr auto Camp { 37.0f };
static constexpr auto Spraypaint { 38.0f };
static constexpr auto FollowUser { 39.0f };
static constexpr auto MoveToPosition { 50.0f };
static constexpr auto DefuseBomb { 89.0f };
static constexpr auto PlantBomb { 89.0f };
static constexpr auto Attack { 90.0f };
static constexpr auto SeekCover { 91.0f };
static constexpr auto Hide { 92.0f };
static constexpr auto Throw { 99.0f };
static constexpr auto DoubleJump { 99.0f };
static constexpr auto Blind { 100.0f };
static constexpr auto ShootBreakable { 100.0f };
static constexpr auto EscapeFromBomb { 100.0f };
};
constexpr float kInfiniteDistance = 9999999.0f;
constexpr float kGrenadeCheckTime = 0.6f;
constexpr float kSprayDistance = 260.0f;
constexpr float kDoubleSprayDistance = kSprayDistance * 2;
constexpr float kMaxChatterRepeatInterval = 99.0f;
constexpr auto kInfiniteDistance = 9999999.0f;
constexpr auto kGrenadeCheckTime = 0.6f;
constexpr auto kSprayDistance = 260.0f;
constexpr auto kDoubleSprayDistance = kSprayDistance * 2;
constexpr auto kMaxChatterRepeatInterval = 99.0f;
constexpr int kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
constexpr int kMaxWeapons = 32;
constexpr int kNumWeapons = 26;
constexpr int kMaxCollideMoves = 3;
constexpr int kGameMaxPlayers = 32;
constexpr int kGameTeamNum = 2;
constexpr int kInvalidNodeIndex = -1;
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
constexpr auto kMaxWeapons = 32;
constexpr auto kNumWeapons = 26;
constexpr auto kMaxCollideMoves = 3;
constexpr auto kGameMaxPlayers = 32;
constexpr auto kGameTeamNum = 2;
constexpr auto kInvalidNodeIndex = -1;
constexpr auto kConfigExtension = "cfg";
// weapon masks
constexpr auto kPrimaryWeaponMask = (cr::bit (Weapon::XM1014) | cr::bit (Weapon::M3) | cr::bit (Weapon::MAC10) | cr::bit (Weapon::UMP45) | cr::bit (Weapon::MP5) | cr::bit (Weapon::TMP) | cr::bit (Weapon::P90) | cr::bit (Weapon::AUG) | cr::bit (Weapon::M4A1) | cr::bit (Weapon::SG552) | cr::bit (Weapon::AK47) | cr::bit (Weapon::Scout) | cr::bit (Weapon::SG550) | cr::bit (Weapon::AWP) | cr::bit (Weapon::G3SG1) | cr::bit (Weapon::M249) | cr::bit (Weapon::Famas) | cr::bit (Weapon::Galil));
constexpr auto kSecondaryWeaponMask = (cr::bit (Weapon::P228) | cr::bit (Weapon::Elite) | cr::bit (Weapon::USP) | cr::bit (Weapon::Glock18) | cr::bit (Weapon::Deagle) | cr::bit (Weapon::FiveSeven));
// links keywords and replies together
struct Keywords {
struct ChatKeywords {
StringArray keywords;
StringArray replies;
StringArray usedReplies;
public:
Keywords () = default;
ChatKeywords () = default;
Keywords (const StringArray &keywords, const StringArray &replies) {
ChatKeywords (const StringArray &keywords, const StringArray &replies) {
this->keywords.clear ();
this->replies.clear ();
this->usedReplies.clear ();
@ -589,7 +583,7 @@ struct ChatCollection {
#include <graph.h>
// this structure links nodes returned from pathfinder
class PathWalk final : public DenyCopying {
class PathWalk final : public NonCopyable {
private:
size_t m_cursor {};
size_t m_length {};
@ -675,9 +669,6 @@ private:
uint32_t m_aimFlags {}; // aiming conditions
uint32_t m_currentTravelFlags {}; // connection flags like jumping
int m_traceSkip[TraceChannel::Num] {}; // trace need to be skipped?
int m_messageQueue[32] {}; // stack for messages
int m_oldButtons {}; // our old buttons
int m_reloadState {}; // current reload state
int m_voicePitch {}; // bot voice pitch
@ -701,6 +692,7 @@ private:
float m_prevTime {}; // time previously checked movement speed
float m_heavyTimestamp {}; // is it time to execute heavy-weight functions
float m_prevSpeed {}; // speed some frames before
float m_prevVelocity {}; // velocity some frames before
float m_timeDoorOpen {}; // time to next door open check
float m_lastChatTime {}; // time bot last chatted
float m_timeLogoSpray {}; // time bot last spray logo
@ -749,6 +741,7 @@ private:
float m_playServerTime {}; // time bot spent in the game
float m_changeViewTime {}; // timestamp to change look at while at freezetime
float m_breakableTime {}; // breakeble acquired time
float m_stuckTimestamp {}; // last time was stuck
bool m_moveToGoal {}; // bot currently moving to goal??
bool m_isStuck {}; // bot is stuck
@ -770,6 +763,7 @@ private:
bool m_grenadeRequested {}; // bot requested change to grenade
bool m_needToSendWelcomeChat {}; // bot needs to greet people on server?
bool m_isCreature {}; // bot is not a player, but something else ? zombie ?
bool m_defuseNotified {}; // bot is notified about bomb defusion
Pickup m_pickupType {}; // type of entity which needs to be used/picked up
PathWalk m_pathWalk {}; // pointer to current node from path
@ -779,7 +773,6 @@ private:
FindPath m_pathType {}; // which pathfinder to use
uint8_t m_enemyParts {}; // visibility flags
uint16_t m_modelMask {}; // model mask bits
TraceResult m_lastTrace[TraceChannel::Num] {}; // last trace result
UniquePtr <class AStarAlgo> m_planner;
edict_t *m_pickupItem {}; // pointer to entity of item to use/pickup
@ -810,7 +803,6 @@ private:
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
Array <edict_t *> m_hostages {}; // pointer to used hostage entities
Array <int32_t> m_nodeHistory {}; // history of selected goals
Path *m_path {}; // pointer to the current path node
String m_chatBuffer {}; // space for strings (say text...)
@ -888,7 +880,6 @@ private:
bool checkChatKeywords (String &reply);
bool isReplyingToChat ();
bool isReachableNode (int index);
bool isBannedNode (int index);
bool updateLiftHandling ();
bool updateLiftStates ();
bool canRunHeavyWeight ();
@ -962,6 +953,7 @@ private:
void logicDuringFreezetime ();
void translateInput ();
void moveToGoal ();
void resetMovement ();
void normal_ ();
void spraypaint_ ();
@ -1193,7 +1185,7 @@ public:
bool isShieldDrawn ();
bool findNextBestNode ();
bool seesEntity (const Vector &dest, bool fromBody = false);
bool canSkipNextTrace (TraceChannel channel);
//bool canSkipNextTrace (TraceChannel channel);
int getAmmo ();
int getAmmo (int id);
@ -1242,16 +1234,6 @@ public:
return m_currentNodeIndex;
}
// set the last bot trace result
void setLastTraceResult (TraceChannel channel, TraceResult *traceResult) {
m_lastTrace[channel] = *traceResult;
}
// get the bot last trace result
TraceResult &getLastTraceResult (TraceChannel channel) {
return m_lastTrace[channel];
}
// is low on admmo on index?
bool isLowOnAmmo (const int index, const float factor) const;

View file

@ -247,7 +247,7 @@ sources = files(
# add the include directories
includes = include_directories([
'.', 'inc', 'ext', 'ext/crlib'
'.', 'inc', 'ext', 'ext/crlib', 'ext/linkage'
], is_system: true)
# if have git and on windows add windows-specific version info

View file

@ -765,6 +765,10 @@ void Bot::instantChatter (int type) {
MessageWriter msg;
int ownIndex = index ();
auto writeChatterSound = [&msg] (ChatterItem item) {
msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.str (), PATH_SEP, item.name));
};
for (auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || (client.ent->v.flags & FL_FAKECLIENT) || client.team != m_team) {
continue;
@ -774,11 +778,11 @@ void Bot::instantChatter (int type) {
if (pev->deadflag & DEAD_DYING) {
client.iconTimestamp[ownIndex] = game.time () + painSound.duration;
msg.writeString (strings.format ("%s/%s.wav", cv_chatter_path.str (), painSound.name));
writeChatterSound (painSound);
}
else if (!(pev->deadflag & DEAD_DEAD)) {
else if (m_notKilled) {
client.iconTimestamp[ownIndex] = game.time () + playbackSound.duration;
msg.writeString (strings.format ("%s/%s.wav", cv_chatter_path.str (), playbackSound.name));
writeChatterSound (playbackSound);
}
msg.writeShort (m_voicePitch).end ();
client.iconFlags[ownIndex] |= ClientFlags::Icon;
@ -1527,6 +1531,15 @@ void Bot::overrideConditions () {
// special handling for reloading
if (!bots.isRoundOver () && getCurrentTaskId () == Task::Normal && m_reloadState != Reload::None && m_isReloading && !isDucking () && !isInNarrowPlace ()) {
if (m_reloadState != Reload::None || m_isReloading) {
const auto maxClip = conf.findWeaponById (m_currentWeapon).maxClip;
const auto curClip = getAmmoInClip ();
// consider not reloading if full ammo in clip
if (curClip >= maxClip) {
m_isReloading = false;
}
}
if (m_seeEnemyTime + 2.5f < game.time () && (m_states & (Sense::SuspectEnemy | Sense::HearingEnemy))) {
m_moveSpeed = m_fearLevel > m_agressionLevel ? 0.0f : getShiftSpeed ();
m_navTimeset = game.time ();
@ -1550,7 +1563,7 @@ void Bot::syncUpdatePredictedIndex () {
auto currentNodeIndex = m_currentNodeIndex;
auto botOrigin = pev->origin;
if (lastEnemyOrigin.empty () || !vistab.isReady ()) {
if (lastEnemyOrigin.empty () || !vistab.isReady () || !util.isAlive (m_enemy)) {
wipePredict ();
return;
}
@ -1583,6 +1596,9 @@ void Bot::syncUpdatePredictedIndex () {
}
void Bot::updatePredictedIndex () {
if (m_lastEnemyOrigin.empty ()) {
return; // do not run task if no last enemy
}
worker.enqueue ([this] () {
syncUpdatePredictedIndex ();
});
@ -2651,11 +2667,6 @@ void Bot::update () {
kick ();
return;
}
pev->button = 0;
m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f;
m_moveAngles = nullptr;
m_canChooseAimDirection = true;
m_notKilled = util.isAlive (ent ());
@ -2714,6 +2725,9 @@ void Bot::update () {
else if (pev->maxspeed < 10.0f) {
logicDuringFreezetime ();
}
else if (!botMovement) {
resetMovement ();
}
runMovement ();
// delay next execution
@ -2826,6 +2840,8 @@ void Bot::logic () {
float movedDistance = 2.0f; // length of different vector (distance bot moved)
resetMovement ();
// increase reaction time
m_actualReactionTime += 0.3f;
@ -2977,6 +2993,7 @@ void Bot::logic () {
// save the previous speed (for checking if stuck)
m_prevSpeed = cr::abs (m_moveSpeed);
m_prevVelocity = cr::abs (pev->velocity.length2d ());
m_lastDamageType = -1; // reset damage
}
@ -3448,7 +3465,7 @@ Vector Bot::isBombAudible () {
}
// we hear bomb if length greater than radius
if (desiredRadius < pev->origin.distance2d (bombOrigin)) {
if (cr::sqrf (desiredRadius) < pev->origin.distanceSq2d (bombOrigin)) {
return bombOrigin;
}
return nullptr;
@ -3457,7 +3474,7 @@ Vector Bot::isBombAudible () {
uint8_t Bot::computeMsec () {
// estimate msec to use for this command based on time passed from the previous command
return static_cast <uint8_t> ((game.time () - m_lastCommandTime) * 1000.0f);
return static_cast <uint8_t> (cr::min (static_cast <int32_t> ((game.time () - m_lastCommandTime) * 1000.0f), 255));
}
bool Bot::canRunHeavyWeight () {
@ -3471,20 +3488,6 @@ bool Bot::canRunHeavyWeight () {
return false;
}
bool Bot::canSkipNextTrace (TraceChannel channel) {
// for optmization purposes skip every second traceline fired, this doesn't affect ai
// behaviour too much, but saves alot of cpu cycles.
constexpr auto kSkipTrace = 3;
// check if we're have to skip
if ((++m_traceSkip[channel] % kSkipTrace) == 0) {
m_traceSkip[channel] = 0;
return true;
}
return false;
}
void Bot::runMovement () {
// the purpose of this function is to compute, according to the specified computation
// method, the msec value which will be passed as an argument of pfnRunPlayerMove. This
@ -3761,7 +3764,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
}
float Bot::getShiftSpeed () {
if (getCurrentTaskId () == Task::SeekCover || isDucking () || (pev->button & IN_DUCK) || (m_oldButtons & IN_DUCK) || (m_currentTravelFlags & PathFlag::Jump) || (m_path != nullptr && m_pathFlags & NodeFlag::Ladder) || isOnLadder () || isInWater () || m_isStuck) {
if (getCurrentTaskId () == Task::SeekCover || isDucking () || (pev->button & IN_DUCK) || (m_oldButtons & IN_DUCK) || (m_currentTravelFlags & PathFlag::Jump) || (m_pathFlags & NodeFlag::Ladder) || isOnLadder () || isInWater () || m_isStuck) {
return pev->maxspeed;
}
return pev->maxspeed * 0.4f;

View file

@ -169,7 +169,7 @@ bool Bot::checkBodyParts (edict_t *target) {
else {
spot.z = target->v.origin.z - standFeet;
}
game.testLineChannel (TraceChannel::Enemy, eyes, spot, ignoreFlags, self, result);
game.testLine (eyes, spot, ignoreFlags, self, &result);
if (hitsTarget ()) {
m_enemyParts |= Visibility::Other;
@ -184,7 +184,7 @@ bool Bot::checkBodyParts (edict_t *target) {
Vector perp (-dir.y, dir.x, 0.0f);
spot = target->v.origin + Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0);
game.testLineChannel (TraceChannel::Enemy, eyes, spot, ignoreFlags, self, result);
game.testLine (eyes, spot, ignoreFlags, self, &result);
if (hitsTarget ()) {
m_enemyParts |= Visibility::Other;
@ -194,7 +194,7 @@ bool Bot::checkBodyParts (edict_t *target) {
}
spot = target->v.origin - Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0);
game.testLineChannel (TraceChannel::Enemy, eyes, spot, ignoreFlags, self, result);
game.testLine (eyes, spot, ignoreFlags, self, &result);
if (hitsTarget ()) {
m_enemyParts |= Visibility::Other;
@ -719,12 +719,9 @@ bool Bot::isPenetrableObstacle2 (const Vector &dest) {
bool Bot::isPenetrableObstacle3 (const Vector &dest) {
// this function returns if enemy can be shoot through some obstacle
if (m_isUsingGrenade || m_difficulty < Difficulty::Normal || !conf.findWeaponById (m_currentWeapon).penetratePower) {
return false;
}
auto power = conf.findWeaponById (m_currentWeapon).penetratePower;
if (power == 0) {
if (m_isUsingGrenade || m_difficulty < Difficulty::Normal || !power) {
return false;
}
TraceResult tr {};
@ -1218,7 +1215,7 @@ void Bot::attackMovement () {
};
auto strafeUpdateTime = [] () {
return game.time () + rg.get (0.5f, 1.0f);
return game.time () + rg.get (1.0f, 1.5f);
};
// to start strafing, we have to first figure out if the target is on the left side or right side
@ -1239,11 +1236,14 @@ void Bot::attackMovement () {
m_strafeSetTime = strafeUpdateTime ();
}
const bool wallOnRight = checkWallOnRight ();
const bool wallOnLeft = checkWallOnLeft ();
if (m_combatStrafeDir == Dodge::Right) {
if (!checkWallOnLeft ()) {
if (!wallOnLeft) {
m_strafeSpeed = -pev->maxspeed;
}
else if (!checkWallOnRight ()) {
else if (!wallOnRight) {
swapStrafeCombatDir ();
m_strafeSetTime = strafeUpdateTime ();
@ -1255,10 +1255,10 @@ void Bot::attackMovement () {
}
}
else {
if (!checkWallOnRight ()) {
if (!wallOnRight) {
m_strafeSpeed = pev->maxspeed;
}
else if (!checkWallOnLeft ()) {
else if (!wallOnLeft) {
swapStrafeCombatDir ();
m_strafeSetTime = strafeUpdateTime ();

View file

@ -48,8 +48,8 @@ void BotConfig::loadMainConfig (bool isFirstLoad) {
String line;
MemFile file;
// this is does the same as exec of engine, but not overwriting values of cvars spcified in cv_ignore_cvars_on_changelevel
if (util.openConfig (strings.format ("%s.cfg", product.folder), "Bot main config file is not found.", &file, false)) {
// this is does the same as exec of engine, but not overwriting values of cvars specified in cv_ignore_cvars_on_changelevel
if (util.openConfig (product.nameLower, "Bot main config file is not found.", &file, false)) {
while (file.getLine (line)) {
line.trim ();
@ -117,7 +117,7 @@ void BotConfig::loadNamesConfig () {
MemFile file;
// naming initialization
if (util.openConfig ("names.cfg", "Name configuration file not found.", &file, true)) {
if (util.openConfig ("names", "Name configuration file not found.", &file, true)) {
m_botNames.clear ();
while (file.getLine (line)) {
@ -172,7 +172,7 @@ void BotConfig::loadWeaponsConfig () {
MemFile file;
// weapon data initialization
if (util.openConfig ("weapon.cfg", "Weapon configuration file not found. Loading defaults.", &file)) {
if (util.openConfig ("weapon", "Weapon configuration file not found. Loading defaults.", &file)) {
while (file.getLine (line)) {
line.trim ();
@ -224,7 +224,7 @@ void BotConfig::loadChatterConfig () {
MemFile file;
// chatter initialization
if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.int_ () == 2 && util.openConfig ("chatter.cfg", "Couldn't open chatter system configuration", &file)) {
if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.int_ () == 2 && util.openConfig ("chatter", "Couldn't open chatter system configuration", &file)) {
m_chatter.clear ();
struct EventMap {
@ -332,7 +332,7 @@ void BotConfig::loadChatterConfig () {
items[1].trim ("(;)");
for (const auto &event : chatterEventMap) {
if (event.str == items[0]) {
if (event.str == items.first ()) {
// this does common work of parsing comma-separated chatter line
auto sentences = items[1].split (",");
@ -364,7 +364,7 @@ void BotConfig::loadChatConfig () {
MemFile file;
// chat config initialization
if (util.openConfig ("chat.cfg", "Chat file not found.", &file, true)) {
if (util.openConfig ("chat", "Chat file not found.", &file, true)) {
StringArray *chat = nullptr;
StringArray keywords {};
@ -467,7 +467,7 @@ void BotConfig::loadLanguageConfig () {
MemFile file;
// localizer inititalization
if (util.openConfig ("lang.cfg", "Specified language not found.", &file, true)) {
if (util.openConfig ("lang", "Specified language not found.", &file, true)) {
String temp;
Twin <String, String> lang;
@ -513,7 +513,7 @@ void BotConfig::loadAvatarsConfig () {
MemFile file;
// avatars inititalization
if (util.openConfig ("avatars.cfg", "Avatars config file not found. Avatars will not be displayed.", &file)) {
if (util.openConfig ("avatars", "Avatars config file not found. Avatars will not be displayed.", &file)) {
m_avatars.clear ();
while (file.getLine (line)) {
@ -577,7 +577,7 @@ void BotConfig::loadDifficultyConfig () {
};
// avatars inititalization
if (util.openConfig ("difficulty.cfg", "Difficulty config file not found. Loading defaults.", &file)) {
if (util.openConfig ("difficulty", "Difficulty config file not found. Loading defaults.", &file)) {
while (file.getLine (line)) {
if (isCommentLine (line) || line.length () < 3) {
@ -612,10 +612,10 @@ void BotConfig::loadDifficultyConfig () {
}
void BotConfig::loadMapSpecificConfig () {
auto mapSpecificConfig = strings.format ("addons/%s/conf/maps/%s.cfg", product.folder, game.getMapName ());
auto mapSpecificConfig = strings.joinPath (folders.addons, folders.bot, folders.config, "maps", strings.format ("%s.%s", game.getMapName (), kConfigExtension));
// check existence of file
if (File::exists (strings.format ("%s/%s", game.getRunningModName (), mapSpecificConfig))) {
if (plat.fileExists (strings.joinPath (game.getRunningModName (), mapSpecificConfig).chars ())) {
game.serverCommand ("exec %s", mapSpecificConfig);
ctrl.msg ("Executed map-specific config: %s", mapSpecificConfig);
@ -630,7 +630,7 @@ void BotConfig::loadCustomConfig () {
m_custom["AMXParachuteCvar"] = "sv_parachute";
// custom inititalization
if (util.openConfig ("custom.cfg", "Custom config file not found. Loading defaults.", &file)) {
if (util.openConfig ("custom", "Custom config file not found. Loading defaults.", &file)) {
m_custom.clear ();
while (file.getLine (line)) {
@ -642,7 +642,7 @@ void BotConfig::loadCustomConfig () {
auto values = line.split ("=");
if (values.length () != 2) {
logger.error ("Bad configuration for custom.cfg");
logger.error ("Bad configuration for custom.%s", kConfigExtension);
return;
}
auto kv = Twin <String, String> (values[0].trim (), values[1].trim ());
@ -661,7 +661,7 @@ void BotConfig::loadLogosConfig () {
MemFile file;
// logos inititalization
if (util.openConfig ("logos.cfg", "Logos config file not found. Loading defaults.", &file)) {
if (util.openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
m_logos.clear ();
while (file.getLine (line)) {
@ -688,7 +688,7 @@ void BotConfig::setupMemoryFiles () {
};
if (setMemoryPointers) {
MemFileStorage::instance ().initizalize (wrapLoadFile, wrapFreeFile);
MemFileStorage::instance ().initizalize (cr::move (wrapLoadFile), cr::move (wrapFreeFile));
setMemoryPointers = false;
}
}

View file

@ -201,9 +201,9 @@ int BotControl::cmdCvars () {
File cfg;
// if save requested, dump cvars to yapb.cfg
// if save requested, dump cvars to main config
if (isSave) {
cfg.open (strings.format ("%s/addons/%s/conf/%s.cfg", game.getRunningModName (), product.folder, product.folder), "wt");
cfg.open (strings.joinPath (game.getRunningModName (), folders.addons, folders.bot, folders.config, strings.format ("%s.%s", product.nameLower, kConfigExtension)), "wt");
cfg.puts ("// Configuration file for %s\n\n", product.name);
}
else {
@ -496,7 +496,7 @@ int BotControl::cmdNodeSave () {
msg ("All nodes has been saved and written to disk (IGNORING QUALITY CONTROL).");
}
else if (strValue (option) == "old") {
else if (strValue (option) == "old" || strValue (option) == "oldformat") {
if (graph.length () >= 1024) {
msg ("Unable to save POD-Bot Format waypoint file. Number of nodes exceeds 1024.");

View file

@ -250,35 +250,6 @@ void Game::testLine (const Vector &start, const Vector &end, int ignoreFlags, ed
engfuncs.pfnTraceLine (start, end, engineFlags, ignoreEntity, ptr);
}
bool Game::testLineChannel (TraceChannel channel, const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult &result) {
// this function traces a line dot by dot, starting from vecStart in the direction of vecEnd,
// ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or false), and stops
// at the first obstacle encountered, returning the results of the trace in the TraceResult structure
// ptr. Such results are (amongst others) the distance traced, the hit surface, the hit plane
// vector normal, etc. See the TraceResult structure for details. This function allows to specify
// whether the trace starts "inside" an entity's polygonal model, and if so, to specify that entity
// in ignoreEntity in order to ignore it as a possible obstacle.
auto bot = bots[ignoreEntity];
// check if bot is firing trace line
if (bot && bot->canSkipNextTrace (channel)) {
result = bot->getLastTraceResult (channel); // set the result from bot stored one
// current call is skipped
return true;
}
else {
testLine (start, end, ignoreFlags, ignoreEntity, &result);
// if we're still reaching here, save the last trace result
if (bot) {
bot->setLastTraceResult (channel, &result);
}
}
return false;
}
void Game::testHull (const Vector &start, const Vector &end, int ignoreFlags, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr) {
// this function traces a hull dot by dot, starting from vecStart in the direction of vecEnd,
// ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or
@ -295,7 +266,7 @@ void Game::testHull (const Vector &start, const Vector &end, int ignoreFlags, in
}
// helper class for reading wave header
class WaveEndianessHelper : public DenyCopying {
class WaveEndianessHelper : public NonCopyable {
private:
#if defined (CR_ARCH_CPU_BIG_ENDIAN)
bool little { false };
@ -321,7 +292,7 @@ public:
};
float Game::getWaveLen (const char *fileName) {
auto filePath = strings.format ("%s/%s.wav", cv_chatter_path.str (), fileName);
auto filePath = strings.joinPath (cv_chatter_path.str (), strings.format ("%s.wav", fileName));
MemFile fp (filePath);
@ -666,7 +637,7 @@ void Game::addNewCvar (const char *name, const char *value, const char *info, bo
reg.initial = static_cast <float> (atof (value));
}
auto eflags = FCVAR_EXTDLL;
int eflags = FCVAR_EXTDLL;
if (varType == Var::Normal) {
eflags |= FCVAR_SERVER;
@ -804,10 +775,10 @@ bool Game::loadCSBinary () {
// search the libraries inside game dlls directory
for (const auto &lib : libs) {
auto path = strings.format ("%s/dlls/%s.%s", modname, lib, DLL_SUFFIX);
auto path = strings.joinPath (modname, "dlls", lib + DLL_SUFFIX);
// if we can't read file, skip it
if (!File::exists (path)) {
if (!plat.fileExists (path.chars ())) {
continue;
}
@ -871,10 +842,16 @@ bool Game::postload () {
game.print (msg);
});
auto ensureBotPathExists = [this] (StringRef dir1, StringRef dir2) {
File::makePath (strings.joinPath (getRunningModName (), folders.addons, folders.bot, dir1, dir2).chars ());
};
// ensure we're have all needed directories
for (const auto &dir : StringArray { "conf/lang", "data/train", "data/graph", "data/logs", "data/pwf" }) {
File::createPath (strings.format ("%s/addons/%s/%s", getRunningModName (), product.folder, dir));
}
ensureBotPathExists (folders.config, folders.lang);
ensureBotPathExists (folders.data, folders.train);
ensureBotPathExists (folders.data, folders.graph);
ensureBotPathExists (folders.data, folders.logs);
ensureBotPathExists (folders.data, folders.podbot);
// set out user agent for http stuff
http.setUserAgent (strings.format ("%s/%s", product.name, product.version));
@ -1250,7 +1227,7 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
auto lightmap = surf->samples + dt * smax + ds;
// compute the lightmap color at a particular point
for (int maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps) {
for (int maps = 0u; maps < MAX_LIGHTMAPS && surf->styles[maps] != 255u; ++maps) {
uint32_t scale = m_lightstyleValue[surf->styles[maps]];
m_point.red += lightmap->r * scale;

View file

@ -9,7 +9,7 @@
// on other than win32/linux platforms i.e. arm we're using xash3d engine to run which exposes
// nice interface to handle with linkents. if ever rehlds or hlds engine will ever run on ARM or
// other platforms, and you wan't to run bot on it without metamod, consider enabling LINKENT_STATIC_THUNKS
// other platforms, and you want to run bot on it without metamod, consider enabling LINKENT_STATIC_THUNKS
// when compiling the bot, to get it supported.
#if defined(LINKENT_STATIC_THUNKS)
void forwardEntity_helper (EntityFunction &addr, const char *name, entvars_t *pev) {

View file

@ -1648,8 +1648,20 @@ bool BotGraph::saveGraphData () {
void BotGraph::saveOldFormat () {
PODGraphHeader header {};
String editorName;
if (game.isNullEntity (m_editor) && !m_graphAuthor.empty ()) {
editorName = m_graphAuthor;
}
else if (!game.isNullEntity (m_editor)) {
editorName = m_editor->v.netname.chars ();
}
else {
editorName = product.name;
}
strings.copy (header.header, kPodbotMagic, sizeof (kPodbotMagic));
strings.copy (header.author, m_editor->v.netname.chars (), cr::bufsize (header.author));
strings.copy (header.author, editorName.chars (), cr::bufsize (header.author));
strings.copy (header.mapName, game.getMapName (), cr::bufsize (header.mapName));
header.mapName[31] = 0;

View file

@ -32,54 +32,6 @@ plugin_info_t Plugin_info = {
PT_ANYTIME, // when unloadable
};
void hook_ClientCommand (edict_t *ent, char const *format, ...) {
// this function forces the client whose player entity is ent to issue a client command.
// How it works is that clients all have a argv global string in their client DLL that
// stores the command string; if ever that string is filled with characters, the client DLL
// sends it to the engine as a command to be executed. When the engine has executed that
// command, this argv string is reset to zero. Here is somehow a curious implementation of
// ClientCommand: the engine sets the command it wants the client to issue in his argv, then
// the client DLL sends it back to the engine, the engine receives it then executes the
// command therein. Don't ask me why we need all this complicated crap. Anyhow since bots have
// no client DLL, be certain never to call this function upon a bot entity, else it will just
// make the server crash. Since hordes of uncautious, not to say stupid, programmers don't
// even imagine some players on their servers could be bots, this check is performed less than
// sometimes actually by their side, that's why we strongly recommend to check it here too. In
// case it's a bot asking for a client command, we handle it like we do for bot commands
if (game.isNullEntity (ent)) {
if (game.is (GameFlags::Metamod)) {
RETURN_META (MRES_SUPERCEDE);
}
return;
}
va_list ap;
auto buffer = strings.chars ();
va_start (ap, format);
vsnprintf (buffer, StringBuffer::StaticBufferSize, format, ap);
va_end (ap);
if (util.isFakeClient (ent) || (ent->v.flags & FL_DORMANT)) {
auto bot = bots[ent];
if (bot) {
bot->issueCommand (buffer);
}
if (game.is (GameFlags::Metamod)) {
RETURN_META (MRES_SUPERCEDE); // prevent bots to be forced to issue client commands
}
return;
}
if (game.is (GameFlags::Metamod)) {
RETURN_META (MRES_IGNORED);
}
engfuncs.pfnClientCommand (ent, buffer);
}
CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
// this function is called right after GiveFnptrsToDll() by the engine in the game DLL (or
// what it BELIEVES to be the game DLL), in order to copy the list of MOD functions that can
@ -496,7 +448,7 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
}
if (ents.needsBypass () && !game.is (GameFlags::Metamod)) {
table->pfnCreateNamedEntity = [] (int classname) -> edict_t *{
table->pfnCreateNamedEntity = [] (string_t classname) -> edict_t *{
if (ents.isPaused ()) {
ents.enable ();
@ -764,9 +716,6 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
}
engfuncs.pfnSetClientMaxspeed (ent, newMaxspeed);
};
table->pfnClientCommand = hook_ClientCommand;
return HLTrue;
}
@ -946,6 +895,11 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *table, globalvars_t *glob) {
memcpy (&engfuncs, table, sizeof (enginefuncs_t));
globals = glob;
// set the global timer function
timerStorage.setTimeFunction ([] () {
return globals->time;
});
if (game.postload ()) {
return;
}

View file

@ -93,7 +93,7 @@ BotManager::BotManager () {
void BotManager::createKillerEntity () {
// this function creates single trigger_hurt for using in Bot::kill, to reduce lags, when killing all the bots
m_killerEntity = engfuncs.pfnCreateNamedEntity (MAKE_STRING ("trigger_hurt"));
m_killerEntity = engfuncs.pfnCreateNamedEntity ("trigger_hurt");
m_killerEntity->v.dmg = kInfiniteDistance;
m_killerEntity->v.dmg_take = 1.0f;
@ -128,12 +128,12 @@ void BotManager::touchKillerEntity (Bot *bot) {
}
const auto &prop = conf.getWeaponProp (bot->m_currentWeapon);
m_killerEntity->v.classname = MAKE_STRING (prop.classname.chars ());
m_killerEntity->v.classname = prop.classname.chars ();
m_killerEntity->v.dmg_inflictor = bot->ent ();
m_killerEntity->v.dmg = (bot->pev->health + bot->pev->armorvalue) * 4.0f;
KeyValueData kv {};
kv.szClassName = const_cast <char *> (prop.classname.chars ());
kv.szClassName = prop.classname.chars ();
kv.szKeyName = "damagetype";
kv.szValue = strings.format ("%d", cr::bit (4));
kv.fHandled = HLFalse;
@ -146,7 +146,7 @@ void BotManager::execGameEntity (edict_t *ent) {
// this function calls gamedll player() function, in case to create player entity in game
if (game.is (GameFlags::Metamod)) {
CALL_GAME_ENTITY (PLID, "player", &ent->v);
MUTIL_CallGameEntity (PLID, "player", &ent->v);
return;
}
ents.callPlayerFunction (ent);
@ -214,7 +214,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
resultName = botName->name;
}
else {
resultName.assignf ("%s_%d.%d", product.folder, rg.get (100, 10000), rg.get (100, 10000)); // just pick ugly random name
resultName.assignf ("%s_%d.%d", product.nameLower, rg.get (100, 10000), rg.get (100, 10000)); // just pick ugly random name
}
}
else {
@ -793,8 +793,25 @@ void BotManager::listBots () {
ctrl.msg ("%-3.5s\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.4s\t%-3.4s\t%-3.5s\t%-3.8s", "index", "name", "personality", "team", "difficulty", "frags", "alive", "timeleft");
auto botTeam = [] (int32_t team) -> String {
switch (team) {
case Team::CT:
return "CT";
case Team::Terrorist:
return "TE";
case Team::Unassigned:
default:
return "UN";
case Team::Spectator:
return "SP";
}
};
for (const auto &bot : bots) {
ctrl.msg ("[%-3.1d]\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.1d\t%-3.1d\t%-3.4s\t%-3.0f secs", bot->index (), bot->pev->netname.chars (), bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful", bot->m_team == Team::CT ? "CT" : "T", bot->m_difficulty, static_cast <int> (bot->pev->frags), bot->m_notKilled ? "yes" : "no", cv_rotate_bots.bool_ () ? bot->m_stayTime - game.time () : 0.0f);
ctrl.msg ("[%-3.1d]\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.1d\t%-3.1d\t%-3.4s\t%-3.0f secs", bot->index (), bot->pev->netname.chars (), bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful", botTeam (bot->m_team), bot->m_difficulty, static_cast <int> (bot->pev->frags), bot->m_notKilled ? "yes" : "no", cv_rotate_bots.bool_ () ? bot->m_stayTime - game.time () : 0.0f);
}
ctrl.msg ("%d bots", m_bots.length ());
}
@ -1160,6 +1177,12 @@ int BotManager::getPlayerPriority (edict_t *ent) {
if (bot->m_hasC4 || bot->m_isVIP || bot->m_hasHostage || bot->m_healthValue < ent->v.health) {
return bot->entindex () + highPrio;
}
auto task = bot->getCurrentTaskId ();
// higher priority if camping or hiding
if (task == Task::Camp || task == Task::Hide) {
return bot->entindex () + highPrio;
}
return bot->entindex ();
}
@ -1189,7 +1212,7 @@ void BotManager::erase (Bot *bot) {
}
if (!bot->m_kickedByRotation && cv_save_bots_names.bool_ ()) {
m_saveBotNames.emplaceLast (bot->pev->netname.chars ());
m_saveBotNames.emplaceLast (bot->pev->netname.str ());
}
bot->markStale ();
@ -1282,6 +1305,7 @@ void Bot::newRound () {
m_grenadeRequested = false;
m_moveToC4 = false;
m_defuseNotified = false;
m_duckDefuse = false;
m_duckDefuseCheckTime = 0.0f;
@ -1310,6 +1334,7 @@ void Bot::newRound () {
m_askCheckTime = rg.get (30.0f, 90.0f);
m_minSpeed = 260.0f;
m_prevSpeed = 0.0f;
m_prevVelocity = 0.0f;
m_prevOrigin = Vector (kInfiniteDistance, kInfiniteDistance, kInfiniteDistance);
m_prevTime = game.time ();
m_lookUpdateTime = game.time ();
@ -1431,6 +1456,7 @@ void Bot::newRound () {
m_combatStrafeDir = Dodge::None;
m_fightStyle = Fight::None;
m_lastFightStyleCheck = 0.0f;
m_stuckTimestamp = 0.0f;
m_checkWeaponSwitch = true;
m_checkKnifeSwitch = true;
@ -1454,20 +1480,9 @@ void Bot::newRound () {
m_soundUpdateTime = 0.0f;
m_heardSoundTime = game.time ();
// clear its message queue
for (auto &msg : m_messageQueue) {
msg = BotMsg::None;
}
m_msgQueue.clear ();
m_nodeHistory.clear ();
m_ignoredBreakable.clear ();
// clear last trace
for (auto i = 0; i < TraceChannel::Num; ++i) {
m_lastTrace[i] = {};
m_traceSkip[i] = 0;
}
// and put buying into its message queue
pushMsgQueue (BotMsg::Buy);
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
@ -1673,7 +1688,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en
}
}
}
Client &target = util.getClient (game.indexOfPlayer (ent));
auto &target = util.getClient (game.indexOfPlayer (ent));
// check if this player alive, and issue something
if ((target.flags & ClientFlags::Alive) && target.radio != 0 && strncmp (cmd, "menuselect", 10) == 0) {
@ -1704,19 +1719,19 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en
void BotManager::notifyBombDefuse () {
// notify all terrorists that CT is starting bomb defusing
if (!isBombPlanted ()) {
return;
}
auto bombPos = graph.getBombOrigin ();
const auto &bombPos = graph.getBombOrigin ();
for (const auto &bot : bots) {
auto task = bot->getCurrentTaskId ();
if (bot->m_notKilled && task != Task::MoveToPosition && task != Task::DefuseBomb && task != Task::EscapeFromBomb) {
if (bot->m_team == Team::CT || bot->pev->origin.distanceSq (bombPos) < cr::sqrf (384.0f)) {
if (!bot->m_defuseNotified && bot->m_notKilled && task != Task::MoveToPosition && task != Task::DefuseBomb && task != Task::EscapeFromBomb) {
if (bot->m_team == Team::Terrorist && bot->pev->origin.distanceSq (bombPos) < cr::sqrf (384.0f)) {
bot->clearSearchNodes ();
bot->m_pathType = FindPath::Fast;
bot->m_position = bombPos;
bot->m_defuseNotified = true;
bot->startTask (Task::MoveToPosition, TaskPri::MoveToPosition, kInvalidNodeIndex, 0.0f, true);
}
}

View file

@ -379,7 +379,7 @@ void MessageDispatcher::netMsgBarTime () {
m_bot->m_hasProgressBar = true; // the progress bar on a hud
// notify bots about defusing has started
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted () && m_bot->m_team == Team::CT) {
bots.notifyBombDefuse ();
}
}
@ -560,7 +560,7 @@ void MessageDispatcher::ensureMessages () {
// re-register our message
m_wanted.foreach ([&] (const String &key, const int32_t &) {
add (key, GET_USER_MSG_ID (PLID, key.chars (), nullptr));
add (key, MUTIL_GetUserMsgID (PLID, key.chars (), nullptr));
});
}

View file

@ -8,11 +8,6 @@
#include <yapb.h>
int Bot::findBestGoal () {
auto pushToHistroy = [&] (int32_t goal) -> int32_t {
m_nodeHistory.push (goal);
return goal;
};
if (m_isCreature) {
if (!graph.m_terrorPoints.empty ()) {
return graph.m_terrorPoints.random ();
@ -110,7 +105,7 @@ int Bot::findBestGoal () {
else if (game.mapIs (MapFlags::Demolition) && m_team == Team::Terrorist && bots.getRoundStartTime () + 10.0f < game.time ()) {
// send some terrorists to guard planted bomb
if (!m_defendedBomb && bots.isBombPlanted () && getCurrentTaskId () != Task::EscapeFromBomb && getBombTimeleft () >= 15.0f) {
return pushToHistroy (m_chosenGoalIndex = findDefendNode (graph.getBombOrigin ()));
return m_chosenGoalIndex = findDefendNode (graph.getBombOrigin ());
}
}
else if (game.mapIs (MapFlags::Escape)) {
@ -149,7 +144,7 @@ int Bot::findBestGoal () {
if (goalDesire > tacticChoice) {
tactic = 3;
}
return pushToHistroy (findGoalPost (tactic, defensiveNodes, offensiveNodes));
return findGoalPost (tactic, defensiveNodes, offensiveNodes);
}
int Bot::findBestGoalWhenBombAction () {
@ -365,12 +360,8 @@ void Bot::resetCollision () {
void Bot::ignoreCollision () {
resetCollision ();
m_prevTime = game.time () + 1.2f;
m_lastCollTime = game.time () + 1.5f;
m_isStuck = false;
m_lastCollTime = game.time () + m_frameInterval * 4.0f;
m_checkTerrain = false;
m_prevSpeed = m_moveSpeed;
m_prevOrigin = pev->origin;
}
void Bot::doPlayerAvoidance (const Vector &normal) {
@ -417,13 +408,13 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
if (game.isNullEntity (m_hindrance)) {
return;
}
const float interval = m_frameInterval * (pev->velocity.lengthSq2d () > 0.0f ? 9.0f : 2.0f);
const float interval = m_frameInterval * (pev->velocity.lengthSq2d () > 0.0f ? 7.5f : 2.0f);
// use our movement angles, try to predict where we should be next frame
Vector right, forward;
m_moveAngles.angleVectors (&forward, &right, nullptr);
Vector predict = pev->origin + forward * m_moveSpeed * interval;
Vector predict = pev->origin + forward * pev->maxspeed * interval;
predict += right * m_strafeSpeed * interval;
predict += pev->velocity * interval;
@ -432,7 +423,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
auto nextFrameDistance = pev->origin.distanceSq (m_hindrance->v.origin + m_hindrance->v.velocity * interval);
// is player that near now or in future that we need to steer away?
if (movedDistance <= cr::sqrf (48.0f) || (distance <= cr::sqrf (56.0f) && nextFrameDistance < distance)) {
if (movedDistance <= cr::sqrf (64.0f) || (distance <= cr::sqrf (72.0f) && nextFrameDistance < distance)) {
auto dir = (pev->origin - m_hindrance->v.origin).normalize2d_apx ();
// to start strafing, we have to first figure out if the target is on the left side or right side
@ -443,7 +434,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
setStrafeSpeed (normal, -pev->maxspeed);
}
if (distance < cr::sqrf (76.0f)) {
if (distance < cr::sqrf (80.0f)) {
if ((dir | forward.normalize2d_apx ()) < 0.0f) {
m_moveSpeed = -pev->maxspeed;
}
@ -455,15 +446,12 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
// if avoiding someone do not consider stuck
TraceResult tr {};
float checkSpeed = isDucking () ? 4.0f : 10.0f;
m_isStuck = false;
// standing still, no need to check?
if ((m_moveSpeed >= checkSpeed || m_strafeSpeed >= checkSpeed) && m_lastCollTime < game.time ()) {
if (m_lastCollTime < game.time () && getCurrentTaskId () != Task::Attack) {
// didn't we move enough previously?
if (movedDistance < 2.0f && m_prevSpeed >= 20.0f) {
if (movedDistance < 2.0f && (m_prevSpeed > 20.0f || m_prevVelocity < m_moveSpeed / 2)) {
m_prevTime = game.time (); // then consider being stuck
m_isStuck = true;
@ -474,7 +462,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
// not stuck yet
else {
// test if there's something ahead blocking the way
if (cantMoveForward (dirNormal, &tr) && !isOnLadder ()) {
if (!isOnLadder () && cantMoveForward (dirNormal, &tr)) {
if (cr::fzero (m_firstCollideTime)) {
m_firstCollideTime = game.time () + 0.2f;
}
@ -489,19 +477,24 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
// not stuck?
if (!m_isStuck) {
if (m_probeTime + 0.5f < game.time ()) {
if (m_probeTime + rg.get (0.5f, 1.0f) < game.time ()) {
resetCollision (); // reset collision memory if not being stuck for 0.5 secs
}
else {
// remember to keep pressing duck if it was necessary ago
// remember to keep pressing stuff if it was necessary ago
if (m_collideMoves[m_collStateIndex] == CollisionState::Duck && (isOnFloor () || isInWater ())) {
pev->button |= IN_DUCK;
}
else if (m_collideMoves[m_collStateIndex] == CollisionState::StrafeLeft) {
setStrafeSpeed (dirNormal, -pev->maxspeed);
}
else if (m_collideMoves[m_collStateIndex] == CollisionState::StrafeRight) {
setStrafeSpeed (dirNormal, pev->maxspeed);
}
}
return;
}
// bot is stuck, but not yet decided what to do?
if (m_collisionState == CollisionState::Undecided) {
uint32_t bits = 0;
@ -549,7 +542,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
dirLeft = true;
}
const auto &testDir = m_moveSpeed > 0.0f ? forward : -forward;
constexpr float blockDistance = 40.0f;
constexpr float blockDistance = 32.0f;
// now check which side is blocked
src = pev->origin + right * blockDistance;
@ -784,6 +777,14 @@ void Bot::moveToGoal () {
}
}
void Bot::resetMovement () {
pev->button = 0;
m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f;
m_moveAngles = nullptr;
}
void Bot::translateInput () {
if (m_duckTime >= game.time ()) {
pev->button |= IN_DUCK;
@ -1047,18 +1048,18 @@ bool Bot::updateNavigation () {
}
}
float desiredDistance = 8.0f;
float nodeDistance = pev->origin.distance (m_pathOrigin);
float desiredDistance = cr::sqrf (8.0f);
float nodeDistance = pev->origin.distanceSq (m_pathOrigin);
// initialize the radius for a special node type, where the node is considered to be reached
if (m_pathFlags & NodeFlag::Lift) {
desiredDistance = 50.0f;
desiredDistance = cr::sqrf (50.0f);
}
else if (isDucking () || (m_pathFlags & NodeFlag::Goal)) {
desiredDistance = 25.0f;
desiredDistance = cr::sqrf (25.0f);
}
else if (m_pathFlags & NodeFlag::Ladder) {
desiredDistance = 24.0f;
else if (isOnLadder () || (m_pathFlags & NodeFlag::Ladder)) {
desiredDistance = cr::sqrf (24.0f);
}
else if (m_currentTravelFlags & PathFlag::Jump) {
desiredDistance = 0.0f;
@ -1067,13 +1068,13 @@ bool Bot::updateNavigation () {
desiredDistance = 0.0f;
}
else if (isOccupiedNode (m_path->number)) {
desiredDistance = 96.0f;
desiredDistance = cr::sqrf (96.0f);
}
else {
desiredDistance = m_path->radius;
desiredDistance = cr::max (cr::sqrf (m_path->radius), desiredDistance);
}
// check if node has a special travelflag, so they need to be reached more precisely
// check if node has a special travel flags, so they need to be reached more precisely
for (const auto &link : m_path->links) {
if (link.flags != 0) {
desiredDistance = 0.0f;
@ -1082,11 +1083,11 @@ bool Bot::updateNavigation () {
}
// needs precise placement - check if we get past the point
if (desiredDistance < 22.0f && nodeDistance < 30.0f && m_pathOrigin.distanceSq (pev->origin + pev->velocity * m_frameInterval) >= cr::sqrf (nodeDistance)) {
if (desiredDistance < cr::sqrf (22.0f) && nodeDistance < cr::sqrf (30.0f) && m_pathOrigin.distanceSq (pev->origin + pev->velocity * m_frameInterval) >= nodeDistance) {
desiredDistance = nodeDistance + 1.0f;
}
// this allows us to prevent stupid bot behaviour when he reaches almost end point of this route, but some one (other bot eg)
// this allows us to prevent stupid bot behavior when he reaches almost end point of this route, but some one (other bot eg)
// is sitting there, so the bot is unable to reach the node because of other player on it, and he starts to jumping and so on
// here we're clearing task memory data (important!), since task executor may restart goal with one from memory, so this process
// will go in cycle, and forcing bot to re-create new route.
@ -1099,7 +1100,6 @@ bool Bot::updateNavigation () {
}
if (nodeDistance < desiredDistance) {
// did we reach a destination node?
if (getTask ()->data == m_currentNodeIndex) {
if (m_chosenGoalIndex != kInvalidNodeIndex) {
@ -1126,9 +1126,9 @@ bool Bot::updateNavigation () {
// bot within 'hearable' bomb tick noises?
if (!bombOrigin.empty ()) {
float distance = bombOrigin.distance (graph[taskTarget].origin);
float distance = bombOrigin.distanceSq (graph[taskTarget].origin);
if (distance > 512.0f) {
if (distance > cr::sqrf (512.0f)) {
if (rg.chance (50) && !graph.isVisited (taskTarget)) {
pushRadioMessage (Radio::SectorClear);
}
@ -2334,7 +2334,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
};
// trace from the bot's eyes straight forward...
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (tr->flFraction < 1.0f) {
@ -2349,7 +2349,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
src = getEyesPos () + Vector (0.0f, 0.0f, -16.0f) - right * -16.0f;
forward = getEyesPos () + Vector (0.0f, 0.0f, -16.0f) + right * 16.0f + normal * 24.0f;
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2361,7 +2361,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
src = getEyesPos () + Vector (0.0f, 0.0f, -16.0f) + right * 16.0f;
forward = getEyesPos () + Vector (0.0f, 0.0f, -16.0f) - right * -16.0f + normal * 24.0f;
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2373,7 +2373,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
src = pev->origin + Vector (0.0f, 0.0f, -19.0f + 19.0f);
forward = src + Vector (0.0f, 0.0f, 10.0f) + normal * 24.0f;
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2382,7 +2382,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
src = pev->origin;
forward = src + normal * 24.0f;
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2395,7 +2395,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
forward = pev->origin + Vector (0.0f, 0.0f, -17.0f) + right * 16.0f + normal * 24.0f;
// trace from the bot's waist straight forward...
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2406,7 +2406,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) {
src = pev->origin + Vector (0.0f, 0.0f, -24.0f) + right * 16.0f;
forward = pev->origin + Vector (0.0f, 0.0f, -24.0f) - right * -16.0f + normal * 24.0f;
traceResult = game.testLineChannel (TraceChannel::Body, src, forward, TraceIgnore::Monsters, ent (), *tr);
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
// check if the trace hit something...
if (checkDoor (tr)) {
@ -2717,7 +2717,7 @@ bool Bot::isBlockedRight () {
bool Bot::checkWallOnLeft () {
TraceResult tr {};
game.testLine (pev->origin, pev->origin - pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
game.testLine (pev->origin, pev->origin + -pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
if (tr.flFraction < 1.0f) {
@ -3040,25 +3040,6 @@ bool Bot::isReachableNode (int index) {
return false;
}
bool Bot::isBannedNode (int index) {
if (graph.exists (cv_debug_goal.int_ ()) || !graph.exists (index)) {
return false;
}
const auto &bucket = graph.getNodesInBucket (graph[index].origin);
// too few nodes in bucket near location, do not ban anything
if (bucket.length <int> () <= kMaxNodeLinks) {
return false;
}
for (const auto &node : m_nodeHistory) {
if (node == index) {
return true;
}
}
return false;
}
void Bot::findShortestPath (int srcIndex, int destIndex) {
// this function finds the shortest path from source index to destination index

View file

@ -418,6 +418,9 @@ void DijkstraAlgo::init (const int length) {
m_distance.resize (length);
m_parent.resize (length);
m_distance.shrink ();
m_parent.shrink ();
}
bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, int *pathDistance) {
@ -432,15 +435,15 @@ bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, i
m_distance[srcIndex] = 0;
while (!m_queue.empty ()) {
auto p = cr::move (m_queue.pop ());
auto current = p.second;
auto &&route = cr::move (m_queue.pop ());
auto current = route.second;
// finished search
if (current == destIndex) {
break;
}
if (m_distance[current] != p.first) {
if (m_distance[current] != route.first) {
continue;
}

View file

@ -69,7 +69,7 @@ void BotPractice::setDamage (int32_t team, int32_t start, int32_t goal, int32_t
float BotPractice::plannerGetDamage (int32_t team, int32_t start, int32_t goal, bool addTeamHighestDamage) {
if (!m_damageUpdateLock.tryLock ()) {
return 1.0f;
return 0.0f;
}
ScopedUnlock <Mutex> unlock (m_damageUpdateLock);
auto damage = static_cast <float> (getDamage (team, start, goal));

View file

@ -302,13 +302,13 @@ String BotStorage::buildPath (int32_t file, bool isMemoryLoad) {
using FilePath = Twin <String, String>;
static HashMap <int32_t, FilePath> paths = {
{ BotFile::Vistable, FilePath ("train", "vis")},
{ BotFile::Practice, FilePath ("train", "prc")},
{ BotFile::Pathmatrix, FilePath ("train", "pmx")},
{ BotFile::LogFile, FilePath ("logs", "txt")},
{ BotFile::Graph, FilePath ("graph", "graph")},
{ BotFile::PodbotPWF, FilePath ("pwf", "pwf")},
{ BotFile::EbotEWP, FilePath ("ewp", "ewp")},
{ BotFile::Vistable, FilePath (folders.train, "vis")},
{ BotFile::Practice, FilePath (folders.train, "prc")},
{ BotFile::Pathmatrix, FilePath (folders.train, "pmx")},
{ BotFile::LogFile, FilePath (folders.logs, "txt")},
{ BotFile::Graph, FilePath (folders.graph, "graph")},
{ BotFile::PodbotPWF, FilePath (folders.podbot, "pwf")},
{ BotFile::EbotEWP, FilePath (folders.ebot, "ewp")},
};
static StringArray path;
@ -320,11 +320,11 @@ String BotStorage::buildPath (int32_t file, bool isMemoryLoad) {
}
// allways append addons/product
path.emplace ("addons");
path.emplace (product.folder);
path.emplace (folders.addons);
path.emplace (folders.bot);
// the datadir
path.emplace ("data");
path.emplace (folders.data);
// append real filepath
path.emplace (paths[file].first);
@ -338,19 +338,19 @@ String BotStorage::buildPath (int32_t file, bool isMemoryLoad) {
auto timebuf = strings.chars ();
strftime (timebuf, StringBuffer::StaticBufferSize, "L%d%m%Y", &timeinfo);
path.emplace (strings.format ("%s_%s.%s", product.folder, timebuf, paths[file].second));
path.emplace (strings.format ("%s_%s.%s", folders.bot, timebuf, paths[file].second));
}
else {
String mapName = game.getMapName ();
path.emplace (strings.format ("%s.%s", mapName.lowercase (), paths[file].second));
}
// finally use correct path separarators for us
// finally use correct path separators for us
return String::join (path, PATH_SEP);
}
int32_t BotStorage::storageToBotFile (int32_t options) {
// converts storage option to stroage filename
// converts storage option to storage filename
if (options & StorageOption::Graph) {
return BotFile::Graph;
@ -380,7 +380,7 @@ void BotStorage::unlinkFromDisk () {
unlinkable.emplace (buildPath (BotFile::Pathmatrix)); // corresponding to matrix
for (const auto &item : unlinkable) {
if (File::exists (item)) {
if (plat.fileExists (item.chars ())) {
plat.removeFile (item.chars ());
ctrl.msg ("File %s, has been deleted from the hard disk", item);
}
@ -388,7 +388,7 @@ void BotStorage::unlinkFromDisk () {
logger.error ("Unable to open %s", item);
}
}
graph.reset (); // re-intialize points
graph.reset (); // re-initialize points
}
#endif // BOT_STORAGE_EXPLICIT_INSTANTIATIONS

View file

@ -233,31 +233,31 @@ bool BotSupport::isFakeClient (edict_t *ent) {
return false;
}
bool BotSupport::openConfig (const char *fileName, const char *errorIfNotExists, MemFile *outFile, bool languageDependant /*= false*/) {
bool BotSupport::openConfig (StringRef fileName, StringRef errorIfNotExists, MemFile *outFile, bool languageDependant /*= false*/) {
if (*outFile) {
outFile->close ();
}
// save config dir
auto configDir = strings.format ("addons/%s/conf", product.folder);
auto configDir = strings.joinPath (folders.addons, folders.bot, folders.config);
if (languageDependant) {
if (strcmp (fileName, "lang.cfg") == 0 && strcmp (cv_language.str (), "en") == 0) {
if (fileName.startsWith ("lang") && strcmp (cv_language.str (), "en") == 0) {
return false;
}
auto langConfig = strings.format ("%s/lang/%s_%s", configDir, cv_language.str (), fileName);
auto langConfig = strings.joinPath (configDir, folders.lang, strings.format ("%s_%s.%s", cv_language.str (), fileName, kConfigExtension));
// check is file is exists for this language
if (!outFile->open (langConfig)) {
outFile->open (strings.format ("%s/lang/en_%s", configDir, fileName));
outFile->open (strings.joinPath (configDir, folders.lang, strings.format ("en_%s.%s", fileName, kConfigExtension)));
}
}
else {
outFile->open (strings.format ("%s/%s", configDir, fileName));
outFile->open (strings.joinPath (configDir, strings.format ("%s.%s", fileName, kConfigExtension)));
}
if (!*outFile) {
logger.error (errorIfNotExists);
logger.error (errorIfNotExists.chars ());
return false;
}
return true;
@ -473,9 +473,6 @@ void BotSupport::syncCalculatePings () {
void BotSupport::emitPings (edict_t *to) {
MessageWriter msg;
// missing from sdk
constexpr int kGamePingSVC = 17;
auto isThirdpartyBot = [] (edict_t *ent) {
return !bots[ent] && (ent->v.flags & FL_FAKECLIENT);
};
@ -490,7 +487,7 @@ void BotSupport::emitPings (edict_t *to) {
client.ping = getPingBitmask (client.ent, rg.get (5, 10), rg.get (15, 40));
}
msg.start (MSG_ONE_UNRELIABLE, kGamePingSVC, nullptr, to)
msg.start (MSG_ONE_UNRELIABLE, SVC_PINGS, nullptr, to)
.writeLong (client.ping)
.end ();
}

View file

@ -48,7 +48,7 @@ void Bot::normal_ () {
getTask ()->data = kInvalidNodeIndex;
}
// reached the destination (goal) waypoint?
// reached the destination (goal) node?
if (updateNavigation ()) {
// if we're reached the goal, and there is not enemies, notify the team
if (!bots.isBombPlanted () && m_currentNodeIndex != kInvalidNodeIndex && (m_pathFlags & NodeFlag::Goal) && rg.chance (15) && numEnemiesNear (pev->origin, 650.0f) == 0) {
@ -65,7 +65,7 @@ void Bot::normal_ () {
}
}
// reached waypoint is a camp waypoint
// reached node is a camp node
if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) {
// check if bot has got a primary weapon and hasn't camped before
@ -184,22 +184,15 @@ void Bot::normal_ () {
}
// no more nodes to follow - search new ones (or we have a bomb)
else if (!hasActiveGoal ()) {
m_moveSpeed = pev->maxspeed;
clearSearchNodes ();
ignoreCollision ();
// did we already decide about a goal before?
auto currIndex = getTask ()->data;
auto destIndex = graph.exists (currIndex) && !isBannedNode (currIndex) && m_prevGoalIndex != currIndex ? currIndex : findBestGoal ();
auto destIndex = graph.exists (currIndex) ? currIndex : findBestGoal ();
// check for existance (this is failover, for i.e. csdm, this should be not true with normal gameplay, only when spawned outside of waypointed area)
// check for existence (this is fail over, for i.e. csdm, this should be not true with normal game play, only when spawned outside of covered area)
if (!graph.exists (destIndex)) {
destIndex = graph.getFarest (pev->origin, 512.0f);
}
if (!graph.exists (cv_debug_goal.int_ ()) && graph.exists (currIndex) && m_prevGoalIndex == currIndex && !(graph[currIndex].flags & NodeFlag::Goal)) {
m_nodeHistory.push (currIndex);
destIndex = graph.getFarest (pev->origin, 1024.0f);
}
m_prevGoalIndex = destIndex;
@ -210,7 +203,7 @@ void Bot::normal_ () {
// override with fast path
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
pathSearchType = rg.chance (60) ? FindPath::Fast : FindPath::Optimal;
pathSearchType = rg.chance (80) ? FindPath::Fast : FindPath::Optimal;
}
ensureCurrentNodeIndex ();
@ -314,8 +307,6 @@ void Bot::huntEnemy_ () {
// do we need to calculate a new path?
else if (!hasActiveGoal ()) {
clearSearchNodes ();
int destIndex = kInvalidNodeIndex;
int goal = getTask ()->data;
@ -410,7 +401,6 @@ void Bot::seekCover_ () {
m_checkTerrain = false;
}
else if (!hasActiveGoal ()) {
clearSearchNodes ();
int destIndex = kInvalidNodeIndex;
if (getTask ()->data != kInvalidNodeIndex) {
@ -518,7 +508,6 @@ void Bot::blind_ () {
m_states |= Sense::SuspectEnemy;
}
else if (!hasActiveGoal ()) {
clearSearchNodes ();
ensureCurrentNodeIndex ();
m_prevGoalIndex = m_blindNodeIndex;
@ -707,8 +696,7 @@ void Bot::moveToPos_ () {
}
auto ensureDestIndexOK = [&] (int &index) {
if (isOccupiedNode (index) || isBannedNode (index)) {
m_nodeHistory.push (index);
if (isOccupiedNode (index)) {
index = findDefendNode (m_position);
}
};
@ -723,8 +711,6 @@ void Bot::moveToPos_ () {
// didn't choose goal waypoint yet?
else if (!hasActiveGoal ()) {
clearSearchNodes ();
int destIndex = kInvalidNodeIndex;
int goal = getTask ()->data;
@ -1050,8 +1036,6 @@ void Bot::followUser_ () {
// didn't choose goal waypoint yet?
if (!hasActiveGoal ()) {
clearSearchNodes ();
int destIndex = graph.getNearest (m_targetEntity->v.origin);
auto points = graph.getNarestInRadius (200.0f, m_targetEntity->v.origin);
@ -1306,8 +1290,6 @@ void Bot::doublejump_ () {
// didn't choose goal waypoint yet?
if (!hasActiveGoal ()) {
clearSearchNodes ();
int destIndex = graph.getNearest (m_doubleJumpOrigin);
if (graph.exists (destIndex)) {
@ -1359,8 +1341,6 @@ void Bot::escapeFromBomb_ () {
// didn't choose goal waypoint yet?
else if (!hasActiveGoal ()) {
clearSearchNodes ();
int bestIndex = kInvalidNodeIndex;
float safeRadius = rg.get (1513.0f, 2048.0f);

View file

@ -132,6 +132,7 @@ void Bot::updateAimDir () {
auto doFailPredict = [this] () {
m_aimFlags &= ~AimFlags::PredictPath;
m_trackingEdict = nullptr;
m_lookAt = m_destOrigin;
};
if (changePredictedEnemy) {
@ -147,7 +148,7 @@ void Bot::updateAimDir () {
}
}
if (graph.exists (predictNode) && pathLength < cv_max_nodes_for_predict.int_ ()) {
if (predictNode != kInvalidNodeIndex && pathLength < cv_max_nodes_for_predict.int_ ()) {
m_lookAt = graph[predictNode].origin;
m_lookAtSafe = m_lookAt;

View file

@ -33,19 +33,15 @@
<ClInclude Include="..\ext\crlib\crlib\simd.h" />
<ClInclude Include="..\ext\crlib\crlib\string.h" />
<ClInclude Include="..\ext\crlib\crlib\thread.h" />
<ClInclude Include="..\ext\crlib\crlib\timers.h" />
<ClInclude Include="..\ext\crlib\crlib\traits.h" />
<ClInclude Include="..\ext\crlib\crlib\twin.h" />
<ClInclude Include="..\ext\crlib\crlib\ulz.h" />
<ClInclude Include="..\ext\crlib\crlib\uniqueptr.h" />
<ClInclude Include="..\ext\crlib\crlib\vector.h" />
<ClInclude Include="..\ext\hlsdk\const.h" />
<ClInclude Include="..\ext\hlsdk\eiface.h" />
<ClInclude Include="..\ext\hlsdk\extdll.h" />
<ClInclude Include="..\ext\hlsdk\metamod.h" />
<ClInclude Include="..\ext\hlsdk\meta_api.h" />
<ClInclude Include="..\ext\hlsdk\model.h" />
<ClInclude Include="..\ext\hlsdk\physint.h" />
<ClInclude Include="..\ext\hlsdk\progdefs.h" />
<ClInclude Include="..\ext\hlsdk\util.h" />
<ClInclude Include="..\ext\linkage\linkage\goldsrc.h" />
<ClInclude Include="..\ext\linkage\linkage\metamod.h" />
<ClInclude Include="..\ext\linkage\linkage\physint.h" />
<ClInclude Include="..\inc\analyze.h" />
<ClInclude Include="..\inc\config.h" />
<ClInclude Include="..\inc\control.h" />
@ -141,6 +137,8 @@
<LinkIncremental>true</LinkIncremental>
<EmbedManifest>false</EmbedManifest>
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>.\release\</OutDir>
@ -168,7 +166,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\vc;..\inc;..\ext;..\ext\crlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\vc;..\inc;..\ext;..\ext\crlib;..\ext\linkage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;CR_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
@ -241,7 +239,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\vc;..\inc;..\ext;..\ext\crlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\vc;..\inc;..\ext;..\ext\crlib;..\ext\linkage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>

View file

@ -13,12 +13,12 @@
<Filter Include="inc\ext\crlib">
<UniqueIdentifier>{bec0fb46-08b4-4bfa-900c-d279a933ff77}</UniqueIdentifier>
</Filter>
<Filter Include="inc\ext\hlsdk">
<UniqueIdentifier>{f6a0fc04-bdf5-479b-8e5a-85eae698541e}</UniqueIdentifier>
</Filter>
<Filter Include="res">
<UniqueIdentifier>{5e73b918-f42b-4df9-bbe9-918289e44ad2}</UniqueIdentifier>
</Filter>
<Filter Include="inc\ext\linkage">
<UniqueIdentifier>{f6a0fc04-bdf5-479b-8e5a-85eae698541e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\inc\config.h">
@ -51,30 +51,6 @@
<ClInclude Include="..\inc\version.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\const.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\eiface.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\extdll.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\meta_api.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\metamod.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\model.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\progdefs.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\util.h">
<Filter>inc\ext\hlsdk</Filter>
</ClInclude>
<ClInclude Include="..\inc\module.h">
<Filter>inc</Filter>
</ClInclude>
@ -174,8 +150,20 @@
<ClInclude Include="..\ext\crlib\crlib\thread.h">
<Filter>inc\ext\crlib</Filter>
</ClInclude>
<ClInclude Include="..\ext\hlsdk\physint.h">
<Filter>inc\ext\hlsdk</Filter>
<ClInclude Include="..\ext\crlib\crlib\timers.h">
<Filter>inc\ext\crlib</Filter>
</ClInclude>
<ClInclude Include="..\ext\crlib\crlib\traits.h">
<Filter>inc\ext\crlib</Filter>
</ClInclude>
<ClInclude Include="..\ext\linkage\linkage\goldsrc.h">
<Filter>inc\ext\linkage</Filter>
</ClInclude>
<ClInclude Include="..\ext\linkage\linkage\metamod.h">
<Filter>inc\ext\linkage</Filter>
</ClInclude>
<ClInclude Include="..\ext\linkage\linkage\physint.h">
<Filter>inc\ext\linkage</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -239,6 +227,12 @@
<ClCompile Include="..\src\vistable.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\vision.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\tasks.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="yapb.rc">