WIP pmove, AI, etc. changes
This commit is contained in:
parent
d5053299dc
commit
822a7221b2
132 changed files with 5198 additions and 1950 deletions
|
@ -1,10 +1,18 @@
|
|||
# Bots
|
||||
|
||||
Bots are handled by BotLib, located under `src/botlib` in the directory tree.
|
||||
Bots are CPU controlled opponents. They can be useful for development, debugging but can also fun to play with.
|
||||
|
||||
They're fake clients, traversing the level, and acting upon objectives they either figure out themselves, or are told to to act a certain way.
|
||||
|
||||
We encourage any multiplayer game to support them, because they often also fill in the function of balancing teams. There's a whole slew of benefits of supporting bots, and players will generally thank you for including them.
|
||||
|
||||
## Technical Info
|
||||
|
||||
Bots are handled by BotLib, located under `src/botlib/` in the source tree.
|
||||
|
||||
Nuclide's BotLib takes some inspiration from **Quake III Arena** its bots, but shares no code or specific ideas or implementations. We do not use **AAS** for navigation, we leverage the route/pathfinding system **FTEQW** provides. Bots also share some code with regular NPC/Monster type entities through the use of the NSNavAI class.
|
||||
|
||||
Games are allowed to handle how they want to integrate bots themselves, but for development purposes there are ways to force bots to spawn.
|
||||
Games are allowed to handle how they want to integrate bots themselves, but for development purposes there are ways to force bots to spawn also.
|
||||
|
||||
# Bot profiles
|
||||
|
||||
|
@ -52,4 +60,38 @@ Force reset bots current trajectory and goals.
|
|||
|
||||
# Bot Console Variables
|
||||
|
||||
See `platform/cvars.cfg` under the `// bots` section.
|
||||
## bot_enable
|
||||
Enable (1) or disable (0) usage of bots in the game. Default is 1.
|
||||
|
||||
## bot_pause
|
||||
Enable (1) or disable (0) an interrupt for the Bot AIs thinking. Default is 0.
|
||||
|
||||
## bot_noChat
|
||||
Enable (1) or disable (0) a suppression of any bot chatter. Default is 0.
|
||||
|
||||
## bot_fastChat
|
||||
Enable (1) or disable (0) bot chatter that does not stop other inputs. Default is 0.
|
||||
|
||||
## bot_debug
|
||||
Enable (1) or disable (0) bot debug features that otherwise won't work. Default is 0.
|
||||
|
||||
## bot_developer
|
||||
Enable (1) or disable (0) bot debug text in console. Default is 0.
|
||||
|
||||
## bot_minClients
|
||||
When set, ensures to fill the server with this many players/bots. Default is -1.
|
||||
|
||||
## bot_aimless
|
||||
Enable (1) or disable (0) bot not knowing where to go. Will keep generating a new place to walk to.
|
||||
|
||||
## bot_crouch
|
||||
Enable (1) or disable (0) the forcing of bots crouching down.
|
||||
|
||||
## bot_walk
|
||||
Enable (1) or disable (0) the restriction of bots to walking speed.
|
||||
|
||||
## bot_prone
|
||||
Enable (1) or disable (0) the forcing of bots to crawl/prone.
|
||||
|
||||
## bot_dont_shoot
|
||||
Enable (1) or disable (0) bot pacifist mode.
|
||||
|
|
|
@ -192,6 +192,8 @@
|
|||
|
||||
[info_intermission](@ref info_intermission)
|
||||
|
||||
[info_landmark](@ref info_landmark)
|
||||
|
||||
[info_node](@ref info_node)
|
||||
|
||||
[info_node_air](@ref info_node_air)
|
||||
|
@ -286,6 +288,8 @@
|
|||
|
||||
[prop_physics](@ref prop_physics)
|
||||
|
||||
[prop_physics_multiplayer](@ref prop_physics_multiplayer)
|
||||
|
||||
[prop_rope](@ref prop_rope)
|
||||
|
||||
[prop_static](@ref prop_static)
|
||||
|
@ -296,6 +300,16 @@
|
|||
|
||||
[random_trigger](@ref random_trigger)
|
||||
|
||||
[script_brushmodel](@ref script_brushmodel)
|
||||
|
||||
[script_model](@ref script_model)
|
||||
|
||||
[script_origin](@ref script_origin)
|
||||
|
||||
[script_struct](@ref script_struct)
|
||||
|
||||
[script_vehicle](@ref script_vehicle)
|
||||
|
||||
[scripted_sentence](@ref scripted_sentence)
|
||||
|
||||
[scripted_sequence](@ref scripted_sequence)
|
||||
|
|
74
Documentation/MapC.md
Normal file
74
Documentation/MapC.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
# MapC Scripting
|
||||
|
||||
**Notice: This is an uncomitted document and is subject to change.**
|
||||
|
||||
Powered by the engine's multi-progs capability, maps can run their own isolated logic.
|
||||
This is inspired by the original MapC effort by [Team Fortress Software/Valve](https://web.archive.org/web/19990221213004/http://www.teamfortress.com:80/tfii/mc2.html) that never got off the ground.
|
||||
|
||||
Ritual's ÜberTools for Quake III also had a scripting system for each map, this is comparable to that also. The same extends to the **GSC** scripts found in Call of Duty that each map has.
|
||||
|
||||
If you're curious about use-cases, you should make yourself familar with what those games do.
|
||||
|
||||
## MapC versus QuakeC
|
||||
|
||||
MapC is basically a superset of QuakeC.
|
||||
You essentially write valid SSQC, but there's extra helper functions that you can use to communicate with entities from the server-side progs. Concepts that are alien to regular QuakeC code.
|
||||
|
||||
If a `mapscript.dat` is next to the map of the same name (`mapscript.bsp`), it will be included into the game.
|
||||
|
||||
An example source file from Nuclide's `base/test_maps.pk3dir/maps/mapscript.mapC`:
|
||||
|
||||
```cpp
|
||||
#pragma PROGS_DAT "mapscript.dat"
|
||||
|
||||
#include "../../../src/server/mapC.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
entity spawnPoint = spawnClass("info_player_start", [0, 0, 128]);
|
||||
spawnPoint.angles = [0, random(-180, 180), 0];
|
||||
spawnPoint.targetname = "SPSpawn";
|
||||
|
||||
spawnPoint = spawnClass("info_player_deathmatch", [0, 0, 128]);
|
||||
spawnPoint.angles = [0, random(-180, 180), 0];
|
||||
spawnPoint.targetname = "MPSpawn";
|
||||
}
|
||||
```
|
||||
|
||||
Here you can see that while we stick to the `entity` base type, we do get to use a new function to spawn entities: `spawnclass(string className, desiredPosition)`.
|
||||
|
||||
This ensures that the server-side progs gets to load all available [EntityDef](EntityDef.md) based entities, as well as all internal, available, class-based entities - and sends those to our map-specific progs.
|
||||
|
||||
If you don't use spawnClass(), expect to not be able to use the I/O system with the entity.
|
||||
|
||||
To have access to all features, make sure to include `mapC.h` from Nuclide's `src/server` directory. That file will continously be updated to add more functionality.
|
||||
|
||||
You can compile the MapC file with fteqcc (`fteqcc mapscript.mapC`) to receive `mapscript.dat`.
|
||||
|
||||
Like with regular QuakeC progs, you only have to include the resulting .dat with your game - although we encourage you to release the sources to all progs for modders and tinkerers to enjoy. It's also a way for users to support the game themselves in case you're no longer able to support it.
|
||||
|
||||
## Use cases, benefits
|
||||
|
||||
When it comes to managing the complexity of events in games like the Call of Duty series, this is a desired substitute to hundreds (sometimes thousands) of entities.
|
||||
|
||||
Boxing the map-specific logic also aids portability. With less dependence on Nuclide or other internal functions to organize and schedule most of its logic, forward compatibility is easily achieved.
|
||||
|
||||
The design has been proven across dozens of games within the Call of Duty series, with little to no changes - serving for both single and multiplayer logic. Managing waves of enemies, or writing entire game-modes using this type of set-up has been proven.
|
||||
|
||||
## Extra features over Vanilla SSQC
|
||||
|
||||
These extra functions are available to MapC programs:
|
||||
|
||||
### spawnClass(className, desiredPos)
|
||||
|
||||
Spawns the specified entity class name at the desired position. If the classname does not exist, it will return a new info_notnull type entity with no model or collision for you to modify.
|
||||
|
||||
### sendInput(targetEntity, inputName, dataString, targetActivator)
|
||||
|
||||
Sends an input event to an NSEntity and with a specific activator. While that can be __NULL__, this, or world most of the time - some inputs very much depend on the activator being valid within their respective contexts.
|
||||
|
||||
## Map-specific entities
|
||||
|
||||
You can bundle an [EntityDef](EntityDef.md) file with your level, like with MapC progs they have to have the same filename as the map, but with the extension ending in '**def**' (e.g. `maps/mapscript.def`).
|
||||
|
||||
The entities within that EntityDef file will be exclusive to that map. No other map can spawn them. If you want to make an EntityDef available to all maps, move it into the `def/` directory of your game directory.
|
57
Documentation/MapTypes.md
Normal file
57
Documentation/MapTypes.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Map Making
|
||||
|
||||
## Which Format You Should Use
|
||||
|
||||
That depends on the job. If you want to work with a modern format, comparable to that of a 2004 game engine and beyond, any variant of Quake III Arena's BSP format can do.
|
||||
We aim to support everything equally.
|
||||
|
||||
For a more authentic, 1990s experience you may want to use Quake II's format instead.
|
||||
|
||||
We have our own variant of the BSP format, which can be compiled by using [vmap](VMap.md).
|
||||
|
||||
### Quake BSP
|
||||
|
||||
This is the default format that all the Quake tools, such as [ericw-tools](https://ericwa.github.io/ericw-tools/) compile into. If you exceed limits, they generally will generate a **"BSP2"** file, which is something our engine also understands. The original engine and format only did monochrome color. This is no issue any longer because modern compilers output so called **lit** files, which contain colored lightmaps externally. If a Quake engine supports colored lights, they'll usually load them automatically.
|
||||
|
||||
However, creating non-planar surfaces or changing the lightmap quality on individual surfaces is not supported in this format. If you want to use features such as crouching or proning you have to compile your map with **BSPX** extensions. Other formats also include more features, which can help optimise the network and rendering performance of a level. So use of this format is discouraged by us.
|
||||
|
||||
You can totally use it if you're going for a certain aesthetic, just be aware of its limitations. You cannot optimise levels beyond a certain point due to a lack of area-portals which were introduced with Quake II BSP.
|
||||
|
||||
### Quake II BSP
|
||||
|
||||
A better choice over Quake's standard BSP format. These support area-portals and proper detail brushes can help optimise the level even further.
|
||||
|
||||
### Quake III Arena BSP
|
||||
|
||||
**The recommended format.** Support for everything Quake II's BSP does, but you can now put a lot of detailed geometry into so called triangle soup, and design your own content volumes (beyond water, lava, slime), and surface flags (make bullets ricochet, or leak water) - make use of curved surfaces, massive maps with terrain and texture blending. Support for different lightmap scales per surface, and alternative vertex-lit levels can also give you tigter controls about lighting performance and visual fidelity.
|
||||
|
||||
### VMAP compiled BSP
|
||||
|
||||
Our own version of the Quake III Arena BSP format. It supports a bunch of new things.
|
||||
The compiler doesn't read .shader files from `scripts/` but instead `.mat` files alongside the textures within the textures directory, as well as a custom patch/curve format.
|
||||
|
||||
Only use this if you really, really want to use the things we developed. You will have a smoother experience with most other formats right now.
|
||||
|
||||
### Other Formats
|
||||
|
||||
While the engine can read other formats, such as BSP30 and beyond - please ensure you do have the rights to use the tools in such fashion. For example, for developers coming from the Half-Life SDK you are not allowed to use compilers and versions deriving from the original sources to make maps for Nuclide based projects. You will have to negotiate a license with Valve or use a free-software tool such as [ericw-tools](https://ericwa.github.io/ericw-tools/).
|
||||
|
||||
## Recommended Tools
|
||||
|
||||
We don't require you to use WorldSpawn or VMAP. You can use any of the above formats, and whatever editor you like to use to get the job done.
|
||||
|
||||
Here's a list of popular editors we've seen people use successfully:
|
||||
|
||||
- NetRadiant-Custom
|
||||
- TrenchBroom
|
||||
- NetRadiant
|
||||
- GtkRadiant
|
||||
- QuArK
|
||||
- JACK (proprietary)
|
||||
|
||||
However we do not provide support for any of them. Please talk to the developers of the respective tools if you're experiencing issues. First ensure that you're able to make levels for your target format.
|
||||
|
||||
For example, create an example map for Quake, test it in Quake and then copy it into your Nuclide directory after verifying it works and that the workflow is right for you.
|
||||
You may need to switch tools if you're not comfortable, and only once you're fully set and familar with the map-making toolchain should you attempt to run the maps in Nuclide.
|
||||
|
||||
As map-making is a complicated process, a lot of issues you can run into while making levels for Nuclide, may actually be issues with the toolchain you're using to make the map. So verify it works in the target format's game of choice first.
|
1
Doxyfile
1
Doxyfile
|
@ -893,6 +893,7 @@ INPUT = src/ \
|
|||
Documentation/Shaders/ \
|
||||
Documentation/Constants.md \
|
||||
Documentation/EntityDef.md \
|
||||
Documentation/MapC.md \
|
||||
Documentation/Surf_data.md \
|
||||
Documentation/Prop_data.md \
|
||||
Documentation/MapTweaks.md \
|
||||
|
|
26
base/radiant.game
Normal file
26
base/radiant.game
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<game
|
||||
type="hl"
|
||||
name="Nuclide"
|
||||
enginepath_linux="/usr/local/games/nuclide/"
|
||||
enginepath_win32="c:/vera/nuclide/"
|
||||
engine_win32="fteqw.exe"
|
||||
engine_linux="fteqw"
|
||||
basegame="platform"
|
||||
basegamename="Nuclide"
|
||||
unknowngamename="Nuclide Game Directory"
|
||||
default_scale="0.5"
|
||||
no_patch="0"
|
||||
no_bsp_monitor="0"
|
||||
show_wads="0"
|
||||
archivetypes="pk3"
|
||||
texturetypes="tga ktx"
|
||||
modeltypes="iqm"
|
||||
maptypes="mapq3"
|
||||
shaders="quake3"
|
||||
entityclass="quake3"
|
||||
entityclasstype="def"
|
||||
entities="quake3"
|
||||
brushtypes="quake"
|
||||
patchtypes="quake3"
|
||||
/>
|
26
base/radiiant.xml
Normal file
26
base/radiiant.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<project version="2.0">
|
||||
<var name="vmap">"[RadiantPath]vmap" -v<cond value="[MonitorAddress]"> -connect [MonitorAddress]</cond> -game platform -fs_basepath "[EnginePath]"<cond value="[GameName]"> -fs_game [GameName]</cond></var>
|
||||
|
||||
|
||||
<build name="Fast Fullbright">
|
||||
<command>[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]"</command>
|
||||
<command>[vmap] -vis -v -fast "[MapFile]"</command>
|
||||
</build>
|
||||
|
||||
<build name="Fast">
|
||||
<command>[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]"</command>
|
||||
<command>[vmap] -vis -v -fast "[MapFile]"</command>
|
||||
<command>[vmap] -light -custinfoparms -v -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]"</command>
|
||||
</build>
|
||||
|
||||
<build name="Full">
|
||||
<command>[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]"</command>
|
||||
<command>[vmap] -vis "[MapFile]"</command>
|
||||
<command>[vmap] -light -custinfoparms -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]"</command>
|
||||
</build>
|
||||
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -12,7 +12,7 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
*/
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -25,11 +25,11 @@ struct
|
|||
} g_camBobVars[4], *pCamBob;
|
||||
|
||||
/* tilts the camera for a head-bob like effect when moving */
|
||||
void
|
||||
Camera_RunBob(__inout vector camera_angle)
|
||||
vector
|
||||
Camera_RunBob(vector camera_angle)
|
||||
{
|
||||
if (!autocvar(v_cambob, 1, "Enables bobbing effect for the first-person camera"))
|
||||
return;
|
||||
return camera_angle;
|
||||
|
||||
int s = (float)getproperty(VF_ACTIVESEAT);
|
||||
pCamBob = &g_camBobVars[s];
|
||||
|
@ -39,15 +39,16 @@ Camera_RunBob(__inout vector camera_angle)
|
|||
speed[2] = 0.0f;
|
||||
pCamBob->m_flSpeed = vlen(speed);
|
||||
|
||||
if (pCamBob->m_flSpeed > 330.0f)
|
||||
pCamBob->m_flSpeed = 330.0f;
|
||||
|
||||
/* don't bother on low speeds */
|
||||
if ( pCamBob->m_flSpeed < 5.0f ) {
|
||||
pCamBob->m_flMove = 0.0f;
|
||||
pCamBob->m_flTime = 0.0f; /* progress has halted, start anew */
|
||||
return;
|
||||
} else if (pSeat->m_ePlayer.flags & FL_ONGROUND && pSeat->m_ePlayer.waterlevel == 0) {
|
||||
pCamBob->m_flMove = clframetime * (pCamBob->m_flSpeed * 0.01);
|
||||
return camera_angle;
|
||||
} else {
|
||||
pCamBob->m_flMove = 0.0f;
|
||||
pCamBob->m_flMove = frametime * (pCamBob->m_flSpeed * 0.01);
|
||||
}
|
||||
|
||||
pCamBob->m_flTime = (pCamBob->m_flTime += pCamBob->m_flMove);
|
||||
|
@ -62,14 +63,15 @@ Camera_RunBob(__inout vector camera_angle)
|
|||
}
|
||||
|
||||
camera_angle[2] += pCamBob->m_flDelta;
|
||||
return camera_angle;
|
||||
}
|
||||
|
||||
/* applies a tilt to the camera for when we're strafing left to right */
|
||||
void
|
||||
Camera_StrafeRoll(__inout vector camera_angle)
|
||||
vector
|
||||
Camera_StrafeRoll(vector camera_angle)
|
||||
{
|
||||
if (!autocvar(v_camroll, 0, "Enables strafe-roll for the first-person camera"))
|
||||
return;
|
||||
return camera_angle;
|
||||
|
||||
float roll;
|
||||
makevectors(camera_angle);
|
||||
|
@ -78,4 +80,38 @@ Camera_StrafeRoll(__inout vector camera_angle)
|
|||
roll *= 0.015f;
|
||||
|
||||
camera_angle[2] += roll;
|
||||
return camera_angle;
|
||||
}
|
||||
|
||||
vector
|
||||
Camera_AddLean(vector viewAngle)
|
||||
{
|
||||
vector shift = anglesToRight(viewAngle);
|
||||
vector output;
|
||||
vector srcPos;
|
||||
float heightChange;
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
if (pSeat->m_iLeanDir > 0i) {
|
||||
pSeat->m_flLeaning += frametime * 5;
|
||||
} else if (pSeat->m_iLeanDir < 0i) {
|
||||
pSeat->m_flLeaning -= frametime * 5;
|
||||
} else {
|
||||
pSeat->m_flLeaning = lerp(pSeat->m_flLeaning, 0.0, frametime * 10);
|
||||
}
|
||||
|
||||
if (pSeat->m_flLeaning > 1.0) {
|
||||
pSeat->m_flLeaning = 1.0f;
|
||||
}
|
||||
|
||||
if (pSeat->m_flLeaning < -1.0) {
|
||||
pSeat->m_flLeaning = -1.0f;
|
||||
}
|
||||
|
||||
heightChange = cos(pSeat->m_flLeaning) * 4;
|
||||
srcPos = pl.GetEyePos();
|
||||
output = shift * (pSeat->m_flLeaning * 15.0);
|
||||
tracebox(srcPos, [-8,-8,-8], [8,8,8], srcPos + output, MOVE_NORMAL, pl);
|
||||
|
||||
return output * trace_fraction + (shift * -1.0) + [0, 0, heightChange];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -12,11 +12,18 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
*/
|
||||
|
||||
var float autocvar_v_bob = 0.01f;
|
||||
var float autocvar_v_bobcycle = 1.0f;
|
||||
var float autocvar_v_bobup = 0.5f;
|
||||
#define BOB_STRENGTH 0.02
|
||||
#define BOB_CYCLE 1.0
|
||||
#define BOB_UP 0.60
|
||||
|
||||
var vector autocvar_bg_bobAmplitudeDucked = [0.0075, 0.0065, 0.0000];
|
||||
var vector autocvar_bg_bobAmplitudeProne = [0.02, 0.005, 0.0000];
|
||||
var vector autocvar_bg_bobAmplitudeSprinting = [0.02, 0.014, 0.0000];
|
||||
var vector autocvar_bg_bobAmplitudeStanding = [0.007, 0.007, 0.0000];
|
||||
var float autocvar_bg_bobMax = 8.0;
|
||||
var float autocvar_player_sprintCameraBob = 0.5;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -27,6 +34,9 @@ struct
|
|||
float m_flBobCycle;
|
||||
float m_flBobCycle2;
|
||||
float m_flSpeed;
|
||||
|
||||
float m_flViewBob;
|
||||
float m_flViewBob2;
|
||||
} g_viewBobVars[4], *pViewBob;
|
||||
|
||||
|
||||
|
@ -45,13 +55,20 @@ Viewmodel_CalcBob(void)
|
|||
float var_bob;
|
||||
float var_cycle;
|
||||
float var_up;
|
||||
bool isSprinting = pSeat->m_ePlayer.vv_flags & VFL_SPRINTING;
|
||||
bool isCrouching = pSeat->m_ePlayer.vv_flags & VFL_CROUCHING;
|
||||
|
||||
var_bob = autocvar_v_bob;
|
||||
var_cycle = autocvar_v_bobcycle;
|
||||
var_up = autocvar_v_bobup;
|
||||
// if (pSeatLocal->m_iSprinting && vlen(pSeat->m_vecPredictedVelocity) > 240)
|
||||
// isSprinting = true;
|
||||
|
||||
pViewBob->m_flBobTime += clframetime;
|
||||
pViewBob->m_flBobTime2 += clframetime;
|
||||
var_bob = BOB_STRENGTH;
|
||||
var_cycle = BOB_CYCLE;
|
||||
var_up = BOB_UP;
|
||||
|
||||
if (isSprinting)
|
||||
var_cycle *= autocvar_player_sprintCameraBob;
|
||||
|
||||
pViewBob->m_flBobTime += frametime;
|
||||
pViewBob->m_flBobCycle = pViewBob->m_flBobTime - (int)(pViewBob->m_flBobTime / var_cycle) * var_cycle;
|
||||
pViewBob->m_flBobCycle /= var_cycle;
|
||||
|
||||
|
@ -66,10 +83,11 @@ Viewmodel_CalcBob(void)
|
|||
pViewBob->m_flSpeed = vlen(vecVel);
|
||||
|
||||
flBob = pViewBob->m_flSpeed * var_bob;
|
||||
flBob = flBob * 0.3 + flBob * 0.7 * sin(pViewBob->m_flBobCycle);
|
||||
pViewBob->m_flBob = bound(-7, flBob, 4);
|
||||
flBob = flBob * sin(pViewBob->m_flBobCycle);
|
||||
pViewBob->m_flBob = flBob;
|
||||
|
||||
/* BOB2, which is half the cycle of bob1 */
|
||||
pViewBob->m_flBobTime2 += frametime;
|
||||
pViewBob->m_flBobCycle2 = pViewBob->m_flBobTime2 - (int)(pViewBob->m_flBobTime2 / (var_cycle * 0.5f)) * (var_cycle * 0.5f);
|
||||
pViewBob->m_flBobCycle2 /= (var_cycle * 0.5f);
|
||||
|
||||
|
@ -79,12 +97,26 @@ Viewmodel_CalcBob(void)
|
|||
pViewBob->m_flBobCycle2 = MATH_PI + MATH_PI * (pViewBob->m_flBobCycle2 - var_up)/(1.0 - var_up);
|
||||
}
|
||||
|
||||
flBob = pViewBob->m_flSpeed * var_bob;
|
||||
flBob = flBob * 0.3 + flBob * 0.7 * sin(pViewBob->m_flBobCycle2);
|
||||
pViewBob->m_flBob2 = bound(-7, flBob, 4);
|
||||
flBob = pViewBob->m_flSpeed * (var_bob * 0.5);
|
||||
flBob = flBob * cos(pViewBob->m_flBobCycle2);
|
||||
pViewBob->m_flBob2 = flBob;
|
||||
|
||||
/* make sure it's adjusted for scale */
|
||||
pViewBob->m_flBob *= autocvar_cg_viewmodelScale;
|
||||
if (isSprinting) {
|
||||
pViewBob->m_flViewBob2 = pViewBob->m_flBob2 * autocvar_bg_bobAmplitudeSprinting[0] * 25.0f;
|
||||
pViewBob->m_flViewBob = pViewBob->m_flBob * autocvar_bg_bobAmplitudeSprinting[1] * 25.0f;
|
||||
pViewBob->m_flBob2 *= autocvar_bg_bobAmplitudeSprinting[0] * 20.0;
|
||||
pViewBob->m_flBob *= autocvar_bg_bobAmplitudeSprinting[1] * 20.0;
|
||||
} else if (isCrouching) {
|
||||
pViewBob->m_flViewBob2 = pViewBob->m_flBob2 * autocvar_bg_bobAmplitudeDucked[0] * 25.0f;
|
||||
pViewBob->m_flViewBob = pViewBob->m_flBob * autocvar_bg_bobAmplitudeDucked[1] * 25.0f;
|
||||
pViewBob->m_flBob2 *= autocvar_bg_bobAmplitudeDucked[0] * 20.0;
|
||||
pViewBob->m_flBob *= autocvar_bg_bobAmplitudeDucked[1] * 20.0;
|
||||
} else {
|
||||
pViewBob->m_flViewBob2 = pViewBob->m_flBob2 * autocvar_bg_bobAmplitudeStanding[0] * 25.0f;
|
||||
pViewBob->m_flViewBob = pViewBob->m_flBob * autocvar_bg_bobAmplitudeStanding[1] * 25.0f;
|
||||
pViewBob->m_flBob2 *= autocvar_bg_bobAmplitudeStanding[0] * 20.0;
|
||||
pViewBob->m_flBob *= autocvar_bg_bobAmplitudeStanding[1] * 20.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -95,13 +127,18 @@ Viewmodel_ApplyBob(entity gun)
|
|||
|
||||
float sintime;
|
||||
float strength;
|
||||
gun.angles[2] = -pViewBob->m_flBob;
|
||||
float kickUp;
|
||||
//gun.angles[2] = pViewBob->m_flBob2 * -2.0f;
|
||||
gun.angles[2] = pViewBob->m_flViewBob * 4.0f;
|
||||
kickUp = pViewBob->m_flViewBob2 * 4.0f;
|
||||
|
||||
vector angmod = [0,0,0];
|
||||
angmod[0] -= pViewBob->m_flBob2 * 0.5f;
|
||||
angmod[1] += pViewBob->m_flBob * 2.5f;
|
||||
angmod[2] += pViewBob->m_flBob * 3.0f;
|
||||
gun.angles += angmod * 1.5f;
|
||||
|
||||
angmod[0] = pViewBob->m_flViewBob2 + kickUp;
|
||||
angmod[1] = pViewBob->m_flViewBob;
|
||||
|
||||
//angmod[2] += pViewBob->m_flBob * 3.0f;
|
||||
gun.angles += angmod;
|
||||
|
||||
/* sway with speed */
|
||||
sintime = sin(time);
|
||||
|
@ -111,19 +148,19 @@ Viewmodel_ApplyBob(entity gun)
|
|||
strength = 240;
|
||||
|
||||
strength = 240 - strength;
|
||||
strength *= 0.005f;
|
||||
strength *= 0.01f;
|
||||
|
||||
#ifdef WASTES
|
||||
float sprint;
|
||||
if (pSeatLocal->m_iSprinting && vlen(pSeat->m_vecPredictedVelocity) > 240) {
|
||||
pSeatLocal->m_flSprintLerp = bound(0.0f, pSeatLocal->m_flSprintLerp + clframetime, 1.0f);
|
||||
if (pSeat->m_ePlayer.vv_flags & VFL_SPRINTING) {
|
||||
pSeat->m_flSprintLerp = bound(0.0f, pSeat->m_flSprintLerp + clframetime, 1.0f);
|
||||
} else {
|
||||
pSeatLocal->m_flSprintLerp = bound(0.0f, pSeatLocal->m_flSprintLerp - clframetime, 1.0f);
|
||||
pSeat->m_flSprintLerp = bound(0.0f, pSeat->m_flSprintLerp - clframetime, 1.0f);
|
||||
}
|
||||
sprint = 20 * pSeatLocal->m_flSprintLerp;
|
||||
sprint = 20 * pSeat->m_flSprintLerp;
|
||||
gun.angles[0] += sprint;
|
||||
gun.angles[1] += sprint + (sprint * pViewBob->m_flBob) * 0.25f;
|
||||
|
||||
#ifdef WASTES
|
||||
if (pSeat->m_ePlayer.gflags & GF_IS_HEALING) {
|
||||
pSeatLocal->m_flHealLerp = bound(0.0f, pSeatLocal->m_flHealLerp + clframetime, 1.0f);
|
||||
} else {
|
||||
|
@ -135,6 +172,31 @@ Viewmodel_ApplyBob(entity gun)
|
|||
|
||||
gun.angles[0] += strength * sintime;
|
||||
gun.angles[1] += strength * sintime;
|
||||
gun.angles[2] += strength * sintime;
|
||||
//gun.angles[2] += strength * sintime;
|
||||
gun.origin += [0,0,-1];
|
||||
|
||||
makevectors(g_view.GetCameraAngle());
|
||||
gun.origin += v_forward * cvar("cl_gunx");
|
||||
gun.origin += v_right * cvar("cl_guny");
|
||||
gun.origin += v_up * cvar("cl_gunz");
|
||||
|
||||
/* lower gun when moving */
|
||||
if (pViewBob->m_flSpeed > 10.0) {
|
||||
gun.origin += (v_up * -pViewBob->m_flSpeed * 0.005f);
|
||||
gun.origin += (v_right * -pViewBob->m_flSpeed * 0.005f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector
|
||||
Camera_AddCamBob(vector cameraAngle)
|
||||
{
|
||||
vector angmod = g_vec_null;
|
||||
|
||||
makevectors(cameraAngle);
|
||||
|
||||
angmod = (pViewBob->m_flBob2 * -v_up);
|
||||
angmod += (pViewBob->m_flBob * -v_right);
|
||||
|
||||
return angmod;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ GameRules::LevelDecodeParms(NSClientPlayer pp)
|
|||
pl.activeweapon = parm11;
|
||||
pl.flags = parm64;
|
||||
|
||||
if (pl.flags & FL_CROUCHING) {
|
||||
if (pl.vv_flags & VFL_CROUCHING) {
|
||||
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
|
||||
} else {
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
|
|
|
@ -47,6 +47,7 @@ SingleplayerRules::PlayerSpawn(NSClientPlayer pl)
|
|||
pl.viewzoom = 1.0;
|
||||
pl.model = "models/player.mdl";
|
||||
setmodel(pl, pl.model);
|
||||
pl.AddEffects(EF_NOSHADOW);
|
||||
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
pl.velocity = [0,0,0];
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#includelist
|
||||
player.qc
|
||||
weapon_common.h
|
||||
weapons.h
|
||||
flags.h
|
||||
fx_blood.qc
|
||||
fx_corpse.qc
|
||||
weapons.qc
|
||||
weapon_common.qc
|
||||
#endlist
|
||||
|
|
|
@ -35,6 +35,7 @@ class player:NSClientPlayer
|
|||
virtual void(float,float) ReceiveEntity;
|
||||
virtual void(void) PredictPreFrame;
|
||||
virtual void(void) PredictPostFrame;
|
||||
virtual void(void) UpdateAliveCam;
|
||||
#else
|
||||
virtual void(void) EvaluateEntity;
|
||||
virtual float(entity, float) SendEntity;
|
||||
|
@ -42,6 +43,41 @@ class player:NSClientPlayer
|
|||
};
|
||||
|
||||
#ifdef CLIENT
|
||||
|
||||
|
||||
void Shake_Update(NSClientPlayer);
|
||||
vector Camera_RunBob(vector);
|
||||
vector Camera_StrafeRoll(vector);
|
||||
vector Camera_AddCamBob(vector);
|
||||
vector Camera_AddLean(vector);
|
||||
void View_DisableViewmodel(void);
|
||||
void
|
||||
player::UpdateAliveCam(void)
|
||||
{
|
||||
vector cam_pos = GetEyePos();
|
||||
|
||||
g_view.SetCameraAngle(view_angles);
|
||||
g_view.SetCameraOrigin(cam_pos + Camera_AddCamBob(view_angles) + Camera_AddLean(view_angles));
|
||||
|
||||
if (vehicle) {
|
||||
NSVehicle veh = (NSVehicle)vehicle;
|
||||
|
||||
if (veh.UpdateView)
|
||||
veh.UpdateView();
|
||||
} else if (health) {
|
||||
if (autocvar_pm_thirdPerson == TRUE) {
|
||||
makevectors(view_angles);
|
||||
vector vStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
|
||||
vector vEnd = vStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
|
||||
traceline(vStart, vEnd, FALSE, this);
|
||||
g_view.SetCameraOrigin(trace_endpos + (v_forward * 5));
|
||||
}
|
||||
}
|
||||
|
||||
Shake_Update(this);
|
||||
g_view.AddPunchAngle(punchangle);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::ReceiveEntity
|
||||
|
|
|
@ -93,8 +93,10 @@ do
|
|||
KEY_MAXS="$(cat /tmp/def_maxs)"
|
||||
KEY_USAGE="$(cat /tmp/def_usage)"
|
||||
KEY_MODEL="$(cat /tmp/def_model)"
|
||||
|
||||
# reset defaults
|
||||
printf -- "" > "/tmp/def_name"
|
||||
printf -- "" > "/tmp/def_color"
|
||||
printf -- "1 0 1" > "/tmp/def_color"
|
||||
printf -- "" > "/tmp/def_mins"
|
||||
printf -- "" > "/tmp/def_mins"
|
||||
printf -- "" > "/tmp/def_maxs"
|
||||
|
|
|
@ -180,6 +180,12 @@ varying vec3 norm;
|
|||
discard;
|
||||
#endif
|
||||
|
||||
#if r_skipDetail == 0
|
||||
#if defined(UPPERLOWER)
|
||||
diffuse_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FAKESHADOWS
|
||||
diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
|
||||
#endif
|
||||
|
@ -234,13 +240,6 @@ varying vec3 norm;
|
|||
if (alpha > 1.0)
|
||||
alpha = 1.0;
|
||||
|
||||
|
||||
#if r_skipDetail == 0
|
||||
#if defined(UPPERLOWER)
|
||||
diffuse_f.rgb *= (texture2D(s_upper, tex_c * 4.0).rgb + 0.5);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(fog3(diffuse_f.rgb), alpha);
|
||||
}
|
||||
#endif
|
||||
|
|
36
platform/base_glsl.pk3dir/glsl/portal.glsl
Normal file
36
platform/base_glsl.pk3dir/glsl/portal.glsl
Normal file
|
@ -0,0 +1,36 @@
|
|||
//======= Copyright (c) 2023 Vera Visions LLC. All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// Unlit surface.
|
||||
//==============================================================================
|
||||
|
||||
!!ver 110
|
||||
!!permu FOG
|
||||
!!samps diffuse
|
||||
|
||||
#include "sys/defs.h"
|
||||
#include "sys/fog.h"
|
||||
|
||||
varying vec2 tex_c;
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
void main ()
|
||||
{
|
||||
tex_c = v_texcoord;
|
||||
gl_Position = ftetransform();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FRAGMENT_SHADER
|
||||
void main ()
|
||||
{
|
||||
vec4 d_f = vec4(1.0, 1.0, 1.0, 1.0) - texture2D( s_diffuse, tex_c );
|
||||
|
||||
if (d_f.a > 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragColor = fog4( d_f );
|
||||
}
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
entityDef bot
|
||||
{
|
||||
spawnclass NSBot
|
||||
"spawnclass" "NSBot"
|
||||
}
|
4
platform/base_scripts.pk3dir/def/player.def
Normal file
4
platform/base_scripts.pk3dir/def/player.def
Normal file
|
@ -0,0 +1,4 @@
|
|||
entityDef player
|
||||
{
|
||||
"spawnclass" "NSClientPlayer"
|
||||
}
|
|
@ -1,26 +1,26 @@
|
|||
entityDef info_player_start
|
||||
{
|
||||
editor_mins "-16 -16 -36"
|
||||
editor_maxs "16 16 36"
|
||||
editor_description "Singleplayer Spawn Point"
|
||||
|
||||
spawnclass NSSpawnPoint
|
||||
"editor_mins" "-16 -16 -36"
|
||||
"editor_maxs" "16 16 36"
|
||||
"editor_description" "Singleplayer Spawn Point"
|
||||
"editor_color" "1 0 0"
|
||||
"spawnclass" "NSSpawnPoint"
|
||||
}
|
||||
|
||||
entityDef info_player_deathmatch
|
||||
{
|
||||
editor_mins "-16 -16 -36"
|
||||
editor_maxs "16 16 36"
|
||||
editor_description "Deathmatch Spawn Point"
|
||||
|
||||
spawnclass NSSpawnPoint
|
||||
"editor_mins" "-16 -16 -36"
|
||||
"editor_maxs" "16 16 36"
|
||||
"editor_description" "Deathmatch Spawn Point"
|
||||
"editor_color" "1 0 0"
|
||||
"spawnclass" "NSSpawnPoint"
|
||||
}
|
||||
|
||||
entityDef info_player_coop
|
||||
{
|
||||
editor_mins "-16 -16 -36"
|
||||
editor_maxs "16 16 36"
|
||||
editor_description "Cooperative Spawn Point"
|
||||
|
||||
spawnclass NSSpawnPoint
|
||||
"editor_mins" "-16 -16 -36"
|
||||
"editor_maxs" "16 16 36"
|
||||
"editor_description" "Cooperative Spawn Point"
|
||||
"editor_color" "1 0 0"
|
||||
"spawnclass" "NSSpawnPoint"
|
||||
}
|
|
@ -141,7 +141,7 @@ seta con_notifylines "0"
|
|||
// set a default locale, because the engine won't
|
||||
seta lang "en_us"
|
||||
// external texture formats that we recognize
|
||||
seta r_imageextensions "vtf tga bmp pcx png jpg"
|
||||
seta r_imageextensions "bmp dds jpg ktx pcx png tga vtf"
|
||||
// store screenshots in TrueVision Targa by default
|
||||
seta scr_sshot_type "tga"
|
||||
// don't force music loops
|
||||
|
|
|
@ -80,6 +80,10 @@ class NSBot:player
|
|||
virtual botstate_t(void) GetState;
|
||||
virtual botpersonality_t(void) GetPersonality;
|
||||
|
||||
virtual float GetForwardSpeed(void);
|
||||
virtual float GetSideSpeed(void);
|
||||
virtual float GetBackSpeed(void);
|
||||
|
||||
virtual void(string) ChatSay;
|
||||
virtual void(string) ChatSayTeam;
|
||||
virtual void(void) Pain;
|
||||
|
@ -109,9 +113,9 @@ entity Bot_AddQuick(void);
|
|||
void
|
||||
Bot_RandomColormap(NSBot target)
|
||||
{
|
||||
vector x = hsv2rgb(random() * 360, 100, 100);
|
||||
vector x = hsvToRGB(random() * 360, 100, 100);
|
||||
float top = x[2] + (x[1] << 8) + (x[0] << 16);
|
||||
x = hsv2rgb(random() * 360, 100, 100);
|
||||
x = hsvToRGB(random() * 360, 100, 100);
|
||||
float bottom = x[2] + (x[1] << 8) + (x[0] << 16);
|
||||
forceinfokey(target, "topcolor", sprintf("0x%x", top));
|
||||
forceinfokey(target, "bottomcolor", sprintf("0x%x", bottom));
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* default client side player movement values */
|
||||
var float autocvar_bot_forwardspeed = 190;
|
||||
var float autocvar_bot_sidespeed = 152;
|
||||
var float autocvar_bot_backspeed = 133;
|
||||
|
||||
botstate_t
|
||||
NSBot::GetState(void)
|
||||
{
|
||||
|
@ -44,6 +49,24 @@ NSBot::GetRunSpeed(void)
|
|||
return 240;
|
||||
}
|
||||
|
||||
float
|
||||
NSBot::GetForwardSpeed(void)
|
||||
{
|
||||
return (autocvar_bot_forwardspeed);
|
||||
}
|
||||
|
||||
float
|
||||
NSBot::GetSideSpeed(void)
|
||||
{
|
||||
return (autocvar_bot_sidespeed);
|
||||
}
|
||||
|
||||
float
|
||||
NSBot::GetBackSpeed(void)
|
||||
{
|
||||
return (autocvar_bot_backspeed);
|
||||
}
|
||||
|
||||
void
|
||||
NSBot::RouteClear(void)
|
||||
{
|
||||
|
@ -79,7 +102,7 @@ NSBot::UseButton(void)
|
|||
pos[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0]));
|
||||
pos[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1]));
|
||||
pos[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2]));
|
||||
dist = vlen(origin - pos);
|
||||
dist = distanceSquared(origin, pos);
|
||||
|
||||
if (dist < bestDist) {
|
||||
bestDist = dist;
|
||||
|
@ -144,9 +167,7 @@ NSBot::SeeThink(void)
|
|||
continue;
|
||||
|
||||
/* first, is the potential enemy in our field of view? */
|
||||
makevectors(v_angle);
|
||||
vector v = normalize(w.origin - origin);
|
||||
flDot = v * v_forward;
|
||||
flDot = vectorNormalize(w.origin - origin) * anglesToForward(v_angle);
|
||||
|
||||
if (flDot < 90/180)
|
||||
continue;
|
||||
|
@ -200,7 +221,7 @@ NSBot::CheckRoute(void)
|
|||
if (m_iCurNode >= 0) {
|
||||
/* if a node is flagged as jumpy, jump! */
|
||||
if (Route_GetNodeFlags(&m_pRoute[m_iCurNode]) & LF_JUMP) {
|
||||
//input_buttons |= INPUT_BUTTON2;
|
||||
//input_buttons |= INPUT_JUMP;
|
||||
velocity = Route_GetJumpVelocity(origin, m_pRoute[m_iCurNode].dest, gravity);
|
||||
}
|
||||
|
||||
|
@ -245,16 +266,15 @@ NSBot::CheckRoute(void)
|
|||
if (m_flNodeGiveup >= 1.0f || m_iCurNode <= BOTROUTE_END) {
|
||||
BotEntLog("Taking too long! Giving up!");
|
||||
RouteClear();
|
||||
} else if (m_flNodeGiveup >= 0.5f) {
|
||||
/* attempt a jump after half a second */
|
||||
|
||||
} else if (m_flNodeGiveup >= 0.5f) { /* attempt a jump after half a second */
|
||||
/* don't bother if it's too high (we're aiming at air... */
|
||||
if ((vecEndPos[2] - 32) < origin[2])
|
||||
input_buttons |= INPUT_BUTTON2;
|
||||
if ((vecEndPos[2] - 32) < origin[2]) {
|
||||
input_buttons |= INPUT_JUMP;
|
||||
}
|
||||
} else {
|
||||
/* entire way-link needs to be crouched. that's the law of the land */
|
||||
if (Route_GetNodeFlags(&m_pRoute[m_iCurNode]) & LF_CROUCH || autocvar_bot_crouch)
|
||||
input_buttons |= INPUT_BUTTON8;
|
||||
input_buttons |= INPUT_CROUCH;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,7 +305,7 @@ NSBot::RunAI(void)
|
|||
}
|
||||
|
||||
/* DEVELOPER CVAR: freeze the bot */
|
||||
if (autocvar_bot_stop)
|
||||
if (autocvar_bot_pause)
|
||||
return;
|
||||
|
||||
/* create our first route */
|
||||
|
@ -344,8 +364,8 @@ NSBot::RunAI(void)
|
|||
/* if we've got a path (we always should) move the bot */
|
||||
if (m_iNodes) {
|
||||
bool goRoute = false;
|
||||
vector vecNewAngles;
|
||||
vector vecDirection;
|
||||
vector vecNewAngles = g_vec_null;
|
||||
vector vecDirection = g_vec_null;
|
||||
|
||||
/* no enemy, or it isn't visible... then stare at nodes! */
|
||||
if (!m_eTarget || enemyVisible == false) {
|
||||
|
@ -369,8 +389,7 @@ NSBot::RunAI(void)
|
|||
|
||||
/* aim ahead if aimPos is somehow invalid */
|
||||
if (aimPos == [0,0,0]) {
|
||||
makevectors(angles);
|
||||
aimPos = origin + v_forward * 128;
|
||||
aimPos = origin + anglesToForward(angles) * 128;
|
||||
}
|
||||
|
||||
/* lerping speed, faster when we've got a target */
|
||||
|
@ -379,28 +398,17 @@ NSBot::RunAI(void)
|
|||
else
|
||||
flLerp = bound(0.0f, frametime * 30, 1.0f);
|
||||
|
||||
/* that's the old angle */
|
||||
makevectors(v_angle);
|
||||
vecNewAngles = v_forward;
|
||||
/* that's actually the old angle */
|
||||
vecNewAngles = anglesToForward(v_angle);
|
||||
|
||||
/* aimDir = new final angle */
|
||||
aimDir = vectoangles(aimPos - origin);
|
||||
makevectors(aimDir);
|
||||
aimDir = vectorToAngles(aimPos - origin);
|
||||
|
||||
/* slowly lerp towards the final angle */
|
||||
vecNewAngles[0] = Math_Lerp(vecNewAngles[0], v_forward[0], flLerp);
|
||||
vecNewAngles[1] = Math_Lerp(vecNewAngles[1], v_forward[1], flLerp);
|
||||
vecNewAngles[2] = Math_Lerp(vecNewAngles[2], v_forward[2], flLerp);
|
||||
vecNewAngles = vectorLerp(vecNewAngles, anglesToForward(aimDir), flLerp);
|
||||
|
||||
/* make sure we're aiming tight */
|
||||
v_angle = vectoangles(vecNewAngles);
|
||||
v_angle[0] = Math_FixDelta(v_angle[0]);
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = Math_FixDelta(v_angle[2]);
|
||||
angles[0] = Math_FixDelta(v_angle[0]);
|
||||
angles[1] = Math_FixDelta(v_angle[1]);
|
||||
angles[2] = Math_FixDelta(v_angle[2]);
|
||||
input_angles = v_angle;
|
||||
input_angles = angles = v_angle = vectorToAngles(vecNewAngles);
|
||||
|
||||
bool shouldWalk = autocvar_bot_walk;
|
||||
|
||||
|
@ -460,21 +468,23 @@ NSBot::RunAI(void)
|
|||
ForceWeaponAttack(traceEnt.WorldSpaceCenter(), 1.0f);
|
||||
}
|
||||
|
||||
/* now we'll set the movevalues relative to the input_angle */
|
||||
/* make them walk when they need to. */
|
||||
if ((m_iCurNode >= 0 && Route_GetNodeFlags(&m_pRoute[m_iCurNode]) & LF_WALK) || shouldWalk)
|
||||
vecDirection = normalize(aimPos - origin) * GetWalkSpeed();
|
||||
SetMoveSpeedScale(0.5f);
|
||||
else
|
||||
vecDirection = normalize(aimPos - origin) * GetRunSpeed();
|
||||
SetMoveSpeedScale(1.0f);
|
||||
|
||||
vecDirection = vectorNormalize(aimPos - GetEyePos()) * g_pmoveVars.pm_walkspeed;
|
||||
makevectors(input_angles);
|
||||
input_movevalues = [v_forward * vecDirection, v_right * vecDirection, v_up * vecDirection];
|
||||
|
||||
input_movevalues[2] = 0;
|
||||
|
||||
#if 1
|
||||
/* duck and stand still when our enemy seems strong */
|
||||
if (m_eTarget && enemyVisible && m_eTarget.health >= 75) {
|
||||
if (m_wtWeaponType == WPNTYPE_RANGED) {
|
||||
input_buttons |= INPUT_BUTTON8;
|
||||
input_buttons |= INPUT_CROUCH;
|
||||
input_movevalues = [0,0,0];
|
||||
}
|
||||
}
|
||||
|
@ -482,14 +492,14 @@ NSBot::RunAI(void)
|
|||
}
|
||||
|
||||
/* press any buttons needed */
|
||||
button0 = input_buttons & INPUT_BUTTON0; // attack
|
||||
button2 = input_buttons & INPUT_BUTTON2; // jump
|
||||
button3 = input_buttons & INPUT_BUTTON3; // tertiary
|
||||
button4 = input_buttons & INPUT_BUTTON4; // reload
|
||||
button5 = input_buttons & INPUT_BUTTON5; // secondary
|
||||
button6 = input_buttons & INPUT_BUTTON6; // use
|
||||
button7 = input_buttons & INPUT_BUTTON7; // unused
|
||||
button8 = input_buttons & INPUT_BUTTON8; // duck
|
||||
button0 = input_buttons & INPUT_PRIMARY; // attack
|
||||
button2 = input_buttons & INPUT_JUMP; // jump
|
||||
button3 = input_buttons & INPUT_PRONE; // prone
|
||||
button4 = input_buttons & INPUT_RELOAD; // reload
|
||||
button5 = input_buttons & INPUT_SECONDARY; // secondary
|
||||
button6 = input_buttons & INPUT_USE; // use
|
||||
button7 = input_buttons & INPUT_SPRINT; // unused
|
||||
button8 = input_buttons & INPUT_CROUCH; // duck
|
||||
movement = input_movevalues;
|
||||
}
|
||||
|
||||
|
@ -515,9 +525,9 @@ void
|
|||
NSBot::SetName(string nickname)
|
||||
{
|
||||
if (autocvar_bot_prefix)
|
||||
forceinfokey(this, "name", sprintf("%s %s", autocvar_bot_prefix, nickname));
|
||||
SetInfoKey("name", sprintf("%s %s", autocvar_bot_prefix, nickname));
|
||||
else
|
||||
forceinfokey(this, "name", nickname);
|
||||
SetInfoKey("name", nickname);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -525,7 +535,7 @@ NSBot::NSBot(void)
|
|||
{
|
||||
classname = "player";
|
||||
targetname = "_nuclide_bot_";
|
||||
forceinfokey(this, "*bot", "1");
|
||||
SetInfoKey("*bot", "1");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -30,8 +30,8 @@ NSBot::Pain(void)
|
|||
|
||||
/* make this pain our new enemy! */
|
||||
if (g_dmg_eAttacker && g_dmg_eAttacker != this) {
|
||||
float enemydist = vlen(origin - m_eTarget.origin);
|
||||
float newdist = vlen(origin - g_dmg_eAttacker.origin);
|
||||
float enemydist = distanceSquared(origin, m_eTarget.origin);
|
||||
float newdist = distanceSquared(origin, g_dmg_eAttacker.origin);
|
||||
|
||||
if (m_eTarget) {
|
||||
if (newdist < enemydist) {
|
||||
|
@ -49,7 +49,7 @@ NSBot::SetEnemy(entity en)
|
|||
m_eTarget = en;
|
||||
|
||||
if (m_eTarget) {
|
||||
m_flEnemyDist = vlen(origin - m_eTarget.origin);
|
||||
m_flEnemyDist = distanceSquared(origin, m_eTarget.origin);
|
||||
} else {
|
||||
m_flEnemyDist = -1;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ BotLib_Alert(vector pos, float radius, float t)
|
|||
|
||||
for (entity w = world; (w = find(w,::targetname, "_nuclide_bot_"));) {
|
||||
/* out of radius */
|
||||
if (vlen(pos - w.origin) > radius)
|
||||
if (distance(pos, w.origin) > radius)
|
||||
continue;
|
||||
|
||||
NSBot f = (NSBot) w;
|
39
src/botlib/cvars.h
Normal file
39
src/botlib/cvars.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* for full description check the docs. */
|
||||
var bool autocvar_bot_enable = true;
|
||||
var bool autocvar_bot_pause = false;
|
||||
var bool autocvar_bot_noChat = false;
|
||||
var bool autocvar_bot_fastChat = false;
|
||||
var bool autocvar_bot_debug = false;
|
||||
var bool autocvar_bot_developer = false;
|
||||
var int autocvar_bot_minClients = -1i;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOTSKILL_EASY = 1,
|
||||
BOTSKILL_MEDIUM,
|
||||
BOTSKILL_HARD
|
||||
} botskill_t;
|
||||
|
||||
var botskill_t autocvar_bot_skill = BOTSKILL_MEDIUM;
|
||||
|
||||
var bool autocvar_bot_aimless = false;
|
||||
var bool autocvar_bot_crouch = false;
|
||||
var bool autocvar_bot_walk = false;
|
||||
var bool autocvar_bot_prone = false;
|
||||
var bool autocvar_bot_dont_shoot = false;
|
|
@ -14,27 +14,14 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cvars.h"
|
||||
#include "NSBot.h"
|
||||
|
||||
vector Route_SelectDestination( NSBot target );
|
||||
|
||||
var int autocvar_bot_aimless = FALSE;
|
||||
|
||||
var int autocvar_nav_linksize = 256;
|
||||
var int autocvar_nav_radius = 8;
|
||||
|
||||
var bool autocvar_bot_crouch = false;
|
||||
var bool autocvar_bot_walk = false;
|
||||
var bool autocvar_bot_stop = false;
|
||||
var bool autocvar_bot_dont_shoot = false;
|
||||
|
||||
var bool autocvar_bot_join_after_player = false;
|
||||
var float autocvar_bot_join_delay = 0.0f;
|
||||
var int autocvar_bot_quota = 0i;
|
||||
var string autocvar_bot_quota_mode = "normal";
|
||||
var string autocvar_bot_chatter = "normal";
|
||||
var bool autocvar_bot_developer = false;
|
||||
|
||||
void
|
||||
_BotLog(string functionName, string msg)
|
||||
{
|
||||
|
@ -59,15 +46,6 @@ _BotEntLog(string className, string functionName, float edictNum, string warnMes
|
|||
@param description(...) contains a formatted string containing a description. */
|
||||
#define BotEntLog(...) if (autocvar_bot_developer) _BotEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOTSKILL_EASY = 1,
|
||||
BOTSKILL_MEDIUM,
|
||||
BOTSKILL_HARD
|
||||
} botskill_t;
|
||||
|
||||
var botskill_t autocvar_bot_skill = BOTSKILL_MEDIUM;
|
||||
|
||||
var string autocvar_bot_prefix = "";
|
||||
|
||||
/* BotScript
|
||||
|
|
0
src/botlib/entities.qc
Normal file
0
src/botlib/entities.qc
Normal file
|
@ -4,8 +4,8 @@
|
|||
defs.h
|
||||
profiles.qc
|
||||
NSBot.qc
|
||||
bot_chat.qc
|
||||
bot_combat.qc
|
||||
chat.qc
|
||||
combat.qc
|
||||
route.qc
|
||||
way.qc
|
||||
way_convert.qc
|
||||
|
|
|
@ -39,7 +39,7 @@ Route_SelectFarthest(float type, vector org, optional vector lastpoi = [0,0,0])
|
|||
entity dest = __NULL__;
|
||||
|
||||
for (temp = world; (temp = findfloat(temp, ::botinfo, type));) {
|
||||
range = vlen(temp.origin - org);
|
||||
range = distanceSquared(temp.origin, org);
|
||||
|
||||
if (lastpoi == temp.origin)
|
||||
continue;
|
||||
|
@ -63,7 +63,7 @@ Route_SelectNearest(float type, vector org, optional vector lastpoi = [0,0,0])
|
|||
entity dest = __NULL__;
|
||||
|
||||
for (temp = world; (temp = findfloat(temp, ::botinfo, type));) {
|
||||
range = vlen(temp.origin - org);
|
||||
range = distanceSquared(temp.origin, org);
|
||||
|
||||
if (lastpoi == temp.origin)
|
||||
continue;
|
||||
|
@ -91,7 +91,7 @@ Route_SelectNearestTeam(float type, vector org, float tt)
|
|||
if (temp.team != tt)
|
||||
continue;
|
||||
|
||||
range = vlen(tempEnt.WorldSpaceCenter() - org);
|
||||
range = distanceSquared(tempEnt.WorldSpaceCenter(), org);
|
||||
|
||||
if ((range < bestrange) && (temp.solid != SOLID_NOT)) {
|
||||
bestrange = range;
|
||||
|
@ -116,7 +116,7 @@ Route_SelectNearestEnemyTeam(float type, vector org, float tt)
|
|||
if (temp.team == tt)
|
||||
continue;
|
||||
|
||||
range = vlen(tempEnt.WorldSpaceCenter() - org);
|
||||
range = distanceSquared(tempEnt.WorldSpaceCenter(), org);
|
||||
|
||||
if ((range < bestrange) && (temp.solid != SOLID_NOT)) {
|
||||
bestrange = range;
|
||||
|
@ -161,14 +161,14 @@ Route_SelectRandomSpot(void)
|
|||
vector
|
||||
Route_SelectDestination(NSBot target)
|
||||
{
|
||||
CGameRules rules;
|
||||
rules = (CGameRules)g_grMode;
|
||||
NSGameRules rules;
|
||||
rules = (NSGameRules)g_grMode;
|
||||
|
||||
NSEntity dest = __NULL__;
|
||||
|
||||
if (rules.IsTeamplay()) {
|
||||
/* we have the goal item, so capture it */
|
||||
if (target.flags & FL_GOALITEM) {
|
||||
if (target.vv_flags & VFL_GOALITEM) {
|
||||
BotLog("%s going for capture", target.netname);
|
||||
dest = Route_SelectNearestTeam(BOTINFO_TEAM_GOALCAPTURE, target.origin, target.team);
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
|
||||
var bool autocvar_r_skipWorld = false;
|
||||
var float autocvar_cg_viewZSmoothingMax = 16;
|
||||
var float autocvar_cg_viewZSmoothingMin = 1;
|
||||
var float autocvar_cg_viewZSmoothingTime = 0.1;
|
||||
|
||||
void
|
||||
NSView::NSView(void)
|
||||
|
@ -100,13 +103,13 @@ NSView::StairSmooth(void)
|
|||
|
||||
/* Have we gone up since last frame? */
|
||||
if ((m_viewTarget.flags & FL_ONGROUND) && (endpos[2] - m_vecLastOrigin[2] > 0)) {
|
||||
endpos[2] = m_vecLastOrigin[2] += (frametime * 150);
|
||||
endpos[2] = m_vecLastOrigin[2] += (frametime * 1000) * autocvar_cg_viewZSmoothingTime;
|
||||
|
||||
if (endpos[2] > origin[2]) {
|
||||
endpos[2] = origin[2];
|
||||
}
|
||||
if (origin[2] - endpos[2] > 18) {
|
||||
endpos[2] = origin[2] - 18;
|
||||
if (origin[2] - endpos[2] > autocvar_cg_viewZSmoothingMax) {
|
||||
endpos[2] = origin[2] - autocvar_cg_viewZSmoothingMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -236,6 +236,7 @@ CMD_ListModelFramegroups(void)
|
|||
print("} framegroups_e;\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_Parse
|
||||
|
@ -305,10 +306,10 @@ Cmd_Parse(string sCMD)
|
|||
sendevent("CallVote", "s", substring(sCMD, 9, strlen(sCMD)-9));
|
||||
break;
|
||||
case "+zoomin":
|
||||
pSeat->m_iZoomed = TRUE;
|
||||
pSeat->m_iZoomed = true;
|
||||
break;
|
||||
case "-zoomin":
|
||||
pSeat->m_iZoomed = FALSE;
|
||||
pSeat->m_iZoomed = false;
|
||||
break;
|
||||
case "buildcubemaps":
|
||||
CMap_Build();
|
||||
|
@ -317,22 +318,24 @@ Cmd_Parse(string sCMD)
|
|||
CMD_titles_test();
|
||||
break;
|
||||
case "+attack2":
|
||||
pSeat->m_iInputAttack2 = TRUE;
|
||||
pSeat->m_iInputAttack2 = true;
|
||||
break;
|
||||
case "-attack2":
|
||||
pSeat->m_iInputAttack2 = FALSE;
|
||||
pSeat->m_iInputAttack2 = false;
|
||||
break;
|
||||
case "+reload":
|
||||
pSeat->m_iInputReload = TRUE;
|
||||
pSeat->m_iInputReload = true;
|
||||
break;
|
||||
case "-reload":
|
||||
pSeat->m_iInputReload = FALSE;
|
||||
pSeat->m_iInputReload = false;
|
||||
break;
|
||||
case "+activate":
|
||||
case "+use":
|
||||
pSeat->m_iInputUse = TRUE;
|
||||
pSeat->m_iInputUse = true;
|
||||
break;
|
||||
case "-activate":
|
||||
case "-use":
|
||||
pSeat->m_iInputUse = FALSE;
|
||||
pSeat->m_iInputUse = false;
|
||||
break;
|
||||
case "+duck":
|
||||
if (autocvar_pm_crouchToggle == true)
|
||||
|
@ -348,6 +351,46 @@ Cmd_Parse(string sCMD)
|
|||
|
||||
pSeat->m_bSpecInput = false;
|
||||
break;
|
||||
case "+prone":
|
||||
pSeat->m_iInputProne = true;
|
||||
break;
|
||||
case "-prone":
|
||||
pSeat->m_iInputProne = false;
|
||||
break;
|
||||
case "+sprint":
|
||||
pSeat->m_iSprinting = true;
|
||||
break;
|
||||
case "-sprint":
|
||||
pSeat->m_iSprinting = false;
|
||||
break;
|
||||
case "+leanleft":
|
||||
pSeat->m_iLeanDir = -1;
|
||||
break;
|
||||
case "-leanleft":
|
||||
pSeat->m_iLeanDir = 0;
|
||||
break;
|
||||
case "+leanright":
|
||||
pSeat->m_iLeanDir = 1;
|
||||
break;
|
||||
case "-leanright":
|
||||
pSeat->m_iLeanDir = 0;
|
||||
break;
|
||||
case "goprone":
|
||||
pSeat->m_dForceStance = STANCE_PRONE;
|
||||
break;
|
||||
case "gocrouch":
|
||||
pSeat->m_dForceStance = STANCE_CROUCH;
|
||||
break;
|
||||
case "+gostand":
|
||||
if (pSeat->m_dForceStance != STANCE_DEFAULT) {
|
||||
pSeat->m_dForceStance = STANCE_DEFAULT;
|
||||
} else {
|
||||
pSeat->m_iInputJump = true;
|
||||
}
|
||||
break;
|
||||
case "-gostand":
|
||||
pSeat->m_iInputJump = false;
|
||||
break;
|
||||
case "invnext":
|
||||
HUD_DrawWeaponSelect_Back();
|
||||
break;
|
||||
|
@ -426,11 +469,12 @@ Cmd_Parse(string sCMD)
|
|||
case "-attack_right":
|
||||
pSeat->m_iInputAttack = false;
|
||||
break;
|
||||
|
||||
case "+menu_right":
|
||||
pSeat->m_iInputReload = TRUE;
|
||||
pSeat->m_iInputReload = true;
|
||||
break;
|
||||
case "-menu_right":
|
||||
pSeat->m_iInputReload = FALSE;
|
||||
pSeat->m_iInputReload = false;
|
||||
break;
|
||||
/* client aliases for server commands */
|
||||
case "addBot":
|
||||
|
@ -495,7 +539,13 @@ Cmd_Parse(string sCMD)
|
|||
case "nodeUnlink":
|
||||
localcmd(sprintf("sv way unlink1 %s\n", argv(1)));
|
||||
break;
|
||||
|
||||
case "traceMaterial":
|
||||
localcmd("sv traceMaterial\n");
|
||||
break;
|
||||
case "bobup":
|
||||
break;
|
||||
case "bobdn":
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
@ -522,6 +572,7 @@ Cmd_Init(void)
|
|||
registercommand("listTitles");
|
||||
registercommand("listClientSoundDef");
|
||||
registercommand("listServerSoundDef");
|
||||
registercommand("traceMaterial");
|
||||
|
||||
/* server commands */
|
||||
registercommand("addBot");
|
||||
|
@ -569,12 +620,22 @@ Cmd_Init(void)
|
|||
registercommand("-attack");
|
||||
registercommand("+attack2");
|
||||
registercommand("-attack2");
|
||||
registercommand("+reload");
|
||||
registercommand("+reload");
|
||||
registercommand("-reload");
|
||||
registercommand("+activate");
|
||||
registercommand("-activate");
|
||||
registercommand("+use");
|
||||
registercommand("-use");
|
||||
registercommand("+duck");
|
||||
registercommand("-duck");
|
||||
registercommand("+prone");
|
||||
registercommand("-prone");
|
||||
registercommand("goprone");
|
||||
registercommand("gocrouch");
|
||||
registercommand("+gostand");
|
||||
registercommand("-gostand");
|
||||
registercommand("+sprint");
|
||||
registercommand("-sprint");
|
||||
|
||||
/* voting */
|
||||
registercommand("vote");
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "NSView.h"
|
||||
#include "NSRadar.h"
|
||||
#include "crosshair.h"
|
||||
#include "../shared/weapons.h"
|
||||
#include "../shared/weapon_common.h"
|
||||
|
||||
var bool g_net_debug = false;
|
||||
var bool g_cheats = false;
|
||||
|
@ -280,6 +282,13 @@ precache_cubemap(string path)
|
|||
precache_pic(strcat(path, "_up"));
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STANCE_DEFAULT = 0,
|
||||
STANCE_CROUCH = 1,
|
||||
STANCE_PRONE = 2,
|
||||
} movementStance_t;
|
||||
|
||||
struct
|
||||
{
|
||||
/* viewmodel stuff */
|
||||
|
@ -340,12 +349,14 @@ struct
|
|||
int m_iPrintLines;
|
||||
|
||||
bool m_iInputAttack;
|
||||
int m_iInputAttack2;
|
||||
int m_iInputReload;
|
||||
int m_iInputUse;
|
||||
int m_iInputDuck;
|
||||
int m_iInputExtra1;
|
||||
int m_iInputExtra2;
|
||||
bool m_iInputAttack2;
|
||||
bool m_iInputReload;
|
||||
bool m_iInputUse;
|
||||
bool m_iInputDuck;
|
||||
bool m_iInputSprint;
|
||||
bool m_iInputProne;
|
||||
bool m_iInputJump;
|
||||
movementStance_t m_dForceStance;
|
||||
float m_flInputBlockTime;
|
||||
|
||||
/* fading */
|
||||
|
@ -355,6 +366,7 @@ struct
|
|||
float m_flFadeStyle;
|
||||
float m_flFadeAlpha;
|
||||
float m_flFadeTime;
|
||||
float m_flSprintLerp;
|
||||
vector m_vecFadeColor;
|
||||
int m_iFadeActive;
|
||||
|
||||
|
@ -375,6 +387,10 @@ struct
|
|||
|
||||
bool m_bInterfaceFocused;
|
||||
bool m_bSpecInput;
|
||||
|
||||
int m_iLeanDir;
|
||||
float m_flLeaning;
|
||||
int m_iSprinting;
|
||||
} g_seats[4], *pSeat;
|
||||
|
||||
var vector g_vecMousePos;
|
||||
|
|
|
@ -235,33 +235,33 @@ EFX_SetEnvironment(int id)
|
|||
void
|
||||
EFX_Interpolate(int id)
|
||||
{
|
||||
mix.flDensity = Math_Lerp(mix.flDensity, g_efx[id].flDensity, g_flEFXTime);
|
||||
mix.flDiffusion = Math_Lerp(mix.flDiffusion, g_efx[id].flDiffusion, g_flEFXTime);
|
||||
mix.flGain = Math_Lerp(mix.flGain, g_efx[id].flGain, g_flEFXTime);
|
||||
mix.flGainHF = Math_Lerp(mix.flGainHF, g_efx[id].flGainHF, g_flEFXTime);
|
||||
mix.flGainLF = Math_Lerp(mix.flGainLF, g_efx[id].flGainLF, g_flEFXTime);
|
||||
mix.flDecayTime = Math_Lerp(mix.flDecayTime, g_efx[id].flDecayTime, g_flEFXTime);
|
||||
mix.flDecayHFRatio = Math_Lerp(mix.flDecayHFRatio, g_efx[id].flDecayHFRatio, g_flEFXTime);
|
||||
mix.flDecayLFRatio = Math_Lerp(mix.flDecayLFRatio, g_efx[id].flDecayLFRatio, g_flEFXTime);
|
||||
mix.flReflectionsGain = Math_Lerp(mix.flReflectionsGain, g_efx[id].flReflectionsGain, g_flEFXTime);
|
||||
mix.flReflectionsDelay = Math_Lerp(mix.flReflectionsDelay, g_efx[id].flReflectionsDelay, g_flEFXTime);
|
||||
mix.flReflectionsPan[0] = Math_Lerp(mix.flReflectionsPan[0], g_efx[id].flReflectionsPan[0], g_flEFXTime);
|
||||
mix.flReflectionsPan[1] = Math_Lerp(mix.flReflectionsPan[1], g_efx[id].flReflectionsPan[1], g_flEFXTime);
|
||||
mix.flReflectionsPan[1] = Math_Lerp(mix.flReflectionsPan[2], g_efx[id].flReflectionsPan[2], g_flEFXTime);
|
||||
mix.flLateReverbGain = Math_Lerp(mix.flLateReverbGain, g_efx[id].flLateReverbGain, g_flEFXTime);
|
||||
mix.flLateReverbDelay = Math_Lerp(mix.flLateReverbDelay, g_efx[id].flLateReverbDelay, g_flEFXTime);
|
||||
mix.flLateReverbPan[0] = Math_Lerp(mix.flLateReverbPan[0], g_efx[id].flLateReverbPan[0], g_flEFXTime);
|
||||
mix.flLateReverbPan[1] = Math_Lerp(mix.flLateReverbPan[1], g_efx[id].flLateReverbPan[1], g_flEFXTime);
|
||||
mix.flLateReverbPan[2] = Math_Lerp(mix.flLateReverbPan[2], g_efx[id].flLateReverbPan[2], g_flEFXTime);
|
||||
mix.flEchoTime = Math_Lerp(mix.flEchoTime, g_efx[id].flEchoTime, g_flEFXTime);
|
||||
mix.flEchoDepth = Math_Lerp(mix.flEchoDepth, g_efx[id].flEchoDepth, g_flEFXTime);
|
||||
mix.flModulationTime = Math_Lerp(mix.flModulationTime, g_efx[id].flModulationTime, g_flEFXTime);
|
||||
mix.flModulationDepth = Math_Lerp(mix.flModulationDepth, g_efx[id].flModulationDepth, g_flEFXTime);
|
||||
mix.flAirAbsorptionGainHF = Math_Lerp(mix.flAirAbsorptionGainHF, g_efx[id].flAirAbsorptionGainHF, g_flEFXTime);
|
||||
mix.flHFReference = Math_Lerp(mix.flHFReference, g_efx[id].flHFReference, g_flEFXTime);
|
||||
mix.flLFReference = Math_Lerp(mix.flLFReference, g_efx[id].flLFReference, g_flEFXTime);
|
||||
mix.flRoomRolloffFactor = Math_Lerp(mix.flRoomRolloffFactor, g_efx[id].flRoomRolloffFactor, g_flEFXTime);
|
||||
mix.iDecayHFLimit = Math_Lerp(mix.iDecayHFLimit, g_efx[id].iDecayHFLimit, g_flEFXTime);
|
||||
mix.flDensity = lerp(mix.flDensity, g_efx[id].flDensity, g_flEFXTime);
|
||||
mix.flDiffusion = lerp(mix.flDiffusion, g_efx[id].flDiffusion, g_flEFXTime);
|
||||
mix.flGain = lerp(mix.flGain, g_efx[id].flGain, g_flEFXTime);
|
||||
mix.flGainHF = lerp(mix.flGainHF, g_efx[id].flGainHF, g_flEFXTime);
|
||||
mix.flGainLF = lerp(mix.flGainLF, g_efx[id].flGainLF, g_flEFXTime);
|
||||
mix.flDecayTime = lerp(mix.flDecayTime, g_efx[id].flDecayTime, g_flEFXTime);
|
||||
mix.flDecayHFRatio = lerp(mix.flDecayHFRatio, g_efx[id].flDecayHFRatio, g_flEFXTime);
|
||||
mix.flDecayLFRatio = lerp(mix.flDecayLFRatio, g_efx[id].flDecayLFRatio, g_flEFXTime);
|
||||
mix.flReflectionsGain = lerp(mix.flReflectionsGain, g_efx[id].flReflectionsGain, g_flEFXTime);
|
||||
mix.flReflectionsDelay = lerp(mix.flReflectionsDelay, g_efx[id].flReflectionsDelay, g_flEFXTime);
|
||||
mix.flReflectionsPan[0] = lerp(mix.flReflectionsPan[0], g_efx[id].flReflectionsPan[0], g_flEFXTime);
|
||||
mix.flReflectionsPan[1] = lerp(mix.flReflectionsPan[1], g_efx[id].flReflectionsPan[1], g_flEFXTime);
|
||||
mix.flReflectionsPan[1] = lerp(mix.flReflectionsPan[2], g_efx[id].flReflectionsPan[2], g_flEFXTime);
|
||||
mix.flLateReverbGain = lerp(mix.flLateReverbGain, g_efx[id].flLateReverbGain, g_flEFXTime);
|
||||
mix.flLateReverbDelay = lerp(mix.flLateReverbDelay, g_efx[id].flLateReverbDelay, g_flEFXTime);
|
||||
mix.flLateReverbPan[0] = lerp(mix.flLateReverbPan[0], g_efx[id].flLateReverbPan[0], g_flEFXTime);
|
||||
mix.flLateReverbPan[1] = lerp(mix.flLateReverbPan[1], g_efx[id].flLateReverbPan[1], g_flEFXTime);
|
||||
mix.flLateReverbPan[2] = lerp(mix.flLateReverbPan[2], g_efx[id].flLateReverbPan[2], g_flEFXTime);
|
||||
mix.flEchoTime = lerp(mix.flEchoTime, g_efx[id].flEchoTime, g_flEFXTime);
|
||||
mix.flEchoDepth = lerp(mix.flEchoDepth, g_efx[id].flEchoDepth, g_flEFXTime);
|
||||
mix.flModulationTime = lerp(mix.flModulationTime, g_efx[id].flModulationTime, g_flEFXTime);
|
||||
mix.flModulationDepth = lerp(mix.flModulationDepth, g_efx[id].flModulationDepth, g_flEFXTime);
|
||||
mix.flAirAbsorptionGainHF = lerp(mix.flAirAbsorptionGainHF, g_efx[id].flAirAbsorptionGainHF, g_flEFXTime);
|
||||
mix.flHFReference = lerp(mix.flHFReference, g_efx[id].flHFReference, g_flEFXTime);
|
||||
mix.flLFReference = lerp(mix.flLFReference, g_efx[id].flLFReference, g_flEFXTime);
|
||||
mix.flRoomRolloffFactor = lerp(mix.flRoomRolloffFactor, g_efx[id].flRoomRolloffFactor, g_flEFXTime);
|
||||
mix.iDecayHFLimit = lerp(mix.iDecayHFLimit, g_efx[id].iDecayHFLimit, g_flEFXTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -22,6 +22,9 @@ Entity_EntityUpdate(float type, float new)
|
|||
case ENT_ENTITY:
|
||||
NSENTITY_READENTITY(NSEntity, new)
|
||||
break;
|
||||
case ENT_PMOVEVARS:
|
||||
NSENTITY_READENTITY(NSPMoveVars, new)
|
||||
break;
|
||||
case ENT_ENTITYRENDERABLE:
|
||||
NSENTITY_READENTITY(NSRenderableEntity, new)
|
||||
break;
|
||||
|
|
|
@ -447,13 +447,7 @@ CSQC_ConsoleCommand(string sCMD)
|
|||
tokenize(sCMD);
|
||||
|
||||
/* give us a chance to override commands */
|
||||
int ret = ClientGame_ConsoleCommand();
|
||||
|
||||
/* successful override */
|
||||
if (ret == (1))
|
||||
return (1);
|
||||
|
||||
return Cmd_Parse(sCMD);
|
||||
return (ClientGame_ConsoleCommand()) ? true : Cmd_Parse(sCMD);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
var bool autocvar_cg_damageShake = false;
|
||||
|
||||
void
|
||||
EV_Damage(void)
|
||||
{
|
||||
|
@ -26,6 +28,13 @@ EV_Damage(void)
|
|||
iDmgTake = readint();
|
||||
iDmgFlags = readint();
|
||||
CSQC_Parse_Damage_New(vecDmgPos, iDmgTake, iDmgFlags);
|
||||
|
||||
if (autocvar_cg_damageShake) {
|
||||
pSeat->m_flShakeDuration += 1.25f;
|
||||
pSeat->m_flShakeAmp += iDmgTake / 16;
|
||||
pSeat->m_flShakeFreq += 0.1;
|
||||
pSeat->m_flShakeTime += pSeat->m_flShakeDuration;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -235,10 +235,8 @@ View_DrawViewModel(void)
|
|||
speed = clframetime * 20;
|
||||
}
|
||||
|
||||
pSeat->m_vecLag[0] = Math_Lerp(pSeat->m_vecLag[0], v_forward[0], speed);
|
||||
pSeat->m_vecLag[1] = Math_Lerp(pSeat->m_vecLag[1], v_forward[1], speed);
|
||||
pSeat->m_vecLag[2] = Math_Lerp(pSeat->m_vecLag[2], v_forward[2], speed);
|
||||
pSeat->m_vecLag = vectoangles(pSeat->m_vecLag);
|
||||
pSeat->m_vecLag = vectorLerp(pSeat->m_vecLag, v_forward, speed);
|
||||
pSeat->m_vecLag = vectorToAngles(pSeat->m_vecLag);
|
||||
m_eViewModel.angles = pSeat->m_vecLag;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,9 +152,7 @@ func_smokevolume::predraw(void)
|
|||
func_smokevolume_cloud cloud = spawn(func_smokevolume_cloud);
|
||||
setorigin(cloud, vecPos);
|
||||
float r = random();
|
||||
cloud.m_vecColor[0] = Math_Lerp(m_vecColor1[0], m_vecColor2[0], r);
|
||||
cloud.m_vecColor[1] = Math_Lerp(m_vecColor1[1], m_vecColor2[1], r);
|
||||
cloud.m_vecColor[2] = Math_Lerp(m_vecColor1[2], m_vecColor2[2], r);
|
||||
cloud.m_vecColor = vectorLerp(m_vecColor1, m_vecColor2, r);
|
||||
cloud.m_flMaxAlpha = m_flAlpha * fracDist;
|
||||
cloud.cloudsize[0] = random(m_flSizeMin, m_flSizeMax);
|
||||
cloud.cloudsize[1] = random(m_flSizeMin, m_flSizeMax);
|
||||
|
|
|
@ -90,6 +90,11 @@ server/point_trigger.qc
|
|||
server/targ_speaker.qc
|
||||
server/target_cdaudio.qc
|
||||
server/env_global.qc
|
||||
server/script_model.qc
|
||||
server/script_brushmodel.qc
|
||||
server/script_origin.qc
|
||||
server/script_struct.qc
|
||||
server/script_vehicle.qc
|
||||
server/trigger_auto.qc
|
||||
server/trigger_autosave.qc
|
||||
server/trigger_cdaudio.qc
|
||||
|
|
|
@ -99,7 +99,6 @@ private:
|
|||
float m_flDelay;
|
||||
string m_strSndPressed;
|
||||
string m_strSndUnpressed;
|
||||
|
||||
bool m_bCanTouch;
|
||||
|
||||
/* input/output */
|
||||
|
@ -281,8 +280,8 @@ func_button::Respawn(void)
|
|||
SetMoverPosition2(GetDirectionalPosition(GetSpawnAngles(), m_flLip));
|
||||
ClearAngles();
|
||||
|
||||
if (health > 0) {
|
||||
takedamage = DAMAGE_YES;
|
||||
if (GetHealth() > 0) {
|
||||
MakeVulnerable();
|
||||
Death = DeathTrigger;
|
||||
}
|
||||
|
||||
|
@ -298,6 +297,12 @@ func_button::Respawn(void)
|
|||
SetMoverPosition2(GetMoverPosition1());
|
||||
}
|
||||
|
||||
if (HasSpawnFlags(SF_BTT_TOUCH_ONLY) == true) {
|
||||
m_bCanTouch = true;
|
||||
} else {
|
||||
m_bCanTouch = false;
|
||||
}
|
||||
|
||||
m_iValue = 0;
|
||||
}
|
||||
|
||||
|
@ -311,8 +316,9 @@ func_button::MoverFinishesMoving(void)
|
|||
/* let's reset our button's health and mark it as shootable */
|
||||
SetHealth(GetSpawnHealth());
|
||||
|
||||
if (GetHealth() > 0)
|
||||
SetTakedamage(DAMAGE_YES);
|
||||
if (GetHealth() > 0) {
|
||||
MakeVulnerable();
|
||||
}
|
||||
|
||||
if (GetMoverState() == MOVER_POS1) {
|
||||
UseOutput(this, m_strOnOut);
|
||||
|
@ -325,7 +331,6 @@ func_button::MoverFinishesMoving(void)
|
|||
m_bCanTouch = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
func_button::MoverStartsMoving(void)
|
||||
{
|
||||
|
@ -338,7 +343,7 @@ func_button::MoverStartsMoving(void)
|
|||
m_iValue = 0;
|
||||
|
||||
if (m_strSndUnpressed) {
|
||||
Sound_Play(this, CHAN_VOICE, m_strSndUnpressed);
|
||||
StartSoundDef(m_strSndUnpressed, CHAN_VOICE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -347,10 +352,10 @@ func_button::MoverStartsMoving(void)
|
|||
void
|
||||
func_button::Trigger(entity act, triggermode_t state)
|
||||
{
|
||||
if (GetMaster(act) == FALSE)
|
||||
if (GetMaster(act) == false) {
|
||||
UseOutput(act, m_strOnUseLocked);
|
||||
return;
|
||||
|
||||
UseOutput(act, m_strOnUseLocked);
|
||||
}
|
||||
|
||||
if (m_flNextTrigger > time) {
|
||||
return;
|
||||
|
@ -365,15 +370,17 @@ func_button::Trigger(entity act, triggermode_t state)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_strSndPressed)
|
||||
Sound_Play(this, CHAN_VOICE, m_strSndPressed);
|
||||
if (m_strSndPressed) {
|
||||
StartSoundDef(m_strSndPressed, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
MoveToPosition(GetMoverPosition2(), m_flSpeed);
|
||||
UseOutput(act, m_strOnPressed);
|
||||
UseTargets(act, TRIG_TOGGLE, m_flDelay);
|
||||
|
||||
if (message)
|
||||
if (message) {
|
||||
env_message_single(act, message);
|
||||
}
|
||||
|
||||
SetHealth(GetSpawnHealth());
|
||||
}
|
||||
|
@ -381,21 +388,18 @@ func_button::Trigger(entity act, triggermode_t state)
|
|||
void
|
||||
func_button::DeathTrigger(void)
|
||||
{
|
||||
SetTakedamage(DAMAGE_NO);
|
||||
MakeInvulnerable();
|
||||
Trigger(g_dmg_eAttacker, TRIG_TOGGLE);
|
||||
}
|
||||
|
||||
void
|
||||
func_button::Touch(entity eToucher)
|
||||
{
|
||||
if (HasSpawnFlags(SF_BTT_TOUCH_ONLY) == false) {
|
||||
if (m_bCanTouch == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bCanTouch == false)
|
||||
return;
|
||||
|
||||
if (eToucher.movetype == MOVETYPE_WALK) {
|
||||
if (eToucher.classname == "player") {
|
||||
Trigger(eToucher, TRIG_TOGGLE);
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +410,7 @@ func_button::PlayerUse(void)
|
|||
if (HasSpawnFlags(SF_BTT_TOUCH_ONLY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Trigger(eActivator, TRIG_TOGGLE);
|
||||
}
|
||||
|
||||
|
@ -415,4 +420,4 @@ func_button::Blocked(entity eBlocker)
|
|||
if (m_flWait >= 0) {
|
||||
MoveToReverse(m_flSpeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,9 +92,9 @@ private:
|
|||
float m_flDelay;
|
||||
float m_flLip;
|
||||
int m_iDamage;
|
||||
int m_iLocked;
|
||||
int m_iForceClosed;
|
||||
bool m_iCanTouch;
|
||||
bool m_bLocked;
|
||||
bool m_bForceClosed;
|
||||
bool m_bCanTouch;
|
||||
|
||||
float m_flSoundWait;
|
||||
string m_strLockedSfx;
|
||||
|
@ -115,14 +115,14 @@ func_door::func_door(void)
|
|||
{
|
||||
m_flLip =
|
||||
m_flNextTrigger =
|
||||
m_flWait =
|
||||
m_flWait = -1; /* verified thorugh through test_door_locked.bsp */
|
||||
m_flDelay = 0.0f;
|
||||
|
||||
m_iDamage =
|
||||
m_iLocked =
|
||||
m_iForceClosed = 0;
|
||||
m_iDamage = 0i;
|
||||
m_bLocked =
|
||||
m_bForceClosed = false;
|
||||
|
||||
m_iCanTouch = false;
|
||||
m_bCanTouch = false;
|
||||
m_flSoundWait = 0.0f;
|
||||
|
||||
targetClose =
|
||||
|
@ -150,8 +150,8 @@ func_door::Save(float handle)
|
|||
SaveFloat(handle, "m_flSoundWait", m_flSoundWait);
|
||||
|
||||
SaveInt(handle, "m_iDamage", m_iDamage);
|
||||
SaveInt(handle, "m_iLocked", m_iLocked);
|
||||
SaveInt(handle, "m_iForceClosed", m_iForceClosed);
|
||||
SaveBool(handle, "m_bLocked", m_bLocked);
|
||||
SaveBool(handle, "m_bForceClosed", m_bForceClosed);
|
||||
|
||||
SaveString(handle, "m_strLockedSfx", m_strLockedSfx);
|
||||
SaveString(handle, "m_strUnlockedSfx", m_strUnlockedSfx);
|
||||
|
@ -187,11 +187,11 @@ func_door::Restore(string strKey, string strValue)
|
|||
case "m_iDamage":
|
||||
m_iDamage = ReadInt(strValue);
|
||||
break;
|
||||
case "m_iLocked":
|
||||
m_iLocked = ReadInt(strValue);
|
||||
case "m_bLocked":
|
||||
m_bLocked = ReadBool(strValue);
|
||||
break;
|
||||
case "m_iForceClosed":
|
||||
m_iForceClosed = ReadInt(strValue);
|
||||
case "m_bForceClosed":
|
||||
m_bForceClosed = ReadBool(strValue);
|
||||
break;
|
||||
|
||||
case "m_strLockedSfx":
|
||||
|
@ -234,23 +234,23 @@ func_door::SpawnKey(string strKey, string strValue)
|
|||
|
||||
switch (strKey) {
|
||||
case "skin":
|
||||
m_waterType = stoi(strValue);
|
||||
m_waterType = ReadInt(strValue);
|
||||
break;
|
||||
case "speed":
|
||||
m_flSpeed = stof(strValue);
|
||||
m_flSpeed = ReadFloat(strValue);
|
||||
break;
|
||||
case "lip":
|
||||
m_flLip = stof(strValue);
|
||||
m_flLip = ReadFloat(strValue);
|
||||
break;
|
||||
case "wait":
|
||||
m_flWait = stof(strValue);
|
||||
m_flWait = ReadFloat(strValue);
|
||||
break;
|
||||
case "netname":
|
||||
targetClose = strValue;
|
||||
netname = __NULL__;
|
||||
break;
|
||||
case "dmg":
|
||||
m_iDamage = stoi(strValue);
|
||||
m_iDamage = ReadInt(strValue);
|
||||
break;
|
||||
case "snd_open":
|
||||
m_strSndOpen = strValue;
|
||||
|
@ -269,7 +269,7 @@ func_door::SpawnKey(string strKey, string strValue)
|
|||
m_strSndMove = strValue;
|
||||
break;
|
||||
case "forceclosed":
|
||||
m_iForceClosed = stoi(strValue);
|
||||
m_bForceClosed = ReadInt(strValue);
|
||||
break;
|
||||
/* GoldSrc compat */
|
||||
case "movesnd":
|
||||
|
@ -282,10 +282,18 @@ func_door::SpawnKey(string strKey, string strValue)
|
|||
break;
|
||||
case "locked_sound":
|
||||
x = stoi(strValue);
|
||||
|
||||
if (x == 0i)
|
||||
break;
|
||||
|
||||
m_strLockedSfx = sprintf("func_button.hlsfx_%i", x+1i);
|
||||
break;
|
||||
case "unlocked_sound":
|
||||
x = stoi(strValue);
|
||||
|
||||
if (x == 0i)
|
||||
break;
|
||||
|
||||
m_strUnlockedSfx = sprintf("func_button.hlsfx_%i", x+1i);
|
||||
break;
|
||||
/* I/O */
|
||||
|
@ -361,9 +369,9 @@ func_door::Respawn(void)
|
|||
m_iValue = 0;
|
||||
|
||||
if (spawnflags & SF_MOV_USE)
|
||||
m_iCanTouch = false;
|
||||
m_bCanTouch = false;
|
||||
else
|
||||
m_iCanTouch = true;
|
||||
m_bCanTouch = true;
|
||||
|
||||
if (HasSpawnFlags(SF_MOV_OPEN)) {
|
||||
SetOrigin(m_vecPos2);
|
||||
|
@ -376,8 +384,12 @@ func_door::Respawn(void)
|
|||
_PortalClose();
|
||||
}
|
||||
|
||||
if (targetname) {
|
||||
m_iLocked = TRUE;
|
||||
if (HasTargetname()) {
|
||||
m_bCanTouch = false;
|
||||
|
||||
if (m_strLockedSfx != __NULL__) {
|
||||
m_bLocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,7 +417,7 @@ func_door::PlayerUse(void)
|
|||
if (!HasSpawnFlags(SF_MOV_USE))
|
||||
return;
|
||||
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
Trigger(eActivator, TRIG_TOGGLE);
|
||||
}
|
||||
|
||||
|
@ -416,23 +428,16 @@ func_door::MoverFinishesMoving(void)
|
|||
MoveToPosition(GetMoverPosition1(), m_flSpeed);
|
||||
}
|
||||
|
||||
|
||||
if (targetClose && targetClose != "") {
|
||||
/* when it starts open the positions are reversed... */
|
||||
if (GetMoverState() == MOVER_POS1 ||
|
||||
(HasSpawnFlags(SF_MOV_OPEN) && GetMoverState() == MOVER_POS2)) {
|
||||
for (entity f = world; (f = find(f, ::targetname, targetClose));) {
|
||||
NSEntity trigger = (NSEntity)f;
|
||||
if (trigger.Trigger != __NULL__) {
|
||||
trigger.Trigger(this, TRIG_TOGGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* we arrived at our starting position within the map */
|
||||
if (GetMoverState() == MOVER_POS1) {
|
||||
if (targetClose)
|
||||
for (entity f = world; (f = find(f, ::targetname, targetClose));) {
|
||||
NSEntity trigger = (NSEntity)f;
|
||||
if (trigger.Trigger != __NULL__) {
|
||||
trigger.Trigger(this, TRIG_TOGGLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_strSndStop) {
|
||||
StartSoundDef(m_strSndStop, CHAN_VOICE, true);
|
||||
} else {
|
||||
|
@ -494,8 +499,19 @@ func_door::MoverStartsMoving(void)
|
|||
void
|
||||
func_door::Trigger(entity act, triggermode_t triggerstate)
|
||||
{
|
||||
if (GetMaster(act) == 0)
|
||||
/* Note: func_door, unlike func_door_rotating, does not respect locked here!
|
||||
This inconsistency is in the original Half-Life as well! */
|
||||
if (!GetMaster(act)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flWait == -1 && GetMoverState() == MOVER_POS2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((GetMoverState() == MOVER_1TO2) || (GetMoverState() == MOVER_2TO1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flNextTrigger > time) {
|
||||
if (HasSpawnFlags(SF_MOV_TOGGLE) == false) {
|
||||
|
@ -521,17 +537,25 @@ func_door::Trigger(entity act, triggermode_t triggerstate)
|
|||
void
|
||||
func_door::Touch(entity eToucher)
|
||||
{
|
||||
if (m_iCanTouch == false)
|
||||
/* locked sound plays only when touched. still need another check in Trigger()
|
||||
to see if it's locked in case it gets trigger targeted */
|
||||
if (m_bLocked || !GetMaster(eToucher)) {
|
||||
/* only bother playing the locked sound when the door is closed. */
|
||||
if (GetMoverState() == MOVER_POS1) {
|
||||
if (m_flSoundWait < time) {
|
||||
StartSoundDef(m_strLockedSfx, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
m_flSoundWait = time + 0.3f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasSpawnFlags(SF_MOV_USE) == true)
|
||||
if (m_bCanTouch == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_iLocked || !GetMaster(eToucher)) {
|
||||
if (m_flSoundWait < time)
|
||||
Sound_Play(this, CHAN_VOICE, m_strLockedSfx);
|
||||
|
||||
m_flSoundWait = time + 0.3f;
|
||||
if (HasSpawnFlags(SF_MOV_USE) == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -540,6 +564,7 @@ func_door::Touch(entity eToucher)
|
|||
}
|
||||
|
||||
if (eToucher.movetype == MOVETYPE_WALK) {
|
||||
/* only trigger if we're not above the door. */
|
||||
if (eToucher.absmin[2] <= maxs[2] - 2) {
|
||||
Trigger(eToucher, TRIG_TOGGLE);
|
||||
}
|
||||
|
@ -553,7 +578,7 @@ func_door::Blocked(entity eBlocker)
|
|||
Damage_Apply(eBlocker, this, m_iDamage, 0, DMG_CRUSH);
|
||||
}
|
||||
|
||||
if (!m_iForceClosed)
|
||||
if (!m_bForceClosed)
|
||||
if (m_flWait >= 0) {
|
||||
MoveToReverse(m_flSpeed);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ private:
|
|||
float m_flWait;
|
||||
float m_flDelay;
|
||||
int m_iDamage;
|
||||
int m_iLocked;
|
||||
bool m_bLocked;
|
||||
bool m_bCanTouch;
|
||||
vector m_vecTurnDir;
|
||||
};
|
||||
|
@ -119,11 +119,11 @@ func_door_rotating::func_door_rotating(void)
|
|||
m_strLockedSfx = __NULL__;
|
||||
m_flSoundWait = 0.0f;
|
||||
m_iDamage = 0i;
|
||||
m_iLocked = 0i;
|
||||
m_flDistance = 90.0f;
|
||||
m_bLocked = false;
|
||||
m_flDistance = 0.0f;
|
||||
m_flSpeed = 100.0f;
|
||||
m_flNextAction = 0.0f;
|
||||
m_flWait = 0.0f;
|
||||
m_flWait = -1;
|
||||
m_flDelay = 4.0f;
|
||||
m_bCanTouch = false;
|
||||
m_vecTurnDir = g_vec_null;
|
||||
|
@ -145,7 +145,7 @@ func_door_rotating::Save(float handle)
|
|||
SaveFloat(handle, "m_flWait", m_flWait);
|
||||
SaveFloat(handle, "m_flDelay", m_flDelay);
|
||||
SaveInt(handle, "m_iDamage", m_iDamage);
|
||||
SaveInt(handle, "m_iLocked", m_iLocked);
|
||||
SaveBool(handle, "m_bLocked", m_bLocked);
|
||||
SaveBool(handle, "m_bCanTouch", m_bCanTouch);
|
||||
SaveVector(handle, "m_vecTurnDir", m_vecTurnDir);
|
||||
}
|
||||
|
@ -190,11 +190,11 @@ func_door_rotating::Restore(string strKey, string strValue)
|
|||
case "m_iDamage":
|
||||
m_iDamage = ReadInt(strValue);
|
||||
break;
|
||||
case "m_iLocked":
|
||||
m_iLocked = ReadInt(strValue);
|
||||
case "m_bLocked":
|
||||
m_bLocked = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bCanTouch":
|
||||
m_bCanTouch = ReadInt(strValue);
|
||||
m_bCanTouch = ReadBool(strValue);
|
||||
break;
|
||||
case "m_vecTurnDir":
|
||||
m_vecTurnDir = ReadVector(strValue);
|
||||
|
@ -280,8 +280,12 @@ func_door_rotating::Respawn(void)
|
|||
SetSolid(SOLID_NOT);
|
||||
}
|
||||
|
||||
if (targetname) {
|
||||
m_iLocked = TRUE;
|
||||
if (HasTargetname() || m_flDistance == 0.0) {
|
||||
if (m_flDistance == 0.0 || m_strLockedSfx != __NULL__) {
|
||||
m_bLocked = true;
|
||||
} else {
|
||||
m_bLocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
SetAngles(GetMoverRotation1());
|
||||
|
@ -331,6 +335,10 @@ func_door_rotating::SpawnKey(string strKey, string strValue)
|
|||
break;
|
||||
case "locked_sound":
|
||||
x = stoi(strValue); /* sanitize */
|
||||
|
||||
if (x == 0i)
|
||||
break;
|
||||
|
||||
m_strLockedSfx = sprintf("func_button.hlsfx_%i", x+1i);
|
||||
break;
|
||||
default:
|
||||
|
@ -347,7 +355,7 @@ func_door_rotating::Unhinge(void)
|
|||
m_bCanTouch = false;
|
||||
SetSolid(SOLID_PHYSICS_BOX);
|
||||
SetMovetype(MOVETYPE_PHYSICS);
|
||||
physics_enable(this, TRUE);
|
||||
physics_enable(this, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -411,11 +419,20 @@ func_door_rotating::MoverStartsMoving(void)
|
|||
void
|
||||
func_door_rotating::Trigger(entity act, triggermode_t state)
|
||||
{
|
||||
if (GetMaster(act) == FALSE) {
|
||||
/* Note: Unlike func_door, this does respect the locked state in Trigger() */
|
||||
if (m_bLocked || !GetMaster(act)) {
|
||||
return;
|
||||
}
|
||||
|
||||
eActivator = act;
|
||||
if (m_flWait == -1 && GetMoverState() == MOVER_POS2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((GetMoverState() == MOVER_1TO2) || (GetMoverState() == MOVER_2TO1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
eActivator = (NSEntity)act;
|
||||
|
||||
/* this door can swing both ways */
|
||||
if (!HasSpawnFlags(SF_ROT_ONEWAY)) {
|
||||
|
@ -454,33 +471,35 @@ func_door_rotating::Trigger(entity act, triggermode_t state)
|
|||
void
|
||||
func_door_rotating::Use(void)
|
||||
{
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
Trigger(eActivator, TRIG_TOGGLE);
|
||||
}
|
||||
|
||||
void
|
||||
func_door_rotating::Touch(entity eToucher)
|
||||
{
|
||||
/* locked sound plays only when touched. still need another check in Trigger()
|
||||
to see if it's locked in case it gets trigger targeted */
|
||||
if (m_bLocked || !GetMaster(eToucher)) {
|
||||
/* only bother playing the locked sound when the door is closed. */
|
||||
if (GetMoverState() == MOVER_POS1) {
|
||||
if (m_flSoundWait < time) {
|
||||
StartSoundDef(m_strLockedSfx, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
m_flSoundWait = time + 0.3f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bCanTouch == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_iLocked || !GetMaster(eToucher)) {
|
||||
if (m_flSoundWait < time)
|
||||
Sound_Play(this, CHAN_VOICE, m_strLockedSfx);
|
||||
|
||||
m_flSoundWait = time + 0.3f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasSpawnFlags(SF_ROT_USE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((GetMoverState() == MOVER_1TO2) || (GetMoverState() == MOVER_2TO1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eToucher.movetype == MOVETYPE_WALK) {
|
||||
Trigger(eToucher, TRIG_TOGGLE);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
nonvirtual void ResetHealth(void);
|
||||
|
||||
private:
|
||||
entity m_eUser;
|
||||
NSEntity m_eUser;
|
||||
float m_flDelay;
|
||||
float m_flCheck;
|
||||
|
||||
|
@ -83,7 +83,7 @@ func_healthcharger::Restore(string strKey, string strValue)
|
|||
{
|
||||
switch (strKey) {
|
||||
case "user":
|
||||
m_eUser = ReadEntity(strValue);
|
||||
m_eUser = (NSEntity)ReadEntity(strValue);
|
||||
break;
|
||||
case "delay":
|
||||
m_flDelay = ReadFloat(strValue);
|
||||
|
@ -162,14 +162,14 @@ func_healthcharger::OnPlayerUse(void)
|
|||
if (eActivator.health <= 0)
|
||||
return;
|
||||
|
||||
eActivator.flags |= FL_USE_RELEASED;
|
||||
eActivator.AddVFlags(VFL_USE_RELEASED);
|
||||
|
||||
/* First come first serve */
|
||||
if (m_eUser && eActivator != m_eUser)
|
||||
return;
|
||||
|
||||
/* First time */
|
||||
if (m_eUser == world) {
|
||||
if (m_eUser == __NULL__) {
|
||||
StartSound(m_strSndFirst, CHAN_VOICE, 0, true);
|
||||
}
|
||||
|
||||
|
@ -177,17 +177,17 @@ func_healthcharger::OnPlayerUse(void)
|
|||
return;
|
||||
|
||||
if (health <= 0) {
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
m_eUser = world;
|
||||
m_eUser = __NULL__;
|
||||
return;
|
||||
}
|
||||
|
||||
if (eActivator.health >= 100) {
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
} else {
|
||||
if (m_eUser == world) {
|
||||
if (m_eUser == __NULL__) {
|
||||
StartSound(m_strSndCharging, CHAN_ITEM, 0, true);
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ func_healthcharger::OnPlayerUse(void)
|
|||
StopSound(CHAN_ITEM, true);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
SetFrame(1);
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
m_eUser = world;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
m_eUser = __NULL__;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ func_healthcharger::customphysics(void)
|
|||
|
||||
if (m_eUser) {
|
||||
StopSound(CHAN_ITEM, true);
|
||||
m_eUser = world;
|
||||
m_eUser = __NULL__;
|
||||
}
|
||||
|
||||
HandleThink();
|
||||
|
|
|
@ -168,7 +168,7 @@ func_recharge::OnPlayerUse(void)
|
|||
return;
|
||||
}
|
||||
|
||||
eActivator.flags |= FL_USE_RELEASED;
|
||||
eActivator.AddVFlags(VFL_USE_RELEASED);
|
||||
|
||||
/* First come first serve */
|
||||
if (m_eUser && eActivator != m_eUser) {
|
||||
|
@ -185,7 +185,7 @@ func_recharge::OnPlayerUse(void)
|
|||
}
|
||||
|
||||
if (health <= 0) {
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
m_eUser = world;
|
||||
return;
|
||||
|
@ -193,7 +193,7 @@ func_recharge::OnPlayerUse(void)
|
|||
|
||||
NSClientPlayer pl = (NSClientPlayer)eActivator;
|
||||
if (pl.armor >= 100) {
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
} else {
|
||||
if (m_eUser == world) {
|
||||
|
@ -213,7 +213,7 @@ func_recharge::OnPlayerUse(void)
|
|||
StopSound(CHAN_ITEM, true);
|
||||
StartSound(m_strSndDone, CHAN_VOICE, 0, true);
|
||||
SetFrame(1);
|
||||
eActivator.flags &= ~FL_USE_RELEASED;
|
||||
eActivator.RemoveVFlags(VFL_USE_RELEASED);
|
||||
m_eUser = world;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -42,15 +42,15 @@ A button that rotates along a pivot point. Used for valves, spigots and alike.
|
|||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "target" : Name of the entity to trigger when opened
|
||||
- "speed" : How fast the button rotates when activated.
|
||||
- "speed" : How fast the button turns when activated.
|
||||
- "health" : If non-zero, the button must be damaged to turn.
|
||||
- "wait" : Time to wait before button resets itself. -1 makes it stay set.
|
||||
- "wait" : Time until the button turns back. A value of -1 makes it stay static.
|
||||
- "distance" : Distance in degrees the button will rotate.
|
||||
|
||||
# SPAWNFLAGS
|
||||
- NONSOLID (1) : Don't do collision testing against this entity.
|
||||
- REVERSE (2) : Rotate the counter-clockwise.
|
||||
- NOAUTORETURN (32) : Will not return by itself.
|
||||
- NONSOLID (1) : Button won't have collision.
|
||||
- REVERSE (2) : Rotates counter-clockwise.
|
||||
- NOAUTORETURN (32) : Will not return by itself.
|
||||
- XAXIS (64) : Rotate along the X-axis.
|
||||
- YAXIS (128) : Rotate along the Y-axis.
|
||||
|
||||
|
@ -247,7 +247,7 @@ func_rot_button::OnPlayerUse(void)
|
|||
void
|
||||
func_rot_button::Touch(entity eToucher)
|
||||
{
|
||||
eActivator = eToucher;
|
||||
eActivator = (NSEntity)eToucher;
|
||||
|
||||
if (HasSpawnFlags(FNCROTBUT_TOUCHABLE))
|
||||
TurnToggle();
|
||||
|
|
|
@ -191,9 +191,7 @@ func_tracktrain::GetPointBetweenNodes(float percentageValue)
|
|||
vector newPos = g_vec_null;
|
||||
path_track nextNode = GetTrackNodeForward();
|
||||
path_track prevNode = GetTrackNodeBack();
|
||||
newPos[0] = Math_Lerp(prevNode.origin[0], nextNode.origin[0], percentageValue);
|
||||
newPos[1] = Math_Lerp(prevNode.origin[1], nextNode.origin[1], percentageValue);
|
||||
newPos[2] = Math_Lerp(prevNode.origin[2], nextNode.origin[2], percentageValue);
|
||||
newPos = vectorLerp(prevNode.origin, nextNode.origin, percentageValue);
|
||||
return newPos;
|
||||
}
|
||||
|
||||
|
@ -658,7 +656,7 @@ func_tracktrain::PathMoveForward(void)
|
|||
/* the direction we're aiming for */
|
||||
vecDiff = GetOrigin() - (eNode.GetOrigin() + [0, 0, m_flHeight]);
|
||||
vecAngleDest = vectoangles(vecDiff);
|
||||
vecAngleDiff = Math_AngleDiff(vecAngleDest, angles);
|
||||
vecAngleDiff = angleDifference(vecAngleDest, angles);
|
||||
vecAngleDiff[2] = 0;
|
||||
|
||||
if (vecAngleDiff[0] > 180)
|
||||
|
@ -743,8 +741,8 @@ func_tracktrain::PathMoveBack(void)
|
|||
|
||||
/* the direction we're aiming for */
|
||||
vecDiff = (eNode.GetOrigin() + [0, 0, m_flHeight]) - GetOrigin();
|
||||
vecAngleDest = vectoangles(vecDiff);
|
||||
vecAngleDiff = Math_AngleDiff(vecAngleDest, angles);
|
||||
vecAngleDest = vectorToAngles(vecDiff);
|
||||
vecAngleDiff = angleDifference(vecAngleDest, angles);
|
||||
vecAngleDiff[2] = 0;
|
||||
|
||||
if (vecAngleDiff[0] > 180)
|
||||
|
@ -980,7 +978,7 @@ func_tracktrain::_AfterSpawn(void)
|
|||
if (IgnoresPitch() == true) {
|
||||
newAngle[0] = 0;
|
||||
} else {
|
||||
newAngle[0] = -Math_FixDelta(newAngle[0]);
|
||||
newAngle[0] = -fixAngleDelta(newAngle[0]);
|
||||
}
|
||||
|
||||
SetAngles(newAngle);
|
||||
|
@ -1074,9 +1072,7 @@ func_tracktrain::OnPlayerUse(void)
|
|||
void
|
||||
func_tracktrain::EvaluateEntity(void)
|
||||
{
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
angles = fixAngle(angles);
|
||||
PlayerAlign();
|
||||
|
||||
EVALUATE_FIELD(modelindex, FNCTKTRNET_MODELINDEX)
|
||||
|
|
|
@ -65,8 +65,8 @@ monster_generic::Respawn(void)
|
|||
SetSize(base_mins, base_maxs);
|
||||
|
||||
if (HasSpawnFlags(MGF_NONSOLID)) {
|
||||
takedamage = DAMAGE_NO;
|
||||
MakeInvulnerable();
|
||||
DisableBleeding();
|
||||
SetSolid(SOLID_NOT);
|
||||
SetCanBleed(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,9 +263,9 @@ point_trigger::WillThisTrigger(entity eAct)
|
|||
return true;
|
||||
if (HasSpawnFlags(PTRIG_ALLIES) && eAct.flags & FL_MONSTER && eAct.m_iAlliance == MAL_FRIEND)
|
||||
return true;
|
||||
if (HasSpawnFlags(PTRIG_VEHPLAYER) && eAct.flags & FL_CLIENT && eAct.flags & FL_INVEHICLE)
|
||||
if (HasSpawnFlags(PTRIG_VEHPLAYER) && eAct.flags & FL_CLIENT && eAct.vv_flags & VFL_INVEHICLE)
|
||||
return true;
|
||||
if (HasSpawnFlags(PTRIG_NOVEHCL) && eAct.flags & FL_CLIENT && !(eAct.flags & FL_INVEHICLE))
|
||||
if (HasSpawnFlags(PTRIG_NOVEHCL) && eAct.flags & FL_CLIENT && !(eAct.vv_flags & VFL_INVEHICLE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
46
src/gs-entbase/server/script_brushmodel.qc
Normal file
46
src/gs-entbase/server/script_brushmodel.qc
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED script_brushmodel (0 .5 .8) ? DYNAMICPATH
|
||||
# OVERVIEW
|
||||
Scripted Brush Model
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Call of Duty (2003).
|
||||
*/
|
||||
class
|
||||
script_brushmodel:NSBrushTrigger
|
||||
{
|
||||
public:
|
||||
void script_brushmodel(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
};
|
||||
|
||||
void
|
||||
script_brushmodel::script_brushmodel(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
script_brushmodel::Trigger(entity entityActivator, triggermode_t state)
|
||||
{
|
||||
|
||||
}
|
||||
|
54
src/gs-entbase/server/script_model.qc
Normal file
54
src/gs-entbase/server/script_model.qc
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED script_model (1 0 0) (-16 -16 -16) (16 16 16) ORIENT_LOD NO_SHADOW NO_STATIC_SHADOWS
|
||||
# OVERVIEW
|
||||
Upon being triggered, the entity will spawn item_food in its place in
|
||||
the shape of a soda can.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "model" : Path of the model.
|
||||
|
||||
# SPAWNFLAGS
|
||||
- ORIENT_LOD (1) : Turn to player when lod models change
|
||||
- NO_SHADOW (2) : Will cast no shadows.
|
||||
- NO_STATIC_SHADOWS (4) : Will cast no lightmap shadows.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Call of Duty (2003).
|
||||
*/
|
||||
class
|
||||
script_model:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void script_model(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
};
|
||||
|
||||
void
|
||||
script_model::script_model(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
script_model::Trigger(entity entityActivator, triggermode_t state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
46
src/gs-entbase/server/script_origin.qc
Normal file
46
src/gs-entbase/server/script_origin.qc
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED script_origin (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
A position hint entity, designed to be used by MapC.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Call of Duty (2003).
|
||||
*/
|
||||
class
|
||||
script_origin:NSBrushTrigger
|
||||
{
|
||||
public:
|
||||
void script_origin(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
};
|
||||
|
||||
void
|
||||
script_origin::script_origin(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
script_origin::Trigger(entity entityActivator, triggermode_t state)
|
||||
{
|
||||
|
||||
}
|
||||
|
46
src/gs-entbase/server/script_struct.qc
Normal file
46
src/gs-entbase/server/script_struct.qc
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED script_struct (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Unknown.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Call of Duty 2 (2005).
|
||||
*/
|
||||
class
|
||||
script_struct:NSBrushTrigger
|
||||
{
|
||||
public:
|
||||
void script_struct(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
};
|
||||
|
||||
void
|
||||
script_struct::script_struct(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
script_struct::Trigger(entity entityActivator, triggermode_t state)
|
||||
{
|
||||
|
||||
}
|
||||
|
48
src/gs-entbase/server/script_vehicle.qc
Normal file
48
src/gs-entbase/server/script_vehicle.qc
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED script_vehicle (1 0 0) (-16 -16 -16) (16 16 16) USABLE
|
||||
# OVERVIEW
|
||||
Unknown.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "model" : Model to use for the vehicle.
|
||||
- "vehicletype" : Name of the vehicle type.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Call of Duty (2003).
|
||||
*/
|
||||
class
|
||||
script_vehicle:NSRenderableEntity
|
||||
{
|
||||
public:
|
||||
void script_vehicle(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
};
|
||||
|
||||
void
|
||||
script_vehicle::script_vehicle(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
script_vehicle::Trigger(entity entityActivator, triggermode_t state)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -233,11 +233,11 @@ trigger_hurt::Touch(entity eToucher)
|
|||
} else {
|
||||
if (HasSpawnFlags(SF_HURT_FIREONPLAYER)) {
|
||||
if (eToucher.flags & FL_CLIENT) {
|
||||
eActivator = eToucher;
|
||||
eActivator = (NSEntity)eToucher;
|
||||
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
|
||||
}
|
||||
} else {
|
||||
eActivator = eToucher;
|
||||
eActivator = (NSEntity)eToucher;
|
||||
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ trigger_multiple::SpawnKey(string strKey, string strValue)
|
|||
{
|
||||
switch (strKey) {
|
||||
case "wait":
|
||||
m_flWait = stof(strValue);
|
||||
m_flWait = ReadFloat(strValue);
|
||||
break;
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
|
@ -201,7 +201,10 @@ trigger_multiple::Input(entity entityActivator, string inputName, string dataFie
|
|||
void
|
||||
trigger_multiple::Touch(entity eToucher)
|
||||
{
|
||||
if (GetMaster(eToucher) == FALSE)
|
||||
if (IsThinking() == true)
|
||||
return;
|
||||
|
||||
if (GetMaster(eToucher) == false)
|
||||
return;
|
||||
|
||||
if (m_bEnabled == false)
|
||||
|
|
|
@ -66,7 +66,7 @@ trigger_playerfreeze::Trigger(entity act, triggermode_t state)
|
|||
|
||||
/* force unfreeze */
|
||||
for (entity f = world; (f = find(f, ::classname, "player"));) {
|
||||
f.flags &= ~FL_FROZEN;
|
||||
f.vv_flags &= ~VFL_FROZEN;
|
||||
}
|
||||
} else {
|
||||
dprint("^2trigger_playerfreeze::^3Trigger^7: " \
|
||||
|
@ -82,6 +82,6 @@ trigger_playerfreeze::customphysics(void)
|
|||
|
||||
/* some games might unset this flag every single frame */
|
||||
for (entity f = world; (f = find(f, ::classname, "player"));) {
|
||||
f.flags |= FL_FROZEN;
|
||||
f.vv_flags |= VFL_FROZEN;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ trigger_teleport::Touch(entity eToucher)
|
|||
return;
|
||||
|
||||
if (eToucher.movetype != MOVETYPE_NONE) {
|
||||
eActivator = eToucher;
|
||||
eActivator = (NSEntity)eToucher;
|
||||
entity eTarget = find(world, ::targetname, target);
|
||||
|
||||
if (eTarget) {
|
||||
|
@ -242,15 +242,15 @@ trigger_teleport::Touch(entity eToucher)
|
|||
setorigin_safe(eToucher, endpos);
|
||||
|
||||
if (m_sndTeleport) {
|
||||
Sound_Play(eToucher, CHAN_VOICE, m_sndTeleport);
|
||||
StartSoundDef(m_sndTeleport, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
if (m_sndTeleportEnter) {
|
||||
Sound_Play(this, CHAN_VOICE, m_sndTeleportEnter);
|
||||
StartSoundDef(m_sndTeleportEnter, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
if (m_sndTeleportExit) {
|
||||
Sound_Play(eTarget, CHAN_VOICE, m_sndTeleportExit);
|
||||
StartSoundDef(m_sndTeleportExit, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
EntLog("Teleported %S to %v", eToucher.netname, endpos);
|
||||
|
|
|
@ -288,7 +288,8 @@ ambient_generic::UseNormal(entity act, triggermode_t state)
|
|||
SndEntLog("Sample: %S Volume: %f; Radius: %d; Pitch: %f", m_strActivePath, m_flVolume, m_flRadius, m_flPitch);
|
||||
|
||||
if (substring(m_strActivePath, 0, 1) == "!") {
|
||||
string seq = Sentences_GetSamples(m_strActivePath);
|
||||
string sentenceWord = strtoupper(m_strActivePath);
|
||||
string seq = Sentences_GetSamples(sentenceWord);
|
||||
|
||||
if (seq == "")
|
||||
return;
|
||||
|
@ -296,7 +297,7 @@ ambient_generic::UseNormal(entity act, triggermode_t state)
|
|||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_SENTENCE);
|
||||
WriteEntity(MSG_MULTICAST, this);
|
||||
WriteInt(MSG_MULTICAST, Sentences_GetID(m_strActivePath));
|
||||
WriteInt(MSG_MULTICAST, Sentences_GetID(sentenceWord));
|
||||
msg_entity = this;
|
||||
multicast(origin, MULTICAST_PHS);
|
||||
} else {
|
||||
|
|
|
@ -475,9 +475,7 @@ env_beam::predraw(void)
|
|||
|
||||
point = center + p;
|
||||
} else {
|
||||
point[0] = Math_Lerp(m_vecStartPos[0], m_vecEndPos[0], progression);
|
||||
point[1] = Math_Lerp(m_vecStartPos[1], m_vecEndPos[1], progression);
|
||||
point[2] = Math_Lerp(m_vecStartPos[2], m_vecEndPos[2], progression);
|
||||
point = vectorLerp(m_vecStartPos, m_vecEndPos, progression);
|
||||
}
|
||||
|
||||
/* get the direction the beam is 'looking' */
|
||||
|
|
|
@ -168,11 +168,9 @@ env_fog_controller::FogRender(void)
|
|||
m_flNextDraw = cltime + 1.0f;
|
||||
|
||||
/* apply the fog. wish there was a builtin for this instead... */
|
||||
localcmd(sprintf("set r_fog_linear 1; fog %f %f %f %f %f %f\n", \
|
||||
localcmd(sprintf("set r_fog_linear 1; fog %f %v %f %f\n", \
|
||||
m_flFogEnd,
|
||||
Math_Lerp(m_vecFogColor[0], m_vecFogColor2[0], delta),
|
||||
Math_Lerp(m_vecFogColor[1], m_vecFogColor2[1], delta),
|
||||
Math_Lerp(m_vecFogColor[2], m_vecFogColor2[2], delta),
|
||||
vectorLerp(m_vecFogColor, m_vecFogColor2, delta),
|
||||
m_flFogMaxDensity,
|
||||
m_flFogStart));
|
||||
|
||||
|
|
|
@ -393,10 +393,7 @@ env_funnel::predraw(void)
|
|||
|
||||
endPos[2] += rand3 * 512.0f;
|
||||
|
||||
finalPos[0] = Math_Lerp(startPos[0], endPos[0], progress);
|
||||
finalPos[1] = Math_Lerp(startPos[1], endPos[1], progress);
|
||||
finalPos[2] = Math_Lerp(startPos[2], endPos[2], progress);
|
||||
|
||||
finalPos = vectorLerp(startPos, endPos, progress);
|
||||
RenderGlow(finalPos, [64, 64], m_flProgression);
|
||||
}
|
||||
|
||||
|
|
|
@ -348,8 +348,8 @@ env_instructor_hint::postdraw(void)
|
|||
hintPos = project(origin + [0, m_flOffset]) - [(textLength * 0.5f), 0];
|
||||
|
||||
if (inView == false) {
|
||||
hintPos[0] = Math_Lerp(32.0f, video_res[0] - sideOffset, positionValues[1]);
|
||||
hintPos[1] = Math_Lerp(32.0f, video_res[1] - 32.0f, positionValues[2]);
|
||||
hintPos[0] = lerp(32.0f, video_res[0] - sideOffset, positionValues[1]);
|
||||
hintPos[1] = lerp(32.0f, video_res[1] - 32.0f, positionValues[2]);
|
||||
}
|
||||
|
||||
/* draw the thing */
|
||||
|
|
|
@ -356,9 +356,7 @@ env_laser::predraw(void)
|
|||
float a = 1.0f;
|
||||
|
||||
/* our steps from a - b */
|
||||
point[0] = Math_Lerp(origin[0], m_vecEndPos[0], progression);
|
||||
point[1] = Math_Lerp(origin[1], m_vecEndPos[1], progression);
|
||||
point[2] = Math_Lerp(origin[2], m_vecEndPos[2], progression);
|
||||
point = vectorLerp(origin, m_vecEndPos, progression);
|
||||
|
||||
/* get the direction the laser is 'looking' */
|
||||
makevectors(vectoangles(m_vecEndPos - origin));
|
||||
|
|
|
@ -161,10 +161,7 @@ env_projectedtexture::EvaluateEntity(void)
|
|||
SetSendFlags(PRTEXFL_CHANGED_ORIGIN);
|
||||
}
|
||||
if (ATTR_CHANGED(angles)) {
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
|
||||
angles = fixAngle(angles);
|
||||
SetSendFlags(PRTEXFL_CHANGED_ANGLES);
|
||||
}
|
||||
SAVE_STATE(origin)
|
||||
|
|
|
@ -55,7 +55,7 @@ A sprite entity manager with fancy overrides.
|
|||
- ENVS_PLAYONCE (2) : Play once from start to finish, then make invisible.
|
||||
|
||||
# NOTES
|
||||
Only used with an external sprite format, like SPR, SPRHL and SPR32.
|
||||
Only used with an external sprite format, like SPR, SPRHL and SPR32, unless the material key is specified.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Half-Life (1998).
|
||||
|
|
|
@ -61,31 +61,36 @@ float
|
|||
env_steam_particle::predraw(void)
|
||||
{
|
||||
float partSize;
|
||||
float lerp = (lifetime / m_flLifeTime);
|
||||
float alpha = m_flAlpha * lerp;
|
||||
float lerpPos = (lifetime / m_flLifeTime);
|
||||
float alpha = m_flAlpha * lerpPos;
|
||||
vector color;
|
||||
vector spriteRight;
|
||||
vector spriteUp;
|
||||
|
||||
if (m_bEmissive)
|
||||
color = m_vecColor;
|
||||
else
|
||||
color = (getlight(origin) / 255);
|
||||
|
||||
partSize = Math_Lerp(m_flStartSize, m_flEndSize, lerp);
|
||||
partSize = lerp(m_flStartSize, m_flEndSize, lerpPos);
|
||||
|
||||
makevectors(g_view.GetCameraAngle());
|
||||
/* we really don't want to do this here, but people
|
||||
will mostly pass image samples and thus won't do orientation on the GPU. */
|
||||
spriteRight = anglesToRight(g_view.GetCameraAngle());
|
||||
spriteUp = anglesToUp(g_view.GetCameraAngle());
|
||||
|
||||
if (m_bType)
|
||||
R_BeginPolygon("textures/sfx/heatsteam", 0, 0);
|
||||
else
|
||||
R_BeginPolygon("textures/sfx/steam", 0, 0);
|
||||
|
||||
R_PolygonVertex(origin + v_right * partSize - v_up * partSize, [1,1], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin - v_right * partSize - v_up * partSize, [0,1], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin - v_right * partSize + v_up * partSize, [0,0], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin + v_right * partSize + v_up * partSize, [1,0], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin + spriteRight * partSize - spriteUp * partSize, [1,1], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin - spriteRight * partSize - spriteUp * partSize, [0,1], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin - spriteRight * partSize + spriteUp * partSize, [0,0], m_vecColor, alpha);
|
||||
R_PolygonVertex(origin + spriteRight * partSize + spriteUp * partSize, [1,0], m_vecColor, alpha);
|
||||
R_EndPolygon();
|
||||
|
||||
if (lerp >= 1.0f) {
|
||||
if (lerpPos >= 1.0f) {
|
||||
remove(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ func_tankmortar::ReceiveEntity(float new, float fChanged)
|
|||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_DRIVER) {
|
||||
m_eDriver = findfloat(world, ::entnum, readentitynum());
|
||||
m_eDriver = (NSEntity)findfloat(world, ::entnum, readentitynum());
|
||||
}
|
||||
|
||||
if (new)
|
||||
|
@ -185,10 +185,7 @@ func_tankmortar::EvaluateEntity(void)
|
|||
SetSendFlags(VEHFL_CHANGED_ORIGIN);
|
||||
}
|
||||
if (ATTR_CHANGED(angles)) {
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
|
||||
angles = fixAngle(angles);
|
||||
SetSendFlags(VEHFL_CHANGED_ANGLES);
|
||||
}
|
||||
if (ATTR_CHANGED(velocity)) {
|
||||
|
@ -322,10 +319,8 @@ func_tankmortar::PlayerInput(void)
|
|||
wantang = v_forward;
|
||||
makevectors(angles);
|
||||
|
||||
endang[0] = Math_Lerp(v_forward[0], wantang[0], input_timelength);
|
||||
endang[1] = Math_Lerp(v_forward[1], wantang[1], input_timelength);
|
||||
endang[2] = Math_Lerp(v_forward[2], wantang[2], input_timelength);
|
||||
angles = vectoangles(endang);
|
||||
endang = vectorLerp(v_forward, wantang, input_timelength);
|
||||
angles = vectorToAngles(endang);
|
||||
PlayerUpdateFlags();
|
||||
}
|
||||
|
||||
|
|
|
@ -815,9 +815,7 @@ func_vehicle::RunVehiclePhysics(void)
|
|||
m_eDriver.velocity = [0,0,0];
|
||||
}
|
||||
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
angles = fixAngle(angles);
|
||||
angles[0] = bound (-45, angles[0], 45);
|
||||
angles[2] = bound (-15, angles[2], 15);
|
||||
|
||||
|
@ -864,11 +862,7 @@ func_vehicle::RunVehiclePhysics(void)
|
|||
v_forward = (m_wlFL.origin + m_wlFR.origin);
|
||||
v_forward -= (m_wlBL.origin + m_wlBR.origin);
|
||||
v_up = -crossproduct(v_forward, v_right);
|
||||
angles = vectoangles(v_forward, v_up);
|
||||
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
angles = vectorToAnglesRoll(v_forward, v_up);
|
||||
|
||||
/* figure out the new chassis position */
|
||||
vector new_origin;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -139,9 +139,7 @@ phys_rope::predraw(void)
|
|||
}
|
||||
|
||||
/* travel further and sag */
|
||||
pos2[0] = Math_Lerp(origin[0], m_vecTarget[0], progress);
|
||||
pos2[1] = Math_Lerp(origin[1], m_vecTarget[1], progress);
|
||||
pos2[2] = Math_Lerp(origin[2], m_vecTarget[2], progress);
|
||||
pos2 = vectorLerp(origin, m_vecTarget, progress);
|
||||
pos2 += (v_up * -sag) * autocvar_rope_sag;
|
||||
|
||||
if (!autocvar_rope_fast)
|
||||
|
@ -320,7 +318,7 @@ void
|
|||
phys_rope::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "RopeMaterial":
|
||||
case "m_strShader":
|
||||
m_strShader = ReadString(strValue);
|
||||
break;
|
||||
case "m_flSag":
|
||||
|
@ -329,7 +327,7 @@ phys_rope::Restore(string strKey, string strValue)
|
|||
case "m_flSwingFactor":
|
||||
m_flSwingFactor = ReadFloat(strValue);
|
||||
break;
|
||||
case "Subdiv":
|
||||
case "m_iSegments":
|
||||
m_iSegments = ReadInt(strValue);
|
||||
break;
|
||||
case "m_vecTarget":
|
||||
|
|
|
@ -154,9 +154,7 @@ prop_rope::predraw(void)
|
|||
}
|
||||
|
||||
/* travel further and sag */
|
||||
pos2[0] = Math_Lerp(origin[0], m_vecTarget[0], progress);
|
||||
pos2[1] = Math_Lerp(origin[1], m_vecTarget[1], progress);
|
||||
pos2[2] = Math_Lerp(origin[2], m_vecTarget[2], progress);
|
||||
pos2 = vectorLerp(origin, m_vecTarget, progress);
|
||||
pos2 += (v_up * -sag) * autocvar_rope_sag;
|
||||
|
||||
if (!autocvar_rope_fast)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#define VEH_SKIDDING FL_USE_RELEASED
|
||||
#define VEH_SKIDDING VFL_USE_RELEASED
|
||||
|
||||
#define VEHSF_NOFLIP 2048
|
||||
|
||||
|
@ -405,7 +405,7 @@ prop_vehicle_driveable_wheel::Accel(float flMoveTime, float m_flTurn)
|
|||
/* test if this car is skidding */
|
||||
float skid = (velocity * v_right);
|
||||
if ( fabs(skid) > vehParent.m_flSkidSpeed ) {
|
||||
vehParent.flags |= VEH_SKIDDING;
|
||||
vehParent.vv_flags |= VEH_SKIDDING;
|
||||
}
|
||||
|
||||
/* nuke sideways velocity. if a wheel is off the ground this probably
|
||||
|
@ -632,11 +632,9 @@ prop_vehicle_driveable::RunVehiclePhysics(void)
|
|||
angles[2] = bound (-45, angles[2], 45);
|
||||
}
|
||||
|
||||
flags &= ~VEH_SKIDDING;
|
||||
vv_flags &= ~VEH_SKIDDING;
|
||||
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
angles = fixAngle(angles);
|
||||
|
||||
velocity[0] = bound(-1000, velocity[0], 1000);
|
||||
velocity[1] = bound(-1000, velocity[1], 1000);
|
||||
|
@ -821,10 +819,7 @@ prop_vehicle_driveable::EvaluateEntity(void)
|
|||
SetSendFlags(VEHFL_ORIGIN);
|
||||
|
||||
if (ATTR_CHANGED(angles)) {
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
|
||||
angles = fixAngle(angles);
|
||||
SetSendFlags(VEHFL_ANGLES);
|
||||
}
|
||||
if (ATTR_CHANGED(modelindex))
|
||||
|
|
|
@ -308,8 +308,8 @@ trigger_camera::GoToTarget(void)
|
|||
|
||||
if (!m_strAimAt) {
|
||||
vector vecAngleDiff = targetNode.GetOrigin() - GetOrigin();
|
||||
vector vecAngleDest = vectoangles(vecAngleDiff);
|
||||
vecAngleDiff = Math_AngleDiff(vecAngleDest, angles);
|
||||
vector vecAngleDest = vectorToAngles(vecAngleDiff);
|
||||
vecAngleDiff = angleDifference(vecAngleDest, angles);
|
||||
SetAngularVelocity(vecAngleDiff * (1 / travelTime));
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ void
|
|||
trigger_push::Touch(entity eToucher)
|
||||
{
|
||||
#ifdef SERVER
|
||||
eActivator = eToucher;
|
||||
eActivator = (NSEntity)eToucher;
|
||||
#endif
|
||||
|
||||
switch(eToucher.movetype) {
|
||||
|
|
|
@ -39,6 +39,7 @@ Only used for the world.
|
|||
- "hdr_iris_multiplier" : HDR effect multiplier. Default is "1.0".
|
||||
- "hdr_iris_fade_up" : HDR iris fade up speed. Default is "0.1".
|
||||
- "hdr_iris_fade_down" : HDR iris fade down speed. Default is "0.5".
|
||||
- "_litwater" : Set to 1 for a HL BSP to have lightmapped water surfaces.
|
||||
|
||||
# NOTES
|
||||
A map must only have one worldspawn entity.
|
||||
|
@ -56,6 +57,8 @@ public:
|
|||
void worldspawn(void);
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string, string);
|
||||
virtual void SpawnKey(string, string);
|
||||
|
||||
private:
|
||||
|
@ -72,6 +75,7 @@ private:
|
|||
float m_flHDRIrisFadeUp;
|
||||
float m_flHDRIrisFadeDown;
|
||||
bool m_bHDREnabled;
|
||||
bool m_bLitWater;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -80,15 +84,19 @@ worldspawn::worldspawn(void)
|
|||
/* defaults */
|
||||
m_flHDRIrisMinValue = 0.0;
|
||||
m_flHDRIrisMaxValue = 1.25;
|
||||
m_flHDRIrisMultiplier = 1.25;
|
||||
m_flHDRIrisFadeUp = 0.1;
|
||||
m_flHDRIrisFadeDown = 0.2;
|
||||
m_bHDREnabled = false;
|
||||
m_bLitWater = false;
|
||||
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
|
||||
m_strSkyName = "desert";
|
||||
m_flHDRIrisMultiplier = 1.5;
|
||||
m_flHDRIrisMaxValue = 1.5;
|
||||
} else {
|
||||
m_strSkyName = "";
|
||||
m_flHDRIrisMultiplier = 0.75;
|
||||
m_flHDRIrisMaxValue = 1.5;
|
||||
}
|
||||
|
||||
m_bStartDark = false;
|
||||
|
@ -115,10 +123,6 @@ worldspawn::worldspawn(void)
|
|||
lightstyle(12, "mmnnmmnnnmmnn");
|
||||
lightstyle(63, "a");
|
||||
|
||||
Skill_Init();
|
||||
EntityDef_Init();
|
||||
MapTweaks_Init();
|
||||
|
||||
precache_model("models/error.vvm");
|
||||
|
||||
if (autocvar_sv_levelexec)
|
||||
|
@ -135,17 +139,36 @@ worldspawn::Spawned(void)
|
|||
blocked = __NULL__;
|
||||
|
||||
forceinfokey(world, "skyname", m_strSkyName);
|
||||
forceinfokey(world, "startdark", ftos(m_bStartDark));
|
||||
forceinfokey(world, "chaptertitle", m_strChapterTitle);
|
||||
forceinfokey(world, "ambientsound", m_strAmbientSound);
|
||||
forceinfokey(world, "bgm", m_strBGMTrack);
|
||||
forceinfokey(world, "gametitle", ftos(m_bGameTitle));
|
||||
|
||||
/* these set cvars so we kinda always want to set them to ~something~ */
|
||||
forceinfokey(world, "hdr_iris_minvalue", ftos(m_flHDRIrisMinValue));
|
||||
forceinfokey(world, "hdr_iris_maxvalue", ftos(m_flHDRIrisMaxValue));
|
||||
forceinfokey(world, "hdr_iris_multiplier", ftos(m_flHDRIrisMultiplier));
|
||||
forceinfokey(world, "hdr_iris_fade_up", ftos(m_flHDRIrisFadeUp));
|
||||
forceinfokey(world, "hdr_iris_fade_down", ftos(m_flHDRIrisFadeDown));
|
||||
forceinfokey(world, "hdr", ftos(m_bHDREnabled));
|
||||
|
||||
/* don't want to litter serverinfo with '0' keys. */
|
||||
if (m_bGameTitle) {
|
||||
forceinfokey(world, "gametitle", ftos(m_bGameTitle));
|
||||
} else {
|
||||
forceinfokey(world, "gametitle", "");
|
||||
}
|
||||
|
||||
if (m_bStartDark) {
|
||||
forceinfokey(world, "startdark", ftos(m_bStartDark));
|
||||
} else {
|
||||
forceinfokey(world, "startdark", "");
|
||||
}
|
||||
|
||||
if (m_bLitWater) {
|
||||
forceinfokey(world, "litwater", ftos(m_bLitWater));
|
||||
} else {
|
||||
forceinfokey(world, "litwater", "");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -196,11 +219,83 @@ worldspawn::SpawnKey(string strKey, string strValue)
|
|||
case "MaxRange":
|
||||
case "sounds":
|
||||
break;
|
||||
case "_litwater":
|
||||
m_bLitWater = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
worldspawn::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
|
||||
SaveString(handle, "m_strSkyName", m_strSkyName);
|
||||
SaveBool(handle, "m_bStartDark", m_bStartDark);
|
||||
SaveBool(handle, "m_bGameTitle", m_bGameTitle);
|
||||
SaveString(handle, "m_strChapterTitle", m_strChapterTitle);
|
||||
SaveString(handle, "m_strAmbientSound", m_strAmbientSound);
|
||||
SaveString(handle, "m_strBGMTrack", m_strBGMTrack);
|
||||
SaveFloat(handle, "m_flHDRIrisMinValue", m_flHDRIrisMinValue);
|
||||
SaveFloat(handle, "m_flHDRIrisMaxValue", m_flHDRIrisMaxValue);
|
||||
SaveFloat(handle, "m_flHDRIrisMultiplier", m_flHDRIrisMultiplier);
|
||||
SaveFloat(handle, "m_flHDRIrisFadeUp", m_flHDRIrisFadeUp);
|
||||
SaveFloat(handle, "m_flHDRIrisFadeDown", m_flHDRIrisFadeDown);
|
||||
SaveBool(handle, "m_bHDREnabled", m_bHDREnabled);
|
||||
SaveBool(handle, "m_bLitWater", m_bLitWater);
|
||||
}
|
||||
|
||||
void
|
||||
worldspawn::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_strSkyName":
|
||||
m_strSkyName = ReadString(strValue);
|
||||
break;
|
||||
case "m_bStartDark":
|
||||
m_bStartDark = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bGameTitle":
|
||||
m_bGameTitle = ReadBool(strValue);
|
||||
break;
|
||||
case "m_strChapterTitle":
|
||||
m_strChapterTitle = ReadString(strValue);
|
||||
break;
|
||||
case "m_strAmbientSound":
|
||||
m_strAmbientSound = ReadString(strValue);
|
||||
break;
|
||||
case "m_strBGMTrack":
|
||||
m_strBGMTrack = ReadString(strValue);
|
||||
break;
|
||||
case "m_flHDRIrisMinValue":
|
||||
m_flHDRIrisMinValue = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flHDRIrisMaxValue":
|
||||
m_flHDRIrisMaxValue = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flHDRIrisMultiplier":
|
||||
m_flHDRIrisMultiplier = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flHDRIrisFadeUp":
|
||||
m_flHDRIrisFadeUp = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flHDRIrisFadeDown":
|
||||
m_flHDRIrisFadeDown = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_bHDREnabled":
|
||||
m_bHDREnabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bLitWater":
|
||||
m_bLitWater = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#includelist
|
||||
../shared/fteextensions.qc
|
||||
../shared/math.h
|
||||
../shared/math.qc
|
||||
../shared/global.h
|
||||
../shared/platform.h
|
||||
../platform/defs.h
|
||||
|
|
|
@ -121,7 +121,7 @@ cz_cbSprayChanged(void)
|
|||
void
|
||||
cz_sldTopcolorChanged(float val)
|
||||
{
|
||||
vector x = hsv2rgb(val * 360, 100, 100);
|
||||
vector x = hsvToRGB(val * 360, 100, 100);
|
||||
float id = x[2] + (x[1] << 8) + (x[0] << 16);
|
||||
cvar_set("topcolor", sprintf("0x%x", id));
|
||||
localcmd(sprintf("seta _cl_topcolor %f\n", val));
|
||||
|
@ -131,7 +131,7 @@ cz_sldTopcolorChanged(float val)
|
|||
void
|
||||
cz_sldBottomcolorChanged(float val)
|
||||
{
|
||||
vector x = hsv2rgb(val * 360, 100, 100);
|
||||
vector x = hsvToRGB(val * 360, 100, 100);
|
||||
float id = x[2] + (x[1] << 8) + (x[0] << 16);
|
||||
cvar_set("bottomcolor", sprintf("0x%x", id));
|
||||
localcmd(sprintf("seta _cl_bottomcolor %f\n", val));
|
||||
|
@ -435,8 +435,8 @@ menu_customize_init(void)
|
|||
cz_sldBottomcolor.SetCallback(cz_sldBottomcolorChanged);
|
||||
Widget_Add(fn_customize, cz_sldBottomcolor);
|
||||
|
||||
g_vecTopcolor = hsv2rgb(cvar("_cl_topcolor") * 360, 100, 100) / 255;
|
||||
g_vecBottomcolor = hsv2rgb(cvar("_cl_bottomcolor") * 360, 100, 100) / 255;
|
||||
g_vecTopcolor = hsvToRGB(cvar("_cl_topcolor") * 360, 100, 100) / 255;
|
||||
g_vecBottomcolor = hsvToRGB(cvar("_cl_bottomcolor") * 360, 100, 100) / 255;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,10 +55,4 @@ Util_CmdToKey(string cmd)
|
|||
}
|
||||
|
||||
return sBindTx;
|
||||
}
|
||||
|
||||
float
|
||||
lerp(float fA, float fB, float fPercent)
|
||||
{
|
||||
return (fA * (1 - fPercent)) + (fB * fPercent);
|
||||
}
|
||||
}
|
|
@ -327,8 +327,8 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type
|
|||
|
||||
/* don't allow any damage */
|
||||
if (PlayerCanAttack(tp) == false) {
|
||||
g_dmg_eAttacker = c;
|
||||
g_dmg_eTarget = t;
|
||||
g_dmg_eAttacker = (NSEntity)c;
|
||||
g_dmg_eTarget = (NSEntity)t;
|
||||
g_dmg_iDamage = 0;
|
||||
g_dmg_iHitBody = 0;
|
||||
g_dmg_iFlags = type;
|
||||
|
@ -359,8 +359,8 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type
|
|||
eTarget.SetHealth(eTarget.GetHealth() - dmg);
|
||||
|
||||
/* the globals... */
|
||||
g_dmg_eAttacker = c;
|
||||
g_dmg_eTarget = t;
|
||||
g_dmg_eAttacker = (NSEntity)c;
|
||||
g_dmg_eTarget = (NSEntity)t;
|
||||
g_dmg_iDamage = dmg;
|
||||
g_dmg_iHitBody = trace_surface_id;
|
||||
g_dmg_iFlags = type;
|
||||
|
@ -519,7 +519,7 @@ NSGameRules::IntermissionEnd(void)
|
|||
if (time < m_flIntermissionTime)
|
||||
return;
|
||||
|
||||
if (!(input_buttons & INPUT_BUTTON0) && !(input_buttons & INPUT_BUTTON2))
|
||||
if (!(input_buttons & INPUT_PRIMARY) && !(input_buttons & INPUT_JUMP))
|
||||
return;
|
||||
|
||||
localcmd("nextmap\n");
|
||||
|
|
65
src/server/cmd_cl.qc
Normal file
65
src/server/cmd_cl.qc
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
bool
|
||||
Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments)
|
||||
{
|
||||
switch (argv(0)) {
|
||||
case "say":
|
||||
if (commandArguments == 2)
|
||||
g_grMode.ChatMessageAll(sender, argv(1));
|
||||
else
|
||||
g_grMode.ChatMessageAll(sender, substring(cmd, 5, -2));
|
||||
break;
|
||||
case "say_team":
|
||||
if (commandArguments == 2)
|
||||
g_grMode.ChatMessageTeam(sender, argv(1));
|
||||
else
|
||||
g_grMode.ChatMessageTeam(sender, substring(cmd, 10, -2));
|
||||
break;
|
||||
case "spectate":
|
||||
if (sender.classname != "player")
|
||||
break;
|
||||
|
||||
player pl = (player)sender;
|
||||
pl.MakeSpectator();
|
||||
break;
|
||||
case "play":
|
||||
if (sender.classname != "spectator")
|
||||
break;
|
||||
|
||||
spawnfunc_player();
|
||||
PutClientInServer();
|
||||
break;
|
||||
case "setpos":
|
||||
if (cvar("sv_cheats") == 1) {
|
||||
setorigin(sender, stov(argv(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
case "timeleft":
|
||||
string msg;
|
||||
string timestring;
|
||||
float timeleft;
|
||||
timeleft = cvar("timelimit") - (time / 60);
|
||||
timestring = Util_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
bprint(PRINT_CHAT, msg);
|
||||
break;
|
||||
default:
|
||||
clientcommand(sender, cmd);
|
||||
}
|
||||
}
|
248
src/server/cmd_sv.qc
Normal file
248
src/server/cmd_sv.qc
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
static void
|
||||
CMD_TraceMaterial(void)
|
||||
{
|
||||
vector traceStart;
|
||||
vector traceEnd;
|
||||
string textureName;
|
||||
|
||||
traceStart = self.origin + self.view_ofs;
|
||||
makevectors(self.v_angle);
|
||||
traceEnd = traceStart + (v_forward * 4096);
|
||||
traceline(traceStart, traceEnd, MOVE_HITMODEL, self);
|
||||
|
||||
trace_surface_id = getsurfacenearpoint(trace_ent, trace_endpos);
|
||||
trace_surfacename = getsurfacetexture(trace_ent, trace_surface_id);
|
||||
|
||||
printf("trace_allsolid: %g\n", trace_allsolid);
|
||||
printf("trace_startsolid: %g\n", trace_startsolid);
|
||||
printf("trace_fraction: %f\n", trace_fraction);
|
||||
printf("trace_endpos: %v\n", trace_endpos);
|
||||
printf("trace_plane_normal: %v\n", trace_plane_normal);
|
||||
printf("trace_plane_dist: %f\n", trace_plane_dist);
|
||||
printf("trace_inopen: %g\n", trace_inopen);
|
||||
printf("trace_inwater: %g\n", trace_inwater);
|
||||
printf("trace_endcontents: %i\n", trace_endcontentsi);
|
||||
printf("trace_surfaceflags: %i\n", trace_surfaceflagsi);
|
||||
printf("trace_brush_id: %i\n", trace_brush_id);
|
||||
printf("trace_brush_faceid: %i\n", trace_brush_faceid);
|
||||
printf("trace_surface_id: %i\n", trace_surface_id);
|
||||
printf("trace_bone_id: %i\n", trace_bone_id);
|
||||
printf("trace_triangle_id: %i\n", trace_triangle_id);
|
||||
printf("trace_surfacename: %S\n", trace_surfacename);
|
||||
|
||||
if (trace_surface_id == 0) {
|
||||
printf("Unable to trace against a valid surface.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
textureName = getsurfacetexture(trace_ent, trace_surface_id);
|
||||
localcmd(sprintf("r_showshader %S\n", textureName));
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_AddBot(void)
|
||||
{
|
||||
string botProfile = strtolower(argv(1));
|
||||
float teamValue = stof(argv(2));
|
||||
float spawnDelay = stof(argv(3));
|
||||
string newName = argv(4);
|
||||
Bot_AddBot_f(botProfile, teamValue, spawnDelay, newName);
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_KillClass(void)
|
||||
{
|
||||
string targetClass;
|
||||
targetClass = argv(1);
|
||||
|
||||
if (targetClass)
|
||||
for (entity a = world; (a = find(a, ::classname, targetClass));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
t.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_KillMovables(void)
|
||||
{
|
||||
for (entity a = world; (a = findfloat(a, ::movetype, MOVETYPE_PHYSICS));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
t.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_Trigger(void)
|
||||
{
|
||||
string targ;
|
||||
targ = argv(1);
|
||||
|
||||
if (targ)
|
||||
for (entity a = world; (a = find(a, ::targetname, targ));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
|
||||
if (t.Trigger)
|
||||
t.Trigger(self, TRIG_TOGGLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_Input(void)
|
||||
{
|
||||
float entNum = stof(argv(1));
|
||||
string inputName = argv(2);
|
||||
string inputData = argv(3);
|
||||
NSEntity inputTarget = (NSEntity)edict_num(entNum);
|
||||
|
||||
if (inputTarget) {
|
||||
inputTarget.Input(self, inputName, inputData);
|
||||
print(sprintf("Sending input to %d, %S: %S\n", entNum, inputName, inputData));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_ListTargets(void)
|
||||
{
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
if (a.targetname) {
|
||||
print(sprintf("%d: %s (%s)\n", num_for_edict(a), a.targetname, a.classname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_Teleport(void)
|
||||
{
|
||||
static entity targetFinder;
|
||||
targetFinder = find(targetFinder, ::targetname, argv(1));
|
||||
|
||||
/* try at least one more time to skip world */
|
||||
if (!targetFinder)
|
||||
targetFinder = find(targetFinder, ::targetname, argv(1));
|
||||
|
||||
if (targetFinder)
|
||||
setorigin(self, targetFinder.origin);
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_TeleportToClass(void)
|
||||
{
|
||||
static entity finder;
|
||||
finder = find(finder, ::classname, argv(1));
|
||||
|
||||
/* try at least one more time to skip world */
|
||||
if (!finder)
|
||||
finder = find(finder, ::classname, argv(1));
|
||||
|
||||
if (finder)
|
||||
setorigin(self, finder.origin);
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_RenetworkEntities(void)
|
||||
{
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
NSEntity ent = (NSEntity)a;
|
||||
ent.SendFlags = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_RespawnEntities(void)
|
||||
{
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
NSEntity ent = (NSEntity)a;
|
||||
ent.Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CMD_Spawn(void)
|
||||
{
|
||||
NSEntity unit = EntityDef_CreateClassname(argv(1));
|
||||
makevectors(self.v_angle);
|
||||
traceline(self.origin, self.origin + (v_forward * 1024), MOVE_NORMAL, self);
|
||||
setorigin(unit, trace_endpos);
|
||||
}
|
||||
|
||||
bool
|
||||
Cmd_ParseServerCommand(void)
|
||||
{
|
||||
switch (argv(0)) {
|
||||
case "addBot":
|
||||
CMD_AddBot();
|
||||
break;
|
||||
case "killAllBots":
|
||||
Bot_KillAllBots();
|
||||
break;
|
||||
case "resetAllBotsGoals":
|
||||
Bot_ResetAllBotsGoals();
|
||||
break;
|
||||
case "listBotProfiles":
|
||||
Bot_ListBotProfiles_f();
|
||||
break;
|
||||
case "killClass":
|
||||
CMD_KillClass();
|
||||
break;
|
||||
case "killMovables":
|
||||
CMD_KillMovables();
|
||||
break;
|
||||
case "trigger":
|
||||
CMD_Trigger();
|
||||
break;
|
||||
case "input":
|
||||
CMD_Input();
|
||||
break;
|
||||
case "listTargets":
|
||||
CMD_ListTargets();
|
||||
break;
|
||||
case "teleport":
|
||||
CMD_Teleport();
|
||||
break;
|
||||
case "teleportToClass":
|
||||
CMD_TeleportToClass();
|
||||
break;
|
||||
case "renetworkEntities":
|
||||
CMD_RenetworkEntities();
|
||||
break;
|
||||
case "respawnEntities":
|
||||
CMD_RespawnEntities();
|
||||
break;
|
||||
case "spawn":
|
||||
CMD_Spawn();
|
||||
break;
|
||||
#ifdef BOT_INCLUDED
|
||||
case "way":
|
||||
Way_Cmd();
|
||||
break;
|
||||
#endif
|
||||
case "listEntityDef":
|
||||
EntityDef_DebugList();
|
||||
break;
|
||||
case "listSoundDef":
|
||||
Sound_DebugList();
|
||||
break;
|
||||
case "traceMaterial":
|
||||
CMD_TraceMaterial();
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
|
@ -23,6 +23,8 @@
|
|||
#include "weapons.h"
|
||||
#include "plugins.h"
|
||||
#include "NSTraceAttack.h"
|
||||
#include "../shared/weapons.h"
|
||||
#include "../shared/weapon_common.h"
|
||||
|
||||
#include "route.h"
|
||||
#include "way.h"
|
||||
|
@ -109,7 +111,7 @@ void Event_ServerModelEvent(float, int, string);
|
|||
|
||||
void Mapcycle_Load(string);
|
||||
|
||||
entity eActivator;
|
||||
NSEntity eActivator;
|
||||
|
||||
/* Generic entity fields */
|
||||
.void(void) PlayerUse;
|
||||
|
@ -129,8 +131,8 @@ string startspot;
|
|||
string __fullspawndata;
|
||||
|
||||
/* damage related tempglobals, like trace_* */
|
||||
entity g_dmg_eAttacker;
|
||||
entity g_dmg_eTarget;
|
||||
NSEntity g_dmg_eAttacker;
|
||||
NSEntity g_dmg_eTarget;
|
||||
int g_dmg_iDamage;
|
||||
int g_dmg_iRealDamage;
|
||||
bodyType_t g_dmg_iHitBody;
|
||||
|
@ -152,6 +154,42 @@ void main(void)
|
|||
#define SAVE_STRING(x,y,z) fputs(x, sprintf("%S \"%s\" ", y, z))
|
||||
#define SAVE_HEX(x,y,z) fputs(x, sprintf("%S \"%x\" ", y, z))
|
||||
|
||||
|
||||
/** When called will turn the entity 'self' into the specified classname.
|
||||
|
||||
This is useful for entities that are already in the game, and need to transition into a different type of entity.
|
||||
|
||||
@param className is the type of class to be changed to. */
|
||||
NSEntity EntityDef_SpawnClassname(string className);
|
||||
|
||||
|
||||
/** Spawns an entity of a specific class. If class doesn't exist, returns __NULL__.
|
||||
|
||||
@param className is the type of class to be instantiated. */
|
||||
NSEntity EntityDef_CreateClassname(string className);
|
||||
|
||||
/** Spawns an entity of a class, guaranteed to be valid.
|
||||
|
||||
This is the primary, encouraged method of spawning entities.
|
||||
If you don't spawn an entity class using this, it will not respond to sendInput().
|
||||
|
||||
If a specified class does not exist, it will create an info_notnull type entity, but with the new, desired classname.
|
||||
|
||||
The only time when this function returns __NULL__ is if the game is unable to allocate any more entities.
|
||||
|
||||
@param className is the type of class to be instantiated. */
|
||||
NSEntity Entity_CreateClass(string className);
|
||||
|
||||
/** Checks if an entity class was defined in an EntityDef.
|
||||
|
||||
You can then use EntityDef_GetKeyValue() to get various key values from said EntityDef.
|
||||
|
||||
@param className specifies which class definition to look for. */
|
||||
bool EntityDef_HasSpawnClass(string className);
|
||||
|
||||
|
||||
/** Retrieves the value of a specific key defined within an EntityDef.
|
||||
|
||||
@param className specifies which class definition to look in.
|
||||
@param keyName specifies the 'key' we want to know its value of. */
|
||||
string EntityDef_GetKeyValue(string className, string keyName);
|
||||
|
|
|
@ -166,6 +166,11 @@ EntityDef_ReadFile(string filePath)
|
|||
/* increment the def count */
|
||||
if (g_entDefCount < ENTITYDEF_MAX)
|
||||
g_entDefCount++;
|
||||
|
||||
if (g_entDefCount >= ENTITYDEF_MAX) {
|
||||
NSError("Reached limit of %d defs.", ENTITYDEF_MAX);
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentDef.entClass = "";
|
||||
currentDef.spawnClass = "";
|
||||
|
@ -199,9 +204,6 @@ EntityDef_ReadFile(string filePath)
|
|||
} else if (word == "inherit") {
|
||||
currentDef.inheritKeys = argv(i+1);
|
||||
i++;
|
||||
} else if (substring(word, 0, 7) == "editor_") {
|
||||
/* do nothing */
|
||||
i++;
|
||||
} else if (substring(word, 0, 4) == "when") {
|
||||
switch (argv(i+2)) {
|
||||
case "equals":
|
||||
|
@ -248,6 +250,7 @@ EntityDef_ReadFile(string filePath)
|
|||
void
|
||||
EntityDef_Init(void)
|
||||
{
|
||||
string mapDef = sprintf("maps/%s.def", cvar_string("mapname"));
|
||||
searchhandle pm;
|
||||
|
||||
InitStart();
|
||||
|
@ -272,22 +275,10 @@ EntityDef_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
int numKeys = tokenize_console(g_entDefTable[i].spawnData);
|
||||
print(sprintf("edef %i: %S\n", i, g_entDefTable[i].entClass));
|
||||
print(sprintf("\tspawnclass: %S\n", g_entDefTable[i].spawnClass));
|
||||
print(sprintf("\tinheritKeys: %S\n", g_entDefTable[i].inheritKeys));
|
||||
print(sprintf("\ttweakDefs %S\n", g_entDefTable[i].tweakDefs));
|
||||
print(sprintf("\ttweakKeys %S\n", g_entDefTable[i].tweakKeys));
|
||||
print(sprintf("\teventList %S\n", g_entDefTable[i].eventList));
|
||||
print("\tspawnData:\n");
|
||||
|
||||
for (int c = 0; c < numKeys; c+=2) {
|
||||
print(sprintf("\t\t%S %S\n", argv(c), argv(c+1)));
|
||||
}
|
||||
/* load the map specific def file */
|
||||
if (FileExists(mapDef)) {
|
||||
EntityDef_ReadFile(mapDef);
|
||||
}
|
||||
#endif
|
||||
|
||||
InitEnd();
|
||||
}
|
||||
|
@ -503,7 +494,10 @@ EntityDef_SpawnClassname(string className)
|
|||
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
EntityDef_Precaches(i);
|
||||
if (time < 1.0) {
|
||||
EntityDef_Precaches(i);
|
||||
}
|
||||
|
||||
NSLog("Spawning eDef %S", className);
|
||||
return EntityDef_PrepareEntity(self, i);
|
||||
}
|
||||
|
@ -594,6 +588,7 @@ CallSpawnfuncByName(entity target, string className)
|
|||
self = oldSelf;
|
||||
}
|
||||
|
||||
|
||||
NSEntity
|
||||
Entity_CreateClass(string className)
|
||||
{
|
||||
|
@ -605,4 +600,23 @@ Entity_CreateClass(string className)
|
|||
}
|
||||
|
||||
return newEntity;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EntityDef_DebugList(void)
|
||||
{
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
int numKeys = tokenize_console(g_entDefTable[i].spawnData);
|
||||
print(sprintf("edef %i: %S\n", i, g_entDefTable[i].entClass));
|
||||
print(sprintf("\tspawnclass: %S\n", g_entDefTable[i].spawnClass));
|
||||
print(sprintf("\tinheritKeys: %S\n", g_entDefTable[i].inheritKeys));
|
||||
print(sprintf("\ttweakDefs %S\n", g_entDefTable[i].tweakDefs));
|
||||
print(sprintf("\ttweakKeys %S\n", g_entDefTable[i].tweakKeys));
|
||||
print(sprintf("\teventList %S\n", g_entDefTable[i].eventList));
|
||||
print("\tspawnData:\n");
|
||||
|
||||
for (int c = 0; c < numKeys; c+=2) {
|
||||
print(sprintf("\t\t%S %S\n", argv(c), argv(c+1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ static int g_ent_spawned;
|
|||
void
|
||||
StartFrame(void)
|
||||
{
|
||||
PMove_StartFrame();
|
||||
|
||||
/* For entity parenting to work, we need to go through and run on every
|
||||
* this method on every NSEntity class */
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
|
@ -180,7 +178,8 @@ PutClientInServer(void)
|
|||
trigger_auto_trigger();
|
||||
|
||||
if (g_grMode.InIntermission() == true) {
|
||||
g_grMode.IntermissionToPlayer((NSClientPlayer)self);
|
||||
NSClientPlayer pl = (NSClientPlayer)self;
|
||||
g_grMode.IntermissionToPlayer(pl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,51 +320,9 @@ SV_ParseClientCommand(string cmd)
|
|||
if (g_grMode.ClientCommand((NSClient)self, cmd) == true)
|
||||
return;
|
||||
|
||||
argc = tokenize(cmd);
|
||||
argc = (int)tokenize(cmd);
|
||||
|
||||
switch (argv(0)) {
|
||||
case "say":
|
||||
if (argc == 2)
|
||||
g_grMode.ChatMessageAll((NSClient)self, argv(1));
|
||||
else
|
||||
g_grMode.ChatMessageAll((NSClient)self, substring(cmd, 5, -2));
|
||||
break;
|
||||
case "say_team":
|
||||
if (argc == 2)
|
||||
g_grMode.ChatMessageTeam((NSClient)self, argv(1));
|
||||
else
|
||||
g_grMode.ChatMessageTeam((NSClient)self, substring(cmd, 10, -2));
|
||||
break;
|
||||
case "spectate":
|
||||
if (self.classname != "player")
|
||||
break;
|
||||
|
||||
player pl = (player)self;
|
||||
pl.MakeSpectator();
|
||||
break;
|
||||
case "play":
|
||||
if (self.classname != "spectator")
|
||||
break;
|
||||
spawnfunc_player();
|
||||
PutClientInServer();
|
||||
break;
|
||||
case "setpos":
|
||||
if (cvar("sv_cheats") == 1) {
|
||||
setorigin(self, stov(argv(1)));
|
||||
}
|
||||
break;
|
||||
case "timeleft":
|
||||
string msg;
|
||||
string timestring;
|
||||
float timeleft;
|
||||
timeleft = cvar("timelimit") - (time / 60);
|
||||
timestring = Util_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
bprint(PRINT_CHAT, msg);
|
||||
break;
|
||||
default:
|
||||
clientcommand(self, cmd);
|
||||
}
|
||||
Cmd_ParseClientCommand((NSClient)self, cmd, argc);
|
||||
}
|
||||
|
||||
/** Called when the QC module gets loaded.
|
||||
|
@ -378,6 +335,10 @@ init(float prevprogs)
|
|||
NSLog("Built: %s %s", __DATE__, __TIME__);
|
||||
NSLog("QCC: %s", __QCCVER__);
|
||||
|
||||
Skill_Init();
|
||||
EntityDef_Init();
|
||||
MapTweaks_Init();
|
||||
MapC_Init();
|
||||
Plugin_Init();
|
||||
|
||||
Constants_Init();
|
||||
|
@ -475,6 +436,7 @@ initents(void)
|
|||
* let's add our own that we can actually trust. */
|
||||
forceinfokey(world, "sv_playerslots", cvar_string("sv_playerslots"));
|
||||
|
||||
MapC_CallMainFunction();
|
||||
Plugin_InitEnts();
|
||||
Mapcycle_Init();
|
||||
Vote_Init();
|
||||
|
@ -535,121 +497,7 @@ ConsoleCmd(string cmd)
|
|||
|
||||
/* time to handle commands that apply to all games */
|
||||
tokenize(cmd);
|
||||
switch (argv(0)) {
|
||||
case "addBot":
|
||||
string botProfile = strtolower(argv(1));
|
||||
float teamValue = stof(argv(2));
|
||||
float spawnDelay = stof(argv(3));
|
||||
string newName = argv(4);
|
||||
Bot_AddBot_f(botProfile, teamValue, spawnDelay, newName);
|
||||
break;
|
||||
case "killAllBots":
|
||||
Bot_KillAllBots();
|
||||
break;
|
||||
case "resetAllBotsGoals":
|
||||
Bot_ResetAllBotsGoals();
|
||||
break;
|
||||
case "listBotProfiles":
|
||||
Bot_ListBotProfiles_f();
|
||||
break;
|
||||
case "killClass":
|
||||
string targetClass;
|
||||
targetClass = argv(1);
|
||||
|
||||
if (targetClass)
|
||||
for (entity a = world; (a = find(a, ::classname, targetClass));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
t.Destroy();
|
||||
}
|
||||
break;
|
||||
case "killMovables":
|
||||
for (entity a = world; (a = findfloat(a, ::movetype, MOVETYPE_PHYSICS));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
t.Destroy();
|
||||
}
|
||||
break;
|
||||
case "trigger":
|
||||
string targ;
|
||||
targ = argv(1);
|
||||
|
||||
if (targ)
|
||||
for (entity a = world; (a = find(a, ::targetname, targ));) {
|
||||
NSEntity t = (NSEntity)a;
|
||||
|
||||
if (t.Trigger)
|
||||
t.Trigger(self, TRIG_TOGGLE);
|
||||
}
|
||||
break;
|
||||
case "input":
|
||||
float entNum = stof(argv(1));
|
||||
string inputName = argv(2);
|
||||
string inputData = argv(3);
|
||||
NSEntity inputTarget = (NSEntity)edict_num(entNum);
|
||||
|
||||
if (inputTarget) {
|
||||
inputTarget.Input(self, inputName, inputData);
|
||||
print(sprintf("Sending input to %d, %S: %S\n", entNum, inputName, inputData));
|
||||
}
|
||||
break;
|
||||
case "listTargets":
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
if (a.targetname) {
|
||||
print(sprintf("%d: %s (%s)\n", num_for_edict(a), a.targetname, a.classname));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "teleport":
|
||||
static entity targetFinder;
|
||||
targetFinder = find(targetFinder, ::targetname, argv(1));
|
||||
|
||||
/* try at least one more time to skip world */
|
||||
if (!targetFinder)
|
||||
targetFinder = find(targetFinder, ::targetname, argv(1));
|
||||
|
||||
if (targetFinder)
|
||||
setorigin(pl, targetFinder.origin);
|
||||
break;
|
||||
case "teleportToClass":
|
||||
static entity finder;
|
||||
finder = find(finder, ::classname, argv(1));
|
||||
|
||||
/* try at least one more time to skip world */
|
||||
if (!finder)
|
||||
finder = find(finder, ::classname, argv(1));
|
||||
|
||||
if (finder)
|
||||
setorigin(pl, finder.origin);
|
||||
break;
|
||||
case "renetworkEntities":
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
NSEntity ent = (NSEntity)a;
|
||||
ent.SendFlags = -1;
|
||||
}
|
||||
break;
|
||||
case "respawnEntities":
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
NSEntity ent = (NSEntity)a;
|
||||
ent.Respawn();
|
||||
}
|
||||
break;
|
||||
case "spawn":
|
||||
NSEntity unit = EntityDef_CreateClassname(argv(1));
|
||||
makevectors(pl.v_angle);
|
||||
traceline(pl.origin, pl.origin + (v_forward * 1024), MOVE_NORMAL, pl);
|
||||
setorigin(unit, trace_endpos);
|
||||
break;
|
||||
#ifdef BOT_INCLUDED
|
||||
case "way":
|
||||
Way_Cmd();
|
||||
break;
|
||||
#endif
|
||||
case "listSoundDef":
|
||||
Sound_DebugList();
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
return Cmd_ParseServerCommand();
|
||||
}
|
||||
|
||||
/** Returns TRUE if the server can pause the server when the 'pause' command
|
||||
|
|
|
@ -15,5 +15,8 @@ modelevent.qc
|
|||
mapcycle.qc
|
||||
entityDef.qc
|
||||
maptweaks.qc
|
||||
scripts.qc
|
||||
cmd_cl.qc
|
||||
cmd_sv.qc
|
||||
entry.qc
|
||||
#endlist
|
||||
|
|
|
@ -81,7 +81,7 @@ CheatersLament(NSClientPlayer playerEntity, vector absAngles, float buttons, flo
|
|||
playerEntity.pb_player_delta = 0.0f;
|
||||
|
||||
/* if the player is firing, calculate the player delta */
|
||||
if (buttons & INPUT_BUTTON0 || buttons & INPUT_BUTTON3) { /* primary & secondary fire counts */
|
||||
if (buttons & INPUT_PRIMARY || buttons & INPUT_SECONDARY) { /* primary & secondary fire counts */
|
||||
vector deltaPosition;
|
||||
float deltaDegrees;
|
||||
|
||||
|
|
114
src/server/mapC.h
Normal file
114
src/server/mapC.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
#pragma target fte_5768
|
||||
#define QWSSQC
|
||||
|
||||
/* MapProgs are map specific QuakeC progs.
|
||||
Include this file with YOUR MapProgs! */
|
||||
|
||||
#include "../shared/fteextensions.qc"
|
||||
#include "../shared/global.h"
|
||||
#include "../shared/math.h"
|
||||
#include "../shared/math_vector.h"
|
||||
|
||||
#define entity_def(x, ...) const string x[] = { __VA_ARGS__ }
|
||||
|
||||
/** Calls a function (with parameters) in a new thread. */
|
||||
#define thread(x) if (fork()) { x; abort(); }
|
||||
|
||||
/** Spawns an entity of a specific class.
|
||||
|
||||
This is the primary, encouraged method of spawning entities in MapC.
|
||||
If you don't spawn an entity class using this, it will not respond to sendInput().
|
||||
|
||||
If a specified class does not exist, it will create an info_notnull type entity, but with the new, desired classname.
|
||||
|
||||
The only time when this function returns __NULL__ is if the server is unable to allocated any more entities.
|
||||
|
||||
@param className is the type of class to be instantiated.
|
||||
@param desiredPos is the world position at which the new entity will be placed. */
|
||||
entity
|
||||
spawnClass(string className, vector desiredPos)
|
||||
{
|
||||
entity(string, vector) spawnFunc = externvalue(0, "MapC_CreateEntityClass");
|
||||
return spawnFunc(className, desiredPos);
|
||||
}
|
||||
|
||||
/** Sends an input (See NSIO::Input) to an entity.
|
||||
|
||||
While you're able to manipulate entities in most ways using bare MapC, you might want to change Nuclide specific attributes of them as well. This can only be done using the I/O system.
|
||||
|
||||
For the variety of inputs an entity supports, please look at the respective entity-specific documentation.
|
||||
|
||||
@param target is the entity which will receive the input
|
||||
@param inputName is the name of the input. E.g. "SetOrigin"
|
||||
@param dataString contains parameters for the input. E.g. "0 0 0"
|
||||
@param activator references which entity is "responsible" for triggering this input. */
|
||||
void
|
||||
sendInput(entity target, string inputName, string dataString, entity activator)
|
||||
{
|
||||
void(entity, entity, string, string) inputFunc = externvalue(0, "MapC_SendEntityInput");
|
||||
inputFunc(target, activator, inputName, setValue);
|
||||
}
|
||||
|
||||
/** Does damage to all entities within a specified radius with a linear falloff.
|
||||
|
||||
@param position specifies the position at which the damage event occurs.
|
||||
@param radius specifies the radius in game units.
|
||||
@param maxDamage the maximum amount of damage this event can do.
|
||||
@param minDamage the damage done to the entities on the outer-most rim of the radius.
|
||||
@param attacker (optional) the source of the attack, defaults to world */
|
||||
void
|
||||
radiusDamage(vector position, float radius, int maxDamage, int minDamage, optional entity attacker)
|
||||
{
|
||||
void(vector, float, int, int, entity) damageFunc = externvalue(0, "MapC_RadiusDamage");
|
||||
damageFunc(position, radius, maxDamage, minDamage, attacker);
|
||||
}
|
||||
|
||||
/** Returns true/false depending on if the entity is an AI character.
|
||||
|
||||
@param entityToCheck specifies the entity to check.*/
|
||||
bool
|
||||
isAI(entity entityToCheck)
|
||||
{
|
||||
bool(entity) checkFunc = externvalue(0, "MapC_IsAI");
|
||||
return checkFunc(entityToCheck);
|
||||
}
|
||||
|
||||
/** Returns true/false depending on if the entity is alive.
|
||||
|
||||
@param entityToCheck specifies the entity to check.*/
|
||||
bool
|
||||
isAlive(entity entityToCheck)
|
||||
{
|
||||
bool(entity) checkFunc = externvalue(0, "MapC_IsAlive");
|
||||
return checkFunc(entityToCheck);
|
||||
}
|
||||
|
||||
/** Returns true/false depending on if the entity is in "god" mode.
|
||||
|
||||
@param entityToCheck specifies the entity to check.*/
|
||||
bool
|
||||
isGodMode(entity entityToCheck)
|
||||
{
|
||||
bool(entity) checkFunc = externvalue(0, "MapC_IsGodMode");
|
||||
return checkFunc(entityToCheck);
|
||||
}
|
||||
|
||||
/** Returns true/false depending on if the entity is a player.
|
||||
|
||||
@param entityToCheck specifies the entity to check.*/
|
||||
bool
|
||||
isPlayer(entity entityToCheck)
|
||||
{
|
||||
bool(entity) checkFunc = externvalue(0, "MapC_IsPlayer");
|
||||
return checkFunc(entityToCheck);
|
||||
}
|
||||
|
||||
/** Returns true/false depending on if the entity is either a player, or AI character.
|
||||
|
||||
@param entityToCheck specifies the entity to check.*/
|
||||
bool
|
||||
isSentient(entity entityToCheck)
|
||||
{
|
||||
bool(entity) checkFunc = externvalue(0, "MapC_IsSentient");
|
||||
return checkFunc(entityToCheck);
|
||||
}
|
|
@ -248,11 +248,21 @@ Nodes_Init(void)
|
|||
#define NODE_LINE_ALPHA 0.25f
|
||||
|
||||
/* draws debug graphics of our node tree */
|
||||
var bool autocvar_r_renderEntityInfo = false;
|
||||
void
|
||||
SV_AddDebugPolygons(void)
|
||||
{
|
||||
Way_DrawDebugInfo();
|
||||
|
||||
if (autocvar_r_renderEntityInfo) {
|
||||
makevectors(self.v_angle);
|
||||
|
||||
for (entity s = world; (s = findfloat(s, ::identity, 1));) {
|
||||
NSEntity drawMe = (NSEntity)s;
|
||||
drawMe.DebugDraw();
|
||||
}
|
||||
}
|
||||
|
||||
if (cvar("developer") != 1)
|
||||
return;
|
||||
|
||||
|
@ -266,25 +276,5 @@ SV_AddDebugPolygons(void)
|
|||
train.RenderDebugInfo();
|
||||
}
|
||||
#endif
|
||||
|
||||
makevectors(self.v_angle);
|
||||
|
||||
for (entity s = world; (s = findfloat(s, ::identity, 1));) {
|
||||
NSEntity drawMe = (NSEntity)s;
|
||||
drawMe.DebugDraw();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
/* draw the rectangles */
|
||||
R_BeginPolygon("textures/dev/info_node", 0, 0);
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
node_t *w = g_pNodes + i;
|
||||
R_PolygonVertex(w->origin + v_right * 8 - v_up * 8, [1,1], NODE_RECT_COLOR, NODE_RECT_ALPHA);
|
||||
R_PolygonVertex(w->origin - v_right * 8 - v_up * 8, [0,1], NODE_RECT_COLOR, NODE_RECT_ALPHA);
|
||||
R_PolygonVertex(w->origin - v_right * 8 + v_up * 8, [0,0], NODE_RECT_COLOR, NODE_RECT_ALPHA);
|
||||
R_PolygonVertex(w->origin + v_right * 8 + v_up * 8, [1,0], NODE_RECT_COLOR, NODE_RECT_ALPHA);
|
||||
R_EndPolygon();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
157
src/server/scripts.qc
Normal file
157
src/server/scripts.qc
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
var float g_mapCProgs;
|
||||
void
|
||||
MapC_Init(void)
|
||||
{
|
||||
string mapProgs;
|
||||
|
||||
/* mapname global is not set yet in init() */
|
||||
mapProgs = sprintf("maps/%s.dat", cvar_string("mapname"));
|
||||
|
||||
/* No mapname.dat, exit out */
|
||||
if (FileExists(mapProgs) == false) {
|
||||
NSError("MapC for level %s at %S does not exist.", mapname, mapProgs);
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog("...adding MapC progs %S",mapProgs);
|
||||
g_mapCProgs = addprogs(mapProgs);
|
||||
}
|
||||
|
||||
void
|
||||
MapC_CallMainFunction(void)
|
||||
{
|
||||
void(void) mainFunction;
|
||||
mainFunction = externvalue(g_mapCProgs, "main");
|
||||
|
||||
if (mainFunction) {
|
||||
externset(g_mapCProgs, world, "self");
|
||||
mainFunction();
|
||||
} else {
|
||||
NSError("%s does not have a main function.", mapname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MapC_CallNamedFunction(entity functionActivator, string targetFunction)
|
||||
{
|
||||
void(void) ourFunction;
|
||||
ourFunction = externvalue(g_mapCProgs, targetFunction);
|
||||
|
||||
if (ourFunction) {
|
||||
externset(g_mapCProgs, functionActivator, "self");
|
||||
ourFunction();
|
||||
} else {
|
||||
NSError("%s does not have a function %s.", mapname, targetFunction);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a new entity. Guaranteed to be something. Never __NULL__
|
||||
unless we're seriously out of memory. */
|
||||
entity
|
||||
MapC_CreateEntityClass(string className, vector desiredPos)
|
||||
{
|
||||
NSEntity newEntity = Entity_CreateClass(className);
|
||||
|
||||
/* That class didn't exist, so let's take the base Nuclide one */
|
||||
if (!newEntity) {
|
||||
newEntity = Entity_CreateClass("NSEntity");
|
||||
}
|
||||
|
||||
/* OOM. It's over. */
|
||||
if (!newEntity) {
|
||||
return __NULL__;
|
||||
}
|
||||
|
||||
newEntity.classname = className;
|
||||
newEntity.Input(newEntity, "SetSpawnOrigin", vtos(desiredPos));
|
||||
newEntity.Input(newEntity, "SetOrigin", vtos(desiredPos));
|
||||
newEntity.Respawn();
|
||||
|
||||
return (entity)newEntity;
|
||||
}
|
||||
|
||||
/* Sends an input to the specified target. */
|
||||
void
|
||||
MapC_SendEntityInput(vector position, float radius, int maxDamage, int minDamage, optional entity attacker)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Damage Category */
|
||||
void
|
||||
MapC_RadiusDamage(entity target, entity activator, string inputName, string setValue)
|
||||
{
|
||||
NSEntity targetEntity = (NSEntity)target;
|
||||
NSEntity theActivator = (NSEntity)activator;
|
||||
targetEntity.Input(theActivator, inputName, setValue);
|
||||
}
|
||||
|
||||
/* Sentient Category */
|
||||
bool
|
||||
MapC_IsAI(entity entityToCheck)
|
||||
{
|
||||
if (entityToCheck.flags & FL_MONSTER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MapC_IsAlive(entity entityToCheck)
|
||||
{
|
||||
if (entityToCheck.takedamage != DAMAGE_NO) {
|
||||
NSSurfacePropEntity livingEnt = (NSSurfacePropEntity)entityToCheck;
|
||||
return livingEnt.IsAlive();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MapC_IsGodMode(entity entityToCheck)
|
||||
{
|
||||
if (entityToCheck.flags & FL_GODMODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MapC_IsPlayer(entity entityToCheck)
|
||||
{
|
||||
if (entityToCheck.flags & FL_CLIENT) {
|
||||
NSClient pl = (NSClient)entityToCheck;
|
||||
|
||||
return pl.IsPlayer();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MapC_IsSentient(entity entityToCheck)
|
||||
{
|
||||
if (MapC_IsAI(entityToCheck) || MapC_IsPlayer(entityToCheck)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -382,4 +382,15 @@ CSEv_DropWeapon(void)
|
|||
player pl = (player)self;
|
||||
Weapon_DropCurrentWeapon(pl);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void
|
||||
CSEv_PlayerSwitchWeapon_i(int w)
|
||||
{
|
||||
player pl = (player)self;
|
||||
|
||||
if (pl.activeweapon != w) {
|
||||
pl.activeweapon = w;
|
||||
Weapons_Draw(pl);
|
||||
}
|
||||
}
|
|
@ -44,6 +44,9 @@ public:
|
|||
|
||||
/* overrides */
|
||||
virtual void OnRemoveEntity(void);
|
||||
virtual float GetForwardSpeed(void);
|
||||
virtual float GetSideSpeed(void);
|
||||
virtual float GetBackSpeed(void);
|
||||
|
||||
#ifdef CLIENT
|
||||
/** Client: Called on the client to give a chance to override input_* variables before networking them takes place. */
|
||||
|
|
|
@ -153,6 +153,24 @@ NSClient::IsPlayer(void)
|
|||
return (false);
|
||||
}
|
||||
|
||||
float
|
||||
NSClient::GetForwardSpeed(void)
|
||||
{
|
||||
return cvar("cl_forwardspeed");
|
||||
}
|
||||
|
||||
float
|
||||
NSClient::GetSideSpeed(void)
|
||||
{
|
||||
return cvar("cl_sidespeed");
|
||||
}
|
||||
|
||||
float
|
||||
NSClient::GetBackSpeed(void)
|
||||
{
|
||||
return cvar("cl_backspeed");
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
NSClient::ClientInputFrame(void)
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
|
||||
virtual void Physics_Fall(float);
|
||||
virtual void Physics_Crouch(void);
|
||||
virtual void Physics_Prone(void);
|
||||
virtual void Physics_Jump(void);
|
||||
virtual void Physics_CheckJump(float);
|
||||
virtual void Physics_SetViewParms(void);
|
||||
|
@ -48,6 +49,15 @@ public:
|
|||
virtual bool IsDead(void);
|
||||
virtual bool IsPlayer(void);
|
||||
virtual void SharedInputFrame(void);
|
||||
|
||||
/** Overridable: Returns whether the client can sprint, with the command +sprint */
|
||||
virtual bool CanSprint(void);
|
||||
/** Overridable: Returns whether the client can prone, with the commands +prone and goprone */
|
||||
virtual bool CanProne(void);
|
||||
/** Overridable: Returns whether the client can crouch, with the commands +crouch and gocrouch */
|
||||
virtual bool CanCrouch(void);
|
||||
/** Overridable: Returns whether the client can lean, with the commands +leanleft and +leanright */
|
||||
virtual bool CanLean(void);
|
||||
|
||||
/** Empty & shared between Client and Server. This is run on every player, every frame, to update their animation cycle. */
|
||||
virtual void UpdatePlayerAnimation(float);
|
||||
|
@ -127,6 +137,7 @@ private:
|
|||
PREDICTED_FLOAT(w_idle_next)
|
||||
PREDICTED_FLOAT(teleport_time)
|
||||
PREDICTED_FLOAT(weapontime)
|
||||
PREDICTED_FLOAT(m_flStamina)
|
||||
PREDICTED_VECTOR(punchangle)
|
||||
|
||||
/* We can't use the default .items field, because FTE will assume
|
||||
|
|
|
@ -41,36 +41,52 @@ NSClientPlayer::IsRealSpectator(void)
|
|||
bool
|
||||
NSClientPlayer::IsDead(void)
|
||||
{
|
||||
if (health > 0)
|
||||
return (false);
|
||||
else
|
||||
return (true);
|
||||
return (health > 0) ? (false) : true;
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::IsPlayer(void)
|
||||
{
|
||||
if (HasFlags(FL_FAKESPEC))
|
||||
return (false);
|
||||
|
||||
return (true);
|
||||
return !HasVFlags(VFL_FAKESPEC);
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::IsFakeSpectator(void)
|
||||
{
|
||||
if (HasFlags(FL_FAKESPEC))
|
||||
return (true);
|
||||
return HasVFlags(VFL_FAKESPEC);
|
||||
}
|
||||
|
||||
return (false);
|
||||
bool
|
||||
NSClientPlayer::CanSprint(void)
|
||||
{
|
||||
return g_pmoveVars.pm_runspeed > 0 ? (true) : false;
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::CanProne(void)
|
||||
{
|
||||
return g_pmoveVars.pm_proneheight > 0 ? (true) : false;
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::CanLean(void)
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::CanCrouch(void)
|
||||
{
|
||||
return g_pmoveVars.pm_crouchheight > 0 ? (true) : false;
|
||||
}
|
||||
|
||||
void
|
||||
NSClientPlayer::PreFrame(void)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
if (Util_IsPaused())
|
||||
if (Util_IsPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is where a game/mod would decide to add more prediction rollback
|
||||
* information. */
|
||||
|
@ -110,8 +126,9 @@ void
|
|||
NSClientPlayer::PostFrame(void)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
if (Util_IsPaused())
|
||||
if (Util_IsPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* give the game/mod a chance to roll back its values too */
|
||||
PredictPostFrame();
|
||||
|
@ -154,12 +171,12 @@ NSClientPlayer::ProcessInput(void)
|
|||
rules.IntermissionEnd();
|
||||
return;
|
||||
} else if (IsAlive() == false) {
|
||||
if (input_buttons & INPUT_BUTTON0)
|
||||
if (input_buttons & INPUT_PRIMARY)
|
||||
rules.PlayerRequestRespawn(this);
|
||||
}
|
||||
|
||||
/* handle use button presses */
|
||||
if (input_buttons & INPUT_BUTTON5)
|
||||
if (input_buttons & INPUT_USE)
|
||||
InputUse_Down();
|
||||
else
|
||||
InputUse_Up();
|
||||
|
@ -186,11 +203,11 @@ NSClientPlayer::ProcessInput(void)
|
|||
}
|
||||
|
||||
/* weapon system */
|
||||
if (input_buttons & INPUT_BUTTON3)
|
||||
if (input_buttons & INPUT_SECONDARY)
|
||||
Weapons_Secondary((player)this);
|
||||
else if (input_buttons & INPUT_BUTTON0)
|
||||
else if (input_buttons & INPUT_PRIMARY)
|
||||
Weapons_Primary((player)this);
|
||||
else if (input_buttons & INPUT_BUTTON4)
|
||||
else if (input_buttons & INPUT_RELOAD)
|
||||
Weapons_Reload((player)this);
|
||||
else
|
||||
Weapons_Release((player)this);
|
||||
|
@ -251,8 +268,8 @@ NSClientPlayer::predraw(void)
|
|||
input_movevalues[0] = dotproduct(velocity, v_forward);
|
||||
input_movevalues[1] = dotproduct(velocity, v_right);
|
||||
input_movevalues[2] = dotproduct(velocity, v_up);
|
||||
input_buttons = (flags & FL_JUMPRELEASED) ? 0 : INPUT_BUTTON2; /* this may not help that much... */
|
||||
input_buttons |= (flags & FL_CROUCHING) ? INPUT_BUTTON8 : 0;
|
||||
input_buttons = (flags & FL_JUMPRELEASED) ? 0 : INPUT_JUMP; /* this may not help that much... */
|
||||
input_buttons |= IsCrouching() ? INPUT_CROUCH : 0;
|
||||
input_angles = v_angle;
|
||||
input_impulse = 0;
|
||||
input_timelength = clframetime;
|
||||
|
@ -273,7 +290,7 @@ NSClientPlayer::predraw(void)
|
|||
RenderFire();
|
||||
|
||||
/* if we're inside of a vehicle, it may want to hide or show us regardless */
|
||||
if (localplayer && HasFlags(FL_INVEHICLE)) {
|
||||
if (localplayer && HasVFlags(VFL_INVEHICLE)) {
|
||||
NSVehicle veh = (NSVehicle)vehicle;
|
||||
|
||||
if (veh)
|
||||
|
@ -386,6 +403,10 @@ NSClientPlayer::UpdateAliveCam(void)
|
|||
g_view.AddPunchAngle(punchangle);
|
||||
}
|
||||
|
||||
var float autocvar_cl_forwardspeed = 190;
|
||||
var float autocvar_cl_sidespeed = 152;
|
||||
var float autocvar_cl_backspeed = 133;
|
||||
|
||||
/*
|
||||
=================
|
||||
NSClientPlayer::ClientInputFrame
|
||||
|
@ -416,35 +437,40 @@ NSClientPlayer::ClientInputFrame(void)
|
|||
if (serverkeyfloat("background") == 1)
|
||||
return;
|
||||
|
||||
if (pSeat->m_iInputAttack2 == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON3;
|
||||
if (pSeat->m_iInputAttack2 == true) {
|
||||
input_buttons |= INPUT_SECONDARY;
|
||||
}
|
||||
if (pSeat->m_iInputReload == true) {
|
||||
input_buttons |= INPUT_RELOAD;
|
||||
}
|
||||
if (pSeat->m_iInputUse == true) {
|
||||
input_buttons |= INPUT_USE;
|
||||
}
|
||||
if (pSeat->m_iInputDuck == true) {
|
||||
input_buttons |= INPUT_CROUCH;
|
||||
}
|
||||
if (pSeat->m_iInputProne == true) {
|
||||
input_buttons |= INPUT_PRONE;
|
||||
}
|
||||
if (pSeat->m_iInputSprint == true) {
|
||||
input_buttons |= INPUT_SPRINT;
|
||||
}
|
||||
if (pSeat->m_iInputJump == true) {
|
||||
input_buttons |= INPUT_JUMP;
|
||||
}
|
||||
|
||||
if (pSeat->m_iInputReload == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON4;
|
||||
}
|
||||
|
||||
if (pSeat->m_iInputUse == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON5;
|
||||
}
|
||||
|
||||
if (pSeat->m_iInputDuck == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON8;
|
||||
}
|
||||
|
||||
if (pSeat->m_iInputExtra1 == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON6;
|
||||
}
|
||||
|
||||
if (pSeat->m_iInputExtra2 == TRUE) {
|
||||
input_buttons |= INPUT_BUTTON7;
|
||||
/* IW style stance override */
|
||||
if (pSeat->m_dForceStance == STANCE_CROUCH) {
|
||||
input_buttons |= INPUT_CROUCH;
|
||||
} else if (pSeat->m_dForceStance == STANCE_PRONE) {
|
||||
input_buttons |= INPUT_PRONE;
|
||||
}
|
||||
|
||||
/* The HUD needs more time */
|
||||
if (pSeat->m_iHUDWeaponSelected) {
|
||||
if ((input_buttons & INPUT_BUTTON0))
|
||||
if ((input_buttons & INPUT_PRIMARY))
|
||||
HUD_DrawWeaponSelect_Trigger();
|
||||
else if ((input_buttons & INPUT_BUTTON3))
|
||||
else if ((input_buttons & INPUT_SECONDARY))
|
||||
pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0;
|
||||
|
||||
pSeat->m_flInputBlockTime = time + 0.2;
|
||||
|
@ -452,9 +478,9 @@ NSClientPlayer::ClientInputFrame(void)
|
|||
|
||||
/* prevent accidental input packets */
|
||||
if (pSeat->m_flInputBlockTime > time) {
|
||||
input_buttons &= ~INPUT_BUTTON0;
|
||||
input_buttons &= ~INPUT_BUTTON3;
|
||||
pSeat->m_iInputAttack2 = FALSE;
|
||||
input_buttons &= ~INPUT_PRIMARY;
|
||||
input_buttons &= ~INPUT_SECONDARY;
|
||||
pSeat->m_iInputAttack2 = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -465,7 +491,7 @@ NSClientPlayer::ClientInputFrame(void)
|
|||
}
|
||||
|
||||
if (pSeat->m_iInputAttack) {
|
||||
input_buttons |= INPUT_BUTTON0;
|
||||
input_buttons |= INPUT_PRIMARY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,6 +503,28 @@ NSClientPlayer::ClientInputFrame(void)
|
|||
if (pSeat->m_flCameraTime > time) {
|
||||
/* TODO: Supress the changing of view_angles/input_angles. */
|
||||
}
|
||||
|
||||
vector movementDir = vectorNormalize(input_movevalues);
|
||||
|
||||
/* normalize movement values */
|
||||
input_movevalues[0] = movementDir[0] * fabs(input_movevalues[0]);
|
||||
input_movevalues[1] = movementDir[1] * fabs(input_movevalues[1]);
|
||||
|
||||
//if (mode_tempstate == 0)
|
||||
if (input_movevalues[0] > 0)
|
||||
if (pSeat->m_iSprinting == true) {
|
||||
input_buttons |= INPUT_SPRINT;
|
||||
input_movevalues[0] *= 1.5f;
|
||||
input_movevalues[1] *= 1.5f;
|
||||
input_movevalues[2] *= 1.5f;
|
||||
|
||||
/* prevent firing of weapons */
|
||||
input_buttons &= ~INPUT_PRIMARY;
|
||||
input_buttons &= ~INPUT_SECONDARY;
|
||||
input_buttons &= ~INPUT_RELOAD;
|
||||
} else {
|
||||
input_buttons &= ~INPUT_SPRINT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -532,6 +580,7 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged)
|
|||
READENTITY_COORD(grapvelocity[1], PLAYER_VELOCITY)
|
||||
READENTITY_COORD(grapvelocity[2], PLAYER_VELOCITY)
|
||||
READENTITY_INT(flags, PLAYER_FLAGS)
|
||||
READENTITY_INT(vv_flags, PLAYER_FLAGS)
|
||||
READENTITY_INT(gflags, PLAYER_FLAGS)
|
||||
READENTITY_INT(pmove_flags, PLAYER_FLAGS)
|
||||
READENTITY_BYTE(activeweapon, PLAYER_WEAPON)
|
||||
|
@ -553,6 +602,7 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged)
|
|||
READENTITY_FLOAT(punchangle[2], PLAYER_PUNCHANGLE)
|
||||
READENTITY_FLOAT(viewzoom, PLAYER_VIEWZOOM)
|
||||
READENTITY_FLOAT(teleport_time, PLAYER_TIMINGS)
|
||||
READENTITY_FLOAT(m_flStamina, PLAYER_TIMINGS)
|
||||
READENTITY_FLOAT(weapontime, PLAYER_TIMINGS)
|
||||
READENTITY_FLOAT(w_attack_next, PLAYER_TIMINGS)
|
||||
READENTITY_FLOAT(w_idle_next, PLAYER_TIMINGS)
|
||||
|
@ -595,6 +645,7 @@ NSClientPlayer::PredictPreFrame(void)
|
|||
SAVE_STATE(basevelocity)
|
||||
SAVE_STATE(grapvelocity)
|
||||
SAVE_STATE(flags)
|
||||
SAVE_STATE(vv_flags)
|
||||
SAVE_STATE(gflags)
|
||||
SAVE_STATE(pmove_flags)
|
||||
SAVE_STATE(activeweapon)
|
||||
|
@ -610,6 +661,7 @@ NSClientPlayer::PredictPreFrame(void)
|
|||
SAVE_STATE(punchangle)
|
||||
SAVE_STATE(viewzoom)
|
||||
SAVE_STATE(teleport_time)
|
||||
SAVE_STATE(m_flStamina)
|
||||
SAVE_STATE(weapontime)
|
||||
SAVE_STATE(w_attack_next)
|
||||
SAVE_STATE(w_idle_next)
|
||||
|
@ -641,6 +693,7 @@ NSClientPlayer::PredictPostFrame(void)
|
|||
ROLL_BACK(basevelocity)
|
||||
ROLL_BACK(grapvelocity)
|
||||
ROLL_BACK(flags)
|
||||
ROLL_BACK(vv_flags)
|
||||
ROLL_BACK(gflags)
|
||||
ROLL_BACK(pmove_flags)
|
||||
ROLL_BACK(activeweapon)
|
||||
|
@ -656,6 +709,7 @@ NSClientPlayer::PredictPostFrame(void)
|
|||
ROLL_BACK(punchangle)
|
||||
ROLL_BACK(viewzoom)
|
||||
ROLL_BACK(teleport_time)
|
||||
ROLL_BACK(m_flStamina)
|
||||
ROLL_BACK(weapontime)
|
||||
ROLL_BACK(w_attack_next)
|
||||
ROLL_BACK(w_idle_next)
|
||||
|
@ -691,6 +745,7 @@ NSClientPlayer::Save(float handle)
|
|||
SaveVector(handle, "angles", angles);
|
||||
SaveFloat(handle, "colormap", colormap);
|
||||
SaveFloat(handle, "flags", flags);
|
||||
SaveFloat(handle, "vv_flags", vv_flags);
|
||||
SaveFloat(handle, "gflags", gflags);
|
||||
SaveFloat(handle, "viewzoom", viewzoom);
|
||||
SaveVector(handle, "view_ofs", view_ofs);
|
||||
|
@ -702,6 +757,7 @@ NSClientPlayer::Save(float handle)
|
|||
SaveFloat(handle, "w_attack_next", w_attack_next);
|
||||
SaveFloat(handle, "w_idle_next", w_idle_next);
|
||||
SaveFloat(handle, "teleport_time", teleport_time);
|
||||
SaveFloat(handle, "m_flStamina", m_flStamina);
|
||||
SaveInt(handle, "weaponframe", weaponframe);
|
||||
SaveFloat(handle, "weapontime", weapontime);
|
||||
SaveInt(handle, "g_items", g_items);
|
||||
|
@ -740,6 +796,9 @@ NSClientPlayer::Restore(string strKey, string strValue)
|
|||
case "flags":
|
||||
flags = ReadFloat(strValue);
|
||||
break;
|
||||
case "vv_flags":
|
||||
vv_flags = ReadFloat(strValue);
|
||||
break;
|
||||
case "gflags":
|
||||
gflags = ReadFloat(strValue);
|
||||
break;
|
||||
|
@ -770,6 +829,9 @@ NSClientPlayer::Restore(string strKey, string strValue)
|
|||
case "teleport_time":
|
||||
teleport_time = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flStamina":
|
||||
m_flStamina = ReadFloat(strValue);
|
||||
break;
|
||||
case "weaponframe":
|
||||
weaponframe = ReadInt(strValue);
|
||||
break;
|
||||
|
@ -821,7 +883,7 @@ NSClientPlayer::MakeTempSpectator(void)
|
|||
SetMovetype(MOVETYPE_NOCLIP);
|
||||
SetTakedamage(DAMAGE_NO);
|
||||
maxspeed = 250;
|
||||
flags |= FL_FAKESPEC;
|
||||
AddVFlags(VFL_FAKESPEC);
|
||||
max_health = health = 0;
|
||||
armor = 0;
|
||||
g_items = 0;
|
||||
|
@ -860,7 +922,7 @@ NSClientPlayer::Death(void)
|
|||
SetVelocity([0,0,0]);
|
||||
SetGravity(1.0f);
|
||||
customphysics = Empty;
|
||||
SetCanBleed(false);
|
||||
DisableBleeding();
|
||||
setsize(this, [0,0,0], [0,0,0]);
|
||||
forceinfokey(this, "*deaths", ftos(deaths));
|
||||
forceinfokey(this, "*dead", "1");
|
||||
|
@ -879,10 +941,14 @@ void
|
|||
NSClientPlayer::MakePlayer(void)
|
||||
{
|
||||
classname = "player";
|
||||
flags = FL_CLIENT;
|
||||
health = max_health = 100;
|
||||
armor = 0;
|
||||
g_items = 0;
|
||||
AddFlags(FL_CLIENT);
|
||||
RemoveVFlags(VFL_FAKESPEC);
|
||||
|
||||
if (health <= 0) {
|
||||
health = max_health = 100;
|
||||
armor = 0;
|
||||
}
|
||||
|
||||
activeweapon = 0;
|
||||
effects = 0;
|
||||
alpha = 1.0f;
|
||||
|
@ -895,12 +961,13 @@ NSClientPlayer::MakePlayer(void)
|
|||
SetGravity(1.0f);
|
||||
SendFlags = UPDATE_ALL;
|
||||
customphysics = Empty;
|
||||
SetCanBleed(true);
|
||||
EnableBleeding();
|
||||
scale = 1.0f;
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
forceinfokey(this, "*spectator", "0");
|
||||
forceinfokey(this, "*deaths", ftos(deaths));
|
||||
forceinfokey(this, "*dead", "0");
|
||||
forceinfokey(this, "*spec", "0");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -924,7 +991,7 @@ at the top of player::EvaluateEntity
|
|||
void
|
||||
NSClientPlayer::EvaluateEntity(void)
|
||||
{
|
||||
pvsflags = (flags & FL_FAKESPEC) ? 0 : PVSF_IGNOREPVS;
|
||||
pvsflags = !HasVFlags(VFL_FAKESPEC) ? 0 : PVSF_IGNOREPVS;
|
||||
|
||||
EVALUATE_FIELD(modelindex, PLAYER_MODELINDEX)
|
||||
EVALUATE_FIELD(colormap, PLAYER_MODELINDEX)
|
||||
|
@ -956,6 +1023,7 @@ NSClientPlayer::EvaluateEntity(void)
|
|||
EVALUATE_VECTOR(grapvelocity, 1, PLAYER_VELOCITY)
|
||||
EVALUATE_VECTOR(grapvelocity, 2, PLAYER_VELOCITY)
|
||||
EVALUATE_FIELD(flags, PLAYER_FLAGS)
|
||||
EVALUATE_FIELD(vv_flags, PLAYER_FLAGS)
|
||||
EVALUATE_FIELD(gflags, PLAYER_FLAGS)
|
||||
EVALUATE_FIELD(pmove_flags, PLAYER_FLAGS)
|
||||
EVALUATE_FIELD(activeweapon, PLAYER_WEAPON)
|
||||
|
@ -977,6 +1045,7 @@ NSClientPlayer::EvaluateEntity(void)
|
|||
EVALUATE_VECTOR(punchangle, 2, PLAYER_PUNCHANGLE)
|
||||
EVALUATE_FIELD(viewzoom, PLAYER_VIEWZOOM)
|
||||
EVALUATE_FIELD(teleport_time, PLAYER_TIMINGS)
|
||||
EVALUATE_FIELD(m_flStamina, PLAYER_TIMINGS)
|
||||
EVALUATE_FIELD(weapontime, PLAYER_TIMINGS)
|
||||
EVALUATE_FIELD(w_attack_next, PLAYER_TIMINGS)
|
||||
EVALUATE_FIELD(w_idle_next, PLAYER_TIMINGS)
|
||||
|
@ -1028,6 +1097,7 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged)
|
|||
SENDENTITY_COORD(grapvelocity[1], PLAYER_VELOCITY)
|
||||
SENDENTITY_COORD(grapvelocity[2], PLAYER_VELOCITY)
|
||||
SENDENTITY_INT(flags, PLAYER_FLAGS)
|
||||
SENDENTITY_INT(vv_flags, PLAYER_FLAGS)
|
||||
SENDENTITY_INT(gflags, PLAYER_FLAGS)
|
||||
SENDENTITY_INT(pmove_flags, PLAYER_FLAGS)
|
||||
SENDENTITY_BYTE(activeweapon, PLAYER_WEAPON)
|
||||
|
@ -1049,6 +1119,7 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged)
|
|||
SENDENTITY_FLOAT(punchangle[2], PLAYER_PUNCHANGLE)
|
||||
SENDENTITY_FLOAT(viewzoom, PLAYER_VIEWZOOM)
|
||||
SENDENTITY_FLOAT(teleport_time, PLAYER_TIMINGS)
|
||||
SENDENTITY_FLOAT(m_flStamina, PLAYER_TIMINGS)
|
||||
SENDENTITY_FLOAT(weapontime, PLAYER_TIMINGS)
|
||||
SENDENTITY_FLOAT(w_attack_next, PLAYER_TIMINGS)
|
||||
SENDENTITY_FLOAT(w_idle_next, PLAYER_TIMINGS)
|
||||
|
@ -1104,7 +1175,7 @@ A wrapper to cleanly reset 'self' as to not mess up the QC VM
|
|||
void
|
||||
_NSClientPlayer_useworkaround(entity eTarget)
|
||||
{
|
||||
eActivator = self;
|
||||
eActivator = (NSEntity)self;
|
||||
entity eOldSelf = self;
|
||||
self = eTarget;
|
||||
self.PlayerUse();
|
||||
|
@ -1121,7 +1192,7 @@ A wrapper to cleanly reset 'self' as to not mess up the QC VM
|
|||
void
|
||||
_NSClientPlayer_unuseworkaround(entity eTarget)
|
||||
{
|
||||
eActivator = self;
|
||||
eActivator = (NSEntity)self;
|
||||
entity eOldSelf = self;
|
||||
self = eTarget;
|
||||
if (self.PlayerUseUnpressed)
|
||||
|
@ -1140,9 +1211,9 @@ looks for an entity that has the .PlayerUse field set to a function and calls it
|
|||
void
|
||||
NSClientPlayer::InputUse_Down(void)
|
||||
{
|
||||
if (health <= 0) {
|
||||
if (IsDead()) {
|
||||
return;
|
||||
} else if (!(flags & FL_USE_RELEASED)) {
|
||||
} else if (!(vv_flags & VFL_USE_RELEASED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1175,17 +1246,17 @@ NSClientPlayer::InputUse_Down(void)
|
|||
|
||||
/* TODO: maybe eRad will return something in the future that'll suppress a successfull use? */
|
||||
if (eRad && found_use == true) {
|
||||
flags &= ~FL_USE_RELEASED;
|
||||
RemoveVFlags(VFL_USE_RELEASED);
|
||||
_NSClientPlayer_useworkaround(eRad);
|
||||
last_used = eRad;
|
||||
|
||||
/* Some entities want to support Use spamming */
|
||||
if (HasFlags(FL_USE_RELEASED) == false) {
|
||||
if (HasVFlags(VFL_USE_RELEASED) == false) {
|
||||
StartSoundDef("Player.WeaponSelected", CHAN_ITEM, false);
|
||||
}
|
||||
} else {
|
||||
StartSoundDef("Player.DenyWeaponSelection", CHAN_ITEM, false);
|
||||
flags &= ~FL_USE_RELEASED;
|
||||
RemoveVFlags(VFL_USE_RELEASED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1199,10 +1270,10 @@ Called when we let go of the +use button
|
|||
void
|
||||
NSClientPlayer::InputUse_Up(void)
|
||||
{
|
||||
if (HasFlags(FL_USE_RELEASED) == false) {
|
||||
if (HasVFlags(VFL_USE_RELEASED) == false) {
|
||||
_NSClientPlayer_unuseworkaround(last_used);
|
||||
last_used = world;
|
||||
flags |= FL_USE_RELEASED;
|
||||
AddVFlags(VFL_USE_RELEASED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1240,7 +1311,7 @@ NSClientPlayer::Footsteps_Update(void)
|
|||
return;
|
||||
} else {
|
||||
/* make it so we step once we land */
|
||||
if (HasFlags(FL_ONGROUND | FL_ONLADDER) == false) {
|
||||
if (HasFlags(FL_ONGROUND) == false && HasVFlags(VFL_ONLADDER) == false) {
|
||||
step_time = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
@ -1254,9 +1325,9 @@ NSClientPlayer::Footsteps_Update(void)
|
|||
tex_name = getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos));
|
||||
|
||||
/* don't step in air */
|
||||
if (HasFlags(FL_ONGROUND | FL_ONLADDER) == false) {
|
||||
if (HasFlags(FL_ONGROUND) == false && HasVFlags(VFL_ONLADDER) == false) {
|
||||
return;
|
||||
} else if (HasFlags(FL_ONLADDER) && HasFlags(FL_ONGROUND) == false) { /* play ladder sounds */
|
||||
} else if (HasVFlags(VFL_ONLADDER) && HasFlags(FL_ONGROUND) == false) { /* play ladder sounds */
|
||||
if (step)
|
||||
StartSoundDef("step_ladder.left", CHAN_BODY, true);
|
||||
else
|
||||
|
@ -1265,7 +1336,7 @@ NSClientPlayer::Footsteps_Update(void)
|
|||
/* switch between feet */
|
||||
step = 1 - step;
|
||||
return;
|
||||
} else if (HasFlags(FL_ONLADDER) && HasFlags(FL_ONGROUND)) { /* at a ladder, but not moving */
|
||||
} else if (HasVFlags(VFL_ONLADDER) && HasFlags(FL_ONGROUND)) { /* at a ladder, but not moving */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,11 +66,11 @@ void
|
|||
NSClientSpectator::ProcessInput(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
if (input_buttons & INPUT_BUTTON0) {
|
||||
if (input_buttons & INPUT_PRIMARY) {
|
||||
InputNext();
|
||||
} else if (input_buttons & INPUT_BUTTON3) {
|
||||
} else if (input_buttons & INPUT_SECONDARY) {
|
||||
InputPrevious();
|
||||
} else if (input_buttons & INPUT_BUTTON2) {
|
||||
} else if (input_buttons & INPUT_JUMP) {
|
||||
InputMode();
|
||||
} else {
|
||||
spec_flags &= ~SPECFLAG_BUTTON_RELEASED;
|
||||
|
@ -163,8 +163,22 @@ NSClientSpectator::ClientInputFrame(void)
|
|||
}
|
||||
|
||||
/* background maps have no input */
|
||||
if (serverkeyfloat("background") == 1)
|
||||
if (serverkeyfloat("background") == 1) {
|
||||
input_impulse = 0;
|
||||
input_buttons = 0;
|
||||
input_movevalues = g_vec_null;
|
||||
return;
|
||||
}
|
||||
|
||||
vector movementDir = vectorNormalize(input_movevalues);
|
||||
|
||||
/* normalize movement values */
|
||||
if (movementDir[0] > 0)
|
||||
input_movevalues[0] = movementDir[0] * GetForwardSpeed();
|
||||
else
|
||||
input_movevalues[0] = movementDir[0] * GetBackSpeed();
|
||||
|
||||
input_movevalues[1] = movementDir[1] * GetSideSpeed();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -61,6 +61,7 @@ private:
|
|||
string m_oldModel; /**< contains the model that the entity spawned with */
|
||||
float m_oldSolid; /**< contains the collision type the entity spawned with */
|
||||
bool m_bIsBrush;
|
||||
vector m_vecEditorColor;
|
||||
|
||||
PREDICTED_VECTOR_N(origin)
|
||||
PREDICTED_VECTOR_N(angles)
|
||||
|
@ -72,11 +73,13 @@ private:
|
|||
PREDICTED_FLOAT_N(movetype)
|
||||
PREDICTED_FLOAT_N(scale)
|
||||
PREDICTED_FLOAT_N(flags)
|
||||
PREDICTED_FLOAT_N(vv_flags)
|
||||
PREDICTED_VECTOR_N(velocity)
|
||||
PREDICTED_VECTOR_N(avelocity)
|
||||
|
||||
#ifdef SERVER
|
||||
string m_parent;
|
||||
string m_parent_old;
|
||||
string m_parent_attachment;
|
||||
PREDICTED_FLOAT_N(frame)
|
||||
PREDICTED_FLOAT_N(skin)
|
||||
|
@ -149,6 +152,9 @@ public:
|
|||
/** Unsets any any angle related values within the entity. */
|
||||
nonvirtual void ClearAngles(void);
|
||||
|
||||
/** Simulates the press of the use/activate key, with the passed entity being the activator. */
|
||||
nonvirtual void UseBy(entity);
|
||||
|
||||
/** Forces the entity to re-network updates to all clients. */
|
||||
nonvirtual void ForceNetworkUpdate(void);
|
||||
#endif
|
||||
|
@ -157,9 +163,9 @@ public:
|
|||
/** Sets the whole effects field. Check the effects_t enum for available effects.*/
|
||||
nonvirtual void SetEffects(float);
|
||||
/** Appends one or more effects to the entity. Check the effects_t enum for available effects.*/
|
||||
nonvirtual void AddEffects(float);
|
||||
nonvirtual void AddEffects(effects_t);
|
||||
/** Removes one or more effects from the entity. Check the effects_t enum for available effects.*/
|
||||
nonvirtual void RemoveEffects(float);
|
||||
nonvirtual void RemoveEffects(effects_t);
|
||||
/** Sets the framegroup sequence of the entity. Must be positive.*/
|
||||
nonvirtual void SetFrame(float);
|
||||
/** Sets the skingroup of the entity. Must be positive. */
|
||||
|
@ -171,7 +177,6 @@ public:
|
|||
/** Sets the movement velocity of the given entity. */
|
||||
nonvirtual void SetVelocity(vector);
|
||||
|
||||
|
||||
/** Adds onto the existing angular velocity. */
|
||||
nonvirtual void AddAngularVelocity(vector);
|
||||
/** Adds onto the existing velocity. */
|
||||
|
@ -201,10 +206,14 @@ public:
|
|||
/** Sets the bounding box size of the entity.
|
||||
This affects both collision and rendering bounds checking. */
|
||||
nonvirtual void SetSize(vector,vector);
|
||||
/** Adds one or more special flags to the entity. */
|
||||
/** Adds one or more engine specific flags to the entity. */
|
||||
nonvirtual void AddFlags(float);
|
||||
/** Remove one or more special flags from the entity. */
|
||||
/** Remove one or more engine specific flags from the entity. */
|
||||
nonvirtual void RemoveFlags(float);
|
||||
/** Adds one or more nuclide specific flags to the entity. */
|
||||
nonvirtual void AddVFlags(float);
|
||||
/** Remove one or more nuclide specific flags from the entity. */
|
||||
nonvirtual void RemoveVFlags(float);
|
||||
|
||||
/** Turns to the specified angle. */
|
||||
nonvirtual void TurnTo(float);
|
||||
|
@ -275,10 +284,14 @@ public:
|
|||
/** Returns the absolute bounding box maxs of the entity,
|
||||
instead of being relative to the world position. */
|
||||
nonvirtual vector GetAbsoluteMaxs(void);
|
||||
/** Returns a flag bitfield that the entity associates with. */
|
||||
/** Returns an engine flags bitfield that the entity associates with. */
|
||||
nonvirtual float GetFlags(void);
|
||||
/** Returns true if the entity has the specified flags. */
|
||||
/** Returns true if the entity has the specified engine flags. */
|
||||
nonvirtual float HasFlags(float);
|
||||
/** Returns a nuclide flags bitfield that the entity associates with. */
|
||||
nonvirtual float GetVFlags(void);
|
||||
/** Returns true if the entity has the specified, nuclide specific, flags. */
|
||||
nonvirtual float HasVFlags(float);
|
||||
/** Returns an absolute value of when the entity will be think again.
|
||||
Any result should be tested against `::GetTime()`. */
|
||||
nonvirtual float GetNextThinkTime(void);
|
||||
|
@ -286,6 +299,8 @@ public:
|
|||
nonvirtual bool IsThinking(void);
|
||||
/** When called, will unset anything related to ongoing think operations. */
|
||||
nonvirtual void ReleaseThink(void);
|
||||
/** When called, will make the entity think busy for the specified amount of time. In that time, IsThinking() will return true. */
|
||||
nonvirtual void ThinkBusy(float);
|
||||
/** When called, will clear anything related to physical movement on the entity. */
|
||||
nonvirtual void ClearVelocity(void);
|
||||
|
||||
|
@ -296,7 +311,6 @@ public:
|
|||
nonvirtual void Hide(void);
|
||||
/** Returns if the entity is currently being hidden explicitly. */
|
||||
nonvirtual bool IsHidden(void);
|
||||
|
||||
/** Returns if the entity is solid or non-solid */
|
||||
nonvirtual bool IsSolid(void);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,14 +14,50 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
/* PICKUP ITEMS */
|
||||
/** id Tech 4 keys to support:
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*! \brief This entity class represents non-player characters. */
|
||||
/*!QUAKED NSMonster (0 0.8 0.8) (-16 -16 0) (16 16 72) WAITTILLSEEN GAG MONSTERCLIP x PRISONER x IGNOREPLAYER WAITFORSCRIPT PREDISASTER FADECORPSE MULTIPLAYER FALLING HORDE
|
||||
# OVERVIEW
|
||||
Represents any item within the players' inventory.
|
||||
These can be used, or be dormant.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "model" : world model.
|
||||
- "model_view" : view model.
|
||||
- "model_world - same as model.
|
||||
- "inv_name" : Fancy title. Can be a localized string.
|
||||
- "inv_weapon" : name of the weapon to give on pickup. can be the same as this entitydef.
|
||||
- "inv_item" : item number. must be unique.
|
||||
- "weapon_scriptobject" : mapC progs with the weapon code within.
|
||||
- "ammoType" : name of the ammo type def entry which the gun uses
|
||||
- "ammoRequired" : set to 1 if we require ammo.
|
||||
- "clipSize" : maximum clip size
|
||||
- "mtr_flashShader" : muzzleflash material to Use.
|
||||
- "model_flash" : muzzleflash model/sprite to use.
|
||||
- "flashColor" : muzzleflash dlight color
|
||||
- "flashRadius" : muzzleflash dlight radius
|
||||
- "def_dropItem" : when this item is dropped from someones inventory, will spawn this entityDef item instead.
|
||||
- "snd_acquire" : pickup noise
|
||||
- "snd_respawn" : respawn noise
|
||||
- "snd_hum" : idle shader
|
||||
- "smoke_muzzle" : smoke particle effect name
|
||||
- "continuousSmoke" : whether the particle effect is continous
|
||||
- "clipSizeDefault" : CUSTOM: Default clip size on pickup.
|
||||
*/
|
||||
class NSItem:NSRenderableEntity
|
||||
{
|
||||
public:
|
||||
void NSItem(void);
|
||||
|
||||
/* overrides */
|
||||
#ifdef SERVER
|
||||
virtual void Spawned(void);
|
||||
virtual void Touch(entity);
|
||||
virtual void Respawn(void);
|
||||
|
@ -35,8 +71,9 @@ public:
|
|||
nonvirtual bool GetFloating(void);
|
||||
nonvirtual void SetSpinning(bool);
|
||||
nonvirtual bool GetSpinning(void);
|
||||
|
||||
nonvirtual void PickupRespawn(void);
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
int m_iClip;
|
||||
|
@ -48,5 +85,5 @@ private:
|
|||
string m_sndRespawn;
|
||||
int m_bFloating;
|
||||
bool m_bSpins;
|
||||
};
|
||||
#endif
|
||||
string m_strInvWeapon;
|
||||
};
|
|
@ -14,10 +14,10 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
NSItem::NSItem(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
m_iClip = -1;
|
||||
m_iWasDropped = 0i;
|
||||
m_iInvItem = 0i;
|
||||
|
@ -25,8 +25,10 @@ NSItem::NSItem(void)
|
|||
m_sndRespawn = __NULL__;
|
||||
m_bFloating = false;
|
||||
m_bSpins = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
NSItem::Spawned(void)
|
||||
{
|
||||
|
@ -74,6 +76,9 @@ void
|
|||
NSItem::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "inv_weapon":
|
||||
m_strInvWeapon = ReadString(strValue);
|
||||
break;
|
||||
case "inv_item":
|
||||
m_iInvItem = ReadInt(strValue);
|
||||
break;
|
||||
|
@ -112,6 +117,7 @@ NSItem::Save(float handle)
|
|||
SaveString(handle, "m_sndRespawn", m_sndRespawn);
|
||||
SaveBool(handle, "m_bFloating", m_bFloating);
|
||||
SaveBool(handle, "m_bSpins", m_bSpins);
|
||||
SaveString(handle, "m_strInvWeapon", m_strInvWeapon);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -139,6 +145,9 @@ NSItem::Restore(string strKey, string strValue)
|
|||
case "m_bSpins":
|
||||
m_bSpins = ReadBool(strValue);
|
||||
break;
|
||||
case "m_strInvWeapon":
|
||||
m_strInvWeapon = ReadString(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
break;
|
||||
|
@ -148,14 +157,18 @@ NSItem::Restore(string strKey, string strValue)
|
|||
void
|
||||
NSItem::Touch(entity eToucher)
|
||||
{
|
||||
NSClientPlayer pl = (NSClientPlayer)eToucher;
|
||||
|
||||
if (eToucher.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* don't remove if AddItem fails */
|
||||
if (Weapons_AddItem((player)eToucher, m_iInvItem, m_iClip) == FALSE) {
|
||||
if (pl.GiveWeapon(m_strInvWeapon) == false) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Logging_Pickup(eToucher, this, __NULL__);
|
||||
StartSoundDef(m_sndAcquire, CHAN_ITEM, true);
|
||||
|
@ -215,4 +228,45 @@ NSItem::PickupRespawn(void)
|
|||
Respawn();
|
||||
StartSoundDef(m_sndRespawn, CHAN_ITEM, true);
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::Draw(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::Holster(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::PrimaryAttack(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::SecondaryAttack(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::Reload(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::Release(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::OnPickup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NSItem::OnInventoryUse(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -334,6 +334,7 @@ public:
|
|||
//virtual void Hide(void);
|
||||
virtual void Spawned(void);
|
||||
virtual void Respawn(void);
|
||||
virtual void Input(entity,string,string);
|
||||
virtual void Pain(void);
|
||||
virtual void Death(void);
|
||||
virtual void Physics(void);
|
||||
|
@ -597,6 +598,8 @@ private:
|
|||
float m_flLeapDamage;
|
||||
bool m_bLeapAttacked;
|
||||
float m_flForceSequence;
|
||||
float m_flSkin;
|
||||
bool m_bGagged;
|
||||
|
||||
nonvirtual void _LerpTurnToEnemy(void);
|
||||
nonvirtual void _LerpTurnToPos(vector);
|
||||
|
|
|
@ -92,6 +92,8 @@ NSMonster::NSMonster(void)
|
|||
m_flLeapDamage = 0;
|
||||
m_bLeapAttacked = false;
|
||||
maxspeed = 1024;
|
||||
m_bGagged = false;
|
||||
m_flSkin = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -519,7 +521,7 @@ NSMonster::Sound(string msg)
|
|||
void
|
||||
NSMonster::Gib(void)
|
||||
{
|
||||
vector vecDir = vectoangles(GetOrigin() - g_dmg_vecLocation);
|
||||
vector vecDir = vectorToAngles(GetOrigin() - g_dmg_vecLocation);
|
||||
SetState(MONSTER_DEAD);
|
||||
SetTakedamage(DAMAGE_NO);
|
||||
|
||||
|
@ -536,8 +538,12 @@ NSMonster::FallNoise(void)
|
|||
void
|
||||
NSMonster::IdleNoise(void)
|
||||
{
|
||||
if (m_flIdleNext > time)
|
||||
if (m_bGagged == true) {
|
||||
return;
|
||||
}
|
||||
if (m_flIdleNext > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
StartSoundDef(m_sndIdle, CHAN_VOICE, true);
|
||||
m_flIdleNext = time + random(m_flIdleMin, m_flIdleMax);
|
||||
|
@ -546,6 +552,10 @@ NSMonster::IdleNoise(void)
|
|||
void
|
||||
NSMonster::AlertNoise(void)
|
||||
{
|
||||
if (m_bGagged == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
StartSoundDef(m_sndSight, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
|
@ -669,17 +679,15 @@ NSMonster::SeeThink(void)
|
|||
|
||||
if (m_eLookAt) {
|
||||
vector vecDelta;
|
||||
makevectors( angles );
|
||||
vecDelta = normalize( (m_eLookAt.origin + m_eLookAt.view_ofs) - GetEyePos() );
|
||||
m_flHeadYaw = (vecDelta * v_right) * -60;
|
||||
m_flHeadYaw = (vecDelta * anglesToRight(angles)) * -60;
|
||||
//print(sprintf("head yaw: %f %v\n", m_flHeadYaw, vecDelta));
|
||||
|
||||
/* this will make the actor 'aim" at the target */
|
||||
{
|
||||
makevectors(v_angle);
|
||||
vector tmp = vectoangles(v_forward);
|
||||
vector tmp = vectorToAngles(anglesToForward(v_angle));
|
||||
subblendfrac = tmp[0] / 90;
|
||||
bonecontrol1 = Math_Lerp(bonecontrol1, m_flHeadYaw, frametime * 15.0f); /* head turning */
|
||||
bonecontrol1 = lerp(bonecontrol1, m_flHeadYaw, frametime * 15.0f); /* head turning */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,8 +715,7 @@ NSMonster::SeeThink(void)
|
|||
/* enemy is not valid anymore, reset it, clear route and search for new enemy */
|
||||
RouteClear();
|
||||
|
||||
makevectors(angles);
|
||||
RouteToPosition(m_eEnemy.origin + (v_forward * -64));
|
||||
RouteToPosition(m_eEnemy.origin + (anglesToForward(angles) * -64));
|
||||
m_flSequenceSpeed = GetWalkSpeed();
|
||||
|
||||
SetState(MONSTER_ALERT);
|
||||
|
@ -743,9 +750,8 @@ NSMonster::SeeThink(void)
|
|||
continue;
|
||||
|
||||
/* first, is the potential enemy in our field of view? */
|
||||
makevectors(angles);
|
||||
vector v = normalize(w.origin - GetEyePos());
|
||||
float flDot = v * v_forward;
|
||||
float flDot = v * anglesToForward(angles);
|
||||
|
||||
if (flDot < SeeFOV()/180)
|
||||
continue;
|
||||
|
@ -793,58 +799,38 @@ NSMonster::GetYawSpeed(void)
|
|||
void
|
||||
NSMonster::_LerpTurnToYaw(vector turnYaw)
|
||||
{
|
||||
#if 0
|
||||
angles[1] = input_angles[1] = v_angle[1] = turnYaw[1];
|
||||
#else
|
||||
float turnSpeed = GetYawSpeed();
|
||||
vector vecWishAngle = turnYaw;
|
||||
float yawDiff = anglesub(turnYaw[1], v_angle[1]);
|
||||
vector oldAngle = angles;
|
||||
vector angleDelta;
|
||||
float oldYaw = angles[1];
|
||||
float yawDiff = 0.0f;
|
||||
yaw_speed = GetYawSpeed() * (frametime * 5);
|
||||
ideal_yaw = turnYaw[1];
|
||||
changeyaw();
|
||||
angleDelta = angleDifference(oldAngle, angles);
|
||||
|
||||
input_angles[1] = v_angle[1] = angles[1];
|
||||
|
||||
/* anything but small turns? halt the player */
|
||||
if (fabs(yawDiff) > 5) {
|
||||
input_movevalues = g_vec_null;
|
||||
}
|
||||
///printf("yawDiff: %f\n", angleDelta[1]);
|
||||
|
||||
if (fabs(yawDiff) > 45) {
|
||||
velocity = g_vec_null;
|
||||
input_movevalues = g_vec_null;
|
||||
if (fabs(angleDelta[1]) > 1.0f) {
|
||||
/* wasn't turning before */
|
||||
if (m_bTurning == false) {
|
||||
|
||||
if (m_bTurning == false)
|
||||
if (yawDiff < 0) {
|
||||
SetFrame(FramegroupForAct(ACT_TURN_RIGHT));
|
||||
} else {
|
||||
SetFrame(FramegroupForAct(ACT_TURN_LEFT));
|
||||
if (yawDiff < 0) {
|
||||
AnimPlay(FramegroupForAct(ACT_TURN_RIGHT));
|
||||
} else {
|
||||
AnimPlay(FramegroupForAct(ACT_TURN_LEFT));
|
||||
}
|
||||
}
|
||||
|
||||
m_bTurning = true;
|
||||
} else {
|
||||
m_bTurning = false;
|
||||
}
|
||||
|
||||
/* min/max out the diff */
|
||||
if (yawDiff > 0) {
|
||||
v_angle[1] += turnSpeed * frametime;
|
||||
|
||||
if (v_angle[1] > vecWishAngle[1])
|
||||
v_angle[1] = vecWishAngle[1];
|
||||
} else if (yawDiff < 0) {
|
||||
v_angle[1] -= turnSpeed * frametime;
|
||||
|
||||
if (v_angle[1] < vecWishAngle[1])
|
||||
v_angle[1] = vecWishAngle[1];
|
||||
}
|
||||
|
||||
/* fix angles */
|
||||
makevectors(v_angle);
|
||||
vecWishAngle = vectoangles( v_forward );
|
||||
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
NSMonster::_LerpTurnToPos(vector turnPos)
|
||||
{
|
||||
vector vecWishAngle = vectoangles(turnPos - origin);
|
||||
vector vecWishAngle = vectorToAngles(turnPos - origin);
|
||||
_LerpTurnToYaw(vecWishAngle);
|
||||
}
|
||||
|
||||
|
@ -868,7 +854,7 @@ NSMonster::_LerpTurnToEnemy(void)
|
|||
|
||||
enemyEyePos = (m_eEnemy.origin + m_eEnemy.view_ofs);
|
||||
|
||||
dirAim = vectoangles(enemyEyePos - GetEyePos());
|
||||
dirAim = vectorToAngles(enemyEyePos - GetEyePos());
|
||||
v_angle[0] = dirAim[0];
|
||||
}
|
||||
|
||||
|
@ -1179,8 +1165,9 @@ NSMonster::FreeState(void)
|
|||
if (findKT) {
|
||||
NSMonsterLog("Killing %S", m_strSequenceKillTarget);
|
||||
findKT.Destroy();
|
||||
findKT.targetname = "";
|
||||
} else {
|
||||
NSError("Could not remove %S!", m_strSequenceKillTarget);
|
||||
EntError("Unable to find %S for removal", m_strSequenceKillTarget);
|
||||
}
|
||||
|
||||
m_strSequenceKillTarget = __NULL__;
|
||||
|
@ -1270,35 +1257,36 @@ NSMonster::RouteEnded(void)
|
|||
void
|
||||
NSMonster::WalkRoute(void)
|
||||
{
|
||||
vector wishAngle = input_angles;
|
||||
|
||||
/* we're busy shooting at something, don't walk */
|
||||
if (GetState() == MONSTER_AIMING && m_eEnemy) {
|
||||
input_angles = vectoangles(m_eEnemy.origin - origin);
|
||||
input_angles[0] = input_angles[2] = 0;
|
||||
wishAngle = vectorToAngles(m_eEnemy.origin - origin);
|
||||
wishAngle[0] = wishAngle[2] = 0;
|
||||
} else if (IsOnRoute()) {
|
||||
input_angles = GetRouteDirection();
|
||||
input_angles[0] = input_angles[2] = 0;
|
||||
wishAngle = GetRouteDirection();
|
||||
wishAngle[0] = wishAngle[2] = 0;
|
||||
input_movevalues = GetRouteMovevalues() * m_flSequenceSpeed;
|
||||
|
||||
/* is something in our way? */
|
||||
makevectors(input_angles);
|
||||
tracebox(origin, mins, maxs, origin + v_forward * 256, MOVE_NORMAL, this);
|
||||
tracebox(origin, [-16, -16, -16], [16, 16, 16], origin + anglesToForward(wishAngle) * 256, MOVE_NORMAL, this);
|
||||
|
||||
/* indeed it is */
|
||||
if (trace_fraction < 1.0f) {
|
||||
vector testOrg = origin + (v_right * 32);
|
||||
vector testOrg = origin + (anglesToRight(wishAngle) * 32) + anglesToForward(wishAngle) * 128;
|
||||
testOrg[2] += mins[2] + 18.0f; /* test at feet level */
|
||||
|
||||
traceline(testOrg, testOrg + v_forward * 256, MOVE_NORMAL, this);
|
||||
traceline(origin, testOrg, MOVE_NORMAL, this);
|
||||
|
||||
/* is space free to the right? */
|
||||
if (trace_fraction == 1.0) {
|
||||
input_movevalues[1] = m_flSequenceSpeed * 0.25f;
|
||||
} else {
|
||||
|
||||
testOrg = origin - (v_right * 32);
|
||||
testOrg = origin - (anglesToRight(wishAngle) * 32) + anglesToForward(wishAngle) * 128;
|
||||
testOrg[2] += mins[2] + 18.0f; /* test at feet level */
|
||||
|
||||
traceline(testOrg, testOrg + v_forward * 256, MOVE_NORMAL, this);
|
||||
traceline(origin, testOrg, MOVE_NORMAL, this);
|
||||
|
||||
/* is space free to the left? */
|
||||
if (trace_fraction == 1.0)
|
||||
|
@ -1307,19 +1295,14 @@ NSMonster::WalkRoute(void)
|
|||
}
|
||||
} else if (GetState() == MONSTER_CHASING && m_eEnemy) {
|
||||
/* we've got 'em in our sights, just need to walk closer */
|
||||
input_angles = vectoangles(m_eEnemy.origin - origin);
|
||||
input_angles[0] = input_angles[2] = 0;
|
||||
wishAngle = vectorToAngles(m_eEnemy.origin - origin);
|
||||
wishAngle[0] = wishAngle[2] = 0;
|
||||
input_movevalues = [GetChaseSpeed(), 0, 0];
|
||||
} else
|
||||
return;
|
||||
|
||||
/* don't move while turning. */
|
||||
if (m_bTurning == true) {
|
||||
input_movevalues = [0,0,0];
|
||||
}
|
||||
|
||||
/* yaw interpolation */
|
||||
_LerpTurnToYaw(input_angles);
|
||||
_LerpTurnToYaw(wishAngle);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1460,8 +1443,6 @@ NSMonster::RunAI(void)
|
|||
AttackThink();
|
||||
}
|
||||
|
||||
void PMoveCustom_RunPlayerPhysics(entity target);
|
||||
void PMoveCustom_RunCrouchPhysics(entity target);
|
||||
void
|
||||
NSMonster::Physics(void)
|
||||
{
|
||||
|
@ -1498,8 +1479,10 @@ NSMonster::Physics(void)
|
|||
|
||||
/* we're ending a scripted sequence, so play its animation */
|
||||
if (GetSequenceState() == SEQUENCESTATE_ENDING) {
|
||||
angles[1] = input_angles[1] = m_vecSequenceAngle[1];
|
||||
SetFrame(m_flSequenceEnd);
|
||||
_LerpTurnToYaw(m_vecSequenceAngle);
|
||||
|
||||
if (m_bTurning == false)
|
||||
SetFrame(m_flSequenceEnd);
|
||||
} else {
|
||||
/* if still alive... */
|
||||
if (IsAlive()) {
|
||||
|
@ -1523,12 +1506,13 @@ NSMonster::Physics(void)
|
|||
|
||||
hitcontentsmaski = CONTENTBITS_MONSTER;
|
||||
|
||||
if (CanCrouch())
|
||||
PMoveCustom_RunCrouchPhysics(this);
|
||||
else
|
||||
PMoveCustom_RunPlayerPhysics(this);
|
||||
/* don't move while turning. */
|
||||
if (m_bTurning == true) {
|
||||
input_movevalues = [0,0,0];
|
||||
}
|
||||
|
||||
SetOrigin(origin);
|
||||
/* complete the move */
|
||||
Physics_Run();
|
||||
}
|
||||
|
||||
if (!(GetFlags() & FL_ONGROUND) && velocity[2] < -415) {
|
||||
|
@ -1578,8 +1562,7 @@ NSMonster::Touch(entity eToucher)
|
|||
vector bestPos = g_vec_null;
|
||||
|
||||
for (float yaw = angles[1]; yaw < (angles[1] + 360.0f); yaw += 1.0f) {
|
||||
makevectors([0, yaw, 0]);
|
||||
tracebox(origin, mins, maxs, origin + (v_forward * 128.0f), FALSE, this);
|
||||
tracebox(origin, mins, maxs, origin + (anglesToForward([0, yaw, 0]) * 128.0f), FALSE, this);
|
||||
|
||||
if (trace_startsolid) {
|
||||
bestYaw = random(0, 360);
|
||||
|
@ -1818,10 +1801,7 @@ NSMonster::Respawn(void)
|
|||
setorigin_safe(this, origin);
|
||||
}
|
||||
|
||||
v_angle = GetSpawnAngles();
|
||||
v_angle[0] = Math_FixDelta(v_angle[0]);
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = Math_FixDelta(v_angle[2]);
|
||||
v_angle = fixAngle(GetSpawnAngles());
|
||||
|
||||
AddFlags(FL_MONSTER);
|
||||
SetTakedamage(DAMAGE_AIM);
|
||||
|
@ -1830,7 +1810,7 @@ NSMonster::Respawn(void)
|
|||
SetHealth(base_health);
|
||||
m_eEnemy = __NULL__;
|
||||
m_iFlags = 0x0;
|
||||
SetCanBleed(true);
|
||||
EnableBleeding();
|
||||
customphysics = Physics;
|
||||
|
||||
SetAngles(v_angle);
|
||||
|
@ -1841,6 +1821,7 @@ NSMonster::Respawn(void)
|
|||
SetEyePos([0, 0, m_flEyeHeight]);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
ScheduleThink(AdjustSpawnPos, 0.0f);
|
||||
SetSkin(m_flSkin);
|
||||
|
||||
if (HasSpawnFlags(MSF_MONSTERCLIP)) {
|
||||
hitcontentsmaski = CONTENTBITS_BOXSOLID | CONTENTBIT_MONSTERCLIP;
|
||||
|
@ -1864,6 +1845,12 @@ NSMonster::Respawn(void)
|
|||
SetFrame(_m_flFrame);
|
||||
}
|
||||
|
||||
if (HasSpawnFlags(MSF_GAG)) {
|
||||
m_bGagged = true;
|
||||
} else {
|
||||
m_bGagged = false;
|
||||
}
|
||||
|
||||
/* automatically start */
|
||||
if (!targetname)
|
||||
if (HasTriggerTarget() == true) {
|
||||
|
@ -1871,6 +1858,31 @@ NSMonster::Respawn(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
NSMonster::Input( entity entityActivator, string inputName, string dataField )
|
||||
{
|
||||
switch (inputName) {
|
||||
case "Sleep":
|
||||
customphysics = __NULL__;
|
||||
ReleaseThink();
|
||||
break;
|
||||
case "Wake":
|
||||
customphysics = Physics;
|
||||
break;
|
||||
case "StartScripting":
|
||||
m_iSequenceState = SEQUENCESTATE_IDLE;
|
||||
break;
|
||||
case "GagEnable":
|
||||
m_bGagged = true;
|
||||
break;
|
||||
case "GagDisable":
|
||||
m_bGagged = false;
|
||||
break;
|
||||
default:
|
||||
super::Input(entityActivator, inputName, dataField);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NSMonster::Trigger(entity act, triggermode_t state)
|
||||
{
|
||||
|
@ -2046,6 +2058,9 @@ NSMonster::SpawnKey(string strKey, string strValue)
|
|||
case "frame":
|
||||
_m_flFrame = ReadFloat(strValue);
|
||||
break;
|
||||
case "skin":
|
||||
m_flSkin = ReadFloat(strValue);
|
||||
break;
|
||||
case "sequence":
|
||||
m_flForceSequence = ReadFloat(strValue);
|
||||
break;
|
||||
|
@ -2171,19 +2186,6 @@ NSMonster::predraw(void)
|
|||
|
||||
render = super::predraw();
|
||||
|
||||
/* are we inside of an interpolation? */
|
||||
if (frame != frame2) {
|
||||
/* we're done lerping */
|
||||
if (lerpfrac <= 0.0f)
|
||||
frame2 = frame;
|
||||
|
||||
lerpfrac -= frametime * 4.0f;
|
||||
} else {
|
||||
/* make sure we're set up for next lerp */
|
||||
lerpfrac = 1.0f;
|
||||
frame2time = frame1time;
|
||||
}
|
||||
|
||||
_RenderDebugViewCone();
|
||||
|
||||
return render;
|
||||
|
@ -2261,11 +2263,10 @@ NSMonster::_RenderDebugViewCone(void)
|
|||
|
||||
if (autocvar(r_showViewCone, 0) == 0)
|
||||
return;
|
||||
|
||||
makevectors(angles);
|
||||
|
||||
testOrg = pSeat->m_ePlayer.origin;
|
||||
v = normalize(testOrg - GetEyePos());
|
||||
flDot = v * v_forward;
|
||||
flDot = v * anglesToForward(angles);
|
||||
|
||||
/* not inside our FoV at all */
|
||||
if (flDot < 90.0f/180) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue