ported HUD code to external progs, monster_human_grunt will hunt the player down properly

and countless things I don't have the energy to list
This commit is contained in:
Marco Cawthorne 2025-04-22 13:52:04 -07:00
parent 8fdf536f50
commit bd9a1ec554
87 changed files with 1899 additions and 1781 deletions

View file

@ -1,43 +1,48 @@
name: pk4
on: [ push, pull_request, workflow_dispatch ]
on:
push:
branches: [ master ]
tags: ['*']
jobs:
build:
runs-on: docker
steps:
name: clone nuclide src tree
- uses: actions/checkout@v3
with:
fetch-depth: 1
repository: vera/nuclide
ref: Develop
- uses: actions/checkout@v3
- name: clone game src tree
uses: actions/checkout@v3
with:
fetch-depth: 1
ref: Develop
path: "./${{ github.event.repository.name }}"
- name: apt install zip
- name: install zip(1)
run: |
apt update
apt install -y \
zip
- name: assemble pk4
- name: build .pk4
run: make dist-pak NAME=bin GAME=${{ github.event.repository.name }}
- uses: actions/upload-artifact@v3
- name: upload log
uses: actions/upload-artifact@v3
with:
name: build-log
path: ./build/bin-content.log
- uses: actions/forgejo-release@v2
- name: upload release
uses: actions/forgejo-release@v2
with:
url: https://code.idtech.space
repo: "${{ github.repository }}"
tag: "${{ github.run_id }}"
tag: "${{ github.ref_name }}"
sha: "${{ github.sha }}"
direction: upload
release-dir: ./build/bin-content/${{ github.event.repository.name }}/

8
.gitignore vendored
View file

@ -1,4 +1,10 @@
*.bsp
*.dat
*.lno
*.bsp
*.mdl
*core.txt
dlcache/*
fte.cfg
mapsrc/*
saves/*
screenshots/*

View file

@ -1,4 +1,4 @@
# ![](img/rt.png) Rad-Therapy
# ![](img/rt.png) Rad-Therapy (FreeHL)
This is a port of the 1998 game 'Half-Life' to Quake(World). Powered by Nuclide and the [FTE Engine](https://www.fteqw.org/).

View file

@ -3,6 +3,7 @@ entityDef ammo_base
"spawnclass" "ncItem"
"snd_acquire" "ammo.pickup"
"snd_respawn" "ammo.respawn"
"mins" "-16 -16 0"
"maxs" "16 16 16"
"mins" "-12 -12 0"
"maxs" "12 12 12"
"droptofloor" "1"
}

View file

@ -42,6 +42,7 @@ entityDef monster_human_grunt
"mindset_idle" "hgrunt_idle"
"mindset_defense" "hgrunt_takeCover"
"mindset_combat" "hgrunt_combatFace"
"mindset_hunt" "hgrunt_searchPlayer"
"squad_leader_body" "1:2"

View file

@ -1,6 +1,6 @@
entityDef monster_tripmine
{
"spawnclass" "HLTripmine"
"spawnclass" "hlTripmine"
"snd_precache1" "TripmineGrenade.Charge"
"snd_precache2" "TripmineGrenade.Activate"
}

View file

@ -1,13 +1,14 @@
entityDef player
{
"spawnclass" "HLPlayer"
"spawnclass" "hlPlayer"
"health" "100"
"maxarmor" "100"
"bleeds" "1"
"propdata" "actor_human"
"armorProtection" "0.2"
"armorBonus" "0.5"
"model" "models/player.mdl"
"snd_stepladderLeft" "step_ladder.left"
"snd_stepladderRight" "step_ladder.right"
"snd_fall" "Player.FallDamage"
@ -26,6 +27,7 @@ entityDef player
entityDef player_mp
{
"spawnclass" "hlPlayer"
"inherit" "player"
"ammo_9mm" "44"
"item" "item_suit"

View file

@ -1,3 +1,12 @@
entityDef weapon_base
{
"spawnclass" "HLWeapon"
"mins" "-16 -16 0"
"maxs" "16 16 16"
"snd_acquire" "Player.PickupWeapon"
"snd_respawn" "item.respawn"
}
#include "weapons/357.def"
#include "weapons/9mmAR.def"
#include "weapons/9mmhandgun.def"

View file

@ -6,7 +6,7 @@ entityDef weapon_357
"editor_usage" ".357 Revolver"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_357.mdl"
"model_view" "models/v_357.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -33,7 +33,7 @@ entityDef weapon_357
"snd_empty" "Weapons.Empty"
"snd_reload" "Weapon_357.Reload"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "1"
"hudSlotPos" "1"
"weight" "15"

View file

@ -6,7 +6,7 @@ entityDef weapon_9mmAR
"editor_usage" "9mm AR"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_9mmAR.mdl"
"model_view" "models/v_9mmAR.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -34,7 +34,7 @@ entityDef weapon_9mmAR
"snd_fire" "Weapon_MP5.Single"
"snd_empty" "Weapons.Empty"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "2"
"hudSlotPos" "0"
"weight" "15"
@ -92,7 +92,10 @@ entityDef projectile_ARgrenade
"def_damage" "damage_ARgrenadeDirect"
"def_splash_damage" "damage_ARgrenadeSplash"
"push" "10000"
"detonate_offset" "24"
"explode_light_color" "1 0.5 0"
"explode_light_radius" "1024"
"explode_light_fadetime" "3"
}
entityDef damage_ARgrenadeDirect
@ -104,6 +107,7 @@ entityDef damage_ARgrenadeSplash
{
"damage" "skill:plr_9mmAR_grenade"
"radius" "160"
"knockback" "300"
}
// multiplayer version

View file

@ -16,7 +16,7 @@ entityDef weapon_9mmhandgun
"editor_usage" "9mm Handgun"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_9mmhandgun.mdl"
"model_view" "models/v_9mmhandgun.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -44,7 +44,7 @@ entityDef weapon_9mmhandgun
"snd_altfire" "Weapon_Glock.Single"
"snd_empty" "Weapons.Empty"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "1"
"hudSlotPos" "0"
"weight" "10"

View file

@ -6,7 +6,7 @@ entityDef weapon_crossbow
"editor_usage" "Crossbow"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_crossbow.mdl"
"model_view" "models/v_crossbow.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -37,7 +37,7 @@ entityDef weapon_crossbow
"snd_empty" "Weapons.Empty"
"snd_reload" "Weapon_Crossbow.Reload"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "2"
"hudSlotPos" "2"
"weight" "10"

View file

@ -6,7 +6,7 @@ entityDef weapon_crowbar
"editor_usage" "Crowbar"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_crowbar.mdl"
"model_view" "models/v_crowbar.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -18,7 +18,7 @@ entityDef weapon_crowbar
"ammoRequired" "0"
"silent_fire" "1"
"testDistance" "-32"
"testDistance" "-48"
"failRate" "0.5"
"fireRate" "0.25"
"snd_fireFailed" "Weapon_Crowbar.Single"
@ -29,7 +29,7 @@ entityDef weapon_crowbar
"act_fireFailed" "4,5,7"
"act_fire" "3,6,8"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "0"
"hudSlotPos" "0"
"weight" "0"
@ -42,9 +42,9 @@ entityDef projectile_crowbar
"spawnclass" "ncProjectile"
"damage" "skill:plr_crowbar"
"is_bullet" "1"
"range" "32"
"decal_impact" "Impact.Shot"
"detonate_on_world" "1"
"range" "48"
"decal_detonate" "Impact.Shot"
"detonate_on_world" "0"
"snd_hitBody" "Weapon_Crowbar.Melee_Hit"
"snd_hitWorld" "Weapon_Crowbar.Melee_HitWorld"
}

View file

@ -6,7 +6,7 @@ entityDef weapon_egon
"editor_usage" "Gluon Gun"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_egon.mdl"
"model_view" "models/v_egon.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -32,7 +32,7 @@ entityDef weapon_egon
"joint_view_trail" "Gauss"
"joint_world_trail" "Gauss"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "3"
"hudSlotPos" "2"
"weight" "15"

View file

@ -6,7 +6,7 @@ entityDef weapon_gauss
"editor_usage" "Tau Cannon"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_gauss.mdl"
"model_view" "models/v_gauss.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -25,7 +25,7 @@ entityDef weapon_gauss
"snd_fire" "Weapon_Gauss.Fire"
"snd_empty" "Weapons.Empty"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "3"
"hudSlotPos" "1"
"weight" "20"

View file

@ -6,7 +6,7 @@ entityDef weapon_handgrenade
"editor_usage" "Hand Grenade"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_grenade.mdl"
"model_view" "models/v_grenade.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -32,7 +32,7 @@ entityDef weapon_handgrenade
"act_delay" "2"
"act_release" "3,4,5"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "4"
"hudSlotPos" "0"
"weight" "5"
@ -47,7 +47,7 @@ entityDef projectile_handgrenade
"fuse" "4"
"thrown" "1"
"detonate_on_fuse" "1"
"detonate_offset" "24"
"detonate_offset" "64"
"bounce" "1"
"angular_velocity" "-350 0 0"
"velocity" "300 0 40"
@ -57,6 +57,11 @@ entityDef projectile_handgrenade
"decal_detonate" "ExplosionScorch"
"def_damage" "damage_handgrenadeDirect"
"def_splash_damage" "damage_handgrenadeSplash"
"explode_light_color" "1 0.5 0"
"explode_light_radius" "1024"
"explode_light_fadetime" "3"
}
entityDef damage_handgrenadeDirect

View file

@ -6,7 +6,7 @@ entityDef weapon_hornetgun
"editor_usage" "Hornet Gun"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_hgun.mdl"
"model_view" "models/v_hgun.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -25,7 +25,7 @@ entityDef weapon_hornetgun
"snd_fire" "Weapon_Hornetgun.Single"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "3"
"hudSlotPos" "3"
"weight" "10"

View file

@ -6,7 +6,7 @@ entityDef weapon_rpg
"editor_usage" "Rocket Launcher"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_rpg.mdl"
"model_view" "models/v_rpg.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -33,7 +33,7 @@ entityDef weapon_rpg
"act_reload" "2"
"act_release" "2"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "3"
"hudSlotPos" "0"
"weight" "20"
@ -71,10 +71,11 @@ entityDef projectile_rocket
"light_radius" "160"
"light_offset" "0 0 0"
"detonate_offset" "24"
"detonate_offset" "64"
"explode_light_color" "2 1.6 0.8"
"explode_light_radius" "320"
"explode_light_fadetime" "0.5"
"explode_light_color" "1 0.5 0"
"explode_light_radius" "1024"
"explode_light_fadetime" "3"
"snd_explode" "fx.explosion"
"offset" "0 7 -3"

View file

@ -6,7 +6,7 @@ entityDef weapon_satchel
"editor_usage" "Satchel"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_satchel.mdl"
"model_view" "models/v_satchel.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -21,7 +21,7 @@ entityDef weapon_satchel
"act_draw" "2"
"act_fire" "3"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "4"
"hudSlotPos" "1"
"weight" "-20"
@ -47,7 +47,9 @@ entityDef projectile_satchel
"model_detonate" "fx_explosion.main"
"snd_explode" "fx.explosion"
"decal_detonate" "ExplosionScorch"
"explode_light_color" "1 0.5 0"
"explode_light_radius" "1024"
"explode_light_fadetime" "3"
}
entityDef damage_satchelExplosion

View file

@ -6,7 +6,7 @@ entityDef weapon_shotgun
"editor_usage" "Shotgun"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_shotgun.mdl"
"model_view" "models/v_shotgun.mdl"
"snd_acquire" "Player.PickupWeapon"
@ -42,7 +42,7 @@ entityDef weapon_shotgun
"snd_reload" "Weapon_Shotgun.Reload"
"snd_reload_end" "Weapon_Shotgun.Special1"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "2"
"hudSlotPos" "1"
"weight" "15"

View file

@ -6,7 +6,7 @@ entityDef weapon_snark
"editor_usage" "Snark"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/w_sqknest.mdl"
"model_view" "models/v_squeak.mdl"
"frame" "1"
@ -28,7 +28,7 @@ entityDef weapon_snark
"act_throw" "5"
"removeOnEmpty" "1"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "4"
"hudSlotPos" "3"
"weight" "5"

View file

@ -6,7 +6,7 @@ entityDef weapon_tripmine
"editor_usage" "Tripmine"
"editor_rotatable" "1"
"spawnclass" "HLWeapon"
"spawnclass" "hlWeapon"
"model" "models/v_tripmine.mdl"
"model_view" "models/v_tripmine.mdl"
"body0" "2"
@ -27,7 +27,7 @@ entityDef weapon_tripmine
"removeOnEmpty" "1"
"snd_fire" "TripmineGrenade.Deploy"
// HLWeapon specific
// hlWeapon specific
"hudSlot" "4"
"hudSlotPos" "2"
"weight" "-10"

View file

@ -4,10 +4,9 @@ typeInfo hgrunt_combatFace
"task_2" "PlayActivity idleAngry"
"task_3" "TurnToEnemy"
"task_4" "PerformSchedule hgrunt_sweep"
"fail_onNewEnemy" "1"
"fail_onDeadEnemy" "1"
"fail_onDamage" "1"
"fail_onCanRangedAttack1" "1"
"fail_onCanRangedAttack2" "1"
"Damage" "ChangeMindset defense"
"CanRangedAttack1" "PerformSchedule hgrunt_rangedAttack1A"
"CanRangedAttack2" "PerformSchedule hgrunt_rangedAttack2"
"Damage" "AlertSquadWithMindset defense"
}

View file

@ -3,5 +3,5 @@ typeInfo hgrunt_foundEnemy
"task_1" "StopMovement"
"task_2" "TurnToEnemy"
"task_3" "PlayActivity signal1"
"task_4" "ChangeMindset combat"
"task_4" "AlertSquadWithMindset combat"
}

View file

@ -4,8 +4,6 @@ typeInfo hgrunt_idle
"task_2" "PlayActivity idle"
"task_3" "Wait 2"
"task_4" "WaitPVS"
"fail_onNewEnemy" "1"
"fail_onDamage" "1"
"NewEnemy" "PerformSchedule hgrunt_foundEnemy"
"Damage" "PerformSchedule hgrunt_takeCover"
"NewEnemy" "AlertSquadWithMindset combat"
"Damage" "AlertSquadWithMindset defense"
}

View file

@ -14,12 +14,12 @@ typeInfo hgrunt_rangedAttack1A
"task_12" "TurnToEnemy"
"task_13" "TaskCheck_FriendlyFire"
"task_14" "AttackRanged1"
"fail_onNewEnemy" "1"
"fail_onDeadEnemy" "1"
"fail_onHeavyDamage" "1"
"fail_onAlertSound" "1"
"fail_onOccludedEnemy" "1"
"fail_onNoAmmo" "1"
"fal_onOccludedEnemy" "1"
"DeadEnemy" "PerformSchedule hgrunt_victoryDance"
"HeavyDamage" "ChangeMindset defense"
"HeavyDamage" "AlertSquadWithMindset defense"
"OccludedEnemy" "AlertSquadWithMindset hunt"
}

View file

@ -14,11 +14,10 @@ typeInfo hgrunt_rangedAttack1B
"task_12" "TurnToEnemy"
"task_13" "TaskCheck_FriendlyFire"
"task_14" "AttackRanged1"
"fail_onNewEnemy" "1"
"fail_onDeadEnemy" "1"
"fail_onHeavyDamage" "1"
"fail_onAlertSound" "1"
"fail_onOccludedEnemy" "1"
"fail_onNoAmmo" "1"
"fal_onOccludedEnemy" "1"
"DeadEnemy" "PerformSchedule hgrunt_victoryDance"
}

View file

@ -15,4 +15,6 @@ typeInfo hgrunt_rangedAttack2
"task_13" "TaskCheck_FriendlyFire"
"task_14" "AttackRanged1"
"DeadEnemy" "PerformSchedule hgrunt_victoryDance"
"OccludedEnemy" "AlertSquadWithMindset hunt"
"fal_onOccludedEnemy" "1"
}

View file

@ -0,0 +1,11 @@
typeInfo hgrunt_searchPlayer
{
"task_1" "TargetNearestPlayer"
"task_2" "RunToEnemyWithinRadius 256"
"NewEnemy" "AlertSquadWithMindset combat"
"Damage"  "AlertSquadWithMindset defense"
"fail_onDeadEnemy" "1"
"fail_onDamage" "1"
"CanRangedAttack1" "AlertSquadWithMindset combat"
"CanRangedAttack2" "AlertSquadWithMindset combat"
}

View file

@ -11,5 +11,6 @@ typeInfo hgrunt_sweep
"fail_onAlertSound" "1"
"CanRangedAttack1" "PerformSchedule hgrunt_rangedAttack1A"
"CanRangedAttack2" "PerformSchedule hgrunt_rangedAttack2"
"Damage" "ChangeMindset defense"
"Damage" "AlertSquadWithMindset defense"
"OccludedEnemy" "AlertSquadWithMindset hunt"
}

View file

@ -9,4 +9,7 @@ typeInfo hgrunt_takeCover
"task_7" "WaitForMovement"
"task_8" "Remember inCover"
"task_9" "PerformSchedule hgrunt_waitInCover"
"task_9" "ChangeMindset combat"
"fail_NewEnemy" "1"
"fail_OccludedEnemy" "1"
}

View file

@ -126,7 +126,7 @@ set pm_waterjumpheight "350"
set r_autoscale "1" // When set, will ensure the game is at 640x480 type scaling.
set r_drawdecals "1" // Shows decal entities managed by the game when set.
set r_ignoreentpvs "0" // override
set r_imageextensions "tga bmp pcx png jpg" // override
set r_imageextensions "ktx tga bmp pcx png jpg" // override
set r_meshpitch "1" // override
set r_pixelscale "0" // When set, will ensure the 3D rendered scene is restricted to 640x480 resolution in definition.
set r_renderEntityInfo "0" // Display visual information about entities in-world.

View file

@ -1,2 +1,3 @@
path "CONCHARS?fmt=h"
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 12

View file

@ -1,2 +1,3 @@
path "CONCHARS?fmt=h"
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 12

View file

@ -1,2 +1,3 @@
path "CONCHARS?fmt=h"
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 12

View file

@ -1,2 +1,3 @@
path fonts/default
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 16

View file

@ -1,3 +1,4 @@
path "creditsfont?fmt=h"
path_ttf fonts/nimbus/NimbusSanL-Bol.otf
size 20
additive 1

View file

@ -1,2 +1,3 @@
path fonts/nimbus/NimbusSanL-Bol.otf
path_ttf fonts/nimbus/NimbusSanL-Bol.otf
size 14

View file

@ -1,3 +1,4 @@
rendersize "21 16"
path fonts/nimbus/NimbusSanL-Bol.otf
path_ttf fonts/nimbus/NimbusSanL-Bol.otf
size 16

View file

@ -1,2 +1,3 @@
rendersize "14 12"
path fonts/nimbus/NimbusSanL-Bol.otf
path fonts/nimbus/NimbusSanL-Bol.otf
path_ttf fonts/nimbus/NimbusSanL-Bol.otf

View file

@ -1,3 +1,4 @@
rendersize "14 11 12"
path fonts/nimbus/NimbusSanL-Reg.otf
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 12

View file

@ -2,4 +2,5 @@ color "255 170 0"
alpha 255
rendersize "12 19"
path fonts/tahoma.ttf
path_ttf fonts/nimbus/NimbusSanL-Reg.otf
size 12

View file

@ -3,7 +3,10 @@
!!samps diffuse lightmap
!!cvardf gl_mono=0
!!cvardf gl_stipplealpha=0
!!cvardf r_waterLit=0
!!cvardf r_waterRipples=0
!!cvardf r_waterRippleResolution=5.0
!!cvardf r_waterRippleRadius=2.0f
#include "sys/defs.h"
#include "sys/fog.h"
@ -104,10 +107,10 @@ vec2 hash22(vec2 p)
#else
#ifdef LIT
#define MAX_RADIUS 2
#define MAX_RADIUS r_waterRippleRadius
#if r_waterRipples ==1
float resolution = 5.0f;
float resolution = r_waterRippleResolution;
float riptime = e_time;
vec2 uv = tc.xy * resolution;
vec2 p0 = floor(uv);
@ -141,8 +144,11 @@ vec2 hash22(vec2 p)
diffuse_f = texture2D(s_diffuse, tc + n.yz);
#endif
//diffuse_f.rgb += pow(clamp(dot(n, normalize(vec3(1., 0.7, 0.5))), 0., 1.), 6.);
#if r_waterLit==1
diffuse_f.rgb *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb;
#endif
#endif
#endif

View file

@ -77,32 +77,54 @@ r_part water
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
}
r_part slime
{
lighttime 0.5
lightradius 256
lightradiusfade 300
lightrgb 0.0 1.0 0.0
lightrgbfade 0.0 0.0 0.0
texture "textures/particles/flames"
tcoords 0 0 0.125 1 1 8 0.125
count 16
scale 8
die 2
rgb 96 255 96
blend add
spawnorg 2
gravity 800
spawnvel 312
cliptype bounce
}
r_part +slime
{
count 0 0 1
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
lighttime 1
lightradius 128
lightradiusfade 300
lightrgb 0.5 1.0 0.5
lightrgbfade 0.19 0.36 0.19
}
r_part lava
{
lighttime 0.5
lightradius 256
lightradiusfade 300
lightrgb 1.0 0.0 0.0
lightrgbfade 0.0 0.0 0.0
texture "textures/particles/flames"
tcoords 0 0 0.125 1 1 8 0.125
count 16
scale 8
die 2
rgb 255 128 25
blend add
spawnorg 2
gravity 800
spawnvel 312
cliptype bounce
}
r_part +lava
{
count 0 0 1
model "sprites/wsplash3.spr" framestart=0 frameend=14 framerate=20 additive
lighttime 1
lightradius 128
lightradiusfade 300
lightrgb 1.0 0.7 0.5
lightrgbfade 0.36 0.19 0.19
}

View file

@ -2,3 +2,4 @@ exec default_controls.cfg
exec default_cvar.cfg
exec default_video.cfg
exec default_valve.cfg
exec fte.cfg

View file

@ -16,6 +16,11 @@ Impact.BigShot
"{bigshot5" "1"
}
Impact.Gauss
{
"{gaussshot1" "1"
}
Impact.Break
{
"{break1" "1"
@ -52,4 +57,4 @@ Blood.Alien
"{yblood6" "1"
"{yblood7" "1"
"{yblood8" "1"
}
}

View file

@ -12,4 +12,4 @@ nodraw
surfaceparm nomarks
surfaceparm nodlight
surfaceparm nodraw
}
}

View file

@ -181,7 +181,7 @@ water
lava
{
part_bulletimpact "impact_default.main"
part_bulletimpact "fx_impact.lava"
bulletimpact "sfx_impact.slosh"
stepleft "step_slosh.left"
stepright "step_slosh.right"
@ -189,7 +189,7 @@ lava
slime
{
part_bulletimpact "impact_default.main"
part_bulletimpact "fx_impact.slime"
bulletimpact "sfx_impact.slosh"
stepleft "step_slosh.left"
stepright "step_slosh.right"

View file

@ -2,6 +2,7 @@ QCC=fteqcc
all:
cd client && $(MAKE)
cd hud && $(MAKE)
cd server && $(MAKE)
cd menu && $(MAKE)
cd rules && $(MAKE)

View file

@ -1,183 +0,0 @@
/*
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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 ncWeapon_SelectWeapon(ncWeapon nextWeapon);
void
HLWeaponSelect::HLWeaponSelect(void)
{
m_selectedWeapon = __NULL__;
m_flHUDWeaponSelectTime = 0.0f;
}
bool
HLWeaponSelect::Active(void)
{
return (m_flHUDWeaponSelectTime > time) ? (true) : (false);
}
void
HLWeaponSelect::Trigger(void)
{
ncWeapon_SelectWeapon(m_selectedWeapon);
Deactivate();
}
void
HLWeaponSelect::Deactivate(void)
{
m_selectedWeapon = __NULL__;
m_flHUDWeaponSelectTime = 0.0f;
}
void
HLWeaponSelect::Draw(void)
{
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
if (!pl.m_activeWeapon) {
return;
}
if (m_flHUDWeaponSelectTime < time) {
m_selectedWeapon = __NULL__;
return;
}
vector vecPos = g_hudmins + [16,16];
float lastSlot = -1;
float currentSlot;
HLWeapon linkedList = __NULL__;
/* since we have something in the inventory, start there */
linkedList = m_firstWeapon;
/* iterate through the inventory*/
while (linkedList) {
/* only iterate over weapons */
if (isWeapon(linkedList) == true) {
currentSlot = linkedList. m_iHudSlot;
/* new slot started, reset Y axis */
if (lastSlot != currentSlot) {
/* new slot, new offset */
if (lastSlot == m_iWantSlot) {
vecPos[0] += 175;
} else {
vecPos[0] += 25;
}
/* quick hack to re-adjust */
if (lastSlot == -1) {
vecPos[0] = g_hudmins[0] + 16;
}
/* slot number icon at the top */
vecPos[1] = g_hudmins[1] + 16;
DrawSlotNum(vecPos, currentSlot + 1);
vecPos[1] += 20;
}
lastSlot = currentSlot;
/* selected slot VS unselected slot */
if (m_iWantSlot == currentSlot) {
if (linkedList == m_selectedWeapon) {
HLSprite_Draw_RGB(linkedList.m_iconSel, vecPos, g_hud_color, true);
HLSprite_Draw_RGB("selection", vecPos, g_hud_color, true);
} else {
HLSprite_Draw_RGB(linkedList.m_icon, vecPos, g_hud_color, true);
}
vecPos[1] += 50;
} else {
DrawSlotNum(vecPos, 0);
vecPos[1] += 25;
}
}
linkedList = (HLWeapon)linkedList.GetNextWeapon();
}
}
static string g_HLWeaponSelectBuckets[] =
{
"bucket0",
"bucket1",
"bucket2",
"bucket3",
"bucket4",
"bucket5",
"bucket6",
"bucket7",
"bucket8",
};
void
HLWeaponSelect::DrawSlotNum(vector vecPos, float fValue)
{
HLSprite_Draw_RGB(g_HLWeaponSelectBuckets[fValue], vecPos, g_hud_color, true);
}
void
HLWeaponSelect::SelectSlot(int wantedSlot, bool fastSwitch)
{
}
void
HLWeaponSelect::SelectNext(bool fastSwitch)
{
ncClient ourPlayer = (ncClient)pSeat->m_ePlayer;
m_firstWeapon = (HLWeapon)ourPlayer.SortWeaponChain();
if (!m_selectedWeapon) {
m_selectedWeapon = (HLWeapon)ourPlayer.m_activeWeapon.GetNextWeapon();
} else {
m_selectedWeapon = (HLWeapon)m_selectedWeapon.GetNextWeapon();
}
/* wrap around */
if (!m_selectedWeapon) {
m_selectedWeapon = m_firstWeapon;
}
m_flHUDWeaponSelectTime = time + 3;
m_iWantSlot = m_selectedWeapon.m_iHudSlot;
m_iWantSlotPos = m_selectedWeapon.m_iHudSlotPos;
}
void
HLWeaponSelect::SelectPrevious(bool fastSwitch)
{
ncClient ourPlayer = (ncClient)pSeat->m_ePlayer;
m_firstWeapon = (HLWeapon)ourPlayer.SortWeaponChain();
if (!m_selectedWeapon) {
m_selectedWeapon = (HLWeapon)ourPlayer.m_activeWeapon.GetPreviousWeapon();
} else {
m_selectedWeapon = (HLWeapon)m_selectedWeapon.GetPreviousWeapon();
}
/* wrap around */
if (!m_selectedWeapon) {
m_selectedWeapon = m_firstWeapon;
}
m_flHUDWeaponSelectTime = time + 3;
m_iWantSlot = m_selectedWeapon.m_iHudSlot;
m_iWantSlotPos = m_selectedWeapon.m_iHudSlotPos;
}

View file

@ -14,10 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void HUD_DrawWeaponSelect_Back(void);
void HUD_DrawWeaponSelect_Forward(void);
void HUD_DrawWeaponSelect_Last(void);
void HUD_SlotSelect(int);
void VGUI_ChooseClass(int);
void VGUI_ChooseTeam(void);
@ -34,39 +30,6 @@ ClientGame_ConsoleCommand(void)
case "chooseteam":
localcmd(sprintf("cmd %s %s\n", argv(0), argv(1)));
break;
case "lastinv":
//HUD_DrawWeaponSelect_Last();
break;
case "slot1":
HUD_SlotSelect(0);
break;
case "slot2":
HUD_SlotSelect(1);
break;
case "slot3":
HUD_SlotSelect(2);
break;
case "slot4":
HUD_SlotSelect(3);
break;
case "slot5":
HUD_SlotSelect(4);
break;
case "slot6":
HUD_SlotSelect(5);
break;
case "slot7":
HUD_SlotSelect(6);
break;
case "slot8":
HUD_SlotSelect(7);
break;
case "slot9":
HUD_SlotSelect(8);
break;
case "slot10":
HUD_SlotSelect(9);
break;
default:
return (0);
}

View file

@ -1,88 +0,0 @@
/*
* Copyright (c) 2019-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var string g_damage_spr_t;
var string g_damage_spr_b;
var string g_damage_spr_l;
var string g_damage_spr_r;
var float autocvar_cg_damageFill = 0.25f;
void
Damage_Precache(void)
{
g_damage_spr_t = spriteframe("sprites/640_pain.spr", 0, 0.0f);
g_damage_spr_r = spriteframe("sprites/640_pain.spr", 1, 0.0f);
g_damage_spr_b = spriteframe("sprites/640_pain.spr", 2, 0.0f);
g_damage_spr_l = spriteframe("sprites/640_pain.spr", 3, 0.0f);
}
void HUD_DamageNotify_Check();
void
Damage_Draw(void)
{
vector center;
vector rel_pos;
float fw, fw_alpha;
float rt, rt_alpha;
if (pSeat->m_flDamageAlpha <= 0.0) {
return;
}
HUD_DamageNotify_Check();
center = video_mins + (g_vidsize / 2);
/* the pos relative to the player + view_dir determines which
* and how bright each indicator is drawn. so first get the relative
* position between us and the attacker, then calculate the strength
* of each direction based on a dotproduct tested against our
* camera direction.
*/
rel_pos = normalize(pSeat->m_vecDamagePos - getproperty(VF_ORIGIN));
makevectors(getproperty(VF_CL_VIEWANGLES));
fw = dotproduct(rel_pos, v_forward);
rt = dotproduct(rel_pos, v_right);
fw_alpha = fabs(fw) * pSeat->m_flDamageAlpha;
if (fw > 0.25f) {
drawpic(center + [-64,-102], g_damage_spr_t,
[128,48], [1,1,1], fw_alpha, DRAWFLAG_ADDITIVE);
} else if (fw < -0.25f) {
drawpic(center + [-64,70], g_damage_spr_b,
[128,48], [1,1,1], fw_alpha, DRAWFLAG_ADDITIVE);
}
rt_alpha = fabs(rt) * pSeat->m_flDamageAlpha;
if (rt > 0.25f) {
drawpic(center + [70,-64], g_damage_spr_r,
[48,128], [1,1,1], rt_alpha, DRAWFLAG_ADDITIVE);
} else if (rt < -0.25f) {
drawpic(center + [-102,-64], g_damage_spr_l,
[48,128], [1,1,1], rt_alpha, DRAWFLAG_ADDITIVE);
}
if (autocvar_cg_damageFill > 0.0) {
vector finalColor = [1,1,1];
finalColor[1] = finalColor[2] = 1.0 - (pSeat->m_flDamageAlpha * autocvar_cg_damageFill);
drawpic(video_mins, "fade_modulate", g_vidsize, finalColor, 1.0, DRAWFLAG_NORMAL);
}
pSeat->m_flDamageAlpha -= clframetime;
}

View file

@ -18,7 +18,6 @@
#include "obituary.h"
#include "particles.h"
#include "hud_sprite.h"
#include "HLWeaponSelect.h"
var int autocvar_cl_autoweaponswitch = TRUE;
@ -62,13 +61,6 @@ struct
float m_flDamageIndicator;
float m_flTitleAlpha;
HLWeaponSelect weaponSelectionHUD;
} g_seatslocal[4], *pSeatLocal;
void HUD_DrawAmmo1(void);
void HUD_DrawAmmo2(void);
void HUD_DrawAmmo3(void);
void HUD_DrawAmmoBar(vector pos, float val, float max, float a);
void HUD_WeaponPickupNotify(int);

View file

@ -19,18 +19,21 @@ ClientGame_EntityUpdate(float id, float new)
{
switch (id) {
case ENT_TRIPMINE:
NSENTITY_READENTITY(HLTripmine, new)
NSENTITY_READENTITY(hlTripmine, new)
break;
case ENT_WEAPON:
NSENTITY_READENTITY(HLWeapon, new)
NSENTITY_READENTITY(hlWeapon, new)
break;
case ENT_PLAYER:
#ifdef SCIHUNT
NSENTITY_READENTITY(SHPlayer, new)
NSENTITY_READENTITY(shPlayer, new)
#else
NSENTITY_READENTITY(HLPlayer, new)
NSENTITY_READENTITY(hlPlayer, new)
#endif
break;
case ENT_HLHUDCOUNTER:
NSENTITY_READENTITY(hlHUDCounter, new)
break;
default:
return (0);
}

View file

@ -18,29 +18,12 @@ int
ClientGame_EventParse(float fHeader)
{
switch (fHeader) {
case EV_OBITUARY:
Obituary_Parse();
break;
case EV_HITNOTIFY:
pSeatLocal->m_flDamageIndicator = 1.0f;
break;
case EV_GAUSSBEAM:
FX_GaussBeam_Parse();
break;
case EV_CHAT:
float fSender = readbyte();
float fTeam = readbyte();
string sMessage = readstring();
CSQC_Parse_Print(Util_ChatFormat(fSender, 0, sMessage), PRINT_CHAT);
break;
case EV_CHAT_TEAM:
float fSender2 = readbyte();
float fTeam2 = readbyte();
string sMessage2 = readstring();
CSQC_Parse_Print(Util_ChatFormat(fSender2, fTeam2, sMessage2), PRINT_CHAT);
break;
case EV_VIEWMODEL:
View_PlayAnimation(readbyte());
break;

View file

@ -1,581 +0,0 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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 HUD_DrawWeaponSelect(void);
/* Use first frame for drawing (needs precache) */
#define NUMSIZE_X 24/256
#define NUMSIZE_Y 24/128
#define HUD_ALPHA 0.5
float spr_hudnum[10] = {
0 / 256,
24 / 256,
(24*2) / 256,
(24*3) / 256,
(24*4) / 256,
(24*5) / 256,
(24*6) / 256,
(24*7) / 256,
(24*8) / 256,
(24*9) / 256
};
/* pre-calculated sprite definitions */
float spr_health[4] = {
80 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_suit1[4] = {
0 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_suit2[4] = {
40 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_flash1[4] = {
160 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_flash2[4] = {
112 / 256, // pos x
24 / 128, // pos u
48 / 256, // size x
32 / 128 // size y
};
/* precaches */
void
HUD_Init(void)
{
g_cross_spr = spriteframe("sprites/crosshairs.spr", 0, 0.0f);
g_laser_spr = spriteframe("sprites/laserdot.spr", 0, 0.0f);
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
g_hud2_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
g_hud3_spr = spriteframe("sprites/640hud3.spr", 0, 0.0f);
g_hud4_spr = spriteframe("sprites/640hud4.spr", 0, 0.0f);
g_hud5_spr = spriteframe("sprites/640hud5.spr", 0, 0.0f);
g_hud6_spr = spriteframe("sprites/640hud6.spr", 0, 0.0f);
g_hud7_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
HUD_AmmoNotify_Init();
HUD_DamageNotify_Init();
HUD_ItemNotify_Init();
}
/* seperator for mainly ammo */
void
HUD_DrawSeperator(vector pos)
{
drawsubpic(pos,
[2,24],
g_hud7_spr,
[240/256, 0],
[2/256, 24/128],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
/* handle single/multiple digits */
void
HUD_DrawNumber(int iNumber, vector vecPos, float fAlpha, vector vColor)
{
drawsubpic(vecPos,
[24,24],
g_hud7_spr,
[spr_hudnum[iNumber], 0],
[NUMSIZE_X, NUMSIZE_Y],
vColor,
fAlpha,
DRAWFLAG_ADDITIVE
);
}
void
HUD_DrawNums(float fNumber, vector vecPos, float fAlpha, vector vColor)
{
int i = fNumber;
if (i > 0) {
while (i > 0) {
HUD_DrawNumber((float)i % 10.0f, vecPos, fAlpha, vColor);
i = i / 10;
vecPos[0] -= 20;
}
} else {
HUD_DrawNumber(0, vecPos, fAlpha, vColor);
}
}
/* health */
void
HUD_DrawHealth(void)
{
vector pos;
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
if (pl.health != pSeatLocal->m_iHealthOld) {
pSeatLocal->m_flHealthAlpha = 1.0;
}
pos = g_hudmins + [88, g_hudres[1] - 42];
if (pl.health > 25) {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
g_hud_color,
pSeatLocal->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, g_hud_color);
} else {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
[1,0,0],
pSeatLocal->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, [1,0,0]);
}
pSeatLocal->m_iHealthOld = pl.health;
if (pSeatLocal->m_flHealthAlpha >= HUD_ALPHA) {
pSeatLocal->m_flHealthAlpha = bound(HUD_ALPHA, pSeatLocal->m_flHealthAlpha - (clframetime * 0.5), 1.0);
} else {
pSeatLocal->m_flHealthAlpha = HUD_ALPHA;
}
}
/* armor/suit charge */
void
HUD_DrawArmor(void)
{
vector pos;
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
pos = g_hudmins + [198, g_hudres[1] - 42];
if (pl.armor != pSeatLocal->m_iArmorOld) {
pSeatLocal->m_flArmorAlpha = 1.0;
}
drawsubpic(
pos + [-80,-9],
[40,40],
g_hud7_spr,
[spr_suit2[0], spr_suit2[1]],
[spr_suit2[2], spr_suit2[3]],
g_hud_color,
pSeatLocal->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
if (pl.armor > 0) {
float perc = bound(0, (pl.armor / 100), 1.0);
drawsubpic(
pos + [-80,-9] + [0, 40 * (1.0-perc)],
[40, 40 * perc],
g_hud7_spr,
[spr_suit1[0],spr_suit1[1] + spr_suit1[3] * (1.0-perc)],
[spr_suit1[2], spr_suit1[3] * perc],
g_hud_color,
pSeatLocal->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
}
HUD_DrawNums(pl.armor, pos, pSeatLocal->m_flArmorAlpha, g_hud_color);
pSeatLocal->m_iArmorOld = pl.armor;
if (pSeatLocal->m_flArmorAlpha >= HUD_ALPHA) {
pSeatLocal->m_flArmorAlpha = bound(HUD_ALPHA, pSeatLocal->m_flArmorAlpha - (clframetime * 0.5), 1.0);
} else {
pSeatLocal->m_flArmorAlpha = HUD_ALPHA;
}
}
/* magazine/clip ammo */
void
HUD_DrawAmmo1(void)
{
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo1 != pSeatLocal->m_iAmmo1Old) {
pSeatLocal->m_flAmmo1Alpha = 1.0;
pSeatLocal->m_iAmmo1Old = pl.a_ammo1;
}
pos = g_hudmins + [g_hudres[0] - 152, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo1, pos, pSeatLocal->m_flAmmo1Alpha, g_hud_color);
HUD_DrawSeperator(pos + [30,0]);
if (pSeatLocal->m_flAmmo1Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo1Alpha = bound(HUD_ALPHA, pSeatLocal->m_flAmmo1Alpha - (clframetime * 0.5), 1.0);
} else {
pSeatLocal->m_flAmmo1Alpha = HUD_ALPHA;
}
}
/* leftover type ammo */
void
HUD_DrawAmmo2(void)
{
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo2 != pSeatLocal->m_iAmmo2Old) {
pSeatLocal->m_flAmmo2Alpha = 1.0;
pSeatLocal->m_iAmmo2Old = pl.a_ammo2;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo2, pos, pSeatLocal->m_flAmmo2Alpha, g_hud_color);
if (pSeatLocal->m_flAmmo2Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo2Alpha = bound(HUD_ALPHA, pSeatLocal->m_flAmmo2Alpha - (clframetime * 0.5), 1.0);
} else {
pSeatLocal->m_flAmmo2Alpha = HUD_ALPHA;
}
}
/* special ammo */
void
HUD_DrawAmmo3(void)
{
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo3 != pSeatLocal->m_iAmmo3Old) {
pSeatLocal->m_flAmmo3Alpha = 1.0;
pSeatLocal->m_iAmmo3Old = pl.a_ammo3;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 74];
HUD_DrawNums(pl.a_ammo3, pos, pSeatLocal->m_flAmmo3Alpha, g_hud_color);
if (pSeatLocal->m_flAmmo3Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo3Alpha = bound(HUD_ALPHA, pSeatLocal->m_flAmmo3Alpha - (clframetime * 0.5), 1.0);
} else {
pSeatLocal->m_flAmmo3Alpha = HUD_ALPHA;
}
}
/* ammo bar */
void
HUD_DrawAmmoBar(vector pos, float val, float max, float a)
{
if (val <= 0)
return;
float perc;
perc = val / max;
drawfill(pos + [10,0], [20,4], g_hud_color, a, DRAWFLAG_NORMAL);
drawfill(pos + [10,0], [20 * perc,4], [0,1,0], a, DRAWFLAG_NORMAL);
}
/* flashlight/torch indicator */
void
HUD_DrawFlashlight(void)
{
vector pos;
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
pos = g_hudmins + [g_hudres[0] - 48, 16];
/* both on, draw both sprites at full intensity */
if (pl.gflags & GF_FLASHLIGHT) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos,
[48,32],
g_hud7_spr,
[spr_flash2[0], spr_flash2[1]],
[spr_flash2[2], spr_flash2[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
}
/* logo animation used during e3 1998 */
void
HUD_DrawLogo(void)
{
vector pos;
static int f;
static float frame_timer;
frame_timer -= clframetime;
pos = [g_hudres[0] - 262, 48];
drawpic(
pos,
sprintf("sprites/640_logo.spr_%i.tga", f),
[256,48],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
if (frame_timer > 0) {
return;
}
frame_timer = 0.1f;
f++;
if (f == 31) {
f = 0;
}
}
/* weapon/ammo pickup notifications */
void
HUD_DrawNotify(void)
{
ncPlayer pl = (ncPlayer)self;
vector pos;
float a;
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
if (pSeatLocal->m_flPickupAlpha <= 0.0f) {
pos[1] += 48;
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
return;
}
a = bound(0.0, pSeatLocal->m_flPickupAlpha, 1.0);
pos[1] += 48 * (1.0 - a);
//Weapons_HUDPic(pl, pSeatLocal->m_iPickupWeapon, 1, pos, a);
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
pSeatLocal->m_flPickupAlpha -= (clframetime * 0.5);
}
void
HUD_WeaponPickupNotify(int w)
{
#if 0
#if defined (VALVE) || defined (GEARBOX)
switch (w) {
case WEAPON_SNARK:
case WEAPON_SATCHEL:
case WEAPON_HANDGRENADE:
case WEAPON_TRIPMINE:
#if defined(GEARBOX)
case WEAPON_PENGUIN:
#endif
return;
default:
}
#endif
#endif
pSeatLocal->m_iPickupWeapon = w;
pSeatLocal->m_flPickupAlpha = 2.5f;
}
void
HUD_DrawDamageIndicator(void)
{
vector cross_pos;
if (pSeatLocal->m_flDamageIndicator <= 0.0)
return;
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
/*drawsubpic(
cross_pos,
[24,24],
g_cross_spr,
[0.0, 72/128],
[0.1875, 0.1875],
[1,1,1] * pSeatLocal->m_flDamageIndicator,
1.0f,
DRAWFLAG_ADDITIVE
);*/
pSeatLocal->m_flDamageIndicator -= clframetime;
}
void
HUD_TimeRemaining(void)
{
vector iconPos = g_hudmins + [16, g_hudres[1] - 64];
/* display time if timelimit is being hit */
if (serverkeyfloat("timelimit")) {
string tempstr = strcat("Time Remaining: ", Util_GetTime());
Font_DrawText_RGB(iconPos, tempstr, g_hud_color, FONT_20);
}
}
/* main entry */
void
HUD_Draw(void)
{
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
#ifndef TFC
#ifndef GEARBOX
g_hud_color = autocvar_con_color * (1 / 255);
#else
if (getplayerkeyfloat(pl.entnum-1, "*team") == 1)
g_hud_color = [255, 150, 0] / 255;
else if (getplayerkeyfloat(pl.entnum-1, "*team") == 2)
g_hud_color = [0, 1, 0];
else
g_hud_color = autocvar_con_color * (1 / 255);
#endif
#endif
/* little point in not drawing these, even if you don't have a suit */
if (pl.m_activeWeapon) {
pl.m_activeWeapon.UpdateGUI();
}
HUD_DrawDamageIndicator();
pSeatLocal->weaponSelectionHUD.Draw();
Obituary_Draw();
Textmenu_Draw();
HUD_TimeRemaining();
if (pl.HasItem("item_suit") == false) {
return;
}
HUD_DamageNotify_Draw();
HUD_DrawHealth();
HUD_DrawArmor();
HUD_DrawFlashlight();
HUD_DrawNotify();
Damage_Draw();
}
/* specatator main entry */
void
HUD_DrawSpectator(void)
{
Textmenu_Draw();
ncSpectator spec = (ncSpectator)pSeat->m_ePlayer;
drawfont = Font_GetID(FONT_20);
vector vecPos = [0.0f, 0.0f, 0.0f];
string strText = __NULL__;
float palpha = 1.0f;
if (spec.spec_mode == SPECMODE_FREE) {
palpha = 0.5f;
}
strText = sprintf("Tracking: %s", getplayerkeyvalue(spec.spec_ent - 1, "name"));
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
vecPos[1] = g_hudmins[1] + g_hudres[1] - 60;
drawstring(vecPos, strText, [20,20], [1,1,1], palpha, DRAWFLAG_ADDITIVE);
strText = sprintf("Mode: %s", g_specmodes[spec.spec_mode]);
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
vecPos[1] = g_hudmins[1] + g_hudres[1] - 40;
drawstring(vecPos, strText, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
}
float
HUD_InputFrame(float inputButtons)
{
if (pSeatLocal->weaponSelectionHUD.Active()) {
if (inputButtons & INPUT_PRIMARY) {
pSeatLocal->weaponSelectionHUD.Trigger();
} else if (inputButtons & INPUT_SECONDARY) {
pSeatLocal->weaponSelectionHUD.Deactivate();
}
inputButtons &= ~INPUT_PRIMARY;
inputButtons &= ~INPUT_SECONDARY;
return (0.2f);
}
return (0.0f);
}
bool
HUD_ConsoleCommand(string commandString)
{
tokenize_console(commandString);
switch (argv(0)) {
case "invnext":
pSeatLocal->weaponSelectionHUD.SelectNext(false);
break;
case "invprev":
pSeatLocal->weaponSelectionHUD.SelectPrevious(false);
break;
default:
return (false);
}
return (true);
}

View file

@ -1,138 +0,0 @@
/*
* Copyright (c) 2022-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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.
*/
#ifndef GEARBOX
#define AMMO_COUNT 12
#else
#define AMMO_COUNT 17
#endif
string g_ammo_spr;
typedef struct
{
float alpha;
int count;
} ammonote_t;
ammonote_t g_ammonotify[AMMO_COUNT];
vector g_ammotype[AMMO_COUNT] = {
[0/256, 72/128], // pistol
[24/256, 72/128], // revolver
[48/256, 72/128], // grenade
[72/256, 72/128], // shell
[96/256, 72/128], // arrow
[120/256, 72/128], // rocket
[0/256, 96/128], // uranium
[24/256, 96/128], // hornet
[48/256, 96/128], // grenade
[72/256, 96/128], // satchel
[96/256, 96/128], // snark
[120/256, 96/128], // tripmine
#ifdef GEARBOX
[24/256, 72/128], // 556 (same as 357)
[24/256, 72/128], // 762 (same as 357)
[200/256, 48/128], // spore
[224/256, 48/128], // shock
[144/256, 72/128], // penguin
#endif
};
void
HUD_AmmoNotify_Init(void)
{
g_ammo_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
}
void
HUD_AmmoNotify_Draw(__inout vector pos)
{
pos[0] = g_hudmins[0] + g_hudres[0] - 40;
for (int i = 0; i < AMMO_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_ammonotify[i].alpha <= 0.0f) {
g_ammonotify[i].count = 0;
continue;
}
/* let's get the src img pos for our type */
srcpos = g_ammotype[i];
a = bound(0, g_ammonotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 32 * a]; /* go up a notch */
drawsubpic(pos,
[24,24],
g_ammo_spr,
srcpos,
[24/256, 24/128],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
drawfont = Font_GetID(FONT_20);
string txt = sprintf("%i", g_ammonotify[i].count);
float offs = stringwidth(txt, FALSE, [20,20]);
drawstring(pos + [-offs - 8,4], sprintf("%i", g_ammonotify[i].count), [20,20], g_hud_color, a, DRAWFLAG_ADDITIVE);
g_ammonotify[i].alpha -= (clframetime * 0.5);
}
}
void
HUD_AmmoNotify_Insert(int type, int count)
{
if (count <= 0)
return;
if (type == 7 && count < 8) // hornet hack!
return;
g_ammonotify[type].count += count;
g_ammonotify[type].alpha = 2.5f;
}
/* called whenever we should check for pickup updates */
void
HUD_AmmoNotify_Check(ncPlayer pl)
{
HUD_AmmoNotify_Insert(0, pl.m_iAmmoTypes[1] - pl.m_iAmmoTypes_net[1]);
HUD_AmmoNotify_Insert(1, pl.m_iAmmoTypes[2] - pl.m_iAmmoTypes_net[2]);
HUD_AmmoNotify_Insert(2, pl.m_iAmmoTypes[12] - pl.m_iAmmoTypes_net[12]);
HUD_AmmoNotify_Insert(3, pl.m_iAmmoTypes[3] - pl.m_iAmmoTypes_net[3]);
HUD_AmmoNotify_Insert(4, pl.m_iAmmoTypes[4] - pl.m_iAmmoTypes_net[4]);
HUD_AmmoNotify_Insert(5, pl.m_iAmmoTypes[5] - pl.m_iAmmoTypes_net[5]);
HUD_AmmoNotify_Insert(6, pl.m_iAmmoTypes[6] - pl.m_iAmmoTypes_net[6]);
HUD_AmmoNotify_Insert(7, pl.m_iAmmoTypes[11] - pl.m_iAmmoTypes_net[11]);
HUD_AmmoNotify_Insert(8, pl.m_iAmmoTypes[7] - pl.m_iAmmoTypes_net[7]);
HUD_AmmoNotify_Insert(9, pl.m_iAmmoTypes[8] - pl.m_iAmmoTypes_net[8]);
HUD_AmmoNotify_Insert(10, pl.m_iAmmoTypes[10] - pl.m_iAmmoTypes_net[10]);
HUD_AmmoNotify_Insert(11, pl.m_iAmmoTypes[9] - pl.m_iAmmoTypes_net[9]);
#ifdef GEARBOX
HUD_AmmoNotify_Insert(12, pl.m_iAmmoTypes[13] - pl.m_iAmmoTypes_net[13]);
HUD_AmmoNotify_Insert(13, pl.m_iAmmoTypes[14] - pl.m_iAmmoTypes_net[14]);
HUD_AmmoNotify_Insert(14, pl.m_iAmmoTypes[15] - pl.m_iAmmoTypes_net[15]);
HUD_AmmoNotify_Insert(15, pl.m_iAmmoTypes[16] - pl.m_iAmmoTypes_net[16]);
HUD_AmmoNotify_Insert(16, pl.m_iAmmoTypes[17] - pl.m_iAmmoTypes_net[17]);
#endif
}

View file

@ -1,152 +0,0 @@
/*
* Copyright (c) 2022-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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 DMG_COUNT 8
string g_dmg1_spr;
string g_dmg2_spr;
typedef struct
{
float alpha;
} dmgnote_t;
dmgnote_t g_dmgnotify[DMG_COUNT];
vector g_dmgtype[DMG_COUNT] = {
[0,0], // chemical
[0.25,0], // drown
[0.5,0], // poison
[0.75,0], // shock
[0,0], // nerve gas
[0.25,0], // freeze / slowfreeze
[0.5,0], // burn / slowburn
[0.75,0], // radiation?
};
void
HUD_DamageNotify_Init(void)
{
g_dmg1_spr = spriteframe("sprites/640hud8.spr", 0, 0.0f);
g_dmg2_spr = spriteframe("sprites/640hud9.spr", 0, 0.0f);
}
void
HUD_DamageNotify_Draw(void)
{
vector pos;
pos = g_hudmins + [16, g_hudres[1] - 128];
for (int i = 0; i < DMG_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_dmgnotify[i].alpha <= 0.0f) {
continue;
}
/* let's get the src img pos for our type */
srcpos = g_dmgtype[i];
a = (sin(cltime * 2.5) * 0.5) + 0.5;
a *= bound(0.0f, g_dmgnotify[i].alpha, 1.0);
if (i < 4)
drawsubpic(pos,
[64,64],
g_dmg1_spr,
srcpos,
[64/256, 64/64],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
else
drawsubpic(pos,
[64,64],
g_dmg2_spr,
srcpos,
[64/256, 64/64],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
g_dmgnotify[i].alpha -= (clframetime * 2.0);
pos -= [0, 64]; /* go up a notch */
}
}
typedef enum
{
DMGNOT_CHEMICAL,
DMGNOT_DROWN,
DMGNOT_POISON,
DMGNOT_SHOCK,
DMGNOT_NERVEGAS,
DMGNOT_FREEZE,
DMGNOT_BURN,
DMGNOT_RADIATION
} dmgnot_e;
#define DMG_NOTIFY_SET(x) g_dmgnotify[x].alpha = 10.0f
/* called whenever we should check for pickup updates */
void
HUD_DamageNotify_Check(void)
{
if (pSeat->m_iDamageFlags & DMG_CHEMICAL) {
pSeat->m_iDamageFlags &= ~DMG_CHEMICAL;
DMG_NOTIFY_SET(DMGNOT_CHEMICAL);
}
if (pSeat->m_iDamageFlags & DMG_BURN) {
pSeat->m_iDamageFlags &= ~DMG_BURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (pSeat->m_iDamageFlags & DMG_SLOWBURN) {
pSeat->m_iDamageFlags &= ~DMG_SLOWBURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (pSeat->m_iDamageFlags & DMG_ELECTRO) {
pSeat->m_iDamageFlags &= ~DMG_ELECTRO;
DMG_NOTIFY_SET(DMGNOT_SHOCK);
}
if (pSeat->m_iDamageFlags & DMG_DROWN) {
pSeat->m_iDamageFlags &= ~DMG_DROWN;
DMG_NOTIFY_SET(DMGNOT_DROWN);
}
if (pSeat->m_iDamageFlags & DMG_NERVEGAS) {
pSeat->m_iDamageFlags &= ~DMG_NERVEGAS;
DMG_NOTIFY_SET(DMGNOT_NERVEGAS);
}
if (pSeat->m_iDamageFlags & DMG_POISON) {
pSeat->m_iDamageFlags &= ~DMG_POISON;
DMG_NOTIFY_SET(DMGNOT_POISON);
}
if (pSeat->m_iDamageFlags & DMG_RADIATION) {
pSeat->m_iDamageFlags &= ~DMG_RADIATION;
DMG_NOTIFY_SET(DMGNOT_RADIATION);
}
if (pSeat->m_iDamageFlags & DMG_FREEZE) {
pSeat->m_iDamageFlags &= ~DMG_FREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
if (pSeat->m_iDamageFlags & DMG_SLOWFREEZE) {
pSeat->m_iDamageFlags &= ~DMG_SLOWFREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
}

View file

@ -1,112 +0,0 @@
#define ITEM_COUNT 3
string g_item_spr;
typedef struct
{
float alpha;
int count;
} itemnote_t;
itemnote_t g_itemnotify[ITEM_COUNT];
vector g_itemtype[ITEM_COUNT] = {
[176/256, 0/256], // battery
[176/256, 48/256], // medkit
[176/256, 96/256], // longjump
};
void
HUD_ItemNotify_Init(void)
{
g_item_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
}
void
HUD_ItemNotify_Draw(__inout vector pos)
{
pos[0] = g_hudmins[0] + g_hudres[0] - 44;
for (int i = 0; i < ITEM_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_itemnotify[i].alpha <= 0.0f) {
g_itemnotify[i].count = 0;
continue;
}
/* let's get the src img pos for our type */
srcpos = g_itemtype[i];
a = bound(0, g_itemnotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 52 * a]; /* go up a notch */
drawsubpic(pos + [-20,0],
[44,44],
g_item_spr,
srcpos,
[44/256, 44/256],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
if (g_itemnotify[i].count > 1) {
drawfont = Font_GetID(FONT_20);
string txt = sprintf("%i", g_itemnotify[i].count);
float offs = stringwidth(txt, FALSE, [20,20]) + 16;
drawstring(pos + [-offs - 8,12], sprintf("%i", g_itemnotify[i].count), [20,20], g_hud_color, a, DRAWFLAG_ADDITIVE);
}
g_itemnotify[i].alpha -= (clframetime * 0.5);
}
}
void
HUD_ItemNotify_Insert(int type, int count)
{
if (count <= 0)
return;
g_itemnotify[type].count += count;
g_itemnotify[type].alpha = 2.5f;
}
/* called whenever we should check for pickup updates */
void
HUD_ItemNotify_Check(ncPlayer pl)
{
#if 0
int healthdiff = (int)bound(0, pl.health - pSeatLocal->m_iHealthOld, 100);
int armordiff = (int)bound(0, pl.armor - pSeatLocal->m_iArmorOld, 100);
bool ljDiff = ((pl.g_items & ITEM_LONGJUMP) > (pSeatLocal->m_iItemsOld & ITEM_LONGJUMP)) ? true : false;
bool suitDiff = ((pl.g_items & ITEM_SUIT) > (pSeatLocal->m_iItemsOld & ITEM_SUIT)) ? true : false;
if ((pl.g_items & ITEM_SUIT)) {
if (suitDiff == false) {
if (healthdiff > 1i) {
HUD_ItemNotify_Insert(1, 1);
}
if (armordiff > 1i) {
HUD_ItemNotify_Insert(0, 1);
}
if (ljDiff) {
HUD_ItemNotify_Insert(2, 1);
}
} else {
/* just picked up a suit, reset display values */
pSeatLocal->m_iHealthOld = (int)pl.health;
pSeatLocal->m_iArmorOld = (int)pl.armor;
pSeatLocal->m_iAmmo1Old = (int)pl.a_ammo1;
pSeatLocal->m_iAmmo2Old = (int)pl.a_ammo2;
pSeatLocal->m_iAmmo3Old = (int)pl.a_ammo3;
pSeatLocal->m_iPickupWeapon = 0i;
pSeatLocal->m_flPickupAlpha = 0.0f;
}
}
pSeatLocal->m_iItemsOld = pl.g_items;
#endif
}

View file

@ -29,7 +29,7 @@ HLSprite_CountEntriesInFile(string fileName)
hudFile = fopen(fileName, FILE_READ);
if (hudFile < 0) {
NSError("Missing file %S", fileName);
ncError("Missing file %S", fileName);
return (-1i);
}
@ -65,7 +65,7 @@ HLSprite_LoadFromFile(string fileName, string prefix)
hudFile = fopen(fileName, FILE_READ);
if (hudFile < 0) {
NSError("Missing file %S", fileName);
ncError("Missing file %S", fileName);
return (false);
}
@ -139,9 +139,9 @@ HLSprite_Init(void)
prefix = substring(hudFile, 8, -4);
HLSprite_LoadFromFile(hudFile, prefix);
}
search_end(sh);
NSLog("...initialized %i HL sprites.", spriteCount);
ncLog("...initialized %i HL sprites.", spriteCount);
}
void
@ -152,7 +152,7 @@ HLSprite_Draw_RGBA(string spriteName, vector spritePos, vector spriteColor, floa
spriteNum = (int)hash_get(g_hashhlsprite, spriteName, -1i);
if (spriteNum == -1i) {
NSError("Cannot draw sprite %S!", spriteName);
ncError("Cannot draw sprite %S!", spriteName);
return;
}
@ -198,9 +198,9 @@ HLSprite_DrawCrosshair(string spriteName)
spriteNum = (int)hash_get(g_hashhlsprite, spriteName, -1i);
if (spriteNum == -1i) {
NSError("Cannot draw sprite %S!", spriteName);
ncError("Cannot draw sprite %S!", spriteName);
return;
}
Cross_DrawSub(g_hlsprites[spriteNum].m_strImage, g_hlsprites[spriteNum].m_vecSize, g_hlsprites[spriteNum].m_vecCanvasPos, g_hlsprites[spriteNum].m_vecCanvasSize);
}
}

View file

@ -1,188 +0,0 @@
/*
* Copyright (c) 2016-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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_ForceChange(ncPlayer pl, int targetWeapon);
vector g_vecHUDNums[6] =
{
[168 / 256, 72 / 128],
[188 / 256, 72 / 128],
[208 / 256, 72 / 128],
[168 / 256, 92 / 128],
[188 / 256, 92 / 128],
[208 / 256, 92 / 128]
};
void
HUD_SelectWeapon(ncWeapon nextWeapon)
{
if (!nextWeapon) {
pSeat->m_iHUDWeaponSelected = 0i;
return;
}
pSeat->m_iHUDWeaponSelected = nextWeapon.GetSharedID();
}
/* Select the next item in the list. */
void
HUD_DrawWeaponSelect_Forward(void)
{
}
void
HUD_DrawWeaponSelect_Back(void)
{
}
void
HUD_DrawWeaponSelect_Trigger(void)
{
}
void
HUD_DrawWeaponSelect_Last(void)
{
}
void
HUD_DrawWeaponSelect_Num(vector vecPos, float fValue)
{
drawsubpic(vecPos, [20,20], g_hud7_spr, g_vecHUDNums[fValue], [20/256, 20/128], g_hud_color, 1, DRAWFLAG_ADDITIVE);
}
int
HUD_InSlotPos(int slot, int pos)
{
return (-1);
}
void
HUD_SlotSelect(int slot)
{
#if 0
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
int curslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
int i;
#endif
if (Textmenu_IsActive() == true) {
Textmenu_Input(slot);
return;
}
#if 0
/* hack to see if we have ANY weapons at all. */
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
pl.StartSoundDef("Player.WeaponSelectionOpen", CHAN_ITEM, false);
} else {
pl.StartSoundDef("Player.WeaponSelectionMoveSlot", CHAN_ITEM, false);
}
/* weren't in that slot? select the first one then */
if (curslot != slot) {
for (i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
pSeat->m_iHUDWeaponSelected = i;
pSeat->m_flHUDWeaponSelectTime = time + 3;
break;
}
}
} else {
int first = -1;
for (i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
if (i < pSeat->m_iHUDWeaponSelected && first == -1) {
first = i;
} else if (i > pSeat->m_iHUDWeaponSelected) {
first = -1;
pSeat->m_iHUDWeaponSelected = i;
pSeat->m_flHUDWeaponSelectTime = time + 3;
break;
}
}
}
if (first > 0) {
pSeat->m_iHUDWeaponSelected = first;
pSeat->m_flHUDWeaponSelectTime = time + 3;
}
}
#endif
}
void
HUD_DrawWeaponSelect(void)
{
#if 0
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
if (pSeat->m_iHUDWeaponSelected) {
pl.StartSoundDef("Player.WeaponSelectionClose", CHAN_ITEM, false);
pSeat->m_iHUDWeaponSelected = 0;
}
return;
}
vector vecPos = g_hudmins + [16,16];
int b;
int wantslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
int wantpos = g_weapons[pSeat->m_iHUDWeaponSelected].slot_pos;
for (int i = 0; i < 5; i++) {
int slot_selected = 0;
vecPos[1] = g_hudmins[1] + 16;
HUD_DrawWeaponSelect_Num(vecPos, i);
vecPos[1] += 20;
for (int x = 0; x < 32; x++) {
if (i == wantslot) {
slot_selected = TRUE;
if (x == wantpos) {
// Selected Sprite
Weapons_HUDPic(pl, pSeat->m_iHUDWeaponSelected, 1, vecPos, 1.0f);
drawsubpic(vecPos, [170,45], g_hud3_spr,
[0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
vecPos[1] += 50;
} else if ((b=HUD_InSlotPos(i, x)) != -1) {
// Unselected Sprite
Weapons_HUDPic(pl, b, 0, vecPos, 1.0f);
vecPos[1] += 50;
}
} else if (HUD_InSlotPos(i, x) != -1) {
HUD_DrawWeaponSelect_Num(vecPos, 5);
vecPos[1] += 25;
}
}
if (slot_selected == TRUE) {
vecPos[0] += 175;
} else {
vecPos[0] += 25;
}
}
#endif
}

View file

@ -32,8 +32,6 @@ ClientGame_Init(float apilevel, string enginename, float engineversion)
registercommand("lastinv");
registercommand("invnext");
registercommand("invprev");
pSeatLocal->weaponSelectionHUD = spawn(HLWeaponSelect);
}
void VGUI_ShowMOTD();
@ -53,21 +51,20 @@ ClientGame_InitDone(void)
void
ClientGame_RendererRestart(string rstr)
{
precache_model("models/v_tripmine.mdl");
precache_model("models/shell.mdl");
precache_model("models/shotgunshell.mdl");
precache.Model("models/v_tripmine.mdl");
precache.Model("models/shell.mdl");
precache.Model("models/shotgunshell.mdl");
/* there's also muzzleflash.spr, but that's just MUZZLE_SMALL again */
precache_model("sprites/muzzleflash1.spr");
precache_model("sprites/muzzleflash2.spr");
precache_model("sprites/muzzleflash3.spr");
MUZZLE_RIFLE = (int)getmodelindex("sprites/muzzleflash1.spr");
MUZZLE_SMALL = (int)getmodelindex("sprites/muzzleflash2.spr");
MUZZLE_WEIRD = (int)getmodelindex("sprites/muzzleflash3.spr");
precache.Model("sprites/muzzleflash1.spr");
precache.Model("sprites/muzzleflash2.spr");
precache.Model("sprites/muzzleflash3.spr");
MUZZLE_RIFLE = (int)precache.Model("sprites/muzzleflash1.spr");
MUZZLE_SMALL = (int)precache.Model("sprites/muzzleflash2.spr");
MUZZLE_WEIRD = (int)precache.Model("sprites/muzzleflash3.spr");
HLSprite_Init();
Damage_Precache();
Obituary_Precache();
FX_GaussBeam_Init();

View file

@ -16,7 +16,6 @@
../../../src/gs-entbase/shared.src
../../../valve/src/shared/include.src
../../../valve/src/client/draw.qc
../../../valve/src/client/damage.qc
../../../valve/src/client/init.qc
../../../valve/src/client/flashlight.qc
../../../valve/src/client/entities.qc
@ -26,12 +25,6 @@
../../../valve/src/client/viewmodel.qc
../../../valve/src/client/obituary.qc
../../../valve/src/client/hud_sprite.qc
../../../valve/src/client/hud_itemnotify.qc
../../../valve/src/client/hud_dmgnotify.qc
../../../valve/src/client/hud_ammonotify.qc
../../../valve/src/client/hud.qc
../../../valve/src/client/HLWeaponSelect.qc
../../../valve/src/client/hud_weaponselect.qc
../../../valve/src/client/scoreboard.qc
../../../src/client/include.src
../../../valve/src/client/vgui_changeclass.qc

View file

@ -66,7 +66,7 @@ VGUIChangeClassButton::OnMouseUp(void)
int teamID = player.GetTeam();
string classType = teams.ClassForIndex(teamID, classSelection);
localcmd(sprintf("cmd %s\n", classType));
localcmd(sprintf("cmd join %s\n", classType));
winClassSelection.Hide();
}

View file

@ -41,6 +41,8 @@ VGUITeamSelectButton::OnMouseUp(void)
if (teams.TotalClasses(tag) > 0i) {
VGUI_ChooseClass(tag);
} else {
localcmd(sprintf("cmd join\n", tag));
}
winChooseTeam.Hide();

View file

@ -1,8 +1,9 @@
1644
1645
1 cfg/skill_manifest.cfg
1 cfg/skill_valve.cfg
1 coop.config
1 csprogs.dat
1 hud.dat
1 data/boot_camp.way
1 data/bounce.way
1 data/crossfire.way

4
src/hud/Makefile Normal file
View file

@ -0,0 +1,4 @@
QCC=fteqcc
all:
$(QCC) $(CFLAGS) -I../../../src/client/ hud.qc

View file

@ -25,6 +25,10 @@ public:
virtual void SelectNext(bool);
virtual void SelectPrevious(bool);
nonvirtual void Event_Opened(void);
nonvirtual void Event_Closed(void);
nonvirtual void Event_SelectionChanged(void);
nonvirtual void Event_SelectionTriggered(void);
virtual bool Active(void);
virtual void Trigger(void);
@ -34,8 +38,9 @@ public:
private:
float m_flHUDWeaponSelectTime;
HLWeapon m_selectedWeapon;
HLWeapon m_firstWeapon;
entity m_selectedWeapon;
entity m_firstWeapon;
entity m_lastWeapon;
int m_iWantSlot;
int m_iWantSlotPos;
};

238
src/hud/WeaponSelect.qc Normal file
View file

@ -0,0 +1,238 @@
/*
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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
HLWeaponSelect::HLWeaponSelect(void)
{
m_selectedWeapon = __NULL__;
m_flHUDWeaponSelectTime = 0.0f;
}
void
HLWeaponSelect::Event_Opened(void)
{
localsound("common/wpn_hudon.wav");
}
void
HLWeaponSelect::Event_Closed(void)
{
localsound("common/wpn_hudoff.wav");
}
void
HLWeaponSelect::Event_SelectionChanged(void)
{
localsound("common/wpn_moveselect.wav");
}
void
HLWeaponSelect::Event_SelectionTriggered(void)
{
localsound("common/wpn_select.wav");
}
bool
HLWeaponSelect::Active(void)
{
return (m_flHUDWeaponSelectTime > time) ? (true) : (false);
}
void
HLWeaponSelect::Trigger(void)
{
weapon.SelectWeapon(m_selectedWeapon);
Deactivate();
}
void
HLWeaponSelect::Deactivate(void)
{
m_selectedWeapon = __NULL__;
m_flHUDWeaponSelectTime = 0.0f;
Event_Closed();
}
void
HLWeaponSelect::Draw(void)
{
if (m_flHUDWeaponSelectTime < time) {
Deactivate();
return;
}
if (!m_selectedWeapon) {
return;
}
vector hudMins = screen.HUDMins();
vector hudRes = screen.HUDSize();
vector vecPos = hudMins + [16,16];
float lastSlot = -1;
float currentSlot;
entity linkedList = __NULL__;
/* since we have something in the inventory, start there */
linkedList = m_firstWeapon;
float totalWidth = 120;
totalWidth += (weapon.GetSlot(m_lastWeapon) * 40);
vecPos = hudMins + [hudRes[0] / 2 - (totalWidth / 2),16];
/* iterate through the inventory*/
while (linkedList) {
/* only iterate over weapons */
if (weapon.IsValid(linkedList) == true) {
currentSlot = weapon.GetSlot(linkedList);
/* new slot started, reset Y axis */
if (lastSlot != currentSlot) {
/* new slot, new offset */
if (lastSlot == m_iWantSlot) {
vecPos[0] += 120;
} else {
vecPos[0] += 40;
}
/* quick hack to re-adjust */
if (lastSlot == -1) {
vecPos[0] = hudMins[0] + (hudRes[0] / 2 - (totalWidth / 2));
}
/* slot number icon at the top */
vecPos[1] = hudMins[1] + 16;
}
/* current slot = big bg rect, for every item */
if (m_iWantSlot == currentSlot) {
draw.RoundedBox(vecPos, [112, 80], [0,0,0], g_fg_alpha);
} else {
//
}
/* new slot started */
if (lastSlot != currentSlot) {
/* every slot number is accompanied by their own tiny bg rect */
if (m_iWantSlot != currentSlot) {
draw.RoundedBox(vecPos, [32, 32], [0,0,0], g_fg_alpha * autocvar_hlhud_bucketNumAlpha );
}
/* draw num on top of the bg */
DrawSlotNum(vecPos + [8,8], currentSlot + 1);
} else {
/* draw a RT specific, faint box for every item in the other slots */
if (m_iWantSlot != currentSlot) {
draw.RoundedBox(vecPos, [32, 32], [0,0,0], g_fg_alpha * autocvar_hlhud_altBucket );
}
}
lastSlot = currentSlot;
/* selected slot VS unselected slot */
if (m_iWantSlot == currentSlot) {
if (linkedList == m_selectedWeapon) {
draw.TextField(vecPos + [0, 8], [112, 80], weapon.GetSelectedIcon(linkedList), FONT_WEAPONICON_SEL, 0);
draw.TextField(vecPos + [3, 60], [106, 14], weapon.GetTitle(linkedList), FONT_WEAPONTEXT, 0);
} else {
draw.TextField(vecPos + [0, 8], [112, 80], weapon.GetIcon(linkedList), FONT_WEAPONICON, 0);
}
vecPos[1] += 88;
} else {
vecPos[1] += 40;
}
}
linkedList = weapon.GetNextWeaponRelativeTo(linkedList);
}
}
void
HLWeaponSelect::DrawSlotNum(vector vecPos, float fValue)
{
draw.Text(vecPos, sprintf("%d", fValue), FONT_WEAPONNUM);
}
void
HLWeaponSelect::SelectSlot(int wantedSlot, bool fastSwitch)
{
}
void
HLWeaponSelect::SelectNext(bool fastSwitch)
{
entity currentWeapon = weapon.GetActiveWeapon();
if (!currentWeapon) {
return;
}
m_firstWeapon = weapon.GetFirstWeaponInInventory();
m_lastWeapon = weapon.GetLastWeaponInInventory();
if (!m_selectedWeapon) {
m_selectedWeapon = weapon.GetNextWeaponRelativeTo(currentWeapon);
} else {
m_selectedWeapon = weapon.GetNextWeaponRelativeTo(m_selectedWeapon);
}
/* wrap around */
if (!m_selectedWeapon) {
m_selectedWeapon = m_firstWeapon;
Event_Opened();
} else {
Event_SelectionChanged();
}
m_flHUDWeaponSelectTime = time + autocvar_hlhud_hideTime;
m_iWantSlot = weapon.GetSlot(m_selectedWeapon);
m_iWantSlotPos = weapon.GetSlotPos(m_selectedWeapon);
}
void
HLWeaponSelect::SelectPrevious(bool fastSwitch)
{
entity currentWeapon = weapon.GetActiveWeapon();
if (!currentWeapon) {
return;
}
m_firstWeapon = weapon.GetFirstWeaponInInventory();
m_lastWeapon = weapon.GetLastWeaponInInventory();
if (!m_selectedWeapon) {
m_selectedWeapon = weapon.GetPreviousWeaponRelativeTo(currentWeapon);
} else {
m_selectedWeapon = weapon.GetPreviousWeaponRelativeTo(m_selectedWeapon);
}
/* wrap around */
if (!m_selectedWeapon) {
m_selectedWeapon = m_firstWeapon;
}
if (m_flHUDWeaponSelectTime < time) {
Event_Opened();
} else {
Event_SelectionChanged();
}
m_flHUDWeaponSelectTime = time + autocvar_hlhud_hideTime;
m_iWantSlot = weapon.GetSlot(m_selectedWeapon);
m_iWantSlotPos = weapon.GetSlotPos(m_selectedWeapon);
}

942
src/hud/hud.qc Normal file
View file

@ -0,0 +1,942 @@
#pragma PROGS_DAT "../../hud.dat"
#include "../../../src/client/api.h"
font_s FONT_SMALL;
font_s FONT_BIG;
font_s FONT_WEAPONICON;
font_s FONT_WEAPONNUM;
font_s FONT_WEAPONNUMB;
font_s FONT_VERDANA;
font_s FONT_WEAPONTEXT;
font_s FONT_WEAPONICON_SEL;
var vector autocvar_hlhud_fgColor = [1.0, 0.86, 0.0];
var float autocvar_hlhud_fgAlpha = 0.39f;
var float autocvar_hlhud_altBucket = 0.0;
var float autocvar_hlhud_bucketNumAlpha = 0.5f;
var float autocvar_hlhud_hideTime = 3.0f;
#define g_fg_color autocvar_hlhud_fgColor
#define g_fg_alpha autocvar_hlhud_fgAlpha
#include "WeaponSelect.h"
#include "WeaponSelect.qc"
var string g_ammoPic;
HLWeaponSelect weaponSelectionHUD;
var float g_oldHealth;
var float g_oldArmor;
var float g_oldClip;
var float g_oldAmmo1;
var float g_oldAmmo2;
var vector g_hudMins;
var vector g_hudRes;
var float g_healthAlpha;
var float g_armorAlpha;
var float g_clipAlpha;
var float g_ammo1Alpha;
var float g_ammo2Alpha;
var float g_ammoDisplayAlpha;
var float g_damageAlpha;
var vector g_damageLocation;
var int g_damageFlags;
var string g_damage_spr_t;
var string g_damage_spr_b;
var string g_damage_spr_l;
var string g_damage_spr_r;
var string g_dmg1_spr;
var string g_dmg2_spr;
var string g_hud1_spr;
var string g_hud2_spr;
var string g_hud3_spr;
var string g_hud4_spr;
var string g_hud5_spr;
var string g_hud6_spr;
var string g_hud7_spr;
var float autocvar_cg_damageFill = 0.25f;
#define AMMO_COUNT 17
typedef struct
{
float alpha;
int count;
} ammonote_t;
ammonote_t g_ammonotify[AMMO_COUNT];
vector g_ammotype[AMMO_COUNT] = {
[0/256, 72/128], // pistol
[24/256, 72/128], // revolver
[48/256, 72/128], // grenade
[72/256, 72/128], // shell
[96/256, 72/128], // arrow
[120/256, 72/128], // rocket
[0/256, 96/128], // uranium
[24/256, 96/128], // hornet
[48/256, 96/128], // grenade
[72/256, 96/128], // satchel
[96/256, 96/128], // snark
[120/256, 96/128], // tripmine
[24/256, 72/128], // 556 (same as 357)
[24/256, 72/128], // 762 (same as 357)
[200/256, 48/128], // spore
[224/256, 48/128], // shock
[144/256, 72/128], // penguin
};
void
HUD_AmmoNotify_Draw(__inout vector pos)
{
pos[0] = g_hudMins[0] + g_hudRes[0] - 40;
for (int i = 0; i < AMMO_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_ammonotify[i].alpha <= 0.0f) {
g_ammonotify[i].count = 0;
continue;
}
/* let's get the src img pos for our type */
srcpos = g_ammotype[i];
a = bound(0, g_ammonotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 32 * a]; /* go up a notch */
drawsubpic(pos,
[24,24],
g_hud7_spr,
srcpos,
[24/256, 24/128],
g_fg_color,
a,
DRAWFLAG_ADDITIVE
);
drawfont = 0;
string txt = sprintf("%i", g_ammonotify[i].count);
float offs = stringwidth(txt, FALSE, [20,20]);
draw.Text_RGBA(pos + [-offs - 8,4], sprintf("%i", g_ammonotify[i].count), g_fg_color, a, FONT_BIG);
g_ammonotify[i].alpha -= (clframetime * 0.5);
}
}
void
HUD_AmmoNotify_Insert(int type, int count)
{
if (count <= 0)
return;
if (type == 7 && count < 8) // hornet hack!
return;
g_ammonotify[type].count += count;
g_ammonotify[type].alpha = 2.5f;
}
/** All available damage types. */
typedef enum
{
DMG_GENERIC = 1, /**< Non specific. */
DMG_CRUSH = 2, /**< Being crushed by something heavy. */
DMG_BULLET = 4, /**< Shot by a gun. */
DMG_SLASH = 8, /**< Cutting, from swords or knives. */
DMG_FREEZE = 16, /**< Ice/freezing temperature damage. */
DMG_BURN = 32, /**< Short flame, or on-fire type damage. */
DMG_VEHICLE = 64, /**< Vehicle ramming into you at speed. */
DMG_FALL = 128, /**< Fall damage */
DMG_EXPLODE = 256, /**< Firery explosion damage. */
DMG_BLUNT = 512, /**< Blunt damage, like from a pipe or a bat. */
DMG_ELECTRO = 1024, /**< Electric shock damage. */
DMG_SOUND = 2048, /**< Noise so irritating it creates damage. */
DMG_ENERGYBEAM = 4096, /**< Energy beam damage. */
DMG_GIB_NEVER = 8192, /**< This damage type doesn't cause gibbing. */
DMG_GIB_ALWAYS = 16384, /**< This damage type will always gib. */
DMG_DROWN = 32768, /**< Drown damage, gets restored over time. */
DMG_PARALYZE = 65536, /**< Paralyzation damage. */
DMG_NERVEGAS = 131072, /**< Toxins to the nerve, special effect? */
DMG_POISON = 262144, /**< Poisonous damage. Similar to nervegas? */
DMG_RADIATION = 524288, /**< Radiation damage. Geiger counter go brrr */
DMG_DROWNRECOVER = 1048576, /**< Health increase from drown recovery. */
DMG_CHEMICAL = 2097152, /**< Chemical damage. */
DMG_SLOWBURN = 4194304, /**< Slow burning, just like burning but different rate. */
DMG_SLOWFREEZE = 8388608, /**< Slow freeze, just freezing but different rate. */
DMG_SKIP_ARMOR = 16777216, /**< This damage will skip armor checks entirely. */
DMG_SKIP_RAGDOLL = 33554432 /**< This damage will not affect ragdolls. */
} damageType_t;
#define DMG_ACID DMG_CHEMICAL
#define DMG_COUNT 8
typedef struct
{
float alpha;
} dmgnote_t;
static dmgnote_t g_dmgnotify[DMG_COUNT];
vector g_dmgtype[DMG_COUNT] = {
[0,0], // chemical
[0.25,0], // drown
[0.5,0], // poison
[0.75,0], // shock
[0,0], // nerve gas
[0.25,0], // freeze / slowfreeze
[0.5,0], // burn / slowburn
[0.75,0], // radiation?
};
void
HLHUD_DamageNotifyDraw(vector hudmins, vector res)
{
vector pos;
pos = hudmins + [16, res[1] - 128];
for (int i = 0; i < DMG_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_dmgnotify[i].alpha <= 0.0f) {
continue;
}
/* let's get the src img pos for our type */
srcpos = g_dmgtype[i];
a = (sin(cltime * 2.5) * 0.5) + 0.5;
a *= bound(0.0f, g_dmgnotify[i].alpha, 1.0);
if (i < 4)
drawsubpic(pos,
[64,64],
g_dmg1_spr,
srcpos,
[64/256, 64/64],
g_fg_color,
a,
DRAWFLAG_ADDITIVE
);
else
drawsubpic(pos,
[64,64],
g_dmg2_spr,
srcpos,
[64/256, 64/64],
g_fg_color,
a,
DRAWFLAG_ADDITIVE
);
g_dmgnotify[i].alpha -= (clframetime * 2.0);
pos -= [0, 64]; /* go up a notch */
}
}
typedef enum
{
DMGNOT_CHEMICAL,
DMGNOT_DROWN,
DMGNOT_POISON,
DMGNOT_SHOCK,
DMGNOT_NERVEGAS,
DMGNOT_FREEZE,
DMGNOT_BURN,
DMGNOT_RADIATION
} dmgnot_e;
#define DMG_NOTIFY_SET(x) g_dmgnotify[x].alpha = 10.0f
#define ITEM_COUNT 3
string g_item_spr;
typedef struct
{
float alpha;
int count;
} itemnote_t;
itemnote_t g_itemnotify[ITEM_COUNT];
vector g_itemtype[ITEM_COUNT] = {
[176/256, 0/256], // battery
[176/256, 48/256], // medkit
[176/256, 96/256], // longjump
};
void
HUD_ItemNotify_Draw(__inout vector pos)
{
pos[0] = g_hudMins[0] + g_hudRes[0] - 44;
for (int i = 0; i < ITEM_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_itemnotify[i].alpha <= 0.0f) {
g_itemnotify[i].count = 0;
continue;
}
/* let's get the src img pos for our type */
srcpos = g_itemtype[i];
a = bound(0, g_itemnotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 52 * a]; /* go up a notch */
drawsubpic(pos + [-20,0],
[44,44],
g_hud2_spr,
srcpos,
[44/256, 44/256],
g_fg_color,
a,
DRAWFLAG_ADDITIVE
);
if (g_itemnotify[i].count > 1) {
drawfont = 0;
string txt = sprintf("%i", g_itemnotify[i].count);
float offs = stringwidth(txt, FALSE, [20,20]) + 16;
draw.Text_RGBA(pos + [-offs - 8,12], sprintf("%i", g_itemnotify[i].count), g_fg_color, a, FONT_BIG);
}
g_itemnotify[i].alpha -= (clframetime * 0.5);
}
}
void
HUD_ItemNotify_Insert(int type, int count)
{
if (count <= 0) {
return;
}
g_itemnotify[type].count += count;
g_itemnotify[type].alpha = 2.5f;
}
void
HUD_PickedUpItem(string itemClass)
{
switch (itemClass) {
case "item_battery":
HUD_ItemNotify_Insert(0i, 1i);
break;
case "item_healthkit":
HUD_ItemNotify_Insert(1i, 1i);
break;
case "item_longjump":
HUD_ItemNotify_Insert(2i, 1i);
break;
}
}
void
HLHUD_UpdateTimers(float health, float armor, float clip, float ammo1, float ammo2)
{
if (health != g_oldHealth) {
g_healthAlpha = 1.0;
}
if (armor != g_oldArmor) {
g_armorAlpha = 1.0;
}
if (clip != g_oldClip) {
g_clipAlpha = 1.0;
}
if (ammo1 != g_oldAmmo1) {
g_ammo1Alpha = 1.0;
}
if (ammo2 != g_oldAmmo2) {
g_ammo2Alpha = 1.0;
}
g_oldHealth = health;
g_oldArmor = armor;
g_oldClip = clip;
g_oldAmmo1 = ammo1;
g_oldAmmo2 = ammo2;
}
void
HLHUD_ClampTimers()
{
g_healthAlpha = bound(g_fg_alpha, g_healthAlpha - (clframetime * 0.5), 1.0);
g_armorAlpha = bound(g_fg_alpha, g_armorAlpha - (clframetime * 0.5), 1.0);
g_clipAlpha = bound(g_fg_alpha, g_clipAlpha - (clframetime * 0.5), 1.0);
g_ammo1Alpha = bound(g_fg_alpha, g_ammo1Alpha - (clframetime * 0.5), 1.0);
g_ammo2Alpha = bound(g_fg_alpha, g_ammo2Alpha - (clframetime * 0.5), 1.0);
g_ammoDisplayAlpha = bound(0.0, g_ammoDisplayAlpha - (clframetime * 5), 1.0);
g_damageAlpha = bound(0.0, g_damageAlpha - (clframetime * 1), 1.0);
}
void
HLHUD_BigNums(vector pos, string numString, float alpha)
{
if (alpha > g_fg_alpha) {
float backAlpha = bound(0.0f, alpha - g_fg_alpha, 1.0f);
draw.Text_RGBA(pos + [random(-2,2), 0], numString, g_fg_color, backAlpha, FONT_WEAPONNUMB);
draw.Text_RGBA(pos, numString, g_fg_color, alpha, FONT_BIG);
} else
draw.Text_RGBA(pos, numString, g_fg_color, alpha, FONT_BIG);
}
void
HUD_Init(void)
{
weaponSelectionHUD = spawn(HLWeaponSelect);
}
void
HUD_ReloadVideoResources(void)
{
font.Load("fonts/chat.font", FONT_SMALL);
font.Load("fonts/font20.font", FONT_BIG);
font.Load("fonts/weaponicon.font", FONT_WEAPONICON);
font.Load("fonts/weaponicon_sel.font", FONT_WEAPONICON_SEL);
font.Load("fonts/weapontext.font", FONT_WEAPONTEXT);
font.Load("fonts/weaponnumbers.font", FONT_WEAPONNUM);
font.Load("fonts/weaponnumbers_blurry.font", FONT_WEAPONNUMB);
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
g_hud2_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
g_hud3_spr = spriteframe("sprites/640hud3.spr", 0, 0.0f);
g_hud4_spr = spriteframe("sprites/640hud4.spr", 0, 0.0f);
g_hud5_spr = spriteframe("sprites/640hud5.spr", 0, 0.0f);
g_hud6_spr = spriteframe("sprites/640hud6.spr", 0, 0.0f);
g_hud7_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
g_damage_spr_t = spriteframe("sprites/640_pain.spr", 0, 0.0f);
g_damage_spr_r = spriteframe("sprites/640_pain.spr", 1, 0.0f);
g_damage_spr_b = spriteframe("sprites/640_pain.spr", 2, 0.0f);
g_damage_spr_l = spriteframe("sprites/640_pain.spr", 3, 0.0f);
g_dmg1_spr = spriteframe("sprites/640hud8.spr", 0, 0.0f);
g_dmg2_spr = spriteframe("sprites/640hud9.spr", 0, 0.0f);
}
/* Use first frame for drawing (needs precache) */
#define NUMSIZE_X 24/256
#define NUMSIZE_Y 24/128
#define HUD_ALPHA 0.5
float spr_hudnum[10] = {
0 / 256,
24 / 256,
(24*2) / 256,
(24*3) / 256,
(24*4) / 256,
(24*5) / 256,
(24*6) / 256,
(24*7) / 256,
(24*8) / 256,
(24*9) / 256
};
/* pre-calculated sprite definitions */
float spr_health[4] = {
80 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_suit1[4] = {
0 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_suit2[4] = {
40 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_flash1[4] = {
160 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_flash2[4] = {
112 / 256, // pos x
24 / 128, // pos u
48 / 256, // size x
32 / 128 // size y
};
void
HUD_DrawNumber(int iNumber, vector vecPos, float fAlpha, vector vColor)
{
drawsubpic(vecPos,
[24,24],
g_hud7_spr,
[spr_hudnum[iNumber], 0],
[NUMSIZE_X, NUMSIZE_Y],
vColor,
fAlpha,
DRAWFLAG_ADDITIVE
);
}
void
HUD_DrawNums(float fNumber, vector vecPos, float fAlpha, vector vColor)
{
int iNumber = fNumber;
if (iNumber > 0) {
while (iNumber > 0) {
HUD_DrawNumber((float)iNumber % 10, vecPos, fAlpha, vColor);
iNumber = iNumber / 10;
vecPos[0] -= 20;
}
} else {
HUD_DrawNumber(0, vecPos, fAlpha, vColor);
}
}
void
HUD_DrawHealth(vector pos, float healthValue)
{
if (healthValue > 25) {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
g_fg_color,
g_healthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(healthValue, pos, g_healthAlpha, g_fg_color);
} else {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
[1,0,0],
g_healthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(healthValue, pos, g_healthAlpha, [1,0,0]);
}
}
void
HUD_DrawArmor(vector pos, float armorValue)
{
drawsubpic(
pos + [-80,-9],
[40,40],
g_hud7_spr,
[spr_suit2[0], spr_suit2[1]],
[spr_suit2[2], spr_suit2[3]],
g_fg_color,
g_armorAlpha,
DRAWFLAG_ADDITIVE
);
if (armorValue > 0) {
float perc = bound(0, (armorValue / 100), 1.0);
drawsubpic(
pos + [-80,-9] + [0, 40 * (1.0-perc)],
[40, 40 * perc],
g_hud7_spr,
[spr_suit1[0],spr_suit1[1] + spr_suit1[3] * (1.0-perc)],
[spr_suit1[2], spr_suit1[3] * perc],
g_fg_color,
g_armorAlpha,
DRAWFLAG_ADDITIVE
);
}
HUD_DrawNums(armorValue, pos, g_armorAlpha, g_fg_color);
}
void
HUD_DrawSeperator(vector pos)
{
drawsubpic(pos,
[2,24],
g_hud7_spr,
[240/256, 0],
[2/256, 24/128],
g_fg_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
void
HUD_DrawAmmo1(vector pos, float ammoValue)
{
HUD_DrawNums(ammoValue, pos, g_clipAlpha, g_fg_color);
HUD_DrawSeperator(pos + [30,0]);
}
void
HUD_DrawAmmo2(vector pos, float ammoValue)
{
HUD_DrawNums(ammoValue, pos, g_ammo1Alpha, g_fg_color);
}
void
HUD_DrawAmmo3(vector pos, float ammoValue)
{
HUD_DrawNums(ammoValue, pos, g_ammo2Alpha, g_fg_color);
}
void
HUD_Draw(void)
{
vector pos;
vector hud_mins, hud_size;
float armorValue = player.GetArmor();
float healthValue = player.GetHealth();
int teamID = player.GetTeam();
float clipValue = weapon.GetClip();
float ammoValue = weapon.GetAmmo1();
float ammoValue2 = weapon.GetAmmo2();
float staminaValue = 1.0 - player.GetStamina();
g_hudMins = hud_mins = screen.HUDMins();
g_hudRes = hud_size = screen.HUDSize();
HLHUD_UpdateTimers(healthValue, armorValue, clipValue, ammoValue, ammoValue2);
HLHUD_DamageNotifyDraw(hud_mins, hud_size);
if (1) {
vector pos = g_hudMins + [g_hudRes[0] - 192, g_hudRes[1] - 128];
pos[1] += 48;
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
}
if (g_damageAlpha > 0.0f) {
vector center;
vector rel_pos;
float fw, fw_alpha;
float rt, rt_alpha;
center = hud_mins + (hud_size / 2);
/* the pos relative to the player + view_dir determines which
* and how bright each indicator is drawn. so first get the relative
* position between us and the attacker, then calculate the strength
* of each direction based on a dotproduct tested against our
* camera direction.
*/
vector playerPosition = player.GetCameraPosition();
vector playerAngle = player.GetCameraAngles();
playerPosition[2] = g_damageLocation[2];
rel_pos = vectorNormalize(g_damageLocation - playerPosition);
fw = vectorDot(rel_pos, anglesToForward(playerAngle));
rt = vectorDot(rel_pos, anglesToRight(playerAngle));
fw_alpha = fabs(fw) * g_damageAlpha;
if (fw > 0.25f) {
draw.Pic(center + [-64,-102], g_damage_spr_t,
[128,48], [1,1,1], fw_alpha, DRAWFLAG_ADDITIVE);
} else if (fw < -0.25f) {
draw.Pic(center + [-64,70], g_damage_spr_b,
[128,48], [1,1,1], fw_alpha, DRAWFLAG_ADDITIVE);
}
rt_alpha = fabs(rt) * g_damageAlpha;
if (rt > 0.25f) {
draw.Pic(center + [70,-64], g_damage_spr_r,
[48,128], [1,1,1], rt_alpha, DRAWFLAG_ADDITIVE);
} else if (rt < -0.25f) {
draw.Pic(center + [-102,-64], g_damage_spr_l,
[48,128], [1,1,1], rt_alpha, DRAWFLAG_ADDITIVE);
}
if (autocvar_cg_damageFill > 0.0) {
vector screenSize = screen.Size();
vector finalColor = [1,1,1];
finalColor[1] = finalColor[2] = 1.0 - (g_damageAlpha * autocvar_cg_damageFill);
draw.Pic(hud_mins, "fade_modulate", screenSize, finalColor, 1.0, DRAWFLAG_NORMAL);
}
g_damageAlpha -= clframetime;
}
/* sprinting overlay */
if (staminaValue < 1.0f) {
pos = hud_mins + [16, hud_size[1] - 90];
if (player.IsSprinting()) {
pos = hud_mins + [16, hud_size[1] - 90];
draw.RoundedBox(pos, [102, 36], [0,0,0], 76/255);
draw.Text_RGBA(pos + [8, 24], "SPRINT", g_fg_color, 1.0f, FONT_VERDANA);
} else {
pos = hud_mins + [16, hud_size[1] - 80];
draw.RoundedBox(pos, [102, 26], [0,0,0], 76/255);
}
draw.Text_RGBA(pos + [8, 5], "AUX POWER", g_fg_color, 1.0f, FONT_VERDANA);
for (float f = 0.0f; f <= 1.0f; f += 0.1f) {
if (f < staminaValue)
draw.Rect(pos + [8,15], [6, 4], g_fg_color, 1.0f);
else
draw.Rect(pos + [8,15], [6, 4], g_fg_color, g_fg_alpha);
pos[0] += 9;
}
} else {
if (teams.TeamCount() > 0i) {
pos = hud_mins + [16, hud_size[1] - 65];
draw.RoundedBox(pos, [66, 16], [0,0,0], 76/255);
draw.Text_RGBA(pos + [8, 5], strcat("Team ", teams.Name(teamID)), teams.Color(teamID), 1.0f, FONT_VERDANA);
}
}
pos = hud_mins + [88, hud_size[1] - 42];
HUD_DrawHealth(pos, healthValue);
pos = hud_mins + [198, hud_size[1] - 42];
HUD_DrawArmor(pos, armorValue);
weaponSelectionHUD.Draw();
if (weapon.AmmoRequired() == false) {
HLHUD_ClampTimers();
return;
}
/* ammo displays */
/* ammo 2 */
if (weapon.UsesSecondaryAmmo() == true) {
pos = hud_mins + [hud_size[0] - 72, hud_size[1] - 74];
HUD_DrawAmmo3(pos, ammoValue2);
} else {
pos = hud_mins + [hud_size[0] - 102 - 16, hud_size[1] - 48];
}
if (weapon.GetClipSize() > 0) {
pos = hud_mins + [hud_size[0] - 152, hud_size[1] - 42];
HUD_DrawAmmo1(pos, clipValue);
}
pos = hud_mins + [hud_size[0] - 72, hud_size[1] - 42];
HUD_DrawAmmo2(pos, ammoValue);
HLHUD_ClampTimers();
}
void
HUD_DrawSpectator(vector hud_mins, vector hud_size)
{
}
void
HUD_WeaponSwitched(string weaponName)
{
//g_ammoPic = entityDef.GetKeyValue(weaponName, "ammoIcon");
g_ammoDisplayAlpha = 1.0f;
}
float
HUD_InputFrame(float inputButtons)
{
if (weaponSelectionHUD.Active()) {
if (inputButtons & INPUT_PRIMARY) {
weaponSelectionHUD.Trigger();
} else if (inputButtons & INPUT_SECONDARY) {
weaponSelectionHUD.Deactivate();
}
return (0.2f);
}
return (0.0f);
}
bool
HUD_ConsoleCommand(string commandString)
{
tokenize_console(commandString);
switch (argv(0)) {
case "invnext":
weaponSelectionHUD.SelectNext(false);
break;
case "invprev":
weaponSelectionHUD.SelectPrevious(false);
break;
default:
return (false);
}
return (true);
}
void
HUD_DamageReceived(vector damageLocation, int damagePoints, int damageFlags)
{
if (damagePoints <= 0i) {
return;
}
g_damageAlpha = 1.0;
g_damageLocation = damageLocation;
g_damageFlags = damageFlags;
if (g_damageFlags & DMG_CHEMICAL) {
g_damageFlags &= ~DMG_CHEMICAL;
DMG_NOTIFY_SET(DMGNOT_CHEMICAL);
}
if (g_damageFlags & DMG_BURN) {
g_damageFlags &= ~DMG_BURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (g_damageFlags & DMG_SLOWBURN) {
g_damageFlags &= ~DMG_SLOWBURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (g_damageFlags & DMG_ELECTRO) {
g_damageFlags &= ~DMG_ELECTRO;
DMG_NOTIFY_SET(DMGNOT_SHOCK);
}
if (g_damageFlags & DMG_DROWN) {
g_damageFlags &= ~DMG_DROWN;
DMG_NOTIFY_SET(DMGNOT_DROWN);
}
if (g_damageFlags & DMG_NERVEGAS) {
g_damageFlags &= ~DMG_NERVEGAS;
DMG_NOTIFY_SET(DMGNOT_NERVEGAS);
}
if (g_damageFlags & DMG_POISON) {
g_damageFlags &= ~DMG_POISON;
DMG_NOTIFY_SET(DMGNOT_POISON);
}
if (g_damageFlags & DMG_RADIATION) {
g_damageFlags &= ~DMG_RADIATION;
DMG_NOTIFY_SET(DMGNOT_RADIATION);
}
if (g_damageFlags & DMG_FREEZE) {
g_damageFlags &= ~DMG_FREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
if (g_damageFlags & DMG_SLOWFREEZE) {
g_damageFlags &= ~DMG_SLOWFREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
}
vector g_ammotype[AMMO_COUNT] = {
[0/256, 72/128], // pistol
[24/256, 72/128], // revolver
[48/256, 72/128], // grenade
[72/256, 72/128], // shell
[96/256, 72/128], // arrow
[120/256, 72/128], // rocket
[0/256, 96/128], // uranium
[24/256, 96/128], // hornet
[48/256, 96/128], // grenade
[72/256, 96/128], // satchel
[96/256, 96/128], // snark
[120/256, 96/128], // tripmine
[24/256, 72/128], // 556 (same as 357)
[24/256, 72/128], // 762 (same as 357)
[200/256, 48/128], // spore
[224/256, 48/128], // shock
[144/256, 72/128], // penguin
};
void
HUD_AmmoChanged(int ammoType, int absoluteValue, int deltaValue)
{
string ammoTypeName = ammo.NameForNum(ammoType);
/* if you wonder why this isn't cleaner, this was ported from
the old HUD code. this can be changed to be decl specific at some point! */
switch (ammoTypeName) {
case "ammo_9mm":
HUD_AmmoNotify_Insert(0, deltaValue);
break;
case "ammo_357":
HUD_AmmoNotify_Insert(1, deltaValue);
break;
case "ammo_m203_grenade":
HUD_AmmoNotify_Insert(2, deltaValue);
break;
case "ammo_buckshot":
HUD_AmmoNotify_Insert(3, deltaValue);
break;
case "ammo_bolt":
HUD_AmmoNotify_Insert(4, deltaValue);
break;
case "ammo_rocket":
HUD_AmmoNotify_Insert(5, deltaValue);
break;
case "ammo_uranium":
HUD_AmmoNotify_Insert(6, deltaValue);
break;
case "ammo_hornet":
HUD_AmmoNotify_Insert(7, deltaValue);
break;
case "ammo_handgrenade":
HUD_AmmoNotify_Insert(8, deltaValue);
break;
case "ammo_satchel":
HUD_AmmoNotify_Insert(9, deltaValue);
break;
case "ammo_snark":
HUD_AmmoNotify_Insert(10, deltaValue);
break;
case "ammo_tripmine":
HUD_AmmoNotify_Insert(11, deltaValue);
break;
case "ammo_556":
HUD_AmmoNotify_Insert(12, deltaValue);
break;
case "ammo_762":
HUD_AmmoNotify_Insert(13, deltaValue);
break;
case "ammo_spore":
HUD_AmmoNotify_Insert(14, deltaValue);
break;
case "ammo_shock":
HUD_AmmoNotify_Insert(15, deltaValue);
break;
case "ammo_penguin":
HUD_AmmoNotify_Insert(16, deltaValue);
break;
}
}

View file

@ -37,14 +37,13 @@ AllowFlashlight(void)
void
CodeCallback_Precache(void)
{
motd.LoadDefault();
precache.Entity("player_mp");
}
void
CodeCallback_StartGameType(void)
{
motd.LoadDefault();
if (IsTeamplay() == true) {
int c;
@ -67,7 +66,7 @@ CodeCallback_StartGameType(void)
game.SetSpawnPoint("info_player_deathmatch");
}
for (entity s = world; (s = ents.NextItem(s));) {
for (entity s = world; (s = next.Item(s));) {
string isWeapon = substring(s.classname, 0, 7);
string isAmmo = substring(s.classname, 0, 5);
@ -79,6 +78,24 @@ CodeCallback_StartGameType(void)
}
}
float
HLDM_IndexForName(string modelName)
{
float modelID = 0;
if (modelName != "") {
string playerModel = "";
playerModel = sprintf("models/player/%s/%s.mdl", modelName, modelName);
modelID = getmodelindex(playerModel);
}
if (modelID) {
return (modelID);
}
return getmodelindex("models/player.mdl");
}
void
HLDM_PlayerSpawn(entity playerEntity)
{
@ -86,7 +103,7 @@ HLDM_PlayerSpawn(entity playerEntity)
ents.ChangeToClass(playerEntity, "player_mp");
if (IsTeamplay() == true) {
if (teams.TeamCount() >= 1) {
float teamCount = tokenizebyseparator(g_strTeamList, ";");
float playerTeam = playerEntity.team;
string teamModel;
@ -121,7 +138,7 @@ HLDM_PlayerSpawn(entity playerEntity)
void
CodeCallback_PlayerSpawn(entity playerEntity)
{
if (IsTeamplay() == false) {
if (teams.TeamCount() <= 0) {
HLDM_PlayerSpawn(playerEntity);
} else {
ents.ChangeToClass(playerEntity, "spectator");
@ -139,7 +156,10 @@ CodeCallback_PlayerDisconnect(entity playerEntity)
bool
CodeCallback_PlayerRequestRespawn(entity playerEntity)
{
CodeCallback_PlayerSpawn(playerEntity);
if (is.Alive(playerEntity) == false) {
HLDM_PlayerSpawn(playerEntity);
}
return (true);
}
@ -160,19 +180,27 @@ CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
void
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
{
int fragLimit = cvars.GetInteger("fraglimit");
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
/* death-counter */
playerEntity.deaths++;
/* update score-counter */
if (ents.isPlayer(attacker)) {
if (is.Player(attacker)) {
if (playerEntity == attacker) {
attacker.frags--;
} else {
attacker.frags++;
}
}
if (fragLimit >= 1) {
if (attacker.frags >= fragLimit) {
game.LoadNextMap();
}
}
}
bool
@ -185,7 +213,7 @@ CodeCallback_ClientCommand(entity playerEntity, string command)
string teamName = argv(1);
/* wrong mode */
if (IsTeamplay() == false) {
if (teams.TeamCount() <= 0) {
break;
}
@ -204,6 +232,20 @@ CodeCallback_ClientCommand(entity playerEntity, string command)
break;
}
}
break;
case "join":
string className = argv(1);
if (is.Alive(playerEntity) == true) {
break;
}
if (STRING_SET(className)) {
ents.ChangeToClass(playerEntity, strcat("player_", className));
game.TeleportToSpawn(playerEntity);
} else {
HLDM_PlayerSpawn(playerEntity);
}
break;
default:
return (false);

View file

@ -113,13 +113,13 @@ CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker
playerEntity.deaths++;
/* update score-counter */
if (ents.isPlayer(attacker)) {
if (is.Player(attacker)) {
if (playerEntity == attacker) {
attacker.frags--;
} else {
attacker.frags++;
}
} else if (ents.isSentient(attacker)) {
} else if (is.Sentient(attacker)) {
teams.AddScore(attacker.team, 1);
}
}
@ -130,7 +130,7 @@ CodeCallback_NPCKilled(entity npcEntity, entity inflictor, entity attacker, stri
combat.Obituary(npcEntity.netname, attacker.netname, weapon, "");
/* update score-counter */
if (ents.isPlayer(attacker)) {
if (is.Player(attacker)) {
if (npcEntity == attacker) {
attacker.frags--;
} else {

View file

@ -37,38 +37,38 @@ CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
{
switch (impulseNum) {
case 100:
ents.Input(self, "UseItem", "item_suit", self);
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
break;
case 101:
ents.Input(self, "SetHealth", "100", self);
ents.Input(self, "SetArmor", "100", self);
ents.Input(self, "GiveItem", "item_suit", self);
ents.Input(self, "GiveItem", "weapon_357", self);
ents.Input(self, "GiveItem", "weapon_9mmAR", self);
ents.Input(self, "GiveItem", "weapon_9mmhandgun", self);
ents.Input(self, "GiveItem", "weapon_crossbow", self);
ents.Input(self, "GiveItem", "weapon_crowbar", self);
ents.Input(self, "GiveItem", "weapon_egon", self);
ents.Input(self, "GiveItem", "weapon_gauss", self);
ents.Input(self, "GiveItem", "weapon_handgrenade", self);
ents.Input(self, "GiveItem", "weapon_hornetgun", self);
ents.Input(self, "GiveItem", "weapon_rpg", self);
ents.Input(self, "GiveItem", "weapon_satchel", self);
ents.Input(self, "GiveItem", "weapon_shotgun", self);
ents.Input(self, "GiveItem", "weapon_snark", self);
ents.Input(self, "GiveItem", "weapon_tripmine", self);
ents.Input(self, "GiveAmmo", "ammo_9mm 255", self);
ents.Input(self, "GiveAmmo", "ammo_357 255", self);
ents.Input(self, "GiveAmmo", "ammo_buckshot 255", self);
ents.Input(self, "GiveAmmo", "ammo_bolt 255", self);
ents.Input(self, "GiveAmmo", "ammo_rocket 255", self);
ents.Input(self, "GiveAmmo", "ammo_uranium 255", self);
ents.Input(self, "GiveAmmo", "ammo_handgrenade 255", self);
ents.Input(self, "GiveAmmo", "ammo_satchel 255", self);
ents.Input(self, "GiveAmmo", "ammo_tripmine 255", self);
ents.Input(self, "GiveAmmo", "ammo_snark 255", self);
ents.Input(self, "GiveAmmo", "ammo_hornet 255", self);
ents.Input(self, "GiveAmmo", "ammo_m203_grenade 255", self);
ents.Input(playerEntity, "SetHealth", "100", world);
ents.Input(playerEntity, "SetArmor", "100", world);
ents.Input(playerEntity, "GiveItem", "item_suit", world);
ents.Input(playerEntity, "GiveItem", "weapon_357", world);
ents.Input(playerEntity, "GiveItem", "weapon_9mmAR", world);
ents.Input(playerEntity, "GiveItem", "weapon_9mmhandgun", world);
ents.Input(playerEntity, "GiveItem", "weapon_crossbow", world);
ents.Input(playerEntity, "GiveItem", "weapon_crowbar", world);
ents.Input(playerEntity, "GiveItem", "weapon_egon", world);
ents.Input(playerEntity, "GiveItem", "weapon_gauss", world);
ents.Input(playerEntity, "GiveItem", "weapon_handgrenade", world);
ents.Input(playerEntity, "GiveItem", "weapon_hornetgun", world);
ents.Input(playerEntity, "GiveItem", "weapon_rpg", world);
ents.Input(playerEntity, "GiveItem", "weapon_satchel", world);
ents.Input(playerEntity, "GiveItem", "weapon_shotgun", world);
ents.Input(playerEntity, "GiveItem", "weapon_snark", world);
ents.Input(playerEntity, "GiveItem", "weapon_tripmine", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_9mm 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_357 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_buckshot 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_bolt 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_rocket 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_uranium 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_handgrenade 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_satchel 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_tripmine 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_snark 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_hornet 255", world);
ents.Input(playerEntity, "GiveAmmo", "ammo_m203_grenade 255", world);
break;
default:
return (false);

View file

@ -40,23 +40,23 @@ HLScientist::Respawn(void)
switch (bodyValue) {
case 1i:
m_flPitch = 105;
SetSentencePitch(105);
netname = "Walter";
SetBodyInGroup(1, 1);
break;
case 2i:
m_flPitch = 100;
SetSentencePitch(100);
netname = "Einstein";
SetBodyInGroup(1, 2);
break;
case 3i:
m_flPitch = 95;
SetSentencePitch(95);
netname = "Luther";
SetBodyInGroup(1, 3);
SetSkin(1);
break;
default:
m_flPitch = 100;
SetSentencePitch(100);
netname = "Slick";
SetBodyInGroup(1, 4);
}

View file

@ -17,9 +17,9 @@
void
Game_Worldspawn(void)
{
Sound_Precache("Player.FlashLightOff");
Sound_Precache("Player.FlashLightOn");
Sound_Precache("item_weaponbox.Pickup");
precache_model("models/player.mdl");
precache_model("models/w_weaponbox.mdl");
precache.Sound("Player.FlashLightOff");
precache.Sound("Player.FlashLightOn");
precache.Sound("item_weaponbox.Pickup");
precache.Model("models/player.mdl");
precache.Model("models/w_weaponbox.mdl");
}

View file

@ -23,7 +23,7 @@ HLGaussBeam::Launch(vector startPos, vector launchDir, float fuseOffset, float p
else
FX_GaussBeam(startPos, launchDir, 0, owner);
NSError("fuseOffset: %f", fuseOffset);
ncError("fuseOffset: %f", fuseOffset);
}
void
@ -85,4 +85,4 @@ HLGaussBeam::GaussAttack(float fuseOffset)
}
}
}
#endif
#endif

62
src/shared/HUDCounter.h Normal file
View file

@ -0,0 +1,62 @@
/*! \brief Shared-Entity: HL HUD Sheet Counter */
/*!QUAKED hlHUDCounter (0 1 0) (-8 -8 -8) (8 8 8)
# OVERVIEW
When active, will display an icon and text at its position that can be seen
by players.
# KEYS
- "targetname" : Name
- "Image" : Path of the material that the game will use for the icon.
- "model" : If set, will use this (sprite) model instead.
- "Text" : A localised string to display next to it.
- "additive" : When 1, will force the image to be drawn additive.
# INPUTS
- "Enable" : Enable the entity.
- "Disable" : Disable the entity.
- "Toggle" : Toggles between enabled/disabled states.
- "SetValue" : Overrides the current counter value.
- "Increment" : Increment by the desired amount.
- "Decrement" : Decrement by the desired amount.
# TRIVIA
This entity was introduced in Nuclide in February of 2025.
@ingroup sharedentity
@ingroup pointentity
*/
class
hlHUDCounter:ncPointTrigger
{
public:
void hlHUDCounter(void);
#ifdef SERVER
virtual void SpawnKey(string,string);
virtual void Save(float);
virtual void Restore(string,string);
virtual void Input(entity,string,string);
virtual void Trigger(entity, triggermode_t);
virtual void EvaluateEntity(void);
virtual float SendEntity(entity,float);
#endif
#ifdef CLIENT
virtual void ReceiveEntity(float, float);
virtual void postdraw(void);
#endif
private:
PREDICTED_INT(m_counterValue)
PREDICTED_STRING(m_strIcon)
PREDICTED_STRING(m_strText)
PREDICTED_BOOL(m_bEnabled)
PREDICTED_BOOL(m_bAdditive)
PREDICTED_VECTOR(m_vecPosXY)
PREDICTED_VECTOR_N(colormod)
#ifdef SERVER
int m_teamScore;
#endif
};

264
src/shared/HUDCounter.qc Normal file
View file

@ -0,0 +1,264 @@
/*
* Copyright (c) 2023 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.
*/
enumflags
{
HUDCOUNTER_CHANGED_ORIGIN,
HUDCOUNTER_CHANGED_IMAGE,
HUDCOUNTER_CHANGED_MODELINDEX,
HUDCOUNTER_CHANGED_TEXT,
HUDCOUNTER_CHANGED_STATE,
HUDCOUNTER_CHANGED_COUNTER,
HUDCOUNTER_CHANGED_POSITION,
HUDCOUNTER_CHANGED_RGBA,
};
void
hlHUDCounter::hlHUDCounter(void)
{
m_strIcon =
m_strText = __NULL__;
m_bEnabled = true;
m_bAdditive = false;
m_vecPosXY = [0.0f, 0.0f, 0.0f];
colormod = [255, 255, 255];
#ifdef SERVER
m_teamScore = 0i;
#endif
}
#ifdef SERVER
void
hlHUDCounter::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "image":
m_strIcon = ReadString(strValue);
break;
case "text":
m_strText = ReadString(strValue);
break;
case "additive":
m_bAdditive = ReadBool(strValue);
break;
case "x":
m_vecPosXY[0] = ReadFloat(strValue);
break;
case "y":
m_vecPosXY[1] = ReadFloat(strValue);
break;
case "rendercolor":
colormod = ReadVector(strValue);
break;
case "teamscore":
m_teamScore = ReadInt(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
}
}
void
hlHUDCounter::Save(float handle)
{
super::Save(handle);
SaveString(handle, "m_strIcon", m_strIcon);
SaveString(handle, "m_strText", m_strText);
SaveBool(handle, "m_bEnabled", m_bEnabled);
SaveBool(handle, "m_bAdditive", m_bAdditive);
SaveInt(handle, "m_counterValue", m_counterValue);
SaveVector(handle, "m_vecPosXY", m_vecPosXY);
}
void
hlHUDCounter::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_strIcon":
m_strIcon = ReadString(strValue);
break;
case "m_strText":
m_strText = ReadString(strValue);
break;
case "m_bAdditive":
m_bAdditive = ReadBool(strValue);
break;
case "m_bEnabled":
m_bEnabled = ReadBool(strValue);
break;
case "m_counterValue":
m_counterValue = ReadInt(strValue);
break;
case "m_vecPosXY":
m_vecPosXY = ReadVector(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
hlHUDCounter::Trigger(entity act, triggermode_t state)
{
switch (state) {
case TRIG_OFF:
m_bEnabled = false;
break;
case TRIG_ON:
m_bEnabled = true;
break;
default:
m_bEnabled = m_bEnabled ? false : true;
}
}
void
hlHUDCounter::Input(entity eAct, string strInput, string strData)
{
switch (strInput) {
case "Enable":
Trigger(eAct, TRIG_ON);
break;
case "Disable":
Trigger(eAct, TRIG_OFF);
break;
case "Toggle":
Trigger(eAct, TRIG_TOGGLE);
break;
case "SetValue":
m_counterValue = ReadInt(strData);
SetModel(GetSpawnString("model"));
break;
case "Increment":
m_counterValue += ReadInt(strData);
break;
case "Decrement":
m_counterValue -= ReadInt(strData);
break;
default:
super::Input(eAct, strInput, strData);
}
}
void
hlHUDCounter::EvaluateEntity(void)
{
if (m_teamScore >= 1i) {
m_counterValue = teams.Score(m_teamScore);
}
EVALUATE_VECTOR(origin, 0, HUDCOUNTER_CHANGED_ORIGIN)
EVALUATE_VECTOR(origin, 1, HUDCOUNTER_CHANGED_ORIGIN)
EVALUATE_VECTOR(origin, 2, HUDCOUNTER_CHANGED_ORIGIN)
EVALUATE_FIELD(modelindex, HUDCOUNTER_CHANGED_MODELINDEX)
EVALUATE_FIELD(m_bAdditive, HUDCOUNTER_CHANGED_MODELINDEX)
EVALUATE_FIELD(m_strIcon, HUDCOUNTER_CHANGED_IMAGE)
EVALUATE_FIELD(m_strText, HUDCOUNTER_CHANGED_TEXT)
EVALUATE_FIELD(m_bEnabled, HUDCOUNTER_CHANGED_STATE)
EVALUATE_FIELD(m_counterValue, HUDCOUNTER_CHANGED_COUNTER)
EVALUATE_FIELD(m_vecPosXY, HUDCOUNTER_CHANGED_POSITION)
EVALUATE_FIELD(colormod, HUDCOUNTER_CHANGED_RGBA)
pvsflags = PVSF_IGNOREPVS;
}
float
hlHUDCounter::SendEntity(entity ePEnt, float flChanged)
{
WriteByte(MSG_ENTITY, ENT_HLHUDCOUNTER);
WriteFloat(MSG_ENTITY, flChanged);
SENDENTITY_COORD(origin[0], HUDCOUNTER_CHANGED_ORIGIN)
SENDENTITY_COORD(origin[1], HUDCOUNTER_CHANGED_ORIGIN)
SENDENTITY_COORD(origin[2], HUDCOUNTER_CHANGED_ORIGIN)
SENDENTITY_FLOAT(modelindex, HUDCOUNTER_CHANGED_MODELINDEX)
SENDENTITY_FLOAT(m_bAdditive, HUDCOUNTER_CHANGED_MODELINDEX)
SENDENTITY_STRING(m_strIcon, HUDCOUNTER_CHANGED_IMAGE)
SENDENTITY_STRING(m_strText, HUDCOUNTER_CHANGED_TEXT)
SENDENTITY_BYTE(m_bEnabled, HUDCOUNTER_CHANGED_STATE)
SENDENTITY_INT(m_counterValue, HUDCOUNTER_CHANGED_COUNTER)
SENDENTITY_FLOAT(m_vecPosXY[0], HUDCOUNTER_CHANGED_POSITION)
SENDENTITY_FLOAT(m_vecPosXY[1], HUDCOUNTER_CHANGED_POSITION)
SENDENTITY_BYTE(colormod[0], HUDCOUNTER_CHANGED_RGBA)
SENDENTITY_BYTE(colormod[1], HUDCOUNTER_CHANGED_RGBA)
SENDENTITY_BYTE(colormod[2], HUDCOUNTER_CHANGED_RGBA)
return true;
}
#endif
#ifdef CLIENT
void
hlHUDCounter::ReceiveEntity(float flNew, float flChanged)
{
READENTITY_COORD(origin[0], HUDCOUNTER_CHANGED_ORIGIN)
READENTITY_COORD(origin[1], HUDCOUNTER_CHANGED_ORIGIN)
READENTITY_COORD(origin[2], HUDCOUNTER_CHANGED_ORIGIN)
READENTITY_FLOAT(modelindex, HUDCOUNTER_CHANGED_MODELINDEX)
READENTITY_FLOAT(m_bAdditive, HUDCOUNTER_CHANGED_MODELINDEX)
READENTITY_STRING(m_strIcon, HUDCOUNTER_CHANGED_IMAGE)
READENTITY_STRING(m_strText, HUDCOUNTER_CHANGED_TEXT)
READENTITY_BYTE(m_bEnabled, HUDCOUNTER_CHANGED_STATE)
READENTITY_INT(m_counterValue, HUDCOUNTER_CHANGED_COUNTER)
READENTITY_FLOAT(m_vecPosXY[0], HUDCOUNTER_CHANGED_POSITION)
READENTITY_FLOAT(m_vecPosXY[1], HUDCOUNTER_CHANGED_POSITION)
READENTITY_BYTE(colormod[0], HUDCOUNTER_CHANGED_RGBA)
READENTITY_BYTE(colormod[1], HUDCOUNTER_CHANGED_RGBA)
READENTITY_BYTE(colormod[2], HUDCOUNTER_CHANGED_RGBA)
setorigin(this, origin);
if (modelindex) {
m_strIcon = spriteframe(modelnameforindex(modelindex), 0, 0.0f);
}
}
void
hlHUDCounter::postdraw(void)
{
if (!m_bEnabled)
return;
float textLength = Font_StringWidth(m_strText, true, FONT_CON);
vector vecProj = g_vec_null;
vector projectedPos = g_vec_null;
float a = 1.0f;
if (m_vecPosXY[0] == -1) {
vecProj[0] = g_hudmins[0] + (g_hudres[0] / 2) - 32;
} else {
vecProj[0] = g_hudmins[0] + ((g_hudres[0] - 64) * m_vecPosXY[0]);
}
if (m_vecPosXY[1] == -1) {
vecProj[1] = g_hudmins[1] + (g_hudres[1] / 2) - 32;
} else {
vecProj[1] = g_hudmins[1] + ((g_hudres[1] - 64) * m_vecPosXY[1]);
}
if (modelindex) {
if (!m_bAdditive) {
drawpic(vecProj, m_strIcon, [64, 64], [1,1,1], a);
} else {
drawpic(vecProj, m_strIcon, [64, 64], [1,1,1], a, DRAWFLAG_ADDITIVE);
}
} else {
HLSprite_Draw_RGBA(m_strIcon, vecProj, colormod / 255, a, m_bAdditive);
}
/* counter */
projectedPos = vecProj + [64, 12];
//HUD_DrawNums((float)m_counterValue, projectedPos, 1.0, colormod / 255);
}
#endif

View file

@ -23,9 +23,9 @@ enumflags
PLAYER_BOTTOMFRAME
};
class HLPlayer:ncPlayer
class hlPlayer:ncPlayer
{
void(void) HLPlayer;
void(void) hlPlayer;
/* animation */
PREDICTED_INT(anim_top)
@ -43,7 +43,6 @@ class HLPlayer:ncPlayer
virtual void PredictPreFrame(void);
virtual void PredictPostFrame(void);
virtual void UpdateAliveCam(void);
virtual void ClientInputFrame(void);
#else
virtual void Death(entity, entity, int, vector, vector, int);
virtual void EvaluateEntity(void);
@ -53,11 +52,11 @@ class HLPlayer:ncPlayer
#endif
};
void Animation_PlayerTop(HLPlayer, float, float);
void Animation_PlayerBottom(HLPlayer, float, float);
void Animation_PlayerTop(hlPlayer, float, float);
void Animation_PlayerBottom(hlPlayer, float, float);
void
HLPlayer::HLPlayer(void)
hlPlayer::hlPlayer(void)
{
anim_top = 0;
anim_top_time = 0;
@ -66,11 +65,11 @@ HLPlayer::HLPlayer(void)
anim_bottom_time = 0;
}
void Animation_PlayerUpdate(HLPlayer);
void Animation_TimerUpdate(HLPlayer, float);
void Animation_PlayerUpdate(hlPlayer);
void Animation_TimerUpdate(hlPlayer, float);
void
HLPlayer::UpdatePlayerAnimation(float timelength)
hlPlayer::UpdatePlayerAnimation(float timelength)
{
/* calculate our skeletal progression */
Animation_PlayerUpdate(this);
@ -79,28 +78,12 @@ HLPlayer::UpdatePlayerAnimation(float timelength)
}
#ifdef CLIENT
void
HLPlayer::ClientInputFrame(void)
{
if (pSeatLocal->weaponSelectionHUD.Active()) {
if (input_buttons & INPUT_PRIMARY) {
pSeatLocal->weaponSelectionHUD.Trigger();
} else if (input_buttons & INPUT_SECONDARY) {
pSeatLocal->weaponSelectionHUD.Deactivate();
}
pSeat->m_flInputBlockTime = time + 0.2;
}
super::ClientInputFrame();
}
void Camera_RunPosBob(vector angles, __inout vector camera_pos);
void Camera_StrafeRoll(__inout vector camera_angle);
void Shake_Update(ncPlayer);
void
HLPlayer::UpdateAliveCam(void)
hlPlayer::UpdateAliveCam(void)
{
vector cam_pos = GetEyePos();
Camera_RunPosBob(view_angles, cam_pos);
@ -119,13 +102,13 @@ HLPlayer::UpdateAliveCam(void)
makevectors(view_angles);
vector vStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
vector vEnd = vStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
traceline(vStart, vEnd, FALSE, this);
traceline(vStart, vEnd, MOVE_NORMAL, this);
g_view.SetCameraOrigin(trace_endpos + (v_forward * 5));
}
}
Shake_Update(this);
g_view.AddPunchAngle(punchangle);
g_view.AddPunchAngle(m_punchAngle);
}
.string oldmodel;
@ -135,7 +118,7 @@ var bool autocvar_cg_flashlightClassic = true;
var float autocvar_r_shadow_realtime_dlight;
void
HLPlayer::UpdatePlayerAttachments(bool visible)
hlPlayer::UpdatePlayerAttachments(bool visible)
{
/* draw the flashlight */
if (gflags & GF_FLASHLIGHT) {
@ -219,15 +202,13 @@ HLPlayer::UpdatePlayerAttachments(bool visible)
}
}
void HUD_AmmoNotify_Check(ncPlayer pl);
void HUD_ItemNotify_Check(ncPlayer pl);
/*
=================
HLPlayer::ReceiveEntity
hlPlayer::ReceiveEntity
=================
*/
void
HLPlayer::ReceiveEntity(float new, float flChanged)
hlPlayer::ReceiveEntity(float new, float flChanged)
{
/* the generic client attributes */
super::ReceiveEntity(new, flChanged);
@ -241,33 +222,27 @@ HLPlayer::ReceiveEntity(float new, float flChanged)
setorigin(this, origin);
/* these only concern the current HLPlayer */
/* these only concern the current hlPlayer */
CSQC_UpdateSeat();
if (this != pSeat->m_ePlayer)
return;
/* do not notify us of updates when spawning initially */
if (flChanged == UPDATE_ALL)
if (flChanged == UPDATE_ALL) {
PredictPreFrame();
if (flChanged & PLAYER_AMMOTYPES ) {
HUD_AmmoNotify_Check(this);
}
if (flChanged & PLAYER_ITEMS || flChanged & PLAYER_HEALTH)
HUD_ItemNotify_Check(this);
}
/*
=================
HLPlayer::PredictPostFrame
hlPlayer::PredictPostFrame
Save the last valid server values away in the _net variants of each field
so we can roll them back later.
=================
*/
void
HLPlayer::PredictPreFrame(void)
hlPlayer::PredictPreFrame(void)
{
/* the generic client attributes */
super::PredictPreFrame();
@ -281,13 +256,13 @@ HLPlayer::PredictPreFrame(void)
/*
=================
HLPlayer::PredictPostFrame
hlPlayer::PredictPostFrame
Where we roll back our values to the ones last sent/verified by the server.
=================
*/
void
HLPlayer::PredictPostFrame(void)
hlPlayer::PredictPostFrame(void)
{
/* the generic client attributes */
super::PredictPostFrame();
@ -301,7 +276,7 @@ HLPlayer::PredictPostFrame(void)
#else
void
HLPlayer::Save(float handle)
hlPlayer::Save(float handle)
{
super::Save(handle);
@ -313,7 +288,7 @@ HLPlayer::Save(float handle)
}
void
HLPlayer::Restore(string strKey, string strValue)
hlPlayer::Restore(string strKey, string strValue)
{
switch (strKey) {
case "anim_top":
@ -337,7 +312,7 @@ HLPlayer::Restore(string strKey, string strValue)
}
void
HLPlayer::EvaluateEntity(void)
hlPlayer::EvaluateEntity(void)
{
/* the generic client attributes */
ncPlayer::EvaluateEntity();
@ -351,7 +326,7 @@ HLPlayer::EvaluateEntity(void)
}
void
HLPlayer::Death(entity inflictor, entity attacker, int damagePoints, vector dir, vector absImpactPos, int hitBody)
hlPlayer::Death(entity inflictor, entity attacker, int damagePoints, vector dir, vector absImpactPos, int hitBody)
{
/* either gib, or make a corpse */
if (GetHealth()< -50) {
@ -384,12 +359,7 @@ HLPlayer::Death(entity inflictor, entity attacker, int damagePoints, vector dir,
break;
}
ncEntity newCorpse = (ncEntity)BodyQue_Spawn(this, deathAnimation);
/* if we were crouching, adjust the bbox (thx 2 lack of crouch death animation) */
if (IsCrouching()) {
newCorpse.SetSize(VEC_HULL_MIN, [16, 16, -16]);
}
MakeCorpse(deathAnimation);
}
super::Death(inflictor, attacker, damagePoints, dir, absImpactPos, hitBody);
@ -397,17 +367,17 @@ HLPlayer::Death(entity inflictor, entity attacker, int damagePoints, vector dir,
/*
=================
HLPlayer::SendEntity
hlPlayer::SendEntity
=================
*/
float
HLPlayer::SendEntity(entity ePEnt, float flChanged)
hlPlayer::SendEntity(entity ePEnt, float flChanged)
{
/* just-in-case. */
if (IsPlayer() == false)
return (0);
/* don't broadcast invisible HLPlayers */
/* don't broadcast invisible hlPlayers */
if (IsFakeSpectator() && ePEnt != this)
return (0);
if (!GetModelindex() && ePEnt != this)
@ -429,7 +399,7 @@ HLPlayer::SendEntity(entity ePEnt, float flChanged)
#endif
void
HLPlayer::Physics_Jump(void)
hlPlayer::Physics_Jump(void)
{
if (waterlevel >= 2) {
if (watertype == CONTENT_WATER) {

View file

@ -15,7 +15,7 @@
*/
/*! \brief Half-Life weapon base class. */
/*!QUAKED HLWeapon (0 0.8 0.8) (-16 -16 0) (16 16 72)
/*!QUAKED hlWeapon (0 0.8 0.8) (-16 -16 0) (16 16 72)
# OVERVIEW
Half-Life specific weapon based on ncWeapon.
@ -32,10 +32,10 @@ Since the weapon specific files only contain short names like `ammo` and `crossh
For example, `ammoIcon` being set to `weapon_foobar.ammo` will look up `ammo` inside `sprites/weapon_foobar.txt`.
*/
class
HLWeapon:ncWeapon
hlWeapon:ncWeapon
{
public:
void HLWeapon(void);
void hlWeapon(void);
virtual void AddedToInventory(void);
@ -60,4 +60,4 @@ private:
ncWeapon m_nextWeapon;
#endif
bool m_bAltModeLaser;
};
};

View file

@ -15,7 +15,7 @@
*/
void
HLWeapon::HLWeapon(void)
hlWeapon::hlWeapon(void)
{
#ifdef CLIENT
m_iHudSlot = 0i;
@ -30,7 +30,7 @@ HLWeapon::HLWeapon(void)
#ifdef SERVER
void
HLWeapon::SpawnKey(string keyName, string setValue)
hlWeapon::SpawnKey(string keyName, string setValue)
{
switch (keyName) {
default:
@ -40,7 +40,7 @@ HLWeapon::SpawnKey(string keyName, string setValue)
#endif
void
HLWeapon::AddedToInventory(void)
hlWeapon::AddedToInventory(void)
{
super::AddedToInventory();
@ -48,31 +48,31 @@ HLWeapon::AddedToInventory(void)
m_ammoIcon = GetDefString("ammoIcon");
if (m_ammoIcon == "") {
m_ammoIcon = sprintf("%s.ammo", strtolower(classname));
m_ammoIcon = sprintf("%s.ammo", strtolower(declclass));
}
m_ammo2Icon = GetDefString("ammo2Icon");
if (m_ammo2Icon == "") {
m_ammo2Icon = sprintf("%s.ammo2", strtolower(classname));
m_ammo2Icon = sprintf("%s.ammo2", strtolower(declclass));
}
m_crossHair = GetDefString("crosshair");
if (m_crossHair == "") {
m_crossHair = sprintf("%s.crosshair", strtolower(classname));
m_crossHair = sprintf("%s.crosshair", strtolower(declclass));
}
m_icon = GetDefString("icon");
if (m_icon == "") {
m_icon = sprintf("%s.weapon", strtolower(classname));
m_icon = sprintf("%s.weapon", strtolower(declclass));
}
m_iconSel = GetDefString("iconSelected");
if (m_iconSel == "") {
m_iconSel = sprintf("%s.weapon_s", strtolower(classname));
m_iconSel = sprintf("%s.weapon_s", strtolower(declclass));
}
if (m_ammoIcon == "none") {
@ -105,8 +105,9 @@ HLWeapon::AddedToInventory(void)
#ifdef CLIENT
void
HLWeapon::UpdateGUI(void)
hlWeapon::UpdateGUI(void)
{
#if 0
ncPlayer ourOwner = __NULL__;
vector ammoPos;
@ -119,7 +120,7 @@ HLWeapon::UpdateGUI(void)
HLSprite_Draw_RGBA(m_ammoIcon, ammoPos, g_hud_color, pSeatLocal->m_flAmmo2Alpha, true);
}
if (m_iMode && m_bAltModeLaser) {
if (FireInfoSelected() && m_bAltModeLaser) {
DrawLaser();
}
@ -128,7 +129,7 @@ HLWeapon::UpdateGUI(void)
vector vMainPos;
float progress;
progress = (m_flOverheating / m_fiOverheatLength);
progress = (OverheatingProgress() / m_fiOverheatLength);
if (progress > 1.0) {
progress = 1.0f;
@ -150,14 +151,14 @@ HLWeapon::UpdateGUI(void)
}
#endif
if (m_bAmmoRequired == false) {
if (RequiresAmmo() == false) {
return;
}
ourOwner = (ncPlayer)GetOwner();
if (m_iClipSize > 0i) {
ourOwner.a_ammo1 = m_iClip;
if (GetClipSize() > 0i) {
ourOwner.a_ammo1 = GetClip();
HUD_DrawAmmo1();
}
@ -174,10 +175,11 @@ HLWeapon::UpdateGUI(void)
HLSprite_Draw_RGBA(m_ammo2Icon, ammoPos, g_hud_color, pSeatLocal->m_flAmmo2Alpha, true);
}
}
#endif
}
void
HLWeapon::DrawLaser(void)
hlWeapon::DrawLaser(void)
{
ncPlayer ourOwner = (ncPlayer)GetOwner();
float lerpValue;

View file

@ -35,7 +35,7 @@ void Animation_Print(string sWow) {
}
void
Animation_TimerUpdate(HLPlayer pl, float ftime)
Animation_TimerUpdate(hlPlayer pl, float ftime)
{
makevectors([0, pl.v_angle[1], 0]);
@ -60,7 +60,7 @@ depending on what the player is doing
=================
*/
void
Animation_PlayerUpdate(HLPlayer pl)
Animation_PlayerUpdate(hlPlayer pl)
{
pl.basebone = gettagindex(pl, "Bip01 Spine1");
@ -116,7 +116,7 @@ Animation_PlayerUpdate(HLPlayer pl)
}
void
Animation_PlayerTop(HLPlayer pl, float topanim, float timer)
Animation_PlayerTop(hlPlayer pl, float topanim, float timer)
{
pl.anim_top = topanim;
pl.anim_top_time = 0.0f;
@ -124,7 +124,7 @@ Animation_PlayerTop(HLPlayer pl, float topanim, float timer)
}
void
Animation_PlayerBottom(HLPlayer pl, float botanim, float timer)
Animation_PlayerBottom(hlPlayer pl, float botanim, float timer)
{
pl.anim_bottom = botanim;
}

View file

@ -1 +1,2 @@
#include "HLWeapon.h"
#include "Weapon.h"
#include "HUDCounter.h"

View file

@ -16,5 +16,6 @@
enum
{
ENT_TRIPMINE = ENT_SEPARATOR
ENT_TRIPMINE = ENT_SEPARATOR,
ENT_HLHUDCOUNTER
};

View file

@ -25,7 +25,7 @@ FX_GaussBeam_Init(void)
TRAIL_GAUSSBEAM = particleeffectnum("weapon_gauss.beam");
precache_model("sprites/yelflare1.spr");
precache_model("sprites/yelflare2.spr");
Sound_Precache("fx.gaussbeam");
SoundDef_Precache("fx.gaussbeam");
}
void
@ -92,7 +92,7 @@ FX_GaussBeam_Piece(vector vecPos, vector vecFlyDir)
float r = random();
Sound_PlayAt(vecPos, "fx.gaussbeam");
SoundDef_PlayAt(vecPos, "fx.gaussbeam");
for (int i = 0; i < 4; i++) {
entity sub = spawn();

View file

@ -3,10 +3,11 @@
../../../valve/src/shared/events.h
../../../valve/src/shared/flags.h
../../../valve/src/shared/skeleton.h
../../../valve/src/shared/player.qc
../../../valve/src/shared/Player.qc
../../../valve/src/shared/animations.qc
../../../valve/src/shared/fx_gaussbeam.qc
../../../valve/src/shared/HLGaussBeam.qc
../../../valve/src/shared/HLWeapon.qc
../../../valve/src/shared/GaussBeam.qc
../../../valve/src/shared/Weapon.qc
../../../valve/src/shared/w_tripmine.qc
../../../valve/src/shared/HUDCounter.qc
#endlist

View file

@ -32,9 +32,9 @@ enum
* Because not being able to place it around levels would be boring.
* Some maps, such as subtransit and a few singleplayer chapters have this. */
class HLTripmine:ncSurfacePropEntity
class hlTripmine:ncSurfacePropEntity
{
void HLTripmine(void);
void hlTripmine(void);
#ifdef SERVER
virtual void Respawn(void);
@ -60,7 +60,7 @@ private:
};
void
HLTripmine::HLTripmine(void)
hlTripmine::hlTripmine(void)
{
#ifdef CLIENT
solid = SOLID_BBOX;
@ -73,14 +73,14 @@ HLTripmine::HLTripmine(void)
#ifdef SERVER
void
HLTripmine::Respawn(void)
hlTripmine::Respawn(void)
{
super::Respawn();
RestoreAngles();
}
void
HLTripmine::Spawned(void)
hlTripmine::Spawned(void)
{
super::Spawned();
@ -99,7 +99,7 @@ HLTripmine::Spawned(void)
}
void
HLTripmine::Death(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
hlTripmine::Death(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
{
vector explosionPos = GetOrigin();
float explosionDamage = Skill_GetValue("plr_tripmine", 150);
@ -116,13 +116,13 @@ HLTripmine::Death(entity inflictor, entity attacker, int damage, vector dir, vec
}
void
HLTripmine::Pain(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
hlTripmine::Pain(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
{
Death(inflictor, attacker, damage, dir, absImpactPos, hitBody);
}
void
HLTripmine::Ready(void)
hlTripmine::Ready(void)
{
traceline(origin, origin + GetForward() * 2048, FALSE, this);
@ -148,7 +148,7 @@ HLTripmine::Ready(void)
}
float
HLTripmine::SendEntity(entity ePEnt, float flChanged)
hlTripmine::SendEntity(entity ePEnt, float flChanged)
{
WriteByte(MSG_ENTITY, ENT_TRIPMINE);
WriteFloat(MSG_ENTITY, flChanged);
@ -168,7 +168,7 @@ HLTripmine::SendEntity(entity ePEnt, float flChanged)
#ifdef CLIENT
void
HLTripmine::ReceiveEntity(float flNew, float flChanged)
hlTripmine::ReceiveEntity(float flNew, float flChanged)
{
this.origin[0] = readcoord();
this.origin[1] = readcoord();
@ -189,7 +189,7 @@ HLTripmine::ReceiveEntity(float flNew, float flChanged)
}
float
HLTripmine::predraw(void)
hlTripmine::predraw(void)
{
if (m_iActive) {
trailparticles(BEAM_TRIPMINE, this, GetOrigin(), m_vecEndPos);