Compare commits

..

No commits in common. "master" and "Documentation" have entirely different histories.

762 changed files with 15329 additions and 50910 deletions

4
.gitignore vendored
View file

@ -39,10 +39,6 @@ qkey
installed.lst
*.kdev4
hl2/*
bshift/*
baseq2/*
gangstawars/*
nightfire/*
*.ico
src/engine/
bin/

View file

@ -1,55 +0,0 @@
# Bots
Bots are handled by BotLib, located under `src/botlib` in the directory 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.
# Bot profiles
Nuclide has support for bot profiles, like in **Quake III Arena**. They work differently although they appear compatible by design. You can define them in a script that looks something like this and is located at `scripts/bots.txt` in your game directory:
```
{
name Albert
model zombie01
topcolor 0xeff
bottomcolor 0xff0020
}
{
name Susie
model police02
topcolor 0xff6b00
bottomcolor 0xff0b00
}
{
name Dog
funname ^4D^2o^1g
model dog01
topcolor 0x9200ff
bottomcolor 0xc800ff
}
```
Only the `name` key is required. The only other special key is `funname` which sets the nickname to be different from the internal name. The other keys are set as user info (setinfo) keys on the bot client.
This will allow games to add whatever extra keys they wish that they can then recognize anywhere in the client/server codebase. No additional networking or APIs necessary. Simply query bot properties via their userinfo.
# Bot Console Commands
## addBot [profile name]
Adds a bot to the current game.
## killAllBots
Force kills and respawns bots in the current game.
## resetAllBotsGoals
Force reset bots current trajectory and goals.
# Bot Console Variables
See `platform/cvars.cfg` under the `// bots` section.

View file

@ -1,13 +1,5 @@
# Building
## Preface
If you don't plan on modifying the engine, then you probably shouldn't! You can grab binaries from [FTEQW](https://www.fteqw.org) and move them into the Nuclide directory under `./bin`.
If you're on Microsoft Windows, you will most likely not be running the `nuclide` launch script anyway, so feel free to move the `fteqw.exe` into the root of the Nuclide directory, and run that as-is instead.
It will mount the game directories specified in the `default.fmf` file, which you can tweak as needed. [For more information, read the relevant documentation regarding launching Nuclide](Documentation/Launching.md)
## Building the Engine {#engine}
The **build_engine.sh** will do that for you. It will still ask you to have at least
@ -79,7 +71,7 @@ The results will be identical.
#### FTE
```
apt-get install libgl-dev gnutls-dev
apt-get install subversion libgl-dev gnutls-dev
```
#### SDL2
@ -94,13 +86,13 @@ apt-get install libsdl2-dev
apt-get install libx11-dev libxcursor-dev libxrender-dev
```
#### Plugin: ODE
#### ODE Plugin
```
apt-get install autoconf automake libtool
```
#### Plugin: FFMPEG
#### FFMPEG Plugin
```
apt-get install libavformat-dev libswscale-dev
@ -108,67 +100,30 @@ apt-get install libavformat-dev libswscale-dev
### OpenBSD
#### FTE
#### Nuclide
```
pkg_add git
```
#### FTE
```
pkg_add subversion
```
#### SDL2
```
pkg_add sdl2
```
#### Plugin: FFMPEG
#### FFMPEG Plugin
```
pkg_add ffmpeg
```
### Arch Linux
#### FTE
```
pacman -S make gcc Xorg git
```
#### Plugin: ODE
```
pacman -S zip automake autoconf
```
#### Plugin: FFMPEG
```
pacman -S ffmpeg4.4
```
*Note:* You will have to manually build this plugin due to FFMPEG breaking ABI between releases and Arch's rolling release nature.
1) Edit build.cfg and change `FFMPEG=YES` to `NO`
2) Browse to src/engine/engine
3) Run this command:
`make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/ffmpeg4.4/ AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"`
4) Copy over `fteplug_ffmpeg.so` to the `bin` folder where nuclide and the build scripts are.
#### SDL2
```
pacman -S sdl2
```
#### WorldSpawn
```
pacman -S pkgconf gtk2 gtkglext
```
### OpenSUSE
#### Nuclide
@ -180,7 +135,7 @@ zypper in git
#### FTE
```
zypper in make gcc gcc-c++ mesa-libGL-devel libgnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
zypper in subversion make gcc gcc-c++ mesa-libGL-devel libgnutls-devel
```
#### SDL2
@ -195,13 +150,7 @@ zypper in libSDL2-devel
zypper in libX11-devel libXcursor-devel libXrandr-devel
```
#### Plugin: ODE
```
zypper in autoconf automake libtool zip
```
#### Plugin: FFMPEG
#### FFMPEG Plugin
```
zypper in ffmpeg-4-libavformat-devel ffmpeg-4-libswscale-devel
@ -210,59 +159,5 @@ zypper in ffmpeg-4-libavformat-devel ffmpeg-4-libswscale-devel
#### Worldspawn
```
zypper in make gtkglext-devel libxml2-devel libjpeg8-devel minizip-devel
zypper in cmake gtkglext-devel libxml2-devel libjpeg8-devel minizip-devel
```
### Fedora
#### FTE
```
dnf install make gcc gcc-c++ mesa-libGL-devel gnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
```
#### SDL2
```
dnf install SDL2-devel
```
#### GLX / X11 (part of libsdl2-dev)
```
dnf install libX11-devel libXcursor-devel libXrender-devel
```
#### Plugin: ODE
```
dnf install autoconf automake libtool zip
```
#### Plugin: FFMPEG
*Note:* You will have to manually build this plugin due to FFMPEG breaking ABI between releases as well as install a custom repository since Fedora ships only latest versions of FFMPEG.
First, you will need to install the RPM Fusion if you don't have it. We recommend reading their official guide: https://rpmfusion.org/Configuration
Then, you can install the required version of FFMPEG:
```
dnf install compat-ffmpeg4-devel
```
Now to build:
1) Edit build.cfg and change `FFMPEG=YES` to `NO`
2) Browse to src/engine/engine
3) Run this command:
`make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/compat-ffmpeg4 AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"`
4) Copy over `fteplug_ffmpeg.so` to the `bin` folder where nuclide and the build scripts are.
#### Worldspawn
```
dnf install make pkgconf gtkglext-devel libxml2-devel libjpeg-turbo-devel minizip-devel
```

View file

@ -1,24 +0,0 @@
# Constants
Often you want to be able to use aliases for values inside your **EntityDef** files.
For that, you can have a name/value pair mapping inside a text file named `scripts/constants.txt`.
```
// some comments here
WEAPON_NONE 0
WEAPON_CROWBAR 1
WEAPON_GLOCK 2
[...]
DEFAULT_NAME "Max"
```
And then you use the identifers in place of those constants. Similar to environment variables in the **UNIX** shell.
```
entityDef weapon_glock {
"spawnclass" "NSItem"
"inv_item" "$WEAPON_GLOCK"
[...]
}
```

View file

@ -1,34 +0,0 @@
# Dedicated Server
# Usage
To initialize a dedicated server, you can run `./nuclide-ds -game yourGame`. It is generally advised to write and execute a server config file you have prepared ahead of time.
Here is an example:
```
hostname "Nuclide Test Server"
set sv_public 2 // 0 - not public, 1 = advertised on master server, 2 = ICE
set deathmatch 1 // request multiplayer modus
set coop 0 // deny coop modus
set maxplayers 16 // 16 players max
set timelimit 10 // 10 minutes per map
set fraglimit 30 // 30 frags per map
set pausable 0 // don't allow players to 'pause'
set rcon_password "" // no rcon
map dm_beck16 // start
```
You can then run the dedicated server like this:
`./nuclide-ds -game yourGame +exec server.cfg`
In production, the exact same style of commands applies to release builds. So if you have a standard engine binary (**fteqwgl64.exe** or a branded executable) things will be identical.
Keep in mind to set any game specific console variables.
# Remote Console (RCon)
In the above config, if you've set rcon_password to anything other than `""` you have access to remotely control the game server.
For example, you can (as a client, once connected) use the command `rcon yourPassword changelevel dm_beck16` to forcefully change the level on the server. Anything that's possible in a conventional dedicated server console is now accessible.

View file

@ -1,45 +0,0 @@
# EntityDef
## Overview
In **id Tech 4**, we have been introduced to external entity definitions. They are pretty straightforward by merely being a set of default values for an existing entity class.
This can be used in a variety of ways.
- Create new entity classes with new behaviour without any code
- Create a base class that other entityDefs can inherit from
- Create prefabs that get updated across all maps
This system can also be used in combination with [MapTweaks](Documentation/MapTweaks.md), where an entityDef is used instead of a base class depending on the parameters you decide to test.
## Syntax
Let's take a look at an example **EntityDef**:
```
entityDef item_health_small {
"spawnclass" "item_health"
"spawnflags" "1"
}
```
This is from the port of *Deathmatch Classic*, and will ensure that **item_health_small** from *Quake III Arena* gets spawned as an **item_health** with its *spawnflags* set to the one that will make it a small health pickup.
You can have as many key/value pairs as you like. However, you can only specify one *spawnclass* and you cannot do circular inheritance.
## Special Keys
These are reserved keys and are meant to be used by the **build_game.sh** script to generate an entities.def file for your game.
| Key | Description |
|--------------------|------------------------------------------------------------------------|
| editor_usage | Description text used by the editor. |
| editor_model | Model to use in the editor. |
| editor_var **KEY** | Description text for the specified key. |
| editor_color | Normalized color vector defining the bounding box color in the editor. |
| editor_mins | Vector defining the mins of the entity bounding box. |
| editor_maxs | Vector defining the maxs of the entity bounding box. |
# References
- [id.sdk page on Entity Defs](http://icculus.org/~marco/notmine/id-dev/www.iddevnet.com/doom3/entitydefs.html)

View file

@ -1,350 +0,0 @@
# Entity Guide
# Overview
[ambient_generic](@ref ambient_generic)
[button_target](@ref button_target)
[cycler](@ref cycler)
[cycler_sprite](@ref cycler_sprite)
[cycler_weapon](@ref cycler_weapon)
[cycler_wreckage](@ref cycler_wreckage)
[env_beam](@ref env_beam)
[env_beverage](@ref env_beverage)
[env_bubbles](@ref env_bubbles)
[env_cascade_light](@ref env_cascade_light)
[env_cubemap](@ref env_cubemap)
[env_explosion](@ref env_explosion)
[env_fade](@ref env_fade)
[env_fire](@ref env_fire)
[env_fog](@ref env_fog)
[env_fog_controller](@ref env_fog_controller)
[env_funnel](@ref env_funnel)
[env_global](@ref env_global)
[env_glow](@ref env_glow)
[env_hudhint](@ref env_hudhint)
[env_instructor_hint](@ref env_instructor_hint)
[env_laser](@ref env_laser)
[env_message](@ref env_message)
[env_model](@ref env_model)
[env_muzzleflash](@ref env_muzzleflash)
[env_particle](@ref env_particle)
[env_physexplosion](@ref env_physexplosion)
[env_projectedtexture](@ref env_projectedtexture)
[env_render](@ref env_render)
[env_shake](@ref env_shake)
[env_shockwave](@ref env_shockwave)
[env_shooter](@ref env_shooter)
[env_smoker](@ref env_smoker)
[env_sound](@ref env_sound)
[env_soundscape](@ref env_soundscape)
[env_spark](@ref env_spark)
[env_sprite](@ref env_sprite)
[env_steam](@ref env_steam)
[env_sun](@ref env_sun)
[func_areaportal](@ref func_areaportal)
[func_areaportalwindow](@ref func_areaportalwindow)
[func_breakable](@ref func_breakable)
[func_brush](@ref func_brush)
[func_button](@ref func_button)
[func_conveyor](@ref func_conveyor)
[func_detail](@ref func_detail)
[func_detail_illusionary](@ref func_detail_illusionary)
[func_door](@ref func_door)
[func_door_rotating](@ref func_door_rotating)
[func_dustcloud](@ref func_dustcloud)
[func_dustmotes](@ref func_dustmotes)
[func_friction](@ref func_friction)
[func_group](@ref func_group)
[func_guntarget](@ref func_guntarget)
[func_healthcharger](@ref func_healthcharger)
[func_illusionary](@ref func_illusionary)
[func_ladder](@ref func_ladder)
[func_lod](@ref func_lod)
[func_monitor](@ref func_monitor)
[func_monsterclip](@ref func_monsterclip)
[func_mortar_field](@ref func_mortar_field)
[func_pendulum](@ref func_pendulum)
[func_physbox](@ref func_physbox)
[func_plat](@ref func_plat)
[func_platrot](@ref func_platrot)
[func_pushable](@ref func_pushable)
[func_recharge](@ref func_recharge)
[func_rot_button](@ref func_rot_button)
[func_rotating](@ref func_rotating)
[func_smokevolume](@ref func_smokevolume)
[func_tank](@ref func_tank)
[func_tankcontrols](@ref func_tankcontrols)
[func_tankmortar](@ref func_tankmortar)
[func_trackchange](@ref func_trackchange)
[func_tracktrain](@ref func_tracktrain)
[func_train](@ref func_train)
[func_traincontrols](@ref func_traincontrols)
[func_vehicle](@ref func_vehicle)
[func_vehiclecontrols](@ref func_vehiclecontrols)
[func_wall](@ref func_wall)
[func_wall_toggle](@ref func_wall_toggle)
[game_counter](@ref game_counter)
[game_counter_set](@ref game_counter_set)
[game_end](@ref game_end)
[game_player_equip](@ref game_player_equip)
[game_player_hurt](@ref game_player_hurt)
[game_player_team](@ref game_player_team)
[game_score](@ref game_score)
[game_team_master](@ref game_team_master)
[game_team_set](@ref game_team_set)
[game_text](@ref game_text)
[game_zone_player](@ref game_zone_player)
[gibshooter](@ref gibshooter)
[info_hint](@ref info_hint)
[info_intermission](@ref info_intermission)
[info_node](@ref info_node)
[info_node_air](@ref info_node_air)
[info_notnull](@ref info_notnull)
[info_null](@ref info_null)
[info_particle_system](@ref info_particle_system)
[info_player_coop](@ref info_player_coop)
[info_player_deathmatch](@ref info_player_deathmatch)
[info_player_start](@ref info_player_start)
[info_teleport_destination](@ref info_teleport_destination)
[info_waypoint](@ref info_waypoint)
[infodecal](@ref infodecal)
[item_food](@ref item_food)
[light](@ref light)
[light_dynamic](@ref light_dynamic)
[light_environment](@ref light_environment)
[light_surface](@ref light_surface)
[logic_achievement](@ref logic_achievement)
[logic_auto](@ref logic_auto)
[logic_case](@ref logic_case)
[logic_relay](@ref logic_relay)
[logic_timer](@ref logic_timer)
[momentary_door](@ref momentary_door)
[momentary_rot_button](@ref momentary_rot_button)
[monster_furniture](@ref monster_furniture)
[monster_generic](@ref monster_generic)
[monstermaker](@ref monstermaker)
[multi_manager](@ref multi_manager)
[multisource](@ref multisource)
[path_corner](@ref path_corner)
[path_track](@ref path_track)
[phys_ballsocket](@ref phys_ballsocket)
[phys_constraint](@ref phys_constraint)
[phys_constraintsystem](@ref phys_constraintsystem)
[phys_convert](@ref phys_convert)
[phys_hinge](@ref phys_hinge)
[phys_keepupright](@ref phys_keepupright)
[phys_rope](@ref phys_rope)
[phys_slideconstraint](@ref phys_slideconstraint)
[player_loadsaved](@ref player_loadsaved)
[player_weaponstrip](@ref player_weaponstrip)
[point_camera](@ref point_camera)
[point_message](@ref point_message)
[point_servercommand](@ref point_servercommand)
[point_spotlight](@ref point_spotlight)
[point_trigger](@ref point_trigger)
[prop_dynamic](@ref prop_dynamic)
[prop_physics](@ref prop_physics)
[prop_rope](@ref prop_rope)
[prop_static](@ref prop_static)
[prop_vehicle_driveable](@ref prop_vehicle_driveable)
[random_speaker](@ref random_speaker)
[random_trigger](@ref random_trigger)
[scripted_sentence](@ref scripted_sentence)
[scripted_sequence](@ref scripted_sequence)
[sky_camera](@ref sky_camera)
[speaker](@ref speaker)
[targ_speaker](@ref targ_speaker)
[target_cdaudio](@ref target_cdaudio)
[trigger_auto](@ref trigger_auto)
[trigger_autosave](@ref trigger_autosave)
[trigger_camera](@ref trigger_camera)
[trigger_cdaudio](@ref trigger_cdaudio)
[trigger_changelevel](@ref trigger_changelevel)
[trigger_changetarget](@ref trigger_changetarget)
[trigger_counter](@ref trigger_counter)
[trigger_endsection](@ref trigger_endsection)
[trigger_gravity](@ref trigger_gravity)
[trigger_hurt](@ref trigger_hurt)
[trigger_look](@ref trigger_look)
[trigger_monsterjump](@ref trigger_monsterjump)
[trigger_multiple](@ref trigger_multiple)
[trigger_once](@ref trigger_once)
[trigger_playerfreeze](@ref trigger_playerfreeze)
[trigger_push](@ref trigger_push)
[trigger_relay](@ref trigger_relay)
[trigger_teleport](@ref trigger_teleport)
[trigger_transition](@ref trigger_transition)
[worldspawn](@ref worldspawn)

View file

@ -8,9 +8,9 @@ For development, use the `nuclide` launch script inside the root directory.
$ ./nuclide
```
Running it on its own will mount only the directory `platform/`. As that's the default defined inside the file `./default.fmf`.
Running it on its own will mount the game dir `base/`. As that's the default defined inside the file `./default.fmf`.
You can mount an additional mod over it like so:
You can mount an additional mod over `base/` like so:
```
$ ./nuclide -game some_other_mod
@ -22,28 +22,10 @@ If you wanted to mount multiple game dirs, you could in theory do it like so:
$ ./nuclide -game first_mod -game second_mod -game third_mod
```
And it'll load those directories in order.
However, if you'd like to be very specific in how a game is run/branded/launched
you should really use **FTE Manifest** files.
Simply plop one into your game directory with the name `manifest.fmf`, then launch
nuclide like so:
```
$ ./nuclide first_mod
```
and it will load `first_mod/manifest.fmf`. You can supply arguments to it by putting them into the second parameter with quotes like so:
```
$ ./nuclide first_mod "-window +set sv_cheats 1"
```
And it'll load those directories in order, on top of `base/`.
However, we advise you only do this for development. If you want proper multiplayer compatibility (slightly different filesystem mount setups can confuse client-server negotation) please use the built-in **Custom game** menu to ensure maximum compatibility to other clients.
If you are running a dedicated server and have issues with multiple game directories, check the value of the cvar `sv_gamedir` on the server. It is meant to be a semicolon separated list of game directories, if multiple ones are supposed to be mounted.
## For release...
You'll want to compile a custom build of the engine with your branding.

View file

@ -1,63 +1,44 @@
# Overview
Welcome to the documentation for Nuclide!
Welcome to the documentation for Nuclide.
This is a software development kit (SDK) and development environment created by [Vera Visions, L.L.C.](https://www.vera-visions.com/). We want to share it with everyone to avoid duplicate effort and in the hopes that it is useful to someone else.
This is a software development kit and development environment created by [Vera Visions, L.L.C.](https://www.vera-visions.com/)
## What this project is {#what}
The Nuclide project produces a freely available game-logic component and
development platform on top of [FTEQW](https://www.fteqw.org); which is the engine we happen to use.
**The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.**
development platform on top of FTEQW; which is the engine we happen to use.
The goal is to create a modern research base for new advancements, as well
as to have a stable base with a decent API for making games.
It comes with a simple example game (simply referred to as 'Base') and some test maps. There's also some other, third-party example projects.
General feature overview:
- The 'missing' SDK for engines like FTEQW
- Support for client-side predicted movement, weaponry and vehicles
- Documented APIs for everything you need to interface with the engine
- APIs and Frameworks for managing updates, mods, servers, and platform specific features
- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games
- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system
- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides
- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces
- Designed to be familar to developers coming from GoldSrc/Source
- VR/XR aware codebase
- All permissively licensed
- Client-side predicted movement and inputs for things like weapons-systems
- Lots of well documented objects to use in level formats supported by FTEQW
- Reference implementations for a lot of features exlusive to FTEQW compared
to other idTech engines
- Designed to be familar to developers who're used to GoldSrc and Source engine
projects
### 1. Why might I want to use it? {#why}
You might be migrating from an engine that is no longer being licensed and don't want to learn a new engine and toolchain.
You might want to develop a game using a lot of complex and well-tested objects
You want to develop a game using a lot of complex and well-tested objects
which might be tedious to implement on your own.
You might want to run or make modifications for a game using Nuclide and need full
You want to run or make modifications for a game using Nuclide and need full
control over what you can do.
### 2. How free is Nuclide? {#license}
Everything in Nuclide is **free software**. The copyright terms for the game-logic are
very permitting. Nuclide *does not use the GPL* as a point of reference in terms of license, it instead uses a **ISC-like license**. This means you can use, copy, modify and
very permitting. Nuclide does not use the GPL as a point of reference, it
instead uses a ISC-like license. This means you can use, copy, modify and
distribute the code and work resulting from it for any purpose.
**Please read the very short 'LICENSE' document for details.**
Please read the very short 'LICENSE' document for details.
### 3. What are the alternatives? {#alternatives}
Implementing systems such as prediction, complex map objects and entities on
your own, from scratch - or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**.
### 4. Any example projects? {#examples}
- [The Wastes](https://store.steampowered.com/app/793670) is a commerical game built using Nuclide.
- [FreeHL](https://www.github.com/eukara/freehl) is a free-software, clean-room clone of Half-Life: Deathmatch also built using Nuclide.
- [FreeCS](https://www.github.com/eukara/freecs) exists in the same vein as FreeHL, but targetting a recreation of Counter-Strike v1.5 (mod version) specifically.
your own or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**.
## Getting started {#prerequisites}
@ -69,13 +50,12 @@ If you do posess a basic knowledge of the following:
- Makefiles
- Compiling your own binaries
- Concept of public and private APIs
- QuakeC
Then you will have a good time.
We strive to keep the codebase portable and conform to open standards wherever possible.
This means that if you develop on Windows, you probably want to install something like WSL or even [Cygwin](https://www.cygwin.com/) to make this bearable.
This means that if you develop on Windows, you probably want to install something like [Cygwin](https://www.cygwin.com/) to make this bearable.
Please don't ask us how to use WSL or Cygwin. We do not provide support for either. We do not develop on Windows.
Please don't ask us how to learn UNIX/Cygwin.
**This is a development kit and a development environment. This is not a game.**
@ -85,4 +65,4 @@ You clone the Nuclide git repository first. There's multiple places to get it, o
`git clone https://github.com/veravisions/nuclide`
And then you can [get started on building the engine and the rest of the toolchain](Building.md). Alternatively, you can also move in the official FTEQW binaries into the Nuclide directory to get started without bootstrapping your own engine + QuakeC compiler.
And then you can [get started on building the engine and the rest of the toolchain](Building.md).

View file

@ -1,36 +0,0 @@
# MapTweaks
## Overview
This is a very customizable system that applies changes to levels/maps depending on a variable amount of parameters. It was invented specifically for Nuclide and designed to work together with [EntityDefs](Documentation/EntityDef.md).
## Syntax
All MapTweaks are defined within `scripts/maptweaks.txt`.
Let's take a look at an example **MapTweak**:
```
hldm_tweak
{
when-cvar deathmatch equals 2
when-serverinfo *bspversion equals 30
replace weapon_gauss info_null
replace weapon_egon info_null
}
```
The `hldm_tweaks` is just a user-defined name. It doesn't affect functionality.
The `when-cvar` and `when-serverinfo` lines are **checks**. each one is checked individually and only if all are positive will the `replace` lines take effect.
You can have as many lines in there as you like.
Other than `equals`, you can also use one of the following keywords when comparing values:
- **less-than**
- **greater-than**
- **is-not**
At this time, `when-cvar` and `when-serverinfo` only do comparisons on numbers. So you cannot check for strings at this time.

View file

@ -4,7 +4,7 @@
## History
In the id Tech series of engines, **id Tech 3/Quake III Arena** was the first to introduce such a system, wrongly referred to back then as **shaders**. This was before vertex and fragment shaders were commonplace in the video-game asset pipeline.
In the idTech series of engines, **id Tech 3/Quake III Arena** was the first to introduce such a system, wrongly referred to back then as **shaders**. This was before vertex and fragment shaders were commonplace in the video-game asset pipeline.
![from pulsing tubes to various animated materials in Quake III Arena](q3a_material.jpg)

View file

@ -9,8 +9,8 @@
Determines the alpha test function used when rendering this surface.
Valid values are **GT0**, **LT128**, and **GE128**. These correspond to
**GREATER THAN 0**, **LESS THAN 128**, and **GREATER THAN OR EQUAL
TO 128**.
**"GREATER THAN 0"**, **"LESS THAN 128"**, and **"GREATER THAN OR EQUAL
TO 128"**.
This function is used when determining if a pixel should be written to
the frame-buffer. For example, if **GT0** is specified, the only the
@ -18,12 +18,13 @@ portions of the texture map with corresponding alpha values greater than
zero will be written to the framebuffer. **By default alpha testing is
disabled.**
Both alpha testing and normal [alpha blending](blendfunc.md) can be used to get
Both alpha testing and normal [alpha
blending](blendFunc) can be used to get
textures that have see-through parts. The difference is that
**alphaFunc** is an all-or-nothing test, while blending smoothly blends
between opaque and translucent at pixel edges.
Alpha test can also be used with
[depthWrite](depthwrite.md), allowing other
[depthWrite](depthWrite), allowing other
effects to be conditionally layered on top of just the opaque pixels by
setting [depthFunc](depthfunc.md) to equal.
setting [depthFunc](depthFunc) to equal.

View file

@ -6,7 +6,8 @@
### Overview
The alpha channel can be specified like the [rgb channels](rgbgen.md). If not specified, it
The alpha channel can be specified like the [rgb
channels](rgbGen). If not specified, it
defaults to 1.0.
### Functions {#functions}
@ -14,7 +15,7 @@ defaults to 1.0.
#### portal {#portal}
This rendering stage keyword is used in conjunction with the
[surfaceparm](surfaceparm.md) keyword
[surfaceparm](surfaceparm) keyword
portal. The function accomplishes the "fade" that causes the scene in
the portal to fade from view. Specifically, it means "Generate alpha
values based on the distance from the viewer to the portal."

View file

@ -23,10 +23,10 @@ It accepts the standard **wave** functions of the type: **sin**,
**triangle**, **square**, **sawtooth** or **inversesawtooth**.
The "div" parameter is used to control the wave "spread" - a value equal
to the [tessSize](vmap_tesssize.md) of the
to the [tessSize](vmap_tessSize) of the
surface is a good default value.
#### normal <siv> <func> <base> <amplitude> <frequency> {#normal_amplitude}
#### normal <siv> <func> <base> &lt;amplitude ~0.1-~0.5&gt; &lt;frequency ~1.0-~4.0&gt; {#normal_amplitude_0.1_0.5_frequency_1.0_4.0}
This deformation affects the normals of a vertex without actually moving
it, which will effect later material options like lighting and
@ -43,14 +43,14 @@ rain, flags.
This forces a bulge to move along the given s and t directions. Designed
for use on curved pipes.
#### move <x> <y> <z> <func> <base> <amplitude> <phase> <freq> {#move}
#### move<x> <y> <z> <func> <base> <amplitude> <phase> <freq> {#move}
This keyword is used to make a brush, curve patch or model appear to
move together as a unit. The **x** **y** and **z** values are the
move together as a unit. The **<x>** **<y>** and **<z>** values are the
distance and direction in game units the object appears to move relative
to it's point of origin in the map.
The **func base amplitude phase** and **freq** values are the
The **<func> <base> <amplitude> <phase>** and **<freq>** values are the
same as found in other wave form manipulations.
The product of the function modifies the values x, y, and z.Therefore,
@ -101,9 +101,9 @@ smaller wave forms occurring in a given area. Larger values create a
lesser density of waves, or otherwise put, the appearance of larger
waves. To look correct this value should closely correspond to the value
(in pixels) set for
[tessSize](vmap_tesssize.md) of the texture.
[tessSize](vmap_tessSize) of the texture.
A value of 100.0 is a good default value (which means your
[tessSize](vmap_tesssize.md) should be close
[tessSize](vmap_tessSize) should be close
to that for things tolook "wavelike").
#### <func> {#section_1}

View file

@ -7,7 +7,7 @@
### Overview
By default, writes to the depth buffer when
[depthFunc](depthfunc.md) passes will happen
[depthFunc](depthFunc) passes will happen
for opaque surfaces and not for translucent surfaces.
Blended surfaces can have the depth writes forced with this function.

View file

@ -7,15 +7,15 @@
### Overview
**Note**: you must also specify "surfaceparm fog" to cause
[vmap](vmap.md) to identify the surfaces inside the volume.
[vmap](vmap) to identify the surfaces inside the volume.
Fogparms only describes how to render the fog on the surfaces.
**red value, green value, blue value**: These are normalized values.
**<red value> <green value> <blue value>** These are normalized values.
To obtain the values that define fog color divide the desired color's
Red, Green and Blue values by 255 to obtain three normalized numbers
within the 0.0 to 1.0 range.
**distance to opaque**: This is the distance, in game units, until the
**<distance toopaque>** This is the distance, in game units, until the
fog becomes totally opaque, as measured from the point of view of the
observer. By making the height of the fog brush shorter than the
distance to opaque, the apparent density of the fog can be reduced

View file

@ -7,6 +7,7 @@
### Overview
Similar to [vmap_surfaceModel (vmap_surfacemodel.md), however
Similar to [vmap_surfaceModel (Material
Command)](vmap_surfaceModel), however
it'll place models at runtime. The density can be controlled via the
cvar `r_clutter_density`.

View file

@ -9,17 +9,17 @@
The texture is essentially a fullbright overlay on top of the
diffuse/albedomap.
Not all [Shaders](Shaders.md) support them. In some, like the
[unlit](unlit.md) shader, the
[diffusemap](diffusemap.md) is always
Not all [Shaders](Shaders) support them. In some, like the
[unlit](unlit_(Shader)) shader, the
[diffusemap](diffusemap) is always
fullbright.
### See also {#see_also}
- [diffusemap](diffusemap.md)
- [normalmap](normalmap.md)
- [specularmap](specularmap.md)
- [uppermap](uppermap.md)
- [lowermap](lowermap.md)
- [reflectmask](reflectmask.md)
- [reflectcube](reflectcube.md)
- [diffusemap](diffusemap)
- [normalmap](normalmap)
- [specularmap](specularmap)
- [uppermap](uppermap)
- [lowermap](lowermap)
- [reflectmask](reflectmask)
- [reflectcube](reflectcube)

View file

@ -6,7 +6,7 @@
### Overview
This implies [noPicMip](nopicmip.md), but
This implies [noPicMip](noPicMip), but
also prevents the generation of any lower resolution mipmaps for use by
the 3d card. This will cause the texture to alias when it gets smaller,
but there are some cases where you would rather have this than a blurry

View file

@ -18,10 +18,10 @@ Check out our [Normal mapping guide](Normal_mapping_guide).
### See also {#see_also}
- [diffusemap](diffusemap.md)
- [specularmap](specularmap.md)
- [fullbrightmap](fullbrightmap.md)
- [uppermap](uppermap.md)
- [lowermap](lowermap.md)
- [reflectmask](reflectmask.md)
- [reflectcube](reflectcube.md)
- [diffusemap](diffusemap)
- [specularmap](specularmap)
- [fullbrightmap](fullbrightmap)
- [uppermap](uppermap)
- [lowermap](lowermap)
- [reflectmask](reflectmask)
- [reflectcube](reflectcube)

View file

@ -4,11 +4,11 @@
material. It also accepts arguments that will recompile a shader with
certain permutations. This is kinda ugly,
Starting in **The Wastes 1.2**, there are the
Starting in [The Wastes](The_Wastes) 1.2, there are the
following shader programs available to you:
- program [unlit](unlit.md)
- program [lightmapped](lightmapped.md)
- program [vertexlit](vertexlit.md)
- program [water](water.md)
- program [refract](refract.md)
- program [unlit](unlit_(Shader))
- program [lightmapped](lightmapped_(Shader))
- program [vertexlit](vertexlit_(Shader))
- program [water](water_(Shader))
- program [refract](refract_(Shader))

View file

@ -11,10 +11,10 @@ will pass the nearest in-world cubemap instead.
### See also {#see_also}
- [diffusemap](diffusemap.md)
- [normalmap](normalmap.md)
- [specularmap](specularmap.md)
- [fullbrightmap](fullbrightmap.md)
- [uppermap](uppermap.md)
- [lowermap](lowermap.md)
- [reflectmask](reflectmask.md)
- [diffusemap](diffusemap)
- [normalmap](normalmap)
- [specularmap](specularmap)
- [fullbrightmap](fullbrightmap)
- [uppermap](uppermap)
- [lowermap](lowermap)
- [reflectmask](reflectmask)

View file

@ -8,18 +8,18 @@
Defines a texture that specifies which parts of a material will reveal a
reflective material, such as a
[cubemap](reflectcube.md). This applies to
[cubemap](reflectcube). This applies to
standard FTEQW. In Nuclide the reflectmask is currently unused with the
included shaders. If you want to apply reflectivity to your materials,
use the alpha channel of your
[normalmap](normalmap.md) instead.
[normalmap](normalmap) instead.
### See also {#see_also}
- [diffusemap](diffusemap.md)
- [normalmap](normalmap.md)
- [specularmap](specularmap.md)
- [fullbrightmap](fullbrightmap.md)
- [uppermap](uppermap.md)
- [lowermap](lowermap.md)
- [reflectcube](reflectcube.md)
- [diffusemap](diffusemap)
- [normalmap](normalmap)
- [specularmap](specularmap)
- [fullbrightmap](fullbrightmap)
- [uppermap](uppermap)
- [lowermap](lowermap)
- [reflectcube](reflectcube)

View file

@ -22,9 +22,8 @@ entity, oneMinusEntity, fromVertex, and lightingDiffuse.
Follow this up with a vector of the color that you'd like the vertex
colors to be set as. An example for green would be:
```
rgbGen const 0.0 1.0 0.0
```
` rgbGen const 0.0 1.0 0.0`
#### identityLighting {#identitylighting}

View file

@ -13,41 +13,40 @@ to use for color, intensity etc.
The renderer will take it into account only if you do not supply any
Stages in the material.
**farbox**: Specifies a set of files to use as an environment box
**<farbox>** Specifies a set of files to use as an environment box
behind all cloudlayers. Specify "-" for no farbox, or a file base name.
A base name of "env/test" would look for files "env/test_rt.tga",
"env/test_lf.tga", "env/test_ft.tga", "env/test_bk.tga",
"env/test_up.tga", "env/test_dn.tga" to use as the right / left / front
/ back / up / down sides.
**cloudheight**: controls apparent curvature of the cloud layers -
**<cloudheight>** controls apparent curvature of the cloud layers -
lower numbers mean more curvature (and thus more distortion at the
horizons). Higher height values create "flatter" skies with less horizon
distortion. Think of height as the radius of a sphere on which the
clouds are mapped. Good ranges are 64 to 256. The default value is 128.
**nearbox**: Specified as farbox, to be alpha blended ontop of the
**<nearbox>** Specified as farbox, to be alpha blended ontop of the
clouds. This has not be tested in a long time, so it probably doesn't
actually work. Set to "-" to ignore.
### Example Sky Material {#example_sky_material}
```
   // Vera Visions Material
   {
       qer_editorImage textures/skies/dune.tga
       skyParms textures/skies/dune/bg 256 -
       noPicMip
       noMipmaps
       
       surfaceParm sky
       surfaceParm noimpact
       surfaceParm nolightmap
       surfaceParm nodlight
       {
           program skybox
           map $cube:textures/skies/dune/bg
           map textures/skies/clouds/dunecloud.tga
           map textures/skies/clouds/dunecloud_layer.tga
       }
   }
```
`   // Vera Visions Material`
`   {`
`       qer_editorImage textures/skies/dune.tga`
`       skyParms textures/skies/dune/bg 256 -`
`       noPicMip`
`       noMipmaps`
`       `
`       surfaceParm sky`
`       surfaceParm noimpact`
`       surfaceParm nolightmap`
`       surfaceParm nodlight`
`       {`
`           program skybox`
`           map $cube:textures/skies/dune/bg`
`           map textures/skies/clouds/dunecloud.tga`
`           map textures/skies/clouds/dunecloud_layer.tga`
`       }`
`   }`

View file

@ -13,10 +13,10 @@ texture it for other purposes, too.
### See also {#see_also}
- [diffusemap](diffusemap.md)
- [normalmap](normalmap.md)
- [fullbrightmap](fullbrightmap.md)
- [uppermap](uppermap.md)
- [lowermap](lowermap.md)
- [reflectmask](reflectmask.md)
- [reflectcube](reflectcube.md)
- [diffusemap](diffusemap)
- [normalmap](normalmap)
- [fullbrightmap](fullbrightmap)
- [uppermap](uppermap)
- [lowermap](lowermap)
- [reflectmask](reflectmask)
- [reflectcube](reflectcube)

View file

@ -8,9 +8,9 @@ by the renderer. A few keywords will only apply to any one of them.
All surfaceparm keywords are preceded by the word surfaceparm as
follows:
```
surfaceparm **fog**
```
:
: surfaceparm **fog**
### Behaviour Keywords {#behaviour_keywords}

View file

@ -2,7 +2,7 @@
## tcmod
### Syntax
**tcMod <func> [...]**
**tcMod <func> &lt;…&gt;**
### Overview
@ -21,12 +21,10 @@ precision, and that can disturb other operations.
Texture coordinates are modified in the order in which **tcMods** are
specified. In otherwords, if you see:
```
 tcMod scale 0.5 0.5
 tcMod scroll 1 1
```
` tcMod scale 0.5 0.5`
` tcMod scroll 1 1`
Then the texture coordinates will be **scaled** then **scrolled**.
Then the texture coordinates will be **scaled then**scrolled'''.
### Functions {#functions}
@ -81,20 +79,20 @@ Stretches the texture coordinates with the given function. Stretching is
defined as stretching the texture coordinate away from the center of the
polygon and then compressing it towards the center of the polygon.
**base**: A base value of one is the original dimension of the texture
**<base>**: A base value of one is the original dimension of the texture
when it reaches the stretch stage. Inserting other '''values positive or
negative in this variable will produce unknown effects.
**amplitude**: This is the measurement of distance the texture will
**<amplitude>**: This is the measurement of distance the texture will
stretch from the base size. It is measured, like scroll, in textures. A
value of 1 here will double the size of the texture at its peak.
**phase**: See the explanation for phase under the deform vertexes
**<phase>**: See the explanation for phase under the deform vertexes
keyword.
**frequency**: this is wave peaks per second.
**<frequency>**: this is wave peaks per second.
**func**:
**<func>**:
- **Sin**: the texture expands smoothly to its peak dimension and then
shrinks smoothly to its valley dimension in a flowing manner.
@ -122,13 +120,13 @@ forth churning and swirling effect on the texture.
The parameters for this are defined as follows:
- **base**: Currently undefined.
- **amplitude**: This is essentially the intensity of the
- **<base>**: Currently undefined.
- **<amplitude>**: This is essentially the intensity of the
disturbance or twisting and squiggling of the texture.
- **phase**: See the explanation for phase under the
- **<phase>**: See the explanation for phase under the
[deformvertexes](DeformVertexes)
keyword.
- **freq**: Frequency. This value is expressed as repetitions or
- **<freq>**: Frequency. This value is expressed as repetitions or
cycles of the wave per second. A value of one would cycle once per
second. A value of 10 would cycle 10 times per second. A value of
0.1 would cycle once every 10 seconds.

View file

@ -15,7 +15,7 @@ Any .vvm consists of multiple input files. These can come in the
following formats:
- SMD (GoldSrc & Source)
- MD5MESH and MD5ANIM (id Tech 4)
- MD5MESH and MD5ANIM (idTech 4)
- FBX
- IQE
- OBJ (no animations)

View file

@ -1,289 +0,0 @@
# Networking
## Preface
Networking in FTEQW is an extension of the design decisions made for QuakeWorld. All you have to know is that we use NACK feedback to network the changes from client to server. There are a lot of other great resources that document the QuakeWorld protocol, so we will focus on the additions that matter here.
## Leveraged by FTE QuakeWorld
In Nuclide, we make heavy use of custom entity networking. In FTE, you can set the entity field `.SendEntity` and `.SendFlags` to control network updates for the given entity. You have to implement your own `.SendEntity` function that communicates:
1. The type of entity (so the client can interpret it once it arrives)
2. The type of information that has changed (you'll see references to `flChanged` in code a lot)
3. The data that itself has to be networked manually, with fixed and agreed upon size.
## Entity updates within Nuclide
To see the type of entity updates we handle internally in Nuclide, look no further than `src/shared/entities.h`. For one-time event updates, you can check `src/shared/events.h`.
Generally, those entity updates happen and are controlled by these three common methods that are implemented by any entity class that chooses to override networking:
- EvaluateEntity
- SendEntity
- ReceiveEntity
Let's go over them, one by one.
### EvaluateEntity
Called once every frame. This is where we check if anything has changed. We commonly use the macros `EVALUATE_FIELD( field, changedFlag )` and `EVALUATE_VECTOR( field, xyz, changedFLAG )` to test if any particular field has changed since last frame.
For these macros to work, your entity needs to have declared attributes with the `PREDICTED_INT( x ) `, `PREDICTED_FLOAT( x )`, `PREDICTED_VECTOR( x )`, `PREDICTED_BOOL( x )`, `PREDICTED_ENTITY( x )`, or `PREDICTED_STRING( x )` macros.
Once the frame ends, we will network the differences in the next method.
### SendEntity
As already mentioned in the FTE section, this is where the actual networking gets done.
This is where we have helper macros for dealing with sending and flagging the updates reliably.
- SENDENTITY_BYTE( field, changedFlag )
- SENDENTITY_SHORT( field, changedFlag )
- SENDENTITY_INT( field, changedFlag )
- SENDENTITY_FLOAT( field, changedFlag )
- SENDENTITY_STRING( field, changedFlag )
- SENDENTITY_COORD( field, changedFlag )
- SENDENTITY_ANGLE( field, changedFlag )
- SENDENTITY_ENTITY( field, changedFlag )
Most of them are self explanatory, but in the case of `SENDENTITY_ANGLE` we actually network a short, since we don't need full floating point precision for most types of angles. Keep that in mind if you're running into precision issues.
### ReceiveEntity
Method is called on the client-side for each respective entity class we want to handle.
First however, we need to talk about the handler.
We allow any game to implement their own handler for entity updates in the function `ClientGame_EntityUpdate(float type, bool isNew)` which you're encouraged to implement. This is where we check for a handler first, then Nuclide will attempt to handle it instead.
We usually just read the flags field (which we assume is a float for most entities) and then call the `ReceiveEntity(float isNew, float flChanged)` method, in which we'll use the following macros to help read networked information:
- READENTITY_BYTE( field, changedFlag )
- READENTITY_SHORT( field, changedFlag )
- READENTITY_INT( field, changedFlag )
- READENTITY_FLOAT( field, changedFlag )
- READENTITY_STRING( field, changedFlag )
- READENTITY_COORD( field, changedFlag )
- READENTITY_ANGLE( field, changedFlag )
- READENTITY_ENTITY( field, changedFlag )
As you can tell, it's the same setup as in `SendEntity` - which is by design. This will make keeping fields in check much easier. A simple find-and-replace of the word **SEND** with **READ** will do the job most of the time.
We'd like to streamline a lot of this further, so this may be subject to change.
## Event updates
The server will use the FTE QuakeWorld supported `SVC_CGAMEPACKET` packet type to network events.
An example of such an event is as follows, it can be called at any time, anywhere on the server:
```
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_TEST);
WriteByte(MSG_MULTICAST, 123);
multicast([0,0,0], MULTICAST_ALL_R);
```
This event will then be sent to **ALL** clients, **reliably** as indicated by the **MULTICAST_ALL_R**. On the client-side, we will handle any event in `Event_Parse(float eventType)` that you are not handling yourself within `ClientGame_EventParse(float eventType)`.
From there you can use the builtins `readbyte()`, `readshort()` etc. which are also used under-the-hood in the macros for entity updates above. Yes, ideally this should be more consistent and nicer to use in the future - but we left it pretty stock in this case.
## Client to Server communication
There's a few different means of networking things to the server as a client.
### sendevent
`sendevent()` is the builtin you call from the client game to communicate, reliably, to
the server game running on the other end.
The first parameter of `sendevent()` specifies the function to call in server game:
```
sendevent( "Myfunction", "" );
```
However, it will not look for `void() Myfunction` on the server game, there is a prefix
reserved for all sendevent calls. That one is `CSEv`.
So in reality, the above command will execute this on the server game:
void CSEv_Myfunction ( void ) { }
Now, what about that second parameter?
.. , "" );
Well, `sendevent()` has the ability to send data. 6 arguments can be passed, max.
That second parameter string specifies the type of data you want to send.
For example, you want to ask the server to set the health of a player to a
specific value...
Client game:
```
sendevent( "SetPlayerHealth", "f", 124 );
```
Server game:
```
void CSEv_SetPlayerHealth_f ( float h ) {
self.health = h; // naughty! clients can spoof these packets...
}
```
As you can see, the `f` indicates the type float.
`s` would indicate a string.
`v` would indicate a vector.
`i` would indicate an integer.
`e` would indicate an entity (more about that in the last chapter).
The second parameter specifying the arguments will append to the name of the
function you're trying to call.
Client game:
```
sendevent( "SetColorAndName", "fffs", 255, 0, 128, "Tommy" );
```
Server game:
```
void CSEv_SetColorAndName_fffs ( float r, float g, float b, string name ) {
self.colormod = [r, g, b];
self.netname = name;
}
```
..is what a longer sendevent with multiple arguments would look like.
6 arguments are the maximum. This is because QuakeC supports 8 arguments max per
function call. If you, however, only want to send floats and require more than
6 arguments, you can store them inside vectors:
Client game:
```
vector v1 = [ myfloat1, myfloat2, myfloat3 ];
vector v2 = [ myfloat4, myfloat5, myfloat6 ];
vector v3 = [ myfloat7, myfloat8, myfloat9 ];
vector v4 = [ myfloat10, myfloat11, myfloat12 ];
vector v5 = [ myfloat13, myfloat14, myfloat15 ];
vector v6 = [ myfloat16, myfloat17, myfloat18 ];
sendevent( "Bah", "vvvvvv", v1, v2, v3, v4, v5, v6 );
```
Server game:
```
void CSEv_Bah_vvvvvv ( vector v1, vector v2, vector v3, vector v4, vector v5,
vector v6 ) {
myfloat1 = v1[0];
myfloat2 = v1[1];
myfloat3 = v1[2];
myfloat4 = v2[0];
...
}
```
#### Note about sendevent() and entities
If you pass an entity via sendevent, it'll in reality send only the entnum.
The entnum is the essentially the entity-id.
If the entity does not exist via the server game (like, it has been removed since or
is a client-side only entity) then the entity parameter on the server game function
call will return `world` aka 0/__NULL__.
For protective reasons, entities that are removed have their entnums reserved
for a specific amount of time before being able to be used again.
Player entities, for example, will allow their entnums to be recycled after 2
seconds. Any other entity its entnum will be reusable after only half a second.
This should avoid most entnum conflicts.
Basically, during this time, the parameter will not return `world`.
**Note**: This is entirely unreliable behaviour.
Check if the .classname is **valid** on the server before doing anything fancy on it.
### clientcommand
Whenever the client issues a `cmd` based command, say: `cmd say foobar` in console or via the client game in general, the server will forward it to the active NSGameRules based game rule class within the `ClientCommand(NSClient client, string command)` method. This is useful for things you do every once in a while.
## ServerInfo
ServerInfo keys can be set by server admins, or the game-logic. Those keys are networked to clients inside the game, as well as outside of the game. They can be queried through tools like `qstat` or `GameSpy`.
### Setting ServerInfo
#### Console (admins/debugging)
When in the console, you can set the key `foo` to the value `bar` like this:
```
serverinfo foo bar
```
#### Server-side code
The same thing can be done in the **SSQC** side with this line of code:
```
forceinfokey(world, "foo", "bar");
```
### Retrieving ServerInfo
#### Console (Debugging)
At any time, the server and clients can enter `serverinfo` by itself into the console, and it will print out all known ServerInfo keys.
Some of the keys are set by the engine, noteworthy ones include `*bspversion` and `mapname`. I encourage you try it and see if there's any keys that seem interesting to you and to make note of them.
#### Client/server-side code
We have two builtins to query ServerInfo keys from the client-side. `serverkey` and `serverkeyfloat`. Their usage goes like this:
```
string maybeBar = serverkey("foo");
float someNum = serverkeyfloat("maxclients");
```
## UserInfo
UserInfo keys are means of allowing clients (and the server, more on that later) to communicate bits of information about themselves to the server and all other clients. Much like **ServerInfo**. Those are networked regardless of whether another client is in the same **PVS**.
### Setting UserInfo
#### Console (clients)
Clients can set their own custom infokey data at any time, using the `setinfo` console command. For example: `setinfo foo bar` will set the infokey `foo` to the value of `bar`.
#### Server-side code
The server can also assign its own infokeys to a player. These can be overriden by the client at any given time - **unless the server prefixes them** with an asterisk. Here is an example: `forceinfokey(somePlayer, "*team", "1");`
Client infokeys are visible to all other clients. That's how most of the scoreboard is filled in with information. So be careful about the type of data you store in them. Storing passwords or other sensitive information is not recommended.
### Retrieving UserInfo
#### Client-side code
On the client-side, if you wanted to query your own players' specific infokey value, you can query it like this:
```
float myTeam = getplayerkeyfloat(player_localnum, "*team");
```
And if you want to query a specific player entity, this is perfectly valid:
```
string theirName = getplayerkey(playerEnty.entnum-1, "name");
```
As to why we have to subtract 1 from an entity its entnum for this, is because the clients in the infokey table start at **0**, and player entities on the server start at **1**; *0 being reserved for `world`*.
#### Server-side code
The server can then read any given infokey on a given client like so:
```
string value = infokey(someplayer, "foo");
float otherValue = infokeyf(someplayer, "somenumber");
```

View file

@ -126,15 +126,4 @@ destruction.
this entity breaks.
- **breakable_model <string>**: Which models to spawn when it breaks.
- **breakable_count <int>**: The amount of models it'll spawn upon
breaking.
- **surfaceprop <string>**: Surfaceprop override for the object.
## Physics Object Commands {#physcommands}
These are only relevant for when you want to use a phyics object, or rather an object that's handled by NSPhysicsEntity, such as prop_physics.
- **mass <float>**: Mass of the object, in kilograms.
- **volume <float>**: Volume of the object, in cubic meters.
- **inertia <float>**: Inertia multiplier.
- **damping <float>**: Linear movement damping multiplier.
- **rotdamping <float>**: Angular movement damping multiplier.
breaking.

View file

@ -1,7 +1,12 @@
# Sound: EFX {#EFX}
## EAX
# Sound: EAX
Creative Technology's **Environmental Audio Extensions**, also known as **EAX**, attempted to create more ambiance within video games by more accurately simulating a real-world audio environment.
The release of Windows Vista deprecated the DirectSound3D API on which EAX relied on in 2007, so Creative Technology encouraged the move to OpenAL's EFX.
Due to the release of Windows Vista which deprecated the DirectSound3D API EAX was based on in 2007, Creative discouraged EAX implementation in favor of its [OpenAL](OpenAL.md)-based EFX equivalent.
EFX is fully supported in **FTEQW** and exposed via user-friendly entities and scripting language in **Nuclide**.
## See also
* [EFX](EFX.md)
* [OpenAL](OpenAL.md)

View file

@ -1,18 +1,16 @@
# Sound: EFX {#EFX}
## EFX
# Sound: EFX
EFX is a system in [OpenAL](OpenAL.md) that delivers high quality sound reverberation. It is the successor to Creative's [Environmental Audio Extensions](EAX.md).
**Nuclide** offers abstraction for new and old entities relying on **digital signal processing**.
## Entities interacting with EFX
## Entities
**env_sound** is most commonly used to change the environmental sound processing of a room/area.
In GoldSrc, it'll specify which enumeration of DSP preset to use for audio playback, in Nuclide however we just map it to a definitions file in the filesystem. See **EFX files** below.
In GoldSrc, it'll specify which enumeration of DSP preset to use for audio playback, in Nuclide however we just map it to a file in the filesystem.
## EFX defintion files
## EFX files
Entities that specify a EFX type, usually want to load one from a file.
@ -46,17 +44,15 @@ Here's an example one, `efx/city.efx`:
Most of the parameters are self explanatory.
## Console Variables
## Debug cvars
With the cvar `s_al_debug` set to 1 you'll get an overlay of information about which EFX file is currently being used, as well as what every single parameter is set to.
With the cvar `>s_al_debug` you'll get an overlay of information about which EFX file is currently being used, as well as what every single parameter is set to.
You can refresh EFX definitions with a simple map restart.
You can refresh EFX definitions with a map restart.
## Legacy translation table
*This section describes behaviour specific to converting entities from Half-Life based levels into the Nuclide environment.*
Here you can see which **efx file** is responsible for handling a legacy **env_sound** room-type.
Here you can see which **.efx file** is responsible for handling a legacy **env_sound** room-type.
**roomtype ID**|**EFX file**
:-----:|:-----:

View file

@ -1,9 +1,9 @@
# Sound: soundDef
Nuclide mimics the sound defintion spec from **id Tech 4** somewhat, albeit
Nuclide mimics the sound defintion spec from **idTech 4** somewhat, albeit
with some changes/enhancements. We call them **soundDefs**.
**The elevator pitch**: To allow for more control over the sounds than what was previously
allowed in id Tech engines we also allow designers to drop sounds into
allowed in idTech engines we also allow designers to drop sounds into
the game without having to set some common parameters every time.
Instead of directly calling which .wav or .ogg file to play, we tell it
@ -79,7 +79,7 @@ This one has multiple sound files specified, which means that **Nuclide** will r
## Power to the developer {#power_to_the_developer}
Unlike the implementation in **id Tech 4**, all of the sound defs handling
Unlike the implementation in **idTech 4**, all of the sound defs handling
is done in the game-logic and is therefore exposed to all developers.
Some mods may want to hook AI callbacks into the system, or create
visual effects when commands are called by a sound def. The

View file

@ -1,15 +0,0 @@
# The XR Subsystem
To support XR (which is the support for Virtual, Augmented or Mixed Reality output) we have a few routines that help deal with this.
## Classes related to XR
We have 3 NSXRInput class instances per NSClient class, which itself belongs to a NSXRSpace.
### Head
The head is an NSXRInput of type XR_INPUT_HEAD. Yes, a head is just like any other XR compatible controller. It has a gyro and it potentially has buttons the user can press.
### Hands
We have two hands available, that will identify themselves as XR_INPUT_LEFT or XR_INPUT_RIGHT respectively. These are your primary tools for interacting with the 3D world.

View file

@ -19,7 +19,7 @@ Make sure you're running the latest version of FTEQW.
If your entire engine/binary crashes to desktop or whatever, it's an FTE bug.
Contact #fte at irc.quakenet.org
If you crash to console, contact #nuclide at irc.libera.chat
If you crash to console, contact #freecs at irc.libera.chat
Notes
=======================================

File diff suppressed because it is too large Load diff

View file

@ -878,11 +878,7 @@ INPUT = src/ \
Documentation/Main.md \
Documentation/Building.md \
Documentation/Launching.md \
Documentation/DedicatedServer.md \
Documentation/Filesystem.md \
Documentation/Networking.md \
Documentation/Bots/BotOverview.md \
Documentation/EntityGuide.md \
Documentation/Classes.md \
Documentation/Materials/MatOverview.md \
Documentation/Materials/MatCommands.md \
@ -891,11 +887,8 @@ INPUT = src/ \
Documentation/Materials/MatShaders.md \
Documentation/Materials/MatGoldSrc.md \
Documentation/Shaders/ \
Documentation/Constants.md \
Documentation/EntityDef.md \
Documentation/Surf_data.md \
Documentation/Prop_data.md \
Documentation/MapTweaks.md \
Documentation/Sound/ \
Documentation/Models/ \
Documentation/History.md \
@ -1262,8 +1255,6 @@ HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE = DARK
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a color-wheel, see

108
README.md
View file

@ -1,45 +1,101 @@
# ![FTE Logo](Documentation/fte.svg) Nuclide - Software Development Kit
Software Development Kit, built around id Technology with focus on advanced features and
Software Development Kit, built around idTech with focus on advanced features and
clean-room implementations of true-and-tested game-logic frameworks.
*It's been used to ship a commercial product. So it's proven to some extent.*
It's been used to ship a commercial product. So it's proven to some extent.
All of this is written in QuakeC, but there's also some GLSL and shell scripts
in here. If you and your team are unfamilar with any of these, you may want something else.
in here. If you and our team is unfamilar with any of these, you may want something else.
You can integrate an engine (FTE) and level design tool (WorldSpawn) directly from this tree. *See the 'Building' section for details.*
They're the projects actually based on idTech (GPL) code and therefore are in their own repositories.
If you're unfamilar with any of these, you may want something else.
**All the code here is ISC-Licensed.**
It's provided here under the terms of that license. You can have it - do what you like with it. Please don't barge in and demand help, support or hand-holding assistance unless you're going to offer us a good rate ($$$) for it. This is all provided AS-IS. It works for plenty of people, but might not for you!
## Features
* Reference codebase for first-person shooters in FTEQW, from scratch
* Has support for 100+ entities found in games such as Quake, Half-Life and Source SDK
* Support for player movement prediction and weapon prediction, for smooth online play
* AI system that's designed to be extendable for both singleplayer and multiplayer (BotLib)
* Waypoint editor
* UI toolkits for both 2D and in-world 3D drawing, like you'd see in Doom III
* Plugins system so that modders can write external plugins that hook into virtually every game
* Plenty of example projects available
- The missing SDK for engines like FTEQW
- Support for client-side predicted movement, weaponry and vehicles
- Documented APIs for everything you need to interface with the engine
- APIs and Frameworks for managing updates, mods, servers, and platform specific features
- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games
- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system
- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides
- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces
- Designed to be familar to developers coming from GoldSrc/Source
- VR/XR aware codebase
- All permissively licensed
## Building
The 'build_engine.sh' script checks out the **FTE Subversion** repository and keeps it up to date,
while also building binaries that are crucial to running and building the game-logic
(which is all QuakeC, to re-iterate) and putting them into the ./bin directory.
Launch the engine with the 'nuclide' and 'nuclide-ds' scripts.
## Documentation
On Windows, please use cygwin, MSYS2 or something for a sensible experience. If that doesn't work you can always resort to WSL. We have no plans on supporting Windows natively, as we don't do development on Windows.
You can find up-to-date documentation over at https://developer.vera-visions.com/
The 'build_editor.sh' script clones the **WorldSpawn** Git repository and installs them into the ./bin directory.
Use the 'worldspawn' and 'vmap' scripts to launch to ensure consistency.
This documentation is built entirely from this repository using doxygen.
You do not need to be on-line to view the documentation.
The 'build_game.sh' script will build the game-logic for the games included
using the QuakeC compiler present in the ./bin directory.
If the compiler isn't found it will ask you to build them. If you are running an operating system that has 'fteqcc' in its repositories, it may very well be out of date.
You can build the HTML documentation by running `doxygen` inside the root
of the repository. The output is located under `Documentation/html/index.html`
For best results, symlink the desired scripts into your home directory's bin folder.
The scripts are designed to be aware of their actual location in the filesystem.
## Packages
This is a development environment/framework. There are will be no binary packages.
## Dependencies
Rough list of dependencies for the average Linux system.
On some systems the names may slightly differ. These should be correct for OpenSUSE.
### Engine
* subversion
* gmake
* gcc
* mesa-libGL-devel
* libgnutls-devel
* libopenal-devel
* libX11-devel
* libXcursor-devel
* libXrandr-devel
* libSDL2-devel (only if you pass BUILD_SDL2=1 to build_engine.sh)
For WinNT and Darwin systems it's recommended you use the SDL2 backend, but native backends
may be available in FTEQW.
The X development packages are obviously only a requirement for when you do not compile an SDL2 build on a UNIX-like system.
Slackware users generally don't need to install anything, unless they explicitly diasable BUILD_ENGINE_DEPENDENCIES inside build.cfg.
### FFMPEG Plugin
* ffmpeg-4-libavformat-devel
* ffmpeg-4-libswscale-devel
You want this plugin if you want playback of a variety of media formats, including video decoding.
Building it can be disabled by editing build.cfg.
### Worldspawn Level Editor
* gcc-c++
* gtk2-devel
* gtkglext-devel
* libxml2-devel
* libjpeg8-devel
* minizip-devel
This is the only component that requires a C++ compiler.
Same as with Nuclide, don't bother us with support. It works for us but it may not work for you.
We cannot help you get other editors working for you. Generally you can use any .bsp format FTEQW supports anyway, so your choice of editor does not matter at all.
## Support
You can get personal support for Nuclide by negotiating a support contract with us. Reach out to marco@vera-visions.com if you want to know about our rates.
Join us in #nuclide on irc.libera.chat and chat if you're interested in using this in production.
**All this is provided to you for free and as-is otherwise.**
## Special Thanks
To id software and specifically John Carmack for having released the sources of
various works of id Technology under free licenses, without which a project like this would be unfeasible.
various idTech games under the GPL2 license, without which we would have no engine for Nuclide.
David Walton for **FTEQW** and the **FTEQCC** compiler, which is the brain of this SDK.
@ -48,7 +104,7 @@ Timothee Besset and the **GtkRadiant** contributors, as well as the NetRadiant t
![idTech Logo](Documentation/idtech.svg)
## License
Copyright (c) 2016-2023 Vera Visions L.L.C.
Copyright (c) 2016-2022 Vera Visions L.L.C.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above

View file

@ -1,13 +0,0 @@
FTEMANIFEST 1
NAME "Test Game"
GAME base
BASEGAME platform
BASEGAME base
// you don't really want to change these
RTCBROKER master.frag-net.com:27950
PROTOCOLNAME "Nuclide"
MAINCONFIG nuclide.cfg
DOWNLOADSURL ""
-exec platform_default.cfg

View file

@ -44,10 +44,8 @@ Camera_RunBob(__inout vector camera_angle)
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) {
} else if (pSeat->m_ePlayer.flags & FL_ONGROUND) {
pCamBob->m_flMove = clframetime * (pCamBob->m_flSpeed * 0.01);
} else {
pCamBob->m_flMove = 0.0f;
}
pCamBob->m_flTime = (pCamBob->m_flTime += pCamBob->m_flMove);

View file

@ -19,5 +19,17 @@ vector g_hudres;
struct
{
float temp;
/* hud.c */
int m_iHealthOld;
float m_flHealthAlpha;
int m_iArmorOld;
float m_flArmorAlpha;
int m_iAmmo1Old;
float m_flAmmo1Alpha;
int m_iAmmo2Old;
float m_flAmmo2Alpha;
int m_iAmmo3Old;
float m_flAmmo3Alpha;
int m_iPickupWeapon;
float m_flPickupAlpha;
} g_seatslocal[4], *pSeatLocal;

View file

@ -14,9 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
const float baseIconSize = 32.0;
const float baseIconPadding = 16.0;
/* main entry */
void
HUD_Init(void)
@ -27,24 +24,10 @@ HUD_Init(void)
void
HUD_Draw(void)
{
vector hudSize = g_view.GetHUDCanvasSize();
vector iconPos = g_view.GetHUDCanvasPos() + (hudSize / 2);
iconPos[1] = (hudSize[1] - baseIconSize) - baseIconPadding;
/* health, armor icons */
drawpic(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)), 0], "gfx/hud/health", [baseIconSize, baseIconSize], [1,1,1], 1.0f);
drawpic(iconPos + [(baseIconSize/2) + (baseIconPadding/2), 0], "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f);
/* ammo icon */
iconPos[0] = (hudSize[0] - baseIconSize) - baseIconPadding;
drawpic(iconPos, "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f);
Textmenu_Draw();
}
/* specatator main entry */
void
HUD_DrawSpectator(void)
{
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2024 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,6 +14,11 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void Util_ChangeClass(entity, string);
string Util_ExtensionFromString(string inputString);
string Util_ChatFormat(float playerNum, float teamNum, string chatMessage);
void
ClientGame_ModelEvent(float flTimeStamp, int iCode, string strData)
{
switch (iCode) {
default:
Event_ProcessModel(flTimeStamp, iCode, strData);
}
}

44
base/src/client/player.qc Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016-2022 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.
*/
void
Player_PreDraw(NSClientPlayer pl, int thirdperson)
{
/* Handle the flashlights... */
if (pl.gflags & GF_FLASHLIGHT) {
vector src;
vector ang;
if (pl.entnum != player_localentnum) {
src = pl.origin + pl.view_ofs;
ang = pl.v_angle;
} else {
src = pSeat->m_vecPredictedOrigin + [0,0,-8];
ang = view_angles;
}
makevectors(ang);
traceline(src, src + (v_forward * 8096), MOVE_NORMAL, pl);
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]);
} else {
float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight");
dynamiclight_set(p, LFIELD_ANGLES, ang);
dynamiclight_set(p, LFIELD_FLAGS, 3);
}
}
}

View file

@ -1,8 +1,10 @@
#pragma target fte_5768
//#pragma flag enable assumeint
#pragma progs_dat "../../csprogs.dat"
#define CSQC
#define CLIENT
#define NEW_INVENTORY
#includelist
/* first the engine, then nuclide headers for client/shared */
@ -22,17 +24,19 @@ defs.h
/* mod specific functions */
../shared/include.src
draw.qc
../../../base/src/client/draw.qc
init.qc
player.qc
entities.qc
camera.qc
cmds.qc
game_event.qc
camera.qc
viewmodel.qc
view.qc
hud.qc
hud_weaponselect.qc
scoreboard.qc
modelevent.qc
/* global client/shared code */
../../../src/client/include.src

48
base/src/client/view.qc Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016-2022 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.
*/
void
View_UpdateWeapon(player pl, entity vm, entity mflash)
{
/* only bother upon change */
if (pSeat->m_iLastWeapon == pl.activeweapon) {
return;
}
pSeat->m_iOldWeapon = pSeat->m_iLastWeapon;
pSeat->m_iLastWeapon = pl.activeweapon;
if (!pl.activeweapon) {
return;
}
/* hack, we changed the wep, move this into Game_Input/PMove */
Weapons_Draw(pl);
/* we forced a weapon call outside the prediction,
* thus we need to update all the net variables to
* make sure these updates are recognized. this is
* vile but it'll have to do for now */
SAVE_STATE(pl.w_attack_next);
SAVE_STATE(pl.w_idle_next);
SAVE_STATE(pl.viewzoom);
SAVE_STATE(pl.weapontime);
/* figure out when the attachments start. in FTE attachments for
* HLMDL are treated as bones. they start at numbones + 1 */
skel_delete(mflash.skeletonindex);
mflash.skeletonindex = skel_create(vm.modelindex);
pSeat->m_iVMBones = skel_get_numbones(mflash.skeletonindex) + 1;
}

View file

@ -84,7 +84,7 @@ Viewmodel_CalcBob(void)
pViewBob->m_flBob2 = bound(-7, flBob, 4);
/* make sure it's adjusted for scale */
pViewBob->m_flBob *= autocvar_cg_viewmodelScale;
pViewBob->m_flBob *= autocvar_r_viewmodelscale;
}
void

1
base/src/progs.src Normal file → Executable file
View file

@ -1,3 +1,2 @@
#pragma sourcefile client/progs.src
#pragma sourcefile server/progs.src
#pragma sourcefile menu/progs.src

64
base/src/server/client.qc Normal file
View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016-2022 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.
*/
/* called every input frame */
void
Game_RunClientCommand(void)
{
player pl = (player)self;
pl.Physics_Run();
}
/* custom chat packet */
void
SV_SendChat(entity sender, string msg, entity eEnt, float fType)
{
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM);
WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1);
WriteByte(MSG_MULTICAST, sender.team);
WriteString(MSG_MULTICAST, msg);
if (eEnt) {
msg_entity = eEnt;
multicast([0,0,0], MULTICAST_ONE);
} else {
multicast([0,0,0], MULTICAST_ALL);
}
localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg));
}
/* client cmd overrides happen here */
void
Game_ParseClientCommand(string cmd)
{
tokenize(cmd);
if (argv(0) == "say") {
SV_SendChat(self, argv(1), world, 0);
return;
} else if (argv(0) == "say_team") {
entity a;
for (a = world; (a = find(a, ::classname, "player"));) {
if (a.team == self.team) {
SV_SendChat(self, argv(1), a, 1);
}
}
return;
}
clientcommand(self, cmd);
}

View file

@ -13,3 +13,27 @@
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* generic function that applies damage, pain and suffering */
void
Damage_Apply(entity t, entity c, float dmg, int w, damageType_t type)
{
CGameRules rules = (CGameRules)g_grMode;
rules.DamageApply(t, c, dmg, w, type);
}
/* physical check of whether or not we can trace important parts of an ent */
float
Damage_CheckTrace(entity t, vector vecHitPos)
{
CGameRules rules = (CGameRules)g_grMode;
return rules.DamageCheckTrace(t, vecHitPos);
}
/* even more pain and suffering, mostly used for explosives */
void
Damage_Radius(vector org, entity attacker, float dmg, float r, int check, int w)
{
CGameRules rules = (CGameRules)g_grMode;
rules.DamageRadius(org, attacker, dmg, r, check, w);
}

View file

@ -16,13 +16,5 @@
#include "gamerules.h"
#include "items.h"
// stubs for spawning
void info_player_deathmatch(void)
{
}
void info_player_start(void)
{
}
#include "flashlight.h"
#include "player.h"

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,4 +14,4 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void CheatersLament(NSClientPlayer, vector, float, float);
void Flashlight_Toggle(void);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,23 +14,22 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
void
NSDebris::NSDebris(void)
Flashlight_Toggle(void)
{
m_strImpactDecal = __NULL__;
}
if (cvar("sv_playerslots") != 1) {
if (cvar("mp_flashlight") != 1) {
return;
}
}
void
NSDebris::Touch(entity touchingEnt)
{
if (m_strImpactDecal)
DecalGroups_Place(m_strImpactDecal, origin);
}
if (self.health <= 0) {
return;
}
void
NSDebris::SetImpactDecal(string impactDecal)
{
m_strImpactDecal = impactDecal;
if (self.gflags & GF_FLASHLIGHT) {
self.gflags &= ~GF_FLASHLIGHT;
} else {
self.gflags |= GF_FLASHLIGHT;
}
}
#endif

View file

@ -16,8 +16,6 @@
class GameRules:CGameRules
{
void GameRules(void);
virtual void(NSClientPlayer) PlayerConnect;
virtual void(NSClientPlayer) PlayerDisconnect;
virtual void(NSClientPlayer) PlayerKill;
@ -30,8 +28,6 @@ class GameRules:CGameRules
class SingleplayerRules:GameRules
{
void SingleplayerRules(void);
/* client */
virtual void(NSClientPlayer) PlayerSpawn;
virtual void(NSClientPlayer) PlayerDeath;
@ -39,11 +35,9 @@ class SingleplayerRules:GameRules
class MultiplayerRules:GameRules
{
int m_iIntermission;
int m_iIntermissionTime;
void MultiplayerRules(void);
virtual void(void) FrameStart;
/* client */

View file

@ -14,12 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
GameRules::GameRules(void)
{
}
void
GameRules::LevelDecodeParms(NSClientPlayer pp)
{
@ -105,11 +99,5 @@ GameRules::PlayerDisconnect(NSClientPlayer pl)
void
GameRules::PlayerKill(NSClientPlayer pl)
{
Damage_Apply(pl, pl, pl.health, 0, DMG_SKIP_ARMOR);
Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR);
}
void
Game_Worldspawn(void)
{
}

View file

@ -14,12 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
MultiplayerRules::MultiplayerRules(void)
{
}
void
MultiplayerRules::FrameStart(void)
{
@ -59,6 +53,7 @@ MultiplayerRules::PlayerDeath(NSClientPlayer pl)
pl.SetSolid(SOLID_NOT);
pl.SetModelindex(0);
pl.takedamage = DAMAGE_NO;
pl.gflags &= ~GF_FLASHLIGHT;
pl.armor = pl.activeweapon = pl.g_items = 0;
pl.think = PutClientInServer;
@ -109,21 +104,12 @@ MultiplayerRules::ConsoleCommand(NSClientPlayer pp, string cmd)
tokenize(cmd);
switch (argv(0)) {
case "bot_add":
Bot_AddQuick();
break;
default:
return (0);
}
return (1);
}
void
Game_InitRules(void)
{
g_grMode = spawn(MultiplayerRules);
if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) {
g_grMode = spawn(SingleplayerRules);
} else {
g_grMode = spawn(MultiplayerRules);
}
}

View file

@ -14,18 +14,13 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
SingleplayerRules::SingleplayerRules(void)
{
}
void
SingleplayerRules::PlayerDeath(NSClientPlayer pl)
{
pl.movetype = MOVETYPE_NONE;
pl.solid = SOLID_NOT;
pl.takedamage = DAMAGE_NO;
pl.gflags &= ~GF_FLASHLIGHT;
pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0;
pl.health = 0;

View file

@ -21,12 +21,11 @@ class item_pickup:NSRenderableEntity
int m_iClip;
int m_iWasDropped;
int id;
void item_pickup(void);
void(void) item_pickup;
virtual void Spawned(void);
virtual void Touch(entity);
virtual void SetItem(int i);
virtual void Respawn(void);
virtual void SetFloating(int);
virtual void PickupRespawn(void);
virtual void(void) Spawned;
virtual void(entity) Touch;
virtual void(int i) SetItem;
virtual void(void) Respawn;
virtual void(int) SetFloating;
};

View file

@ -14,64 +14,75 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void item_pickup::Touch(entity eToucher)
void
item_pickup::Touch(entity eToucher)
{
player pl = (player)eToucher;
if (eToucher.classname != "player") {
return;
}
/* don't allow players inside vehicles to pick anything up by accident */
if (eToucher.flags & FL_INVEHICLE || pl.vehicle) {
return;
}
/* don't remove if AddItem fails */
if (Weapons_AddItem((player)eToucher, id, m_iClip) == FALSE) {
if (Weapons_AddItem((NSClientPlayer)eToucher, id, m_iClip) == FALSE) {
return;
}
Logging_Pickup(eToucher, this, __NULL__);
Sound_Play(other, CHAN_ITEM, "weapon.pickup");
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
#ifdef WASTES
Sound_Play(eToucher, CHAN_ITEM, "item_weapon.pickup");
#endif
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
Destroy();
} else {
Disappear();
ScheduleThink(PickupRespawn, 30.0f);
ScheduleThink(Respawn, 30.0f);
}
}
void item_pickup::SetItem(int i)
void
item_pickup::SetItem(int i)
{
id = i;
m_oldModel = Weapons_GetWorldmodel(id);
SetModel(GetSpawnModel());
SetSize([-16,-16,0], [16,16,16]);
Respawn();
}
void item_pickup::SetFloating(int i)
void
item_pickup::SetFloating(int i)
{
m_bFloating = rint(bound(0, m_bFloating, 1));
}
void
item_pickup::PickupRespawn(void)
{
Respawn();
Sound_Play(this, CHAN_ITEM, "item.respawn");
}
void item_pickup::Respawn(void)
item_pickup::Respawn(void)
{
SetSolid(SOLID_TRIGGER);
SetOrigin(GetSpawnOrigin());
botinfo = BOTINFO_WEAPON;
/* At some points, the item id might not yet be set */
if (GetSpawnModel()) {
SetModel(GetSpawnModel());
if (m_oldModel) {
SetModel(m_oldModel);
}
SetSize([-16,-16,0], [16,16,16]);
ReleaseThink();
if (!m_iWasDropped) {
m_iClip = -1;
} else {
if (time > 30.0f)
Sound_Play(this, CHAN_ITEM, "item.respawn");
}
if (!m_bFloating) {
DropToFloor();
SetMovetype(MOVETYPE_TOSS);
@ -82,11 +93,12 @@ void
item_pickup::Spawned(void)
{
super::Spawned();
Sound_Precache("item.respawn");
Sound_Precache("weapon.pickup");
#ifdef WASTES
Sound_Precache("item_weapon.pickup");
#endif
}
void item_pickup::item_pickup(void)
void
item_pickup::item_pickup(void)
{
}

18
base/src/server/player.h Normal file
View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2016-2022 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.
*/
void Player_UseDown(void);
void Player_UseUp(void);

127
base/src/server/player.qc Normal file
View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2016-2022 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.
*/
/*
====================
UseWorkaround
====================
*/
void
UseWorkaround(entity eTarget)
{
eActivator = self;
entity eOldSelf = self;
self = eTarget;
self.PlayerUse();
self = eOldSelf;
}
void
UnUseWorkaround(entity eTarget)
{
eActivator = self;
entity eOldSelf = self;
self = eTarget;
if (self.PlayerUseUnpressed)
self.PlayerUseUnpressed();
self = eOldSelf;
}
/*
====================
Player_UseDown
====================
*/
void
Player_UseDown(void)
{
vector vecSrc;
player pl = (player)self;
if (self.health <= 0) {
return;
} else if (!(self.flags & FL_USE_RELEASED)) {
return;
}
makevectors(self.v_angle);
vecSrc = self.origin + self.view_ofs;
int oldmask = self.hitcontentsmaski;
self.hitcontentsmaski = CONTENTBITS_POINTSOLID;
traceline(vecSrc, vecSrc + (v_forward * 64), MOVE_HITMODEL, self);
self.hitcontentsmaski = oldmask;
if (trace_ent.PlayerUse) {
self.flags &= ~FL_USE_RELEASED;
UseWorkaround(trace_ent);
pl.last_used = trace_ent;
/* Some entities want to support Use spamming */
if (!(self.flags & FL_USE_RELEASED)) {
Sound_Play(self, CHAN_ITEM, "player.use");
}
} else {
Sound_Play(self, CHAN_ITEM, "player.use_denied");
self.flags &= ~FL_USE_RELEASED;
}
}
/*
====================
Player_UseUp
====================
*/
void
Player_UseUp(void) {
player pl = (player)self;
if (!(self.flags & FL_USE_RELEASED)) {
UnUseWorkaround(pl.last_used);
pl.last_used = world;
self.flags |= FL_USE_RELEASED;
}
}
void Weapons_Draw(NSClientPlayer);
void
CSEv_PlayerSwitchWeapon_i(int w)
{
player pl = (player)self;
#ifdef WASTES
if (pl.gflags & GF_IS_HEALING)
return;
#endif
if (pl.activeweapon != w) {
pl.activeweapon = w;
Weapons_Draw(pl);
}
}
void
Player_Precache(void)
{
searchhandle pm;
pm = search_begin("models/player/*/*.mdl", TRUE, TRUE);
for (int i = 0; i < search_getsize(pm); i++) {
precache_model(search_getfilename(pm, i));
}
search_end(pm);
}

View file

@ -4,13 +4,13 @@
#define QWSSQC
#define SERVER
#define NEW_INVENTORY
#includelist
/* engine, then nuclide headers & functions */
../../../src/shared/fteextensions.qc
../../../src/shared/defs.h
../../../src/server/defs.h
../../../src/botlib/botinfo.h
../../../src/gs-entbase/server.src
../../../src/gs-entbase/shared.src
@ -23,11 +23,18 @@ defs.h
../../../src/botlib/include.src
/* mod specific functions */
player.qc
spectator.qc
gamerules.qc
gamerules_singleplayer.qc
gamerules_multiplayer.qc
modelevent.qc
client.qc
server.qc
damage.qc
items.qc
flashlight.qc
modelevent.qc
spawn.qc
/* global server/shared code */
../../../src/server/include.src

35
base/src/server/server.qc Normal file
View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2016-2022 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.
*/
void
Game_InitRules(void)
{
if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) {
g_grMode = spawn(SingleplayerRules);
} else {
g_grMode = spawn(MultiplayerRules);
}
}
void
Game_Worldspawn(void)
{
Sound_Precache("player.use");
Sound_Precache("player.use_denied");
precache_model("models/player.mdl");
Weapons_Init();
Player_Precache();
}

41
base/src/server/spawn.qc Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2016-2022 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.
*/
void
info_player_start(void)
{
self.solid = SOLID_TRIGGER;
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
}
void
info_player_deathmatch(void)
{
self.solid = SOLID_TRIGGER;
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
}
void
info_player_team1(void)
{
self.classname = "info_player_deathmatch";
}
void
info_player_team2(void)
{
self.classname = "info_player_deathmatch";
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,13 +14,20 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/** This entity class represents spawnpoints.
*/
class NSSpawnPoint:NSPointTrigger
void
Game_SpectatorThink(void)
{
public:
void NSSpawnPoint(void);
}
/* overrides */
virtual void Respawn(void);
};
void
Game_SpectatorConnect(void)
{
}
void
Game_SpectatorDisconnect(void)
{
}

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2016-2022 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.
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -15,17 +15,20 @@
*/
void
NSSpawnPoint::NSSpawnPoint(void)
Animation_TimerUpdate(player pl, float ftime)
{
}
/*
=================
Animation_PlayerUpdate
Called every frame to update the animation sequences
depending on what the player is doing
=================
*/
void
NSSpawnPoint::Respawn(void)
Animation_PlayerUpdate(player pl)
{
InitPointTrigger();
setorigin_safe(this, GetSpawnOrigin());
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
SetSolid(SOLID_NOT);
SetMovetype(MOVETYPE_NONE);
botinfo = BOTINFO_SPAWNPOINT;
}

View file

@ -15,26 +15,26 @@
*/
/* game flags */
#define GF_SEMI_TOGGLED (int)(1<<0)
#define GF_FLASHLIGHT (int)(1<<1)
#define GF_UNUSED3 (int)(1<<2)
#define GF_UNUSED4 (int)(1<<3)
#define GF_UNUSED5 (int)(1<<4)
#define GF_UNUSED6 (int)(1<<5)
#define GF_UNUSED7 (int)(1<<6)
#define GF_UNUSED8 (int)(1<<7)
#define GF_UNUSED9 (int)(1<<8)
#define GF_UNUSED10 (int)(1<<9)
#define GF_UNUSED11 (int)(1<<10)
#define GF_UNUSED12 (int)(1<<11)
#define GF_UNUSED13 (int)(1<<12)
#define GF_UNUSED14 (int)(1<<14)
#define GF_UNUSED15 (int)(1<<16)
#define GF_UNUSED16 (int)(1<<13)
#define GF_UNUSED17 (int)(1<<17)
#define GF_UNUSED18 (int)(1<<18)
#define GF_UNUSED19 (int)(1<<19)
#define GF_UNUSED20 (int)(1<<20)
#define GF_UNUSED21 (int)(1<<21)
#define GF_UNUSED22 (int)(1<<22)
#define GF_UNUSED23 (int)(1<<23)
#define GF_SEMI_TOGGLED (1<<0)
#define GF_FLASHLIGHT (1<<1)
#define GF_UNUSED3 (1<<2)
#define GF_UNUSED4 (1<<3)
#define GF_UNUSED5 (1<<4)
#define GF_UNUSED6 (1<<5)
#define GF_UNUSED7 (1<<6)
#define GF_UNUSED8 (1<<7)
#define GF_UNUSED9 (1<<8)
#define GF_UNUSED10 (1<<9)
#define GF_UNUSED11 (1<<10)
#define GF_UNUSED12 (1<<11)
#define GF_UNUSED13 (1<<12)
#define GF_UNUSED14 (1<<14)
#define GF_UNUSED15 (1<<16)
#define GF_UNUSED16 (1<<13)
#define GF_UNUSED17 (1<<17)
#define GF_UNUSED18 (1<<18)
#define GF_UNUSED19 (1<<19)
#define GF_UNUSED20 (1<<20)
#define GF_UNUSED21 (1<<21)
#define GF_UNUSED22 (1<<22)
#define GF_UNUSED23 (1<<23)

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2016-2022 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.
*/
#ifdef CLIENT
void
FX_BreakModel_Init(void)
{
}
#endif
void
FX_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float fStyle)
{
}

View file

@ -49,13 +49,13 @@ FX_Corpse_Spawn(player pl, float anim)
{
NSRenderableEntity body_next = (NSRenderableEntity)FX_Corpse_Next();
setorigin(body_next, pl.origin + [0,0,32]);
body_next.SetMovetype(MOVETYPE_TOSS);
body_next.SetSolid(SOLID_CORPSE);
setmodel(body_next, pl.model);
setsize(body_next, VEC_HULL_MIN, VEC_HULL_MAX);
body_next.SetMovetype(MOVETYPE_TOSS);
body_next.SetSolid(SOLID_TRIGGER);
body_next.SetModelindex(pl.modelindex);
body_next.SetAngles(pl.angles);
body_next.velocity = (pl.velocity) + [0,0,120];
body_next.velocity = (pl.velocity);
body_next.colormap = pl.colormap;
body_next.SetFrame(anim);
return (entity)body_next;

29
base/src/shared/fx_explosion.qc Executable file
View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016-2022 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.
*/
#ifdef CLIENT
void
FX_Explosion_Init(void)
{
}
#endif
void
FX_Explosion(vector vecPos)
{
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2016-2022 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.
*/
#ifdef CLIENT
void
FX_GibHuman_Init(void)
{
}
#endif
void
FX_GibHuman(vector vecOrigin, vector vecDir, float flForce)
{
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016-2022 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.
*/
#ifdef CLIENT
void
FX_Impact_Init(void)
{
}
#endif
void
FX_Impact(impactType_t iType, vector vecPos, vector vNormal)
{
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,37 +14,33 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*!QUAKED game_end (1 .5 0) (-8 -8 -8) (8 8 8)
# OVERVIEW
Upon being triggered, the intermission secret will commence in multiplayer games.
# KEYS
- "targetname" : Name
- "master" : Name of the multisource regulating its usage.
# TRIVIA
This entity was introduced in Half-Life (1998).
*/
class
game_end:NSEntity
{
public:
void game_end(void);
virtual void Trigger(entity, triggermode_t);
};
#ifdef CLIENT
var float PARTICLE_SPARK;
void
game_end::game_end(void)
FX_Spark_Init(void)
{
Sound_Precache("env_spark.sfx");
PARTICLE_SPARK = particleeffectnum("fx_spark.effect");
}
#endif
void
game_end::Trigger(entity activatingEntity, triggermode_t triggerMode)
FX_Spark(vector pos, vector ang)
{
if (GetMaster(activatingEntity) == FALSE) {
return;
}
g_grMode.IntermissionStart();
}
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_SPARK);
WriteCoord(MSG_MULTICAST, pos[0]);
WriteCoord(MSG_MULTICAST, pos[1]);
WriteCoord(MSG_MULTICAST, pos[2]);
WriteCoord(MSG_MULTICAST, ang[0]);
WriteCoord(MSG_MULTICAST, ang[1]);
WriteCoord(MSG_MULTICAST, ang[2]);
msg_entity = self;
multicast(pos, MULTICAST_PVS);
#else
pointparticles(PARTICLE_SPARK, pos, ang, 1);
Sound_PlayAt(pos, "env_spark.sfx");
#endif
}

View file

@ -1,10 +1,27 @@
#includelist
flags.h
player.qc
weapon_common.h
weapons.h
flags.h
animations.h
animations.qc
pmove.qc
fx_blood.qc
fx_breakmodel.qc
fx_explosion.qc
fx_gibhuman.qc
fx_spark.qc
fx_impact.qc
fx_corpse.qc
items.h
weapons.h
weapon_basesemi.qc
weapon_baseshotgun.qc
weapon_baseautomatic.qc
weapons.qc
weapon_common.qc
input.qc
#endlist

61
base/src/shared/input.qc Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016-2022 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.
*/
void
Game_Input(player pl)
{
#ifdef SERVER
CGameRules rules = (CGameRules)g_grMode;
if (rules.m_iIntermission) {
rules.IntermissionEnd();
return;
}
if (input_buttons & INPUT_BUTTON5)
pl.InputUse_Down();
else
pl.InputUse_Up();
if (pl.impulse == 100)
Flashlight_Toggle();
pl.impulse = 0;
#endif
if (pl.health <= 0) {
Weapons_Release(pl);
return;
}
NSVehicle veh = (NSVehicle)pl.vehicle;
bool canfire = true;
if (veh)
if (veh.PreventPlayerFire() == true)
canfire = false;
if (canfire == false)
return;
if (input_buttons & INPUT_BUTTON0)
Weapons_Primary(pl);
else if (input_buttons & INPUT_BUTTON4)
Weapons_Reload(pl);
else if (input_buttons & INPUT_BUTTON3)
Weapons_Secondary(pl);
else
Weapons_Release(pl);
}

16
base/src/shared/items.h Normal file
View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2016-2022 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.
*/

72
base/src/shared/pmove.qc Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2016-2022 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.
*/
#define PHY_JUMP_CHAINWINDOW 0.5
#define PHY_JUMP_CHAIN 100
#define PHY_JUMP_CHAINDECAY 50
.float waterlevel;
.float watertype;
float
GamePMove_Maxspeed(player target)
{
return ((target.flags & FL_CROUCHING) ? 135 : 270);
}
void
GamePMove_Fall(player target, float impactspeed)
{
if (impactspeed > 580) {
#ifdef SERVER
float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580));
Damage_Apply(target, world, fFallDamage, 0, DMG_FALL);
Sound_Play(target, CHAN_VOICE, "player.fall");
#endif
target.punchangle += [15,0,(input_sequence & 1) ? 15 : -15];
} else if (impactspeed > 400) {
target.punchangle += [15,0,0];
#ifdef SERVER
Sound_Play(target, CHAN_VOICE, "player.lightfall");
#endif
}
}
void
GamePMove_Jump(player target)
{
float flJumptimeDelta;
float flChainBonus;
if (target.waterlevel >= 2) {
if (target.watertype == CONTENT_WATER) {
target.velocity[2] = 100;
} else if (target.watertype == CONTENT_SLIME) {
target.velocity[2] = 80;
} else {
target.velocity[2] = 50;
}
} else {
target.velocity[2] += 240;
}
if (target.jumptime > 0) {
flJumptimeDelta = 0 - (target.jumptime - PHY_JUMP_CHAINWINDOW);
flChainBonus = PHY_JUMP_CHAIN - (((PHY_JUMP_CHAINWINDOW - (PHY_JUMP_CHAINWINDOW - flJumptimeDelta)) * 2) * PHY_JUMP_CHAINDECAY);
target.velocity[2] += flChainBonus;
}
target.jumptime = PHY_JUMP_CHAINWINDOW;
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2016-2022 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.
*/
enum
{
AUTO_FIRE_FAILED,
AUTO_FIRED,
AUTO_LAST,
AUTO_EMPTY
};
int
w_baseauto_fire(int w, .int mag, int d, vector bs)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return (AUTO_FIRE_FAILED);
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return (AUTO_FIRE_FAILED);
}
if (pl.(mag) <= 0) {
pl.gflags |= GF_SEMI_TOGGLED;
return (AUTO_EMPTY);
}
pl.(mag)--;
#ifdef SERVER
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, d, bs, w);
#endif
if (pl.(mag) == 0)
return (AUTO_LAST);
else
return (AUTO_FIRED);
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016-2022 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.
*/
enum
{
MELEE_FAILED,
MELEE_MISS,
MELEE_HIT,
MELEE_HITBODY
};
int
w_basemelee_fire(int d, int w)
{
int anim = 0;
vector src;
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return (MELEE_FAILED);
}
Weapons_MakeVectors(pl);
src = pl.origin + pl.view_ofs;
/* make sure we can gib corpses */
int oldhitcontents = self.hitcontentsmaski;
self.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE;
traceline(src, src + (v_forward * 32), FALSE, pl);
self.hitcontentsmaski = oldhitcontents;
pl.w_attack_next = 0.5f;
pl.w_idle_next = 2.5f;
if (trace_fraction >= 1.0) {
return (MELEE_MISS);
}
#ifdef SERVER
if (trace_ent.takedamage) {
Damage_Apply(trace_ent, pl, d, w, DMG_BLUNT);
}
#endif
return (MELEE_HIT);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,29 +14,35 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
class
func_trackautochange:func_trackchange
enum
{
void func_trackautochange(void);
virtual void MoverFinishesMoving(void);
SEMI_FIRE_FAILED,
SEMI_FIRED,
SEMI_LAST,
SEMI_EMPTY
};
void
func_trackautochange::func_trackautochange(void)
int
w_baseprojectile_fire(player pl, int w, .int mag, void(player) spawnfunc)
{
}
void
func_trackautochange::MoverFinishesMoving(void)
{
NSEntity ourTrain = (NSEntity)find(world, ::targetname, m_strTrainName);
super::MoverFinishesMoving();
if (ourTrain) {
ourTrain.Trigger(this, TRIG_TOGGLE);
if (pl.w_attack_next > 0.0) {
return (SEMI_FIRE_FAILED);
}
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return (SEMI_FIRE_FAILED);
}
if (pl.(mag) <= 0) {
return (SEMI_EMPTY);
}
pl.(mag)--;
#ifdef SERVER
spawnfunc(pl);
#endif
if (pl.(mag) == 0)
return (SEMI_LAST);
else
return (SEMI_FIRED);
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2016-2022 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.
*/
enum
{
SEMI_FIRE_FAILED,
SEMI_FIRED,
SEMI_LAST,
SEMI_EMPTY
};
int
w_basesemi_fire(int w, .int mag, int d, vector bs)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return (SEMI_FIRE_FAILED);
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return (SEMI_FIRE_FAILED);
}
if (pl.(mag) <= 0) {
pl.gflags |= GF_SEMI_TOGGLED;
return (SEMI_EMPTY);
}
pl.(mag)--;
#ifdef SERVER
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, d, bs, w);
#endif
pl.gflags |= GF_SEMI_TOGGLED;
if (pl.(mag) == 0)
return (SEMI_LAST);
else
return (SEMI_FIRED);
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2016-2022 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.
*/
enum
{
SHOTGUN_FIRE_FAILED,
SHOTGUN_FIRED,
SHOTGUN_LAST,
SHOTGUN_EMPTY
};
int
w_baseshotgun_fire(int w, .int mag, int c, int d, vector bs)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return (SHOTGUN_FIRE_FAILED);
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return (SHOTGUN_FIRE_FAILED);
}
if (pl.(mag) <= 0) {
pl.gflags |= GF_SEMI_TOGGLED;
return (SHOTGUN_EMPTY);
}
pl.(mag)--;
#ifdef SERVER
TraceAttack_FireBullets(c, pl.origin + pl.view_ofs, d, bs, w);
#endif
if (pl.(mag) == 0)
return (SHOTGUN_LAST);
else
return (SHOTGUN_FIRED);
}
enum
{
SHOTTY_IDLE,
SHOTTY_RELOAD_START,
SHOTTY_RELOAD,
SHOTTY_RELOAD_END,
SHOTTY_COCKSOUND
};
void
w_baseshotgun_reload(.int mag, .int ammo, int max)
{
player pl = (player)self;
if (pl.(mag) >= max) {
return;
}
if (pl.(ammo) <= 0) {
return;
}
if (pl.mode_tempstate > SHOTTY_IDLE) {
return;
}
pl.mode_tempstate = SHOTTY_RELOAD_START;
pl.w_idle_next = 0.0f;
}
enum
{
SHOTGUN_IDLE,
SHOTGUN_BUSY,
SHOTGUN_START_RELOAD,
SHOTGUN_RELOAD,
SHOTGUN_END_RELOAD
};
int
w_baseshotgun_release(.int mag, .int ammo, int max)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return (SHOTGUN_BUSY);
}
if (pl.mode_tempstate == SHOTTY_RELOAD_START) {
pl.mode_tempstate = SHOTTY_RELOAD;
pl.w_idle_next = 0.65f;
return (SHOTGUN_START_RELOAD);
} else if (pl.mode_tempstate == SHOTTY_RELOAD) {
pl.(mag)++;
pl.(ammo)--;
if (pl.(ammo) <= 0 || pl.(mag) >= max) {
pl.mode_tempstate = SHOTTY_RELOAD_END;
}
Weapons_UpdateAmmo(pl, pl.(mag), pl.(ammo), pl.mode_tempstate);
pl.w_idle_next = 0.5f;
return (SHOTGUN_RELOAD);
} else if (pl.mode_tempstate == SHOTTY_RELOAD_END) {
pl.mode_tempstate = SHOTTY_IDLE;
pl.w_idle_next = 10.0f;
pl.w_attack_next = 0.5f;
return (SHOTGUN_END_RELOAD);
}
return (SHOTGUN_IDLE);
}

View file

@ -169,9 +169,6 @@ Weapons_Draw(player pl)
{
int i = pl.activeweapon;
/* In case the previous weapon hid the model */
Weapons_EnableModel();
pl.w_attack_next = 0.5f;
pl.w_idle_next = 2.5f;
pl.viewzoom = 1.0f;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,7 +14,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* weapon Indices for the weapon table */
enum
{
WEAPON_NONE
};
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Vera Visions LLC.
* Copyright (c) 2016-2022 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
@ -14,7 +14,9 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef NEW_INVENTORY
weapon_t w_null = {};
weapon_t g_weapons[] = {
w_null
};
#endif

View file

@ -1,268 +0,0 @@
59
-496 -80 336.031 16.000000 2
1 464.000000 0
58 63.118530 0
-32 -80 336.031 48.000000 2
0 464.000000 0
2 196.116043 0
-32 -272 336 16.000000 2
1 196.116043 0
3 327.968750 0
-32 -272 48.0312 32.000000 3
2 327.968750 0
4 96.332756 0
25 260.461121 0
32 -344 48.0312 16.000000 3
3 96.332756 0
5 72.000000 0
25 320.898743 0
32 -416 48.0312 16.000000 3
4 72.000000 0
6 321.993774 0
47 448.000000 4
-256 -416 -95.9688 16.000000 3
5 321.993774 0
7 128.000000 0
9 324.863037 0
-256 -288 -95.9688 32.000000 3
6 128.000000 0
8 256.000000 0
9 265.932312 0
0 -288 -95.9688 32.000000 2
7 256.000000 0
9 72.000000 0
0 -216 -95.9688 16.000000 4
6 324.863037 0
7 265.932312 0
8 72.000000 0
10 72.000000 0
0 -144 -95.9688 16.000000 4
12 128.249756 0
21 96.332756 0
9 72.000000 0
11 113.701363 0
-88 -83 -95.9688 16.000000 6
16 264.484406 0
14 147.078217 0
21 80.399002 0
12 111.139549 0
24 68.818604 2
10 113.701363 0
8 -16 -95.9688 16.000000 5
10 128.249756 0
21 171.207474 0
13 115.377640 0
11 111.139549 0
24 104.000000 2
-88 48 -95.9688 16.000000 5
15 264.000000 0
19 456.000000 0
14 150.306351 0
12 115.377640 0
24 75.471855 2
-224 -16 -95.9688 32.000000 7
20 131.939377 0
13 150.306351 0
11 147.078217 0
24 141.760361 2
23 143.108353 6
16 146.860474 0
15 143.108353 0
-352 48 -95.9688 16.000000 4
13 264.000000 0
19 192.000000 0
23 90.509666 6
14 143.108353 0
-352 -88 -95.9688 16.000000 7
11 264.484406 0
17 146.860474 0
20 111.139549 0
22 132.181686 2
18 200.000000 0
14 146.860474 0
23 96.332756 0
-480 -16 -95.9688 16.000000 4
19 90.509666 0
16 146.860474 0
23 143.108353 6
22 71.554176 2
-544 -144 -95.9688 16.000000 4
20 288.000000 0
19 192.000000 0
22 96.000000 2
16 200.000000 0
-544 48 -95.9688 16.000000 4
13 456.000000 0
15 192.000000 0
17 90.509666 0
18 192.000000 0
-256 -144 -95.9688 16.000000 4
18 288.000000 0
16 111.139549 0
14 131.939377 0
48 293.720947 0
-96 -152 -95.9688 8.000000 3
10 96.332756 0
12 171.207474 0
11 80.399002 0
-480 -80 -63.9688 8.000000 1
23 146.642426 6
-352 -16 -31.9688 16.000000 4
14 143.108353 0
16 96.332756 0
15 90.509666 0
17 143.108353 0
-88 -16 -55.9688 8.000000 4
12 104.000000 0
13 75.471855 0
11 68.818604 0
14 141.760361 0
-288 -320 48.0312 32.000000 3
3 260.461121 0
4 320.898743 0
26 416.000000 0
-704 -320 48.0312 32.000000 4
25 416.000000 0
27 416.000000 0
30 640.000000 0
35 800.000000 0
-704 -736 48.0312 32.000000 7
26 416.000000 0
28 385.331024 0
30 224.000000 0
31 558.855957 0
34 257.992249 0
35 384.000000 0
29 390.609772 0
-320 -768 48.0312 32.000000 3
27 385.331024 0
29 202.385773 0
45 101.192886 0
-384 -960 48.0312 16.000000 5
28 202.385773 0
30 320.000000 0
36 160.000000 0
45 135.764496 0
27 390.609772 0
-704 -960 48.0312 48.000000 5
26 640.000000 0
27 224.000000 0
29 320.000000 0
34 320.000000 0
35 160.000000 0
-928 -1248 48.0312 32.000000 4
27 558.855957 0
32 163.168625 0
38 350.907410 0
34 481.065491 0
-960 -1408 48.0312 32.000000 2
31 163.168625 0
33 640.000000 0
-320 -1408 48.0312 32.000000 4
36 295.025421 0
37 275.274414 0
45 544.940369 0
32 640.000000 0
-960 -768 48.0312 32.000000 4
27 257.992249 0
30 320.000000 0
35 435.247070 0
31 481.065491 0
-704 -1120 48.0312 32.000000 5
26 800.000000 0
27 384.000000 0
30 160.000000 0
34 435.247070 0
37 204.899979 0
-384 -1120 48.0312 32.000000 3
29 160.000000 0
33 295.025421 0
45 273.408112 0
-544 -1248 48.0312 32.000000 2
33 275.274414 0
35 204.899979 0
-608 -1248 192.031 16.000000 2
31 350.907410 0
39 224.000000 0
-384 -1248 192.031 16.000000 4
38 224.000000 0
40 128.000000 0
41 416.000000 0
43 167.044907 0
-384 -1376 192.031 16.000000 2
39 128.000000 0
33 160.797836 2
-384 -832 192.031 16.000000 3
39 416.000000 0
42 384.000000 0
43 260.461121 0
-768 -832 192.031 16.000000 3
41 384.000000 0
34 248.386688 2
30 203.017105 2
-432 -1088 192.031 16.000000 3
39 167.044907 0
41 260.461121 0
44 65.969688 2
-496 -1088 176.031 32.000000 4
43 65.969688 0
30 275.738922 0
35 246.316772 0
27 428.429626 0
-288 -864 48.0312 16.000000 5
28 101.192886 0
29 135.764496 0
33 544.940369 0
36 273.408112 0
46 96.000000 4
-192 -864 48.0312 16.000000 2
47 224.000000 0
45 96.000000 0
32 -864 48.0312 16.000000 2
46 224.000000 0
5 448.000000 0
0 -144 48.0312 16.000000 4
49 96.000000 0
50 273.408112 0
51 265.932312 0
20 293.720947 0
0 -48 48.0312 32.000000 3
48 96.000000 0
50 256.000000 0
52 480.000000 0
-256 -48 48.0312 32.000000 4
48 273.408112 0
49 256.000000 0
51 108.811768 0
52 224.000000 0
-192 40 48.0312 16.000000 4
48 265.932312 0
50 108.811768 0
52 301.144470 0
56 266.413116 0
-480 -48 48.0312 32.000000 3
49 480.000000 0
50 224.000000 0
51 301.144470 0
-552 -80 192.031 16.000000 2
57 78.790863 0
58 163.712769 0
0 -48 192.031 32.000000 3
55 256.000000 0
56 101.192886 0
57 480.000000 0
-256 -48 192.031 32.000000 3
54 256.000000 0
57 224.000000 0
56 303.578644 0
32 48 192.031 16.000000 3
54 101.192886 0
51 266.413116 0
55 303.578644 0
-480 -48 192.031 32.000000 3
53 78.790863 0
54 480.000000 0
55 224.000000 0
-555.969 -78.9344 355.692 16.000000 2
0 63.118530 0
53 163.712769 0

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,272 +0,0 @@
// entity 0
{
"classname" "worldspawn"
"mode" "0"
"sounds" "2"
"author" "Gethyn & Marco"
"mapversion" "220"
"team1" "0"
"team2" "4"
"message" "Test Everything!"
"sun_pos" "85 76 0"
// brush 0
{
( 320 320 256 ) ( -320 -312 256 ) ( -320 320 256 ) measure/wall64a [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 320 320 248 ) ( -320 320 256 ) ( -320 320 248 ) measure/wall64a [ 1 0 0 28 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 320 256 ) ( 320 -312 248 ) ( 320 -312 256 ) measure/wall64a [ 0 1 0 8 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 -312 256 ) ( -320 -312 248 ) ( -320 -312 256 ) measure/wall64a [ 1 0 0 20 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 320 248 ) ( -320 -312 256 ) ( -320 -312 248 ) measure/wall64a [ 0 1 0 4 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 -312 248 ) ( -320 320 248 ) ( -320 -312 248 ) measure/wall64a [ 1 0 0 84 ] [ -0 -1 -0 0 ] -0 1 1 0 0 0
}
// brush 1
{
( 320 320 256 ) ( -320 312 256 ) ( -320 320 256 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 320 320 -32 ) ( -320 320 256 ) ( -320 320 -32 ) measure/wall128gr [ 1 0 0 28 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 360 256 ) ( 320 360 -32 ) ( 320 -324 256 ) measure/wall128gr [ 0 1 0 8 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 312 -32 ) ( -320 320 -32 ) ( -320 312 -32 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( -320 320 -32 ) ( -320 312 256 ) ( -320 312 -32 ) measure/wall128gr [ 0 1 0 4 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 312 256 ) ( -320 312 -32 ) ( -320 312 256 ) measure/wall128gr [ 1 0 0 84 ] [ -0 -0 -1 0 ] -0 1 1 0 0 0
}
// brush 2
{
( 312 320 256 ) ( 320 -312 256 ) ( 312 -312 256 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 366 320 256 ) ( -324 320 256 ) ( 366 320 -32 ) measure/wall128gr [ 1 0 0 28 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 320 256 ) ( 320 -312 -32 ) ( 320 -312 256 ) measure/wall128gr [ 0 1 0 8 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 320 -32 ) ( 312 -312 -32 ) ( 320 -312 -32 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 320 -312 256 ) ( 312 -312 -32 ) ( 312 -312 256 ) measure/wall128gr [ 1 0 0 20 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 312 320 -32 ) ( 312 -312 256 ) ( 312 -312 -32 ) measure/wall128gr [ 0 1 0 20 ] [ -0 -0 -1 0 ] -0 1 1 0 0 0
}
// brush 3
{
( 320 320 -32 ) ( -320 320 0 ) ( -320 320 -32 ) measure/wall64a [ 1 0 0 28 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 360 256 ) ( 320 360 -32 ) ( 320 -324 256 ) measure/wall64a [ 0 1 0 8 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 -320 -32 ) ( -320 320 -32 ) ( -320 -320 -32 ) measure/wall64a [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 320 -320 0 ) ( -320 -320 -32 ) ( -320 -320 0 ) measure/wall64a [ 1 0 0 20 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 320 -32 ) ( -320 -320 0 ) ( -320 -320 -32 ) measure/wall64a [ 0 1 0 4 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 -320 0 ) ( -320 -320 0 ) ( -320 320 0 ) measure/wall64a [ 1 0 0 84 ] [ -0 -1 -0 0 ] -0 1 1 0 0 0
}
// brush 4
{
( -320 320 256 ) ( -312 -312 256 ) ( -320 -312 256 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( -320 320 256 ) ( -312 320 -32 ) ( -312 320 256 ) measure/wall128gr [ 1 0 0 28 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -312 320 -32 ) ( -320 -312 -32 ) ( -312 -312 -32 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( -320 -312 -32 ) ( -312 -312 256 ) ( -312 -312 -32 ) measure/wall128gr [ 1 0 0 20 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 320 -32 ) ( -320 -312 256 ) ( -320 -312 -32 ) measure/wall128gr [ 0 1 0 4 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -312 320 256 ) ( -312 -312 -32 ) ( -312 -312 256 ) measure/wall128gr [ 0 1 0 20 ] [ -0 -0 -1 0 ] -0 1 1 0 0 0
}
// brush 5
{
( -318 -312 256 ) ( 504 -312 256 ) ( 504 -320 256 ) measure/wall128gr [ 1 0 0 16 ] [ -0 -1 -0 60 ] -0 0.5 0.5 0 0 0
( 320 -312 256 ) ( 320 -320 128 ) ( 320 -320 256 ) measure/wall128gr [ 0 1 0 8 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -502 -320 128 ) ( 320 -320 256 ) ( 320 -320 128 ) measure/wall128gr [ 1 0 0 240 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -318 -322 -32 ) ( -318 362 -32 ) ( -318 -322 256 ) measure/wall128gr [ 0 1 0 4 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -318 -312 256 ) ( 504 -312 128 ) ( 504 -312 256 ) measure/wall128gr [ 1 0 0 84 ] [ -0 -0 -1 0 ] -0 1 1 0 0 0
( -318 -320 0 ) ( 504 -320 0 ) ( 504 -312 0 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
}
// brush 6
{
patchDef2
{
measure/wall128
( 3 3 0 0 0 )
(
( ( -64 296 88 -10 -0.59375 ) ( -64 296 114 -10 -0.796875 ) ( -64 296 140 -10 -1 ) )
( ( 0 296 88 -9.5 -0.59375 ) ( 0 296 114 -9.5 -0.796875 ) ( 0 296 140 -9.5 -1 ) )
( ( 64 296 88 -9 -0.59375 ) ( 64 296 114 -9 -0.796875 ) ( 64 296 140 -9 -1 ) )
)
}
}
// brush 7
{
patchDef2
{
measure/wall128g
( 3 3 0 0 0 )
(
( ( -64 24 208 -10 -1.625 ) ( -64 -2 208 -10 -1.625 ) ( -64 -28 208 -10 -1.625 ) )
( ( 0 24 208 -9.5 -1.625 ) ( 0 -2 208 -9.5 -1.625 ) ( 0 -28 208 -9.5 -1.625 ) )
( ( 64 24 208 -9 -1.625 ) ( 64 -2 208 -9 -1.625 ) ( 64 -28 208 -9 -1.625 ) )
)
}
}
// brush 8
{
patchDef2
{
measure/wall128b
( 3 3 0 0 0 )
(
( ( -296 -64 88 -10 -0.59375 ) ( -296 -64 114 -10 -0.796875 ) ( -296 -64 140 -10 -1 ) )
( ( -296 0 88 -9.5 -0.59375 ) ( -296 0 114 -9.5 -0.796875 ) ( -296 0 140 -9.5 -1 ) )
( ( -296 64 88 -9 -0.59375 ) ( -296 64 114 -9 -0.796875 ) ( -296 64 140 -9 -1 ) )
)
}
}
// brush 9
{
patchDef2
{
measure/wall128g
( 3 3 0 0 0 )
(
( ( -24 -64 208 -9.6875 -1.625 ) ( 2 -64 208 -9.484375 -1.625 ) ( 28 -64 208 -9.28125 -1.625 ) )
( ( -24 0 208 -9.6875 -1.625 ) ( 2 0 208 -9.484375 -1.625 ) ( 28 0 208 -9.28125 -1.625 ) )
( ( -24 64 208 -9.6875 -1.625 ) ( 2 64 208 -9.484375 -1.625 ) ( 28 64 208 -9.28125 -1.625 ) )
)
}
}
// brush 10
{
patchDef2
{
measure/wall128gr
( 3 3 0 0 0 )
(
( ( 296 64 88 -10 -0.59375 ) ( 296 64 114 -10 -0.796875 ) ( 296 64 140 -10 -1 ) )
( ( 296 0 88 -9.5 -0.59375 ) ( 296 0 114 -9.5 -0.796875 ) ( 296 0 140 -9.5 -1 ) )
( ( 296 -64 88 -9 -0.59375 ) ( 296 -64 114 -9 -0.796875 ) ( 296 -64 140 -9 -1 ) )
)
}
}
// brush 11
{
patchDef2
{
measure/wall64
( 3 3 0 0 0 )
(
( ( 64 24 16 -10 -1.625 ) ( 64 -2 16 -10 -1.625 ) ( 64 -28 16 -10 -1.625 ) )
( ( 0 24 16 -9.5 -1.625 ) ( 0 -2 16 -9.5 -1.625 ) ( 0 -28 16 -9.5 -1.625 ) )
( ( -64 24 16 -9 -1.625 ) ( -64 -2 16 -9 -1.625 ) ( -64 -28 16 -9 -1.625 ) )
)
}
}
// brush 12
{
patchDef2
{
measure/wall64
( 3 3 0 0 0 )
(
( ( 24 -64 16 -9.6875 -1.625 ) ( -2 -64 16 -9.484375 -1.625 ) ( -28 -64 16 -9.28125 -1.625 ) )
( ( 24 0 16 -9.6875 -1.625 ) ( -2 0 16 -9.484375 -1.625 ) ( -28 0 16 -9.28125 -1.625 ) )
( ( 24 64 16 -9.6875 -1.625 ) ( -2 64 16 -9.484375 -1.625 ) ( -28 64 16 -9.28125 -1.625 ) )
)
}
}
// brush 13
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( -192 304 40.0000190735 -176 -3.0000023842 ) ( -192 304 120.0000076294 -176 -13.0000009537 ) ( -192 304 200.0000305176 -176 -23.0000038147 ) )
( ( 0 304 40.0000190735 -152 -3.0000023842 ) ( 0 304 120.0000076294 -152 -13.0000009537 ) ( 0 304 200.0000305176 -152 -23.0000038147 ) )
( ( 192 304 40.0000190735 -128 -3.0000023842 ) ( 192 304 120.0000076294 -128 -13.0000009537 ) ( 192 304 200.0000305176 -128 -23.0000038147 ) )
)
}
}
// brush 14
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( 304 192 40.0000190735 152 -3.0000023842 ) ( 304 192 120.0000076294 152 -13.0000009537 ) ( 304 192 200.0000305176 152 -23.0000038147 ) )
( ( 304 0 40.0000190735 128 -3.0000023842 ) ( 304 0 120.0000076294 128 -13.0000009537 ) ( 304 0 200.0000305176 128 -23.0000038147 ) )
( ( 304 -192 40.0000190735 104 -3.0000023842 ) ( 304 -192 120.0000076294 104 -13.0000009537 ) ( 304 -192 200.0000305176 104 -23.0000038147 ) )
)
}
}
// brush 15
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( -304 -192 40.0000190735 104 -3.0000023842 ) ( -304 -192 120.0000076294 104 -13.0000009537 ) ( -304 -192 200.0000305176 104 -23.0000038147 ) )
( ( -304 0 40.0000190735 128 -3.0000023842 ) ( -304 0 120.0000076294 128 -13.0000009537 ) ( -304 0 200.0000305176 128 -23.0000038147 ) )
( ( -304 192 40.0000190735 152 -3.0000023842 ) ( -304 192 120.0000076294 152 -13.0000009537 ) ( -304 192 200.0000305176 152 -23.0000038147 ) )
)
}
}
// brush 16
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( -128 -128 224 -168 -112 ) ( 0 -128 224 -152 -112 ) ( 128 -128 224 -136 -112 ) )
( ( -128 0 224 -168 -128 ) ( 0 0 224 -152 -128 ) ( 128 0 224 -136 -128 ) )
( ( -128 128 224 -168 -144 ) ( 0 128 224 -152 -144 ) ( 128 128 224 -136 -144 ) )
)
}
}
// brush 17
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( 128 -128.0000610352 8 -136 -111.9999923706 ) ( 0 -128.0000610352 8 -152 -111.9999923706 ) ( -128 -128.0000610352 8 -168 -111.9999923706 ) )
( ( 128 0 8 -136 -128 ) ( 0 0 8 -152 -128 ) ( -128 0 8 -168 -128 ) )
( ( 128 128 8 -136 -144 ) ( 0 128 8 -152 -144 ) ( -128 128 8 -168 -144 ) )
)
}
}
// brush 18
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( -64 -304 40.0000190735 -160 -3.0000023842 ) ( -64 -304 120.0000076294 -160 -13.0000009537 ) ( -64 -304 200.0000305176 -160 -23.0000038147 ) )
( ( -160 -304 40.0000190735 -172 -3.0000023842 ) ( -160 -304 120.0000076294 -172 -13.0000009537 ) ( -160 -304 200.0000305176 -172 -23.0000038147 ) )
( ( -256 -304 40.0000190735 -184 -3.0000023842 ) ( -256 -304 120.0000076294 -184 -13.0000009537 ) ( -256 -304 200.0000305176 -184 -23.0000038147 ) )
)
}
}
// brush 19
{
patchDef2
{
sfx/reflection
( 3 3 0 0 0 )
(
( ( 288 -304 40.0000190735 -160 -3.0000023842 ) ( 288 -304 120.0000076294 -160 -13.0000009537 ) ( 288 -304 200.0000305176 -160 -23.0000038147 ) )
( ( 192 -304 40.0000190735 -172 -3.0000023842 ) ( 192 -304 120.0000076294 -172 -13.0000009537 ) ( 192 -304 200.0000305176 -172 -23.0000038147 ) )
( ( 96 -304 40.0000190735 -184 -3.0000023842 ) ( 96 -304 120.0000076294 -184 -13.0000009537 ) ( 96 -304 200.0000305176 -184 -23.0000038147 ) )
)
}
}
}
// entity 1
{
"classname" "env_cubemap"
"origin" "0.000000 0.000000 112.000000"
"scale" "64"
}
// entity 2
{
"classname" "light"
"_color" "1 1 1"
"light" "140"
"origin" "0.000000 0.000000 112.000000"
}
// entity 3
{
"classname" "info_player_start"
"origin" "-248.000000 0.000000 40.000000"
}
// entity 4
{
"classname" "info_player_deathmatch"
"origin" "-248.000000 64.000000 40.000000"
}

View file

@ -1,6 +1,5 @@
// Vera Visions Material
{
program lightmapped#MASK=0.5
surfaceParm alphashadow
program lightmapped
diffusemap textures/measure/rail.tga
}

View file

@ -110,7 +110,7 @@ then
else
printf "WorldSpawn is NOT present, cloning...\n"
cd ./src/
git clone "https://vcs.vera-visions.com/tech/worldspawn" worldspawn
git clone https://git.code.sf.net/p/worldspawn/code worldspawn
cd ./worldspawn
fi

View file

@ -108,7 +108,7 @@ mkdir -p ./bin
# SVN is no more
if [ -d "$FTE_SVNDIR" ]
then
printf "Detected Subversion repo... Please remove ./src/engine before proceeding.\n"
printf "Detected Subversion repo... Please remove ./src/engine before proceeding."
exit
fi
@ -135,7 +135,7 @@ then
else
printf "Engine is NOT present, cloning...\n"
cd ./src/
git clone "https://vcs.vera-visions.com/tech/engine" engine
git clone "https://github.com/VeraVisions/fteqw" engine
cd ./engine/engine
fi

View file

@ -1,35 +1,6 @@
#!/bin/sh
. ./build.cfg
safe_copy()
{
if [ -f "$1" ]
then
cp -v "$1" "$2"
fi
}
radiant_build()
{
if [ "$SKIP_RADIANT" = "1" ]; then
exit 0
fi
./make_mapdef.sh "$1"
# copy files over to RADIANT
if [ ! -z "$RADIANT_PATH" ]
then
if [ -d "$RADIANT_PATH/gamepacks/games" ];
then
mkdir -p "$RADIANT_PATH/gamepacks/$1.game/$1/"
safe_copy "./$1/radiant.game" "$RADIANT_PATH/gamepacks/games/$1.game"
safe_copy "./$1/entities.def" "$RADIANT_PATH/gamepacks/$1.game/$1/entities.def"
safe_copy "./$1/radiant.xml" "$RADIANT_PATH/gamepacks/$1.game/default_build_menu.xml"
fi
fi
}
if [ "$SKIP_UPDATE" = "1" ]; then
BUILD_UPDATE=0
fi
@ -38,7 +9,7 @@ fi
if [ "$BUILD_UPDATE" -eq 1 ]; then
if ! [ -x "$(command -v git)" ]; then
printf "'git' is not installed.\n"
exit 1
exit
fi
fi
@ -63,7 +34,7 @@ if [ -x "$(command -v fteqcc)" ]; then
make
cd "$SCRPATH"
radiant_build "$1"
./make_mapdef.sh "$1"
exit 0
fi
@ -99,8 +70,10 @@ if [ -x "$(command -v fteqcc)" ]; then
cd ..
export GAMEDIR=$(basename $PWD)
cd $OLDDIR
radiant_build "$GAMEDIR"
if [ -f "$SCRPATH"/bin/worldspawn ]; then
./make_mapdef.sh $GAMEDIR
fi
done;
else
printf "FTEQCC compiler is not present, please run build_engine.sh\n"
fi
fi

View file

@ -1,6 +1,8 @@
FTEMANIFEST 1
GAME base
NAME "Nuclide"
BASEGAME platform
BASEGAME base
// you don't really want to change these
RTCBROKER master.frag-net.com:27950

30
get_gamepacks.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh
. ./build.cfg
set -e
SCRPATH="$( cd "$( dirname $(readlink -nf $0) )" && pwd )"
grab_mod()
{
if [ -f "$SCRPATH/$1"/LICENSE ]; then
cd "$SCRPATH/$1"
if [ "$BUILD_UPDATE" -eq 1 ]; then
git pull
fi
else
cd "$SCRPATH"
git clone "$2" "$1"
fi
cd "$SCRPATH"
}
grab_mod gearbox https://www.github.com/eukara/freegearbox
grab_mod rewolf https://www.github.com/eukara/freegunman
grab_mod poke646 https://www.github.com/eukara/freepoke646
grab_mod tfc https://www.github.com/eukara/freetfc
grab_mod scihunt https://www.github.com/eukara/freesci
grab_mod hunger https://www.github.com/eukara/freehunger
grab_mod valve https://www.github.com/eukara/freehl
grab_mod cstrike https://www.github.com/eukara/freecs
grab_mod ts https://www.github.com/Frag-Net/FreeTS

Some files were not shown because too many files have changed in this diff Show more