Compare commits
No commits in common. "Develop" and "master" have entirely different histories.
BIN
.dir.tiff
|
@ -1,6 +1,6 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2016-2025, Marco "eukara" Cawthorne <marco@icculus.org>
|
||||
Copyright (c) 2016-2021, Marco "eukara" Hladik <marco@icculus.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
1
PAK_NAME
|
@ -1 +0,0 @@
|
|||
package_tfc.pk3
|
1
PROJECT
|
@ -1 +0,0 @@
|
|||
TeamEffort
|
|
@ -1,5 +1,4 @@
|
|||
#  Team Effort
|
||||
|
||||
# FreeTFC
|
||||
Clean-room reimplementation of Team Fortress Classic in QuakeC.
|
||||
|
||||

|
||||
|
@ -9,7 +8,8 @@ Clone the repository into the Nuclide-SDK:
|
|||
|
||||
> git clone REPOURL tfc
|
||||
|
||||
Then run `make game GAME=tfc`!
|
||||
then either run Nuclide's ./build_game.sh shell script, or issue 'make' inside
|
||||
./tfc/src!
|
||||
|
||||
Obviously make sure that Nuclide has fteqw and fteqcc set-up for building.
|
||||
|
||||
|
@ -29,7 +29,7 @@ We've had people ask in the oddest of places for help, please don't do that.
|
|||
## License
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2016-2025 Marco Cawthorne <marco@icculus.org>
|
||||
Copyright (c) 2016-2021 Marco Hladik <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
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
set sk_plr_ac1 "32"
|
||||
set sk_plr_ac2 "32"
|
||||
set sk_plr_ac3 "32"
|
||||
set sk_plr_autorifle1 "8"
|
||||
set sk_plr_autorifle2 "8"
|
||||
set sk_plr_autorifle3 "8"
|
||||
set sk_plr_bioweapon1 "8"
|
||||
set sk_plr_bioweapon2 "8"
|
||||
set sk_plr_bioweapon3 "8"
|
||||
set sk_plr_bioweapon_infection1 "8"
|
||||
set sk_plr_bioweapon_infection2 "8"
|
||||
set sk_plr_bioweapon_infection3 "8"
|
||||
set sk_plr_crowbar1 "18"
|
||||
set sk_plr_crowbar2 "18"
|
||||
set sk_plr_crowbar3 "18"
|
||||
set sk_plr_flamethrower1 "20"
|
||||
set sk_plr_flamethrower2 "20"
|
||||
set sk_plr_flamethrower3 "20"
|
||||
set sk_plr_flamethrower_afterburn1 "2"
|
||||
set sk_plr_flamethrower_afterburn2 "2"
|
||||
set sk_plr_flamethrower_afterburn3 "2"
|
||||
set sk_plr_incendiarylauncher1 "80"
|
||||
set sk_plr_incendiarylauncher2 "80"
|
||||
set sk_plr_incendiarylauncher3 "80"
|
||||
set sk_plr_incendiarylauncher_splash1 "40"
|
||||
set sk_plr_incendiarylauncher_splash2 "40"
|
||||
set sk_plr_incendiarylauncher_splash3 "40"
|
||||
set sk_plr_knife1 "36"
|
||||
set sk_plr_knife2 "36"
|
||||
set sk_plr_knife3 "36"
|
||||
set sk_plr_medikit_overheal1 "5"
|
||||
set sk_plr_medikit_overheal2 "5"
|
||||
set sk_plr_medikit_overheal3 "5"
|
||||
set sk_plr_nail1 "9"
|
||||
set sk_plr_nail2 "9"
|
||||
set sk_plr_nail3 "9"
|
||||
set sk_plr_nail_super1 "12"
|
||||
set sk_plr_nail_super2 "12"
|
||||
set sk_plr_nail_super3 "12"
|
||||
set sk_player_arm1 "1"
|
||||
set sk_player_arm2 "1"
|
||||
set sk_player_arm3 "1"
|
||||
set sk_player_chest1 "1"
|
||||
set sk_player_chest2 "1"
|
||||
set sk_player_chest3 "1"
|
||||
set sk_player_head1 "3"
|
||||
set sk_player_head2 "3"
|
||||
set sk_player_head3 "3"
|
||||
set sk_player_leg1 "1"
|
||||
set sk_player_leg2 "1"
|
||||
set sk_player_leg3 "1"
|
||||
set sk_player_stomach1 "1"
|
||||
set sk_player_stomach2 "1"
|
||||
set sk_player_stomach3 "1"
|
||||
set sk_plr_shotgun1 "4"
|
||||
set sk_plr_shotgun2 "4"
|
||||
set sk_plr_shotgun3 "4"
|
||||
set sk_plr_shotgun_super1 "4"
|
||||
set sk_plr_shotgun_super2 "4"
|
||||
set sk_plr_shotgun_super3 "4"
|
||||
set sk_plr_pipebomb1 "80"
|
||||
set sk_plr_pipebomb2 "80"
|
||||
set sk_plr_pipebomb3 "80"
|
||||
set sk_plr_pipebomb_splash1 "40"
|
||||
set sk_plr_pipebomb_splash2 "40"
|
||||
set sk_plr_pipebomb_splash3 "40"
|
||||
set sk_plr_railgun1 "23"
|
||||
set sk_plr_railgun2 "23"
|
||||
set sk_plr_railgun3 "23"
|
||||
set sk_plr_railgun_charge1 "100"
|
||||
set sk_plr_railgun_charge2 "100"
|
||||
set sk_plr_railgun_charge3 "100"
|
||||
set sk_plr_railgun_charge_splash1 "25"
|
||||
set sk_plr_railgun_charge_splash2 "25"
|
||||
set sk_plr_railgun_charge_splash3 "25"
|
||||
set sk_plr_rpg1 "100"
|
||||
set sk_plr_rpg2 "100"
|
||||
set sk_plr_rpg3 "100"
|
||||
set sk_plr_rpg_splash1 "25"
|
||||
set sk_plr_rpg_splash2 "25"
|
||||
set sk_plr_rpg_splash3 "25"
|
||||
set sk_plr_sniperrifle1 "18"
|
||||
set sk_plr_sniperrifle2 "18"
|
||||
set sk_plr_sniperrifle3 "18"
|
||||
set sk_plr_spanner1 "18"
|
||||
set sk_plr_spanner2 "18"
|
||||
set sk_plr_spanner3 "18"
|
||||
set sk_plr_stickybomb1 "80"
|
||||
set sk_plr_stickybomb2 "80"
|
||||
set sk_plr_stickybomb3 "80"
|
||||
set sk_plr_stickybomb_splash1 "40"
|
||||
set sk_plr_stickybomb_splash2 "40"
|
||||
set sk_plr_stickybomb_splash3 "40"
|
||||
set sk_plr_tranq1 "18"
|
||||
set sk_plr_tranq2 "18"
|
||||
set sk_plr_tranq3 "18"
|
||||
set sk_plr_umbrella1 "18"
|
||||
set sk_plr_umbrella2 "18"
|
||||
set sk_plr_umbrella3 "18"
|
|
@ -1 +0,0 @@
|
|||
exec "skill.cfg"
|
|
@ -1,30 +0,0 @@
|
|||
// these have to be defined by the game.
|
||||
entityDef ammo_types {
|
||||
"ammo_none" "0"
|
||||
"ammo_rockets" "1"
|
||||
"ammo_nails" "2"
|
||||
"ammo_cells" "3"
|
||||
"ammo_shells" "4"
|
||||
"ammo_medkits" "5"
|
||||
"ammo_detpack" "6"
|
||||
}
|
||||
|
||||
entityDef ammo_names {
|
||||
"ammo_none" "None"
|
||||
"ammo_rockets" "Rockets"
|
||||
"ammo_nails" "Nails"
|
||||
"ammo_cells" "Cells"
|
||||
"ammo_shells" "Shells"
|
||||
"ammo_medkits" "Medkit"
|
||||
"ammo_detpack" "Depack"
|
||||
}
|
||||
|
||||
entityDef ammo_max {
|
||||
"ammo_none" "0"
|
||||
"ammo_rockets" "255"
|
||||
"ammo_nails" "255"
|
||||
"ammo_cells" "255"
|
||||
"ammo_shells" "255"
|
||||
"ammo_medkits" "255"
|
||||
"ammo_detpack" "255"
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
entityDef item_suit
|
||||
{
|
||||
"spawnclass" "ncItem"
|
||||
"model" "models/w_suit.mdl"
|
||||
"mins" "-16 -16 0"
|
||||
"maxs" "16 16 16"
|
||||
"inv_carry" "1"
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
entityDef player
|
||||
{
|
||||
"spawnclass" "TFPlayer"
|
||||
}
|
||||
|
||||
entityDef player_shared
|
||||
{
|
||||
"inherit" "player"
|
||||
"item" "item_suit"
|
||||
}
|
||||
|
||||
entityDef player_scout
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/scout/scout.mdl"
|
||||
"health" "75"
|
||||
"armor" "25"
|
||||
"maxarmor" "50"
|
||||
"pm_walkspeed" "400" // 450 in QWTF
|
||||
"ammo_shells" "17"
|
||||
"ammo_nails" "100"
|
||||
"max_ammo_shells" "50"
|
||||
"max_ammo_nails" "200"
|
||||
"max_ammo_cells" "100"
|
||||
"max_ammo_rockets" "25"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_shotgun,tf_weapon_ng"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_sniper
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/sniper/sniper.mdl"
|
||||
"health" "90"
|
||||
"armor" "0"
|
||||
"maxarmor" "50"
|
||||
"pm_walkspeed" "300"
|
||||
"ammo_shells" "60"
|
||||
"ammo_nails" "50"
|
||||
"max_ammo_shells" "75"
|
||||
"max_ammo_nails" "100"
|
||||
"max_ammo_cells" "50"
|
||||
"max_ammo_rockets" "25"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_sniperrifle,tf_weapon_autorifle,tf_weapon_ng"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_soldier
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/soldier/soldier.mdl"
|
||||
"health" "100"
|
||||
"armor" "100"
|
||||
"maxarmor" "200"
|
||||
"pm_walkspeed" "240"
|
||||
"ammo_shells" "26"
|
||||
"ammo_rockets" "6"
|
||||
"max_ammo_shells" "100"
|
||||
"max_ammo_nails" "100"
|
||||
"max_ammo_cells" "50"
|
||||
"max_ammo_rockets" "50"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_supershotgun,tf_weapon_shotgun,tf_weapon_rpg"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_demo
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/demo/demo.mdl"
|
||||
"health" "90"
|
||||
"armor" "50"
|
||||
"maxarmor" "100"
|
||||
"pm_walkspeed" "280"
|
||||
"ammo_shells" "22"
|
||||
"ammo_rockets" "14"
|
||||
"max_ammo_shells" "75"
|
||||
"max_ammo_nails" "50"
|
||||
"max_ammo_cells" "50"
|
||||
"max_ammo_rockets" "50"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_shotgun,tf_weapon_gl,tf_weapon_pl"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_medic
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/medic/medic.mdl"
|
||||
"health" "90"
|
||||
"armor" "50"
|
||||
"maxarmor" "100"
|
||||
"pm_walkspeed" "320"
|
||||
"ammo_shells" "26"
|
||||
"ammo_nails" "50"
|
||||
"max_ammo_shells" "75"
|
||||
"max_ammo_nails" "150"
|
||||
"max_ammo_cells" "50"
|
||||
"max_ammo_rockets" "25"
|
||||
"weapon" "tf_weapon_medikit,tf_weapon_supershotgun,tf_weapon_shotgun,tf_weapon_superng"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_heavy
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/hvyweapon/hvyweapon.mdl"
|
||||
"health" "100"
|
||||
"armor" "150"
|
||||
"maxarmor" "300"
|
||||
"pm_walkspeed" "228"
|
||||
"ammo_shells" "176"
|
||||
"max_ammo_shells" "200"
|
||||
"max_ammo_nails" "200"
|
||||
"max_ammo_cells" "50"
|
||||
"max_ammo_rockets" "25"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_supershotgun,tf_weapon_shotgun,tf_weapon_ac"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_pyro
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/pyro/pyro.mdl"
|
||||
"health" "100"
|
||||
"armor" "50"
|
||||
"maxarmor" "150"
|
||||
"pm_walkspeed" "300"
|
||||
"ammo_shells" "12"
|
||||
"ammo_cells" "120"
|
||||
"ammo_rockets" "5"
|
||||
"max_ammo_shells" "40"
|
||||
"max_ammo_nails" "50"
|
||||
"max_ammo_cells" "200"
|
||||
"max_ammo_rockets" "60"
|
||||
"weapon" "tf_weapon_axe,tf_weapon_shotgun,tf_weapon_flamethrower,tf_weapon_ic"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_spy
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/spy/spy.mdl"
|
||||
"health" "90"
|
||||
"armor" "25"
|
||||
"maxarmor" "100"
|
||||
"pm_walkspeed" "300"
|
||||
"ammo_shells" "24"
|
||||
"ammo_nails" "50"
|
||||
"max_ammo_shells" "40"
|
||||
"max_ammo_nails" "50"
|
||||
"max_ammo_cells" "30"
|
||||
"max_ammo_rockets" "15"
|
||||
"weapon" "tf_weapon_knife,tf_weapon_tranq,tf_weapon_supershotgun,tf_weapon_ng"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_engineer
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/engineer/engineer.mdl"
|
||||
"health" "80"
|
||||
"armor" "25"
|
||||
"maxarmor" "50"
|
||||
"pm_walkspeed" "300"
|
||||
"ammo_shells" "4"
|
||||
"ammo_nails" "25"
|
||||
"ammo_cells" "100"
|
||||
"max_ammo_shells" "50"
|
||||
"max_ammo_nails" "50"
|
||||
"max_ammo_cells" "200"
|
||||
"max_ammo_rockets" "30"
|
||||
"weapon" "tf_weapon_spanner,tf_weapon_railgun,tf_weapon_supershotgun"
|
||||
"current_weapon" "1"
|
||||
}
|
||||
|
||||
entityDef player_civilian
|
||||
{
|
||||
"inherit" "player_shared"
|
||||
"model" "models/player/civilian/civilian.mdl"
|
||||
"health" "50"
|
||||
"armor" "0"
|
||||
"maxarmor" "0"
|
||||
"pm_walkspeed" "300"
|
||||
"ammo_shells" "0"
|
||||
"ammo_nails" "0"
|
||||
"ammo_cells" "0"
|
||||
"max_ammo_shells" "0"
|
||||
"max_ammo_nails" "0"
|
||||
"max_ammo_cells" "0"
|
||||
"max_ammo_rockets" "0"
|
||||
"weapon" "tf_weapon_umbrella"
|
||||
"current_weapon" "1"
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#include "weapons/ac.def"
|
||||
#include "weapons/autorifle.def"
|
||||
#include "weapons/axe.def"
|
||||
#include "weapons/flamethrower.def"
|
||||
#include "weapons/gl.def"
|
||||
#include "weapons/ic.def"
|
||||
#include "weapons/knife.def"
|
||||
#include "weapons/medikit.def"
|
||||
#include "weapons/ng.def"
|
||||
#include "weapons/pl.def"
|
||||
#include "weapons/railgun.def"
|
||||
#include "weapons/rpg.def"
|
||||
#include "weapons/shotgun.def"
|
||||
#include "weapons/sniperrifle.def"
|
||||
#include "weapons/spanner.def"
|
||||
#include "weapons/superng.def"
|
||||
#include "weapons/supershotgun.def"
|
||||
#include "weapons/tranq.def"
|
||||
#include "weapons/umbrella.def"
|
|
@ -1,55 +0,0 @@
|
|||
entityDef tf_weapon_ac
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Assualt Cannon"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_tfac.mdl"
|
||||
"model_view" "models/v_tfac.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfAssaultCannon"
|
||||
"inv_name" "Assualt Cannon"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "2"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"actLoop" "4"
|
||||
"act_holster" "6"
|
||||
"act_draw" "5"
|
||||
"act_fireStart" "2"
|
||||
"act_fireStop" "3"
|
||||
"act_idle" "0,1"
|
||||
|
||||
"snd_fireStart" "Weapon_Minigun.WindUp"
|
||||
"snd_fireLoop" "Weapon_Minigun.Fire"
|
||||
"snd_fireEnd" "Weapon_Minigun.WindDown"
|
||||
"snd_empty" "Weapon_Minigun.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "4"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "30"
|
||||
}
|
||||
|
||||
entityDef projectile_tfAssaultCannon
|
||||
{
|
||||
"inherit" "projectile_bullet_base"
|
||||
"damage" "skill:plr_ac"
|
||||
"hitscans" "12"
|
||||
"spread" "0.08716 0.08716"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfAssaultCannon
|
||||
{
|
||||
"def_onFire" "projectile_tfAssaultCannon"
|
||||
"fireRate" "0.1"
|
||||
"punchAngle" "-2 0 0"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
entityDef tf_weapon_autorifle
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Automatic Rifle"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_9mmhandgun.mdl"
|
||||
"model_view" "models/v_tfc_sniper.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfAutoRifle"
|
||||
"inv_name" "Automatic Rifle"
|
||||
"inv_ammo_shells" "75"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "6"
|
||||
"act_holster" "8"
|
||||
"act_draw" "7"
|
||||
"act_idle" "5"
|
||||
|
||||
"snd_fire" "Weapon_SMG.Single"
|
||||
"snd_empty" "Weapon_SMG.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "2"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
entityDef projectile_tfAutoRifleBullet
|
||||
{
|
||||
"inherit" "projectile_bullet_base"
|
||||
"damage" "skill:plr_autorifle"
|
||||
"spread" "0.025 0.025"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfAutoRifle
|
||||
{
|
||||
"def_onFire" "projectile_tfAutoRifleBullet"
|
||||
"ammoType" "ammo_shells"
|
||||
"fireRate" "0.085"
|
||||
"punchAngle" "-2 0 0"
|
||||
"model_flash" "sprites/muzzleflash1.spr"
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
entityDef tf_weapon_axe
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Crowbar (Axe)"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_crowbar.mdl"
|
||||
"model_view" "models/v_tfc_crowbar.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_melee" "damage_tfAxe"
|
||||
"melee_distance" "32"
|
||||
"inv_name" "Crowbar (Axe)"
|
||||
"ammoType" ""
|
||||
"ammoRequired" "0"
|
||||
"clipSize" "0"
|
||||
"silent_fire" "1"
|
||||
|
||||
"meleeRateMiss" "0.5"
|
||||
"meleeRateHit" "0.5"
|
||||
|
||||
"act_idle" "0"
|
||||
"act_draw" "1"
|
||||
"act_holster" "2"
|
||||
"act_fireFailed" "4,5,7"
|
||||
"act_fire" "3,6,8"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "0"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "0"
|
||||
"crosshair" "none"
|
||||
"ammoIcon" "none"
|
||||
}
|
||||
|
||||
entityDef damage_tfAxe
|
||||
{
|
||||
"damage" "skill:plr_crowbar"
|
||||
"gib" "1"
|
||||
|
||||
"snd_hit" "Weapon_Crowbar.HitWorld"
|
||||
"snd_hitFlesh" "Weapon_Crowbar.HitFlesh"
|
||||
"snd_miss" "Weapon_Crowbar.Miss"
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
entityDef tf_weapon_flamethrower
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Flamethrower"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_egon.mdl"
|
||||
"model_view" "models/v_flame.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfFlameThrower"
|
||||
"inv_name" "Flamethrower"
|
||||
"ammoType" "ammo_cells"
|
||||
"ammoRequired" "1"
|
||||
|
||||
"act_fire" "5,6,7,8"
|
||||
"act_holster" "10"
|
||||
"act_draw" "9"
|
||||
"act_idle" "0,1"
|
||||
|
||||
"snd_fire" "Weapon_FlameThrower.Fire"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "3"
|
||||
"hudSlotPos" "1"
|
||||
"weight" "30"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfFlameThrower
|
||||
{
|
||||
"def_onFire" "projectile_tfFire"
|
||||
"ammoPerShot" "2"
|
||||
"fireRate" ".2"
|
||||
"punchAngle" "-2 0 0"
|
||||
"act_fire" "5,6"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
}
|
||||
|
||||
entityDef projectile_tfFire
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "sprites/fthrow.spr"
|
||||
|
||||
"def_damage" "tfFireDirect"
|
||||
|
||||
"health" "0"
|
||||
"velocity" "250"
|
||||
"angular_velocity" "0 0 200"
|
||||
"fuse" "10"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"impact_damage_effect" "1"
|
||||
"impact_gib" "1"
|
||||
|
||||
"thrust" "2000"
|
||||
"thrust_start" "0.1"
|
||||
"thrust_end" "2"
|
||||
|
||||
"light_color" "1 0.8 0.4"
|
||||
"light_radius" "160"
|
||||
"light_offset" "0 0 0"
|
||||
|
||||
}
|
||||
|
||||
entityDef damage_tfFireDirect
|
||||
{
|
||||
"damage" "skill:plr_flamethrower"
|
||||
}
|
||||
|
||||
entityDef damage_tfFireAfterburn
|
||||
{
|
||||
"damage" "skill:plr_flamethrower_afterburn"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfFlameThrower
|
||||
{
|
||||
"def_onFire" "projectile_tfFire"
|
||||
"punchAngle" "-10 0 0"
|
||||
"reloadTime" "0.6"
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
entityDef tf_weapon_gl
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Grenade Launcher"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_glauncher.mdl"
|
||||
"model_view" "models/v_tfgl.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfGrenadeLauncher"
|
||||
"inv_name" "Grenade Launcher"
|
||||
"clipSize" "6"
|
||||
"ammoType" "ammo_rockets"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "2"
|
||||
"act_holster" "10"
|
||||
"act_reloadStart" "4"
|
||||
"act_reload" "4"
|
||||
"act_reloadEnd" "5"
|
||||
"act_draw" "8"
|
||||
"act_idle" "0"
|
||||
|
||||
"snd_fire" "Weapon_GrenadeLauncher.Single"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "3"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfGrenadeLauncher
|
||||
{
|
||||
"def_onFire" "projectile_tfPipebomb"
|
||||
"fireRate" "0.8"
|
||||
"punchAngle" "-4 0 0"
|
||||
}
|
||||
|
||||
entityDef projectile_tfPipebomb
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/pipebomb.mdl"
|
||||
"skin" "1"
|
||||
"frame" "1"
|
||||
"fuse" "4"
|
||||
"detonate_on_fuse" "1"
|
||||
"bounce" "1"
|
||||
"angular_velocity" "-350 0 0"
|
||||
"velocity" "300 0 40"
|
||||
"model_detonate" "fx_explosion.main"
|
||||
"snd_explode" "Weapon_Grenade_Pipebomb.Explode"
|
||||
"snd_bounce" "Weapon_Grenade_Pipebomb.Bounce"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"smoke_fly" "weapon_rpg.trail"
|
||||
|
||||
"def_damage" "damage_tfPipebombDirect"
|
||||
"def_splash_damage" "damage_tfPipebombSplash"
|
||||
}
|
||||
|
||||
entityDef damage_tfPipebombDirect
|
||||
{
|
||||
"damage" "skill:plr_pipebomb"
|
||||
}
|
||||
|
||||
entityDef damage_tfPipebombSplash
|
||||
{
|
||||
"damage" "skill:plr_pipebomb_splash"
|
||||
"radius" "250"
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
entityDef tf_weapon_ic
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Incendiary Cannon"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_9mmhandgun.mdl"
|
||||
"model_view" "models/v_tfc_rpg.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfIncendiaryCannon"
|
||||
"inv_name" "Incendiary Cannon"
|
||||
"ammoType" "ammo_rockets"
|
||||
"ammoRequired" "1" // 3 in Quake Team Fortress
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-4 0 0"
|
||||
|
||||
"act_idle" "0,1"
|
||||
"act_idleEmpty" "10,11"
|
||||
"act_draw" "4"
|
||||
"act_drawEmpty" "6"
|
||||
"act_holster" "3"
|
||||
"act_holsterEmpty" "5"
|
||||
"act_reloadStart" "7"
|
||||
"act_reload" "8"
|
||||
"act_reloadEnd" "9"
|
||||
"act_fire" "2"
|
||||
|
||||
"snd_fire" "Weapon_FlameThrower.FireRocket"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "4"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "20"
|
||||
}
|
||||
|
||||
entityDef projectile_tfIncendiaryRocket
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/rpgrocket.mdl"
|
||||
|
||||
"def_damage" "damage_tfIncendiaryRocketDirect"
|
||||
"def_splash_damage" "damage_tfIncendiaryRocketSplash"
|
||||
|
||||
"health" "0"
|
||||
"velocity" "250"
|
||||
"angular_velocity" "0 0 200"
|
||||
"fuse" "10"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"impact_damage_effect" "1"
|
||||
"impact_gib" "1"
|
||||
|
||||
"thrust" "2000"
|
||||
"thrust_start" "0.1"
|
||||
"thrust_end" "2"
|
||||
|
||||
"smoke_fly" "weapon_rpg.trail"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"model_detonate" "fx_explosion.main"
|
||||
"light_color" "1 0.8 0.4"
|
||||
"light_radius" "160"
|
||||
"light_offset" "0 0 0"
|
||||
|
||||
"explode_light_color" "2 1.6 0.8"
|
||||
"explode_light_radius" "320"
|
||||
"explode_light_fadetime" "0.5"
|
||||
|
||||
"snd_explode" "fx.explosion"
|
||||
}
|
||||
|
||||
entityDef damage_tfIncendiaryRocketDirect
|
||||
{
|
||||
"damage" "skill:plr_incendiarylauncher"
|
||||
}
|
||||
|
||||
entityDef damage_tfIncendiaryRocketSplash
|
||||
{
|
||||
"damage" "skill:plr_incendiarylauncher_splash"
|
||||
"radius" "250"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfIncendiaryCannon
|
||||
{
|
||||
"def_onFire" "projectile_tfIncendiaryRocket"
|
||||
"punchAngle" "-10 0 0"
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
entityDef tf_weapon_knife
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Knife"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_knife.mdl"
|
||||
"model_view" "models/v_tfc_knife.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_melee" "damage_tfKnife"
|
||||
"melee_distance" "32"
|
||||
"inv_name" "Knife"
|
||||
"ammoType" ""
|
||||
"ammoRequired" "0"
|
||||
"clipSize" "0"
|
||||
"silent_fire" "1"
|
||||
|
||||
"meleeRateMiss" "0.35"
|
||||
"meleeRateHit" "0.35"
|
||||
|
||||
"act_idle" "0,1"
|
||||
"act_draw" "4"
|
||||
"act_holster" "5"
|
||||
"act_fireFailed" "2"
|
||||
"act_fire" "3"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "0"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "0"
|
||||
"crosshair" "none"
|
||||
"ammoIcon" "none"
|
||||
}
|
||||
}
|
||||
|
||||
entityDef damage_tfKnife
|
||||
{
|
||||
"damage" "skill:plr_knife"
|
||||
"gib" "1"
|
||||
|
||||
"snd_hit" "Weapon_Knife.HitWorld"
|
||||
"snd_hitFlesh" "Weapon_Knife.HitFlesh"
|
||||
"snd_miss" "Weapon_Knife.Miss"
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
entityDef tf_weapon_medikit
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Medkit"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_medkit.mdl"
|
||||
"model_view" "models/v_tfc_medkit.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_melee" "damage_tfMedikit"
|
||||
"melee_distance" "32"
|
||||
"inv_name" "Medikit"
|
||||
"ammoType" ""
|
||||
"ammoRequired" "0"
|
||||
"clipSize" "0"
|
||||
"silent_fire" "1"
|
||||
|
||||
"meleeRateMiss" "0.35"
|
||||
"meleeRateHit" "0.35"
|
||||
|
||||
"act_idle" "0,1"
|
||||
"act_draw" "5"
|
||||
"act_holster" "4"
|
||||
"act_fireFailed" "3"
|
||||
"act_fire" "2"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "0"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "30"
|
||||
"crosshair" "none"
|
||||
"ammoIcon" "none"
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
||||
// Does initial damage then triggers tfInfection
|
||||
entityDef damage_tfBioweapon
|
||||
{
|
||||
"damage" "skill:plr_bioweapon"
|
||||
"snd_hitFlesh" "Weapon_Bioweapon.HitFlesh"
|
||||
}
|
||||
|
||||
// Damages every couple seconds until death or heal
|
||||
// Spreads to other players (except medic)
|
||||
entityDef damage_tfBioweaponInfection
|
||||
{
|
||||
"damage" "skill:plr_bioweapon_infection"
|
||||
}
|
||||
|
||||
// Initial heal will always fully heal player
|
||||
entityDef damage_tfMedikit
|
||||
{
|
||||
"snd_hitFlesh" "Weapon_Medikit.HitFlesh"
|
||||
}
|
||||
|
||||
// Overheal applys heal every attack, maxes at 50+
|
||||
entityDef damage_tfMedikitOverheal
|
||||
{
|
||||
"damage" "skill:plr_medikit_overheal"
|
||||
"snd_hitFlesh" "Weapon_Medikit.Overheal"
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
entityDef tf_weapon_ng
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Nail Gun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_nailgun2.mdl"
|
||||
"model_view" "models/v_tfc_nailgun.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfNailGun"
|
||||
"inv_name" "Nail Gun"
|
||||
"inv_ammo_nails" "25"
|
||||
"ammoType" "ammo_nails"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"act_idle" "0,1"
|
||||
"act_draw" "4"
|
||||
"act_fire" "5,6,7"
|
||||
"snd_fire" "Weapon_NailGun.Single"
|
||||
"snd_empty" "Weapon_NailGun.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "3"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "20"
|
||||
}
|
||||
|
||||
entityDef debris_tfNail
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/nail.mdl"
|
||||
}
|
||||
|
||||
entityDef projectile_tfNail
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/nail.mdl"
|
||||
"velocity" "1000 0 0"
|
||||
"angular_velocity" "0 0 20"
|
||||
"mins" "0 0 0"
|
||||
"maxs" "0 0 0"
|
||||
"damage" "skill:plr_nail"
|
||||
"snd_explode" "impact.tfNail"
|
||||
"snd_hit" "impact.tfNailHitFlesh"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"projectile_debris" "debris_tfNail"
|
||||
"model_detonate" "impact_default.main"
|
||||
"decal_detonate" "Impact.Shot"
|
||||
"debris_count" "1"
|
||||
"debris_stick" "1"
|
||||
"debris_offset" "-2 0 0"
|
||||
"offset" "0 3 -6"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfNailGun
|
||||
{
|
||||
"def_onFire" "projectile_tfNail"
|
||||
"fireRate" "0.1"
|
||||
"punchAngle" "-4 0 0"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
entityDef tf_weapon_pl
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Sticky Launcher"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_glauncher.mdl"
|
||||
"model_view" "models/v_tfgl.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfStickyLauncher"
|
||||
"detonateOnFire" "projectile_tfStickybomb"
|
||||
"inv_name" "Sticky Launcher"
|
||||
"clipSize" "6"
|
||||
"ammoType" "ammo_rockets"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "3"
|
||||
"act_holster" "11"
|
||||
"act_reloadStart" "6"
|
||||
"act_reload" "6"
|
||||
"act_reloadEnd" "7"
|
||||
"act_draw" "9"
|
||||
"act_idle" "1"
|
||||
|
||||
"snd_fire" "Weapon_StickyBombLauncher.Single"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "4"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfStickyLauncher
|
||||
{
|
||||
"def_onFire" "projectile_tfStickybomb"
|
||||
"fireRate" "0.8"
|
||||
"punchAngle" "-4 0 0"
|
||||
}
|
||||
|
||||
entityDef projectile_tfStickybomb
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/pipebomb.mdl"
|
||||
"frame" "1"
|
||||
"bounce" "1"
|
||||
"angular_velocity" "-350 0 0"
|
||||
"velocity" "300 0 40"
|
||||
"model_detonate" "fx_explosion.main"
|
||||
"snd_explode" "Weapon_Grenade_Pipebomb.Explode"
|
||||
"snd_bounce" "Weapon_Grenade_Pipebomb.Bounce"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
|
||||
"def_damage" "damage_tfStickybombDirect"
|
||||
"def_splash_damage" "damage_tfStickybombSplash"
|
||||
}
|
||||
|
||||
entityDef damage_tfStickybombDirect
|
||||
{
|
||||
"damage" "skill:plr_stickybomb"
|
||||
}
|
||||
|
||||
entityDef damage_tfStickybombSplash
|
||||
{
|
||||
"damage" "skill:plr_stickybomb_splash"
|
||||
"radius" "250"
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
entityDef tf_weapon_railgun
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "RailGun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_9mmhandgun.mdl"
|
||||
"model_view" "models/v_tfc_railgun.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfRailGun"
|
||||
// "def_altFireInfo" "fireInfo_tfRailGunCharge" // Fortress Forever style charge attack
|
||||
"inv_name" "RailGun"
|
||||
"ammoType" "ammo_nails"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "1"
|
||||
// "actAltFire" "1"
|
||||
"act_holster" "3"
|
||||
"act_draw" "2"
|
||||
"act_idle" "0"
|
||||
|
||||
"snd_fire" "Weapon_Railgun.Single"
|
||||
"snd_altfire" "Weapon_Railgun.WindUp"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "1"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
entityDef projectile_tfRailShot
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" ""
|
||||
|
||||
"def_damage" "damage_tfRailDirect"
|
||||
|
||||
"health" "0"
|
||||
"velocity" "250"
|
||||
"angular_velocity" "0 0 200"
|
||||
"fuse" "10"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"impact_damage_effect" "1"
|
||||
"impact_gib" "1"
|
||||
|
||||
"thrust" "2000"
|
||||
"thrust_start" "0.1"
|
||||
"thrust_end" "2"
|
||||
|
||||
"smoke_fly" "weapon_railgun.trail"
|
||||
"decal_detonate" "Impact.BigShot"
|
||||
"model_detonate" "fx_spark.main"
|
||||
"snd_explode" "fx.spark
|
||||
"light_color" "0 0.5 0"
|
||||
"light_radius" "160"
|
||||
"light_offset" "0 0 0"
|
||||
}
|
||||
|
||||
entityDef projectile_tfRailChargedShot
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" ""
|
||||
|
||||
"def_damage" "damage_tfRailChargeDirect"
|
||||
"def_splash_damage" "damage_tfTailChargedSplash"
|
||||
|
||||
"health" "0"
|
||||
"velocity" "250"
|
||||
"angular_velocity" "0 0 200"
|
||||
"fuse" "10"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"impact_damage_effect" "1"
|
||||
"impact_gib" "1"
|
||||
|
||||
"thrust" "2000"
|
||||
"thrust_start" "0.1"
|
||||
"thrust_end" "2"
|
||||
|
||||
"smoke_fly" "weapon_railgun.trail"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"model_detonate" "fx_explosion.main"
|
||||
"light_color" "0 0.5 0"
|
||||
"light_radius" "160"
|
||||
"light_offset" "0 0 0"
|
||||
|
||||
"explode_light_color" "2 1.6 0.8"
|
||||
"explode_light_radius" "320"
|
||||
"explode_light_fadetime" "0.5"
|
||||
|
||||
"snd_explode" "fx.explosion"
|
||||
}
|
||||
|
||||
entityDef damage_tfRailDirect
|
||||
{
|
||||
"damage" "skill:plr_railgun"
|
||||
}
|
||||
|
||||
entityDef damage_tfRailChargeDirect
|
||||
{
|
||||
"damage" "skill:plr_railgun_charge"
|
||||
}
|
||||
|
||||
entityDef damage_tfTailChargedSplash
|
||||
{
|
||||
"damage" "skill:plr_railgun_charge_splash"
|
||||
"radius" "250"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfRailGun
|
||||
{
|
||||
"def_onFire" "projectile_tfRailShot"
|
||||
"ammoPerShot" "1"
|
||||
"fireRate" "0.4"
|
||||
"punchAngle" "-2 0 0"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfRailGunCharge
|
||||
{
|
||||
"def_onFire" "projectile_tfRailChargedShot"
|
||||
"ammoPerShot" "1"
|
||||
"fireRate" "0.75"
|
||||
"punchAngle" "-10 0 0"
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
entityDef tf_weapon_rpg
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Rocket Launcher"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_rpg.mdl"
|
||||
"model_view" "models/v_tfc_rpg.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
"def_fireInfo" "fireInfo_tfRPG"
|
||||
"ammoType" "ammo_rockets"
|
||||
"clipSize" "4"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"inv_ammo_rockets" "1"
|
||||
"fireRate" "2.5"
|
||||
|
||||
"act_idle" "0,1"
|
||||
"act_idleEmpty" "10,11"
|
||||
"act_draw" "4"
|
||||
"act_drawEmpty" "6"
|
||||
"act_holster" "3"
|
||||
"act_holsterEmpty" "5"
|
||||
"act_reloadStart" "7"
|
||||
"act_reload" "8"
|
||||
"act_reloadEnd" "9"
|
||||
"act_fire" "2"
|
||||
"snd_fire" "Weapon_RPG.Single"
|
||||
"snd_empty" "Weapon_Pistol.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "3"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "20"
|
||||
}
|
||||
|
||||
entityDef projectile_tfRocket
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/rpgrocket.mdl"
|
||||
|
||||
"def_damage" "damage_tfRocketDirect"
|
||||
"def_splash_damage" "damage_tfRocketSplash"
|
||||
|
||||
"health" "0"
|
||||
"velocity" "250"
|
||||
"angular_velocity" "0 0 200"
|
||||
"fuse" "10"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"impact_damage_effect" "1"
|
||||
"impact_gib" "1"
|
||||
|
||||
"thrust" "2000"
|
||||
"thrust_start" "0.1"
|
||||
"thrust_end" "2"
|
||||
|
||||
"smoke_fly" "weapon_rpg.trail"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"model_detonate" "fx_explosion.main"
|
||||
"light_color" "1 0.8 0.4"
|
||||
"light_radius" "160"
|
||||
"light_offset" "0 0 0"
|
||||
|
||||
"explode_light_color" "2 1.6 0.8"
|
||||
"explode_light_radius" "320"
|
||||
"explode_light_fadetime" "0.5"
|
||||
|
||||
"snd_explode" "fx.explosion"
|
||||
}
|
||||
|
||||
entityDef damage_tfRocketDirect
|
||||
{
|
||||
"damage" "skill:plr_rpg"
|
||||
}
|
||||
|
||||
entityDef damage_tfRocketSplash
|
||||
{
|
||||
"damage" "skill:plr_rpg_splash"
|
||||
"radius" "250"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfRPG
|
||||
{
|
||||
"def_onFire" "projectile_tfRocket"
|
||||
"punchAngle" "-10 0 0"
|
||||
"reloadTime" "0.6"
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
entityDef tf_weapon_shotgun
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Single-Barrel Shotgun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_shotgun.mdl"
|
||||
"model_view" "models/v_tfc_12gauge.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfShotgun"
|
||||
"inv_name" "Single-Barrel Shotgun"
|
||||
"inv_ammo_shells" "4"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "1"
|
||||
"clipSize" "8"
|
||||
|
||||
"act_fire" "1"
|
||||
"act_holster" "7"
|
||||
"act_reloadStart" "5"
|
||||
"act_reload" "3"
|
||||
"act_reloadEnd" "4"
|
||||
"act_draw" "6"
|
||||
"act_idle" "0,8,9"
|
||||
|
||||
//TODO Fast Reload
|
||||
|
||||
"snd_fire" "Weapon_Shotgun.Single"
|
||||
"snd_empty" "Weapon_Shotgun.Empty"
|
||||
|
||||
"snd_reload" "Weapon_Shotgun.Reload"
|
||||
"snd_reload_end" "Weapon_Shotgun.Pump"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "1"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
// TODO Damage should be 4-24
|
||||
entityDef projectile_tfShotgun
|
||||
{
|
||||
"inherit" "projectile_bullet_base"
|
||||
"damage" "skill:plr_shotgun"
|
||||
"hitscans" "12"
|
||||
"spread" "0.08716 0.08716"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfShotgun
|
||||
{
|
||||
"def_onFire" "projectile_tfShotgun"
|
||||
"ammoPerShot" "1"
|
||||
"fireRate" "0.5"
|
||||
"punchAngle" "-2 0 0"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
"reloadTime" "0.2"
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
entityDef tf_weapon_sniperrifle
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Sniper Rifle"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_sniper2.mdl"
|
||||
"model_view" "models/v_tfc_sniper.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfSniperRifle"
|
||||
"inv_name" "Sniper Rifle"
|
||||
"inv_ammo_shells" "75"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "6"
|
||||
"act_holster" "8"
|
||||
"act_draw" "7"
|
||||
"act_idle" "5"
|
||||
|
||||
"snd_fire" "Weapon_SniperRifle.Single"
|
||||
"snd_empty" "Weapon_SniperRifle.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "1"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "20"
|
||||
|
||||
"zoomDuration" "0"
|
||||
"zoomFov" "20"
|
||||
"zoomFovStep" "5"
|
||||
"zoomFovMin" "5"
|
||||
"zoomFovMax" "40"
|
||||
}
|
||||
|
||||
entityDef projectile_tfSniperRifleBullet
|
||||
{
|
||||
"inherit" "projectile_bullet_base"
|
||||
"damage" "skill:plr_sniperrifle"
|
||||
"spread" "0.025 0.025"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfSniperRifle
|
||||
{
|
||||
"def_onFire" "projectile_tfSniperRifleBullet"
|
||||
"ammoType" "ammo_shells"
|
||||
"fireRate" "0.75"
|
||||
"punchAngle" "-2 0 0"
|
||||
"model_flash" "sprites/muzzleflash1.spr"
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
entityDef tf_weapon_spanner
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Wrench"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_spanner.mdl"
|
||||
"model_view" "models/v_tfc_spanner.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_melee" "damage_tfWrench"
|
||||
"melee_distance" "32"
|
||||
"inv_name" "Wrench"
|
||||
"ammoType" "ammo_cells"
|
||||
"ammoRequired" "0"
|
||||
"ammoPerShot" "0"
|
||||
"punchAngle" "0 0 0"
|
||||
"silent_fire" "1"
|
||||
|
||||
"act_idle" "0"
|
||||
"act_draw" "4"
|
||||
"act_holster" "5"
|
||||
"act_fireFailed" "1,2"
|
||||
"act_fire" "3"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "0"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "0"
|
||||
"crosshair" "none"
|
||||
"ammoIcon" "none"
|
||||
}
|
||||
|
||||
entityDef damage_tfWrench
|
||||
{
|
||||
"damage" "skill:plr_spanner"
|
||||
|
||||
"snd_hit" "Weapon_Wrench.HitWorld"
|
||||
"snd_hitFlesh" "Weapon_Wrench.HitFlesh"
|
||||
"snd_miss" "Weapon_Wrench.Miss"
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
entityDef tf_weapon_superng
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Super Nail Gun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_snailgun2.mdl"
|
||||
"model_view" "models/v_tfc_supernailgun.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfSuperNailGun"
|
||||
"inv_name" "Super Nail Gun"
|
||||
"inv_ammo_nails" "50"
|
||||
"ammoType" "ammo_nails"
|
||||
"ammoRequired" "1"
|
||||
"act_idle" "0,1"
|
||||
"act_draw" "4"
|
||||
"act_fire" "5,6,7"
|
||||
|
||||
"snd_fire" "Weapon_SyringeGun.Single"
|
||||
"snd_empty" "Weapon_SyringeGun.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "3"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "20"
|
||||
}
|
||||
|
||||
entityDef projectile_tfSuperNail
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/nail.mdl"
|
||||
"velocity" "1000 0 0"
|
||||
"angular_velocity" "0 0 20"
|
||||
"mins" "0 0 0"
|
||||
"maxs" "0 0 0"
|
||||
"damage" "skill:plr_nail_super"
|
||||
"snd_explode" "impact.tfNail"
|
||||
"snd_hit" "impact.tfNailHitFlesh"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"projectile_debris" "debris_tfNail"
|
||||
"model_detonate" "impact_default.main"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"debris_count" "1"
|
||||
"debris_stick" "1"
|
||||
"debris_offset" "-2 0 0"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfSuperNailGun
|
||||
{
|
||||
"def_onFire" "projectile_tfSuperNail"
|
||||
"ammoPerShot" "1"
|
||||
"fireRate" "0.1"
|
||||
"punchAngle" "-4 0 0"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
entityDef tf_weapon_supershotgun
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Double-Barrel Shotgun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_shotgun.mdl"
|
||||
"model_view" "models/v_tfc_shotgun.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfSuperShotgun"
|
||||
"inv_name" "Double-Barrel Shotgun"
|
||||
"inv_ammo_shells" "4"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "2"
|
||||
"clipSize" "16"
|
||||
|
||||
"act_fire" "1"
|
||||
"act_holster" "7"
|
||||
"act_reloadStart" "5"
|
||||
"act_reload" "3"
|
||||
"act_reloadEnd" "4"
|
||||
"act_draw" "6"
|
||||
"act_idle" "0,8,9"
|
||||
|
||||
"snd_fire" "Weapon_SuperShotgun.Single"
|
||||
"snd_empty" "Weapon_Shotgun.Empty"
|
||||
|
||||
"snd_reload" "Weapon_Shotgun.Reload"
|
||||
"snd_reload_end" "Weapon_Shotgun.Pump"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "2"
|
||||
"hudSlotPos" "1"
|
||||
"weight" "20"
|
||||
}
|
||||
|
||||
|
||||
// TODO Damage should be 4-56
|
||||
entityDef projectile_tfSuperShotgun
|
||||
{
|
||||
"inherit" "projectile_bullet_base"
|
||||
"damage" "skill:plr_shotgun_super"
|
||||
"hitscans" "12"
|
||||
"spread" "0.08716 0.08716"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfSuperShotgun
|
||||
{
|
||||
"def_onFire" "projectile_tfSuperShotgun"
|
||||
"ammoPerShot" "2"
|
||||
"fireRate" "0.7"
|
||||
"punchAngle" "-4 0 0"
|
||||
"model_flash" "sprites/muzzleflash2.spr"
|
||||
"reloadTime" "0.4"
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
entityDef tf_weapon_tranq
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Tranquilizer Gun"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/w_9mmhandgun.mdl"
|
||||
"model_view" "models/v_tfc_pistol.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_fireInfo" "fireInfo_tfTranq"
|
||||
"inv_name" "Tranquilizer Gun"
|
||||
"ammoType" "ammo_shells"
|
||||
"ammoRequired" "1"
|
||||
"ammoPerShot" "1"
|
||||
"punchAngle" "-2 0 0"
|
||||
|
||||
"act_fire" "3"
|
||||
"actAltFire" "3"
|
||||
"act_fireLast" "4"
|
||||
"actAltFireLast" "4"
|
||||
"act_holster" "8"
|
||||
"act_reload" "6"
|
||||
"act_reloadEmpty" "5"
|
||||
"act_draw" "7"
|
||||
"act_idle" "0,1,2"
|
||||
"view_geomset" "geomset 2 2\n"
|
||||
|
||||
"snd_fire" "Weapon_Tranq.Single"
|
||||
"snd_empty" "Weapon_Tranq.ClipEmpty"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "1"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "10"
|
||||
}
|
||||
|
||||
entityDef fireInfo_tfTranq
|
||||
{
|
||||
"def_onFire" "projectile_tfTranq"
|
||||
"fireRate" "2.0"
|
||||
"punchAngle" "-4 0 0"
|
||||
}
|
||||
|
||||
entityDef projectile_tfTranq
|
||||
{
|
||||
"spawnclass" "ncProjectile"
|
||||
"model" "models/nail.mdl"
|
||||
"velocity" "1000 0 0"
|
||||
"angular_velocity" "0 0 20"
|
||||
"mins" "0 0 0"
|
||||
"maxs" "0 0 0"
|
||||
"damage" "skill:plr_tranq"
|
||||
"snd_explode" "impact.tfNail"
|
||||
"snd_hit" "impact.tfNailHitFlesh"
|
||||
"detonate_on_fuse" "0"
|
||||
"detonate_on_death" "1"
|
||||
"detonate_on_world" "1"
|
||||
"detonate_on_actor" "1"
|
||||
"projectile_debris" "debris_tfNail"
|
||||
"model_detonate" "impact_default.main"
|
||||
"decal_detonate" "ExplosionScorch"
|
||||
"debris_count" "1"
|
||||
"debris_stick" "1"
|
||||
"debris_offset" "-2 0 0"
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
entityDef tf_weapon_umbrella
|
||||
{
|
||||
"editor_color" ".3 .3 1"
|
||||
"editor_mins" "-16 -16 -16"
|
||||
"editor_maxs" "16 16 16"
|
||||
"editor_usage" "Umbrella"
|
||||
"editor_rotatable" "1"
|
||||
|
||||
"spawnclass" "HLWeapon"
|
||||
"model" "models/p_umbrella.mdl"
|
||||
"model_view" "models/v_umbrella.mdl"
|
||||
"snd_acquire" "weapon.pickup"
|
||||
"snd_respawn" "item.respawn"
|
||||
|
||||
// weapon specific
|
||||
"def_melee" "damage_tfUmbrella"
|
||||
"melee_distance" "32"
|
||||
"inv_name" "Umbrella"
|
||||
"ammoType" ""
|
||||
"ammoRequired" "0"
|
||||
"clipSize" "0"
|
||||
"silent_fire" "1"
|
||||
|
||||
"meleeRateMiss" "0.5"
|
||||
"meleeRateHit" "0.5"
|
||||
|
||||
"act_idle" "0"
|
||||
"act_draw" "1"
|
||||
"act_holster" "2"
|
||||
"act_fireFailed" "4,5,7"
|
||||
"act_fire" "3,6,8"
|
||||
|
||||
// HLWeapon specific
|
||||
"hudSlot" "0"
|
||||
"hudSlotPos" "0"
|
||||
"weight" "0"
|
||||
"crosshair" "none"
|
||||
"ammoIcon" "none"
|
||||
}
|
||||
|
||||
entityDef damage_tfUmbrella
|
||||
{
|
||||
"damage" "skill:plr_umbrella"
|
||||
"gib" "1"
|
||||
|
||||
"snd_hit" "Weapon_Umbrella.HitWorld"
|
||||
"snd_hitFlesh" "Weapon_Umbrella.HitFlesh"
|
||||
"snd_miss" "Weapon_Umbrella.Miss"
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
Weapon_Bioweapon.HitFlesh
|
||||
{
|
||||
pitch 0.75
|
||||
sample items/medshot4.wav
|
||||
}
|
||||
|
||||
Weapon_Crowbar.HitWorld
|
||||
{
|
||||
alerts
|
||||
sample weapons/cbar_hit1.wav
|
||||
sample weapons/cbar_hit2.wav
|
||||
}
|
||||
|
||||
Weapon_Crowbar.HitFlesh
|
||||
{
|
||||
alerts
|
||||
sample weapons/cbar_hitbod1.wav
|
||||
sample weapons/cbar_hitbod2.wav
|
||||
sample weapons/cbar_hitbod3.wav
|
||||
}
|
||||
|
||||
Weapon_Crowbar.Miss
|
||||
{
|
||||
sample weapons/cbar_miss1.wav
|
||||
}
|
||||
|
||||
Weapon_FlameThrower.Fire
|
||||
{
|
||||
sample weapons/flmfire2.wav
|
||||
}
|
||||
|
||||
Weapon_FlameThrower.FireRocket
|
||||
{
|
||||
sample weapons/sgun1.wav
|
||||
}
|
||||
|
||||
Weapon_Grenade_Pipebomb.Bounce
|
||||
{
|
||||
sample weapons/grenade_hit1.wav
|
||||
sample weapons/grenade_hit2.wav
|
||||
sample weapons/grenade_hit3.wav
|
||||
}
|
||||
|
||||
Weapon_Grenade_Pipebomb.Explode
|
||||
{
|
||||
sample weapons/explode3.wav
|
||||
sample weapons/explode4.wav
|
||||
sample weapons/explode5.wav
|
||||
}
|
||||
|
||||
Weapon_GrenadeLauncher.Single
|
||||
{
|
||||
sample weapons/glauncher.wav
|
||||
}
|
||||
|
||||
Weapon_Knife.HitWorld
|
||||
{
|
||||
alerts
|
||||
sample weapons/cbar_hit1.wav
|
||||
sample weapons/cbar_hit2.wav
|
||||
}
|
||||
|
||||
Weapon_Knife.HitFlesh
|
||||
{
|
||||
alerts
|
||||
sample weapons/cbar_hitbod1.wav
|
||||
sample weapons/cbar_hitbod2.wav
|
||||
sample weapons/cbar_hitbod3.wav
|
||||
}
|
||||
|
||||
Weapon_Knife.Miss
|
||||
{
|
||||
sample weapons/cbar_miss1.wav
|
||||
}
|
||||
|
||||
Weapon_Medikit.HitFlesh
|
||||
{
|
||||
sample items/medshot4.wav
|
||||
}
|
||||
|
||||
Weapon_Minigun.Fire
|
||||
{
|
||||
alerts
|
||||
pitch 0.75
|
||||
sample weapons/asscan2.wav
|
||||
}
|
||||
|
||||
Weapon_Minigun.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_Minigun.WindDown
|
||||
{
|
||||
alerts
|
||||
sample weapons/asscan3.wav
|
||||
}
|
||||
|
||||
Weapon_Minigun.WindUp
|
||||
{
|
||||
alerts
|
||||
sample weapons/asscan1.wav
|
||||
}
|
||||
|
||||
Weapon_Medikit.Overheal
|
||||
{
|
||||
pitch 1.5
|
||||
sample items/smallmedkit1.wav
|
||||
}
|
||||
|
||||
Weapon_Medikit.HitFlesh
|
||||
{
|
||||
sample items/smallmedkit1.wav
|
||||
}
|
||||
|
||||
Weapon_NailGun.Single
|
||||
{
|
||||
sample weapons/airgun_1.wav
|
||||
}
|
||||
|
||||
Weapon_NailGun.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_RPG.Single
|
||||
{
|
||||
sample weapons/rocketfire1.wav
|
||||
}
|
||||
|
||||
Weapon_Pistol.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_Railgun.Single
|
||||
{
|
||||
sample weapons/railgun.wav
|
||||
}
|
||||
|
||||
Weapon_Railgun.WindUp
|
||||
{
|
||||
pitch 0.5
|
||||
sample weapons/railgun.wav
|
||||
}
|
||||
|
||||
Weapon_Shotgun.Single
|
||||
{
|
||||
sample weapons/sbarrel1.wav
|
||||
}
|
||||
|
||||
Weapon_SuperShotgun.Single
|
||||
{
|
||||
sample weapons/shotgn2.wav
|
||||
}
|
||||
|
||||
Weapon_Shotgun.Pump
|
||||
{
|
||||
sample weapons/scock1.wav
|
||||
}
|
||||
|
||||
Weapon_Shotgun.Reload
|
||||
{
|
||||
sample weapons/reload3.wav
|
||||
}
|
||||
|
||||
Weapon_SMG.Single
|
||||
{
|
||||
sample weapons/sniper.wav
|
||||
}
|
||||
|
||||
Weapon_SMG.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_SniperRifle.Single
|
||||
{
|
||||
sample ambience/rifle1.wav
|
||||
}
|
||||
|
||||
Weapon_SniperRifle.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_StickyBombLauncher.Single
|
||||
{
|
||||
sample weapons/glauncher2.wav
|
||||
}
|
||||
|
||||
Weapon_SyringeGun.Single
|
||||
{
|
||||
sample weapons/spike2.wav
|
||||
}
|
||||
|
||||
Weapon_SyringeGun.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_Tranq.Single
|
||||
{
|
||||
sample weapons/dartgun.wav
|
||||
}
|
||||
|
||||
Weapon_Tranq.ClipEmpty
|
||||
{
|
||||
sample weapons/dryfire1.wav
|
||||
}
|
||||
|
||||
Weapon_Wrench.HitFlesh
|
||||
{
|
||||
sample weapons/cbar_hitbod1.wav
|
||||
sample weapons/cbar_hitbod2.wav
|
||||
sample weapons/cbar_hitbod3.wav
|
||||
}
|
||||
|
||||
Weapon_Wrench.HitWorld
|
||||
{
|
||||
sample weapons/cbar_hit1.wav
|
||||
sample weapons/cbar_hit2.wav
|
||||
}
|
||||
|
||||
Weapon_Wrench.Miss
|
||||
{
|
||||
sample weapons/cbar_miss1.wav
|
||||
}
|
||||
|
||||
engineer.build
|
||||
{
|
||||
sample weapons/building.wav
|
||||
}
|
||||
|
||||
engineer.turret_set
|
||||
{
|
||||
sample weapons/turrset.wav
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
set "hostname" "Team Effort Server"
|
||||
set "maxplayers" "8"
|
||||
set g_gametype "default"
|
BIN
icon.tga
BIN
img/te.png
Before Width: | Height: | Size: 5.3 KiB |
2
instructions.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
In order to play this FreeHL addon, please move the folder this file is
|
||||
in into the same place where 'valve' and 'default.fmf' reside. Thanks!
|
14
manifest.fmf
Normal file
|
@ -0,0 +1,14 @@
|
|||
FTEMANIFEST 1
|
||||
GAME tfc
|
||||
NAME "Team Fortress"
|
||||
BASEGAME platform
|
||||
BASEGAME valve
|
||||
BASEGAME tfc
|
||||
|
||||
// you don't really want to change these
|
||||
RTCBROKER master.frag-net.com:27950
|
||||
PROTOCOLNAME "Nuclide"
|
||||
MAINCONFIG game.cfg
|
||||
DOWNLOADSURL "http://www.frag-net.com/dl/packages"
|
||||
|
||||
-exec platform_default.cfg
|
BIN
maps/2fort.jpg
Before Width: | Height: | Size: 6.3 KiB |
BIN
maps/avanti.jpg
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 7.8 KiB |
BIN
maps/casbah.jpg
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 6.6 KiB |
BIN
maps/cz2.jpg
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 6.8 KiB |
BIN
maps/flagrun.jpg
Before Width: | Height: | Size: 7.3 KiB |
BIN
maps/hunted.jpg
Before Width: | Height: | Size: 6.3 KiB |
BIN
maps/push.jpg
Before Width: | Height: | Size: 4.7 KiB |
BIN
maps/rock2.jpg
Before Width: | Height: | Size: 4.8 KiB |
BIN
maps/warpath.jpg
Before Width: | Height: | Size: 6.5 KiB |
BIN
maps/well.jpg
Before Width: | Height: | Size: 5 KiB |
5
quake.rc
|
@ -1,5 +0,0 @@
|
|||
exec default_controls.cfg
|
||||
exec default_cvar.cfg
|
||||
exec default_video.cfg
|
||||
exec default_valve.cfg
|
||||
exec default_tfc.cfg
|
|
@ -3,4 +3,3 @@ CC=fteqcc
|
|||
all:
|
||||
cd client && $(MAKE)
|
||||
cd server && $(MAKE)
|
||||
cd rules && $(MAKE)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
QCC=fteqcc
|
||||
CC=fteqcc
|
||||
|
||||
all:
|
||||
$(QCC) $(CFLAGS) -I../../../src/platform/ -I../../../valve/src/shared/ progs.src
|
||||
$(CC) progs.src
|
||||
|
|
|
@ -14,14 +14,11 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
void VGUI_ChooseClass(int);
|
||||
void VGUI_ChooseClass(void);
|
||||
|
||||
bool
|
||||
int
|
||||
ClientGame_ConsoleCommand(void)
|
||||
{
|
||||
int s = (int)getproperty(VF_ACTIVESEAT);
|
||||
pSeatTFC = &g_seats_tfc[s];
|
||||
|
||||
switch(argv(0)) {
|
||||
case "build":
|
||||
sendevent("TFCBuild", "i", stoi(argv(1)));
|
||||
|
@ -31,42 +28,27 @@ ClientGame_ConsoleCommand(void)
|
|||
break;
|
||||
case "chooseclass":
|
||||
case "changeclass":
|
||||
VGUI_ChooseClass(userinfo.GetInteger(pSeat->m_ePlayer, "*team"));
|
||||
VGUI_ChooseClass();
|
||||
break;
|
||||
case "chooseteam":
|
||||
case "changeteam":
|
||||
VGUI_ChooseTeam();
|
||||
break;
|
||||
|
||||
case "+gren1":
|
||||
pSeatTFC->m_bInputGren1 = true;
|
||||
pSeat->m_iInputExtra1 = TRUE;
|
||||
break;
|
||||
case "-gren1":
|
||||
pSeatTFC->m_bInputGren1 = false;
|
||||
pSeat->m_iInputExtra1 = FALSE;
|
||||
break;
|
||||
case "+gren2":
|
||||
pSeatTFC->m_bInputGren2 = true;
|
||||
pSeat->m_iInputExtra2 = TRUE;
|
||||
break;
|
||||
case "-gren2":
|
||||
pSeatTFC->m_bInputGren2 = false;
|
||||
break;
|
||||
/* stubbed out, so they won't get forwarded to Nuclide */
|
||||
case "goprone":
|
||||
case "gocrouch":
|
||||
case "+prone":
|
||||
case "-prone":
|
||||
case "+gostand":
|
||||
case "-gostand":
|
||||
case "+sprint":
|
||||
case "-sprint":
|
||||
break;
|
||||
case "invnext":
|
||||
pSeatLocal->weaponSelectionHUD.SelectNext(false);
|
||||
break;
|
||||
case "invprev":
|
||||
pSeatLocal->weaponSelectionHUD.SelectPrevious(false);
|
||||
pSeat->m_iInputExtra2 = FALSE;
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
return (0);
|
||||
}
|
||||
return (true);
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../../../valve/src/shared/defs.h"
|
||||
#define MAX_A_CELLS 200
|
||||
|
||||
var string g_dmsg_spr;
|
||||
|
@ -29,10 +28,5 @@ var string g_tfchud7_spr;
|
|||
|
||||
var int MUZZLE_ROUND;
|
||||
|
||||
void TFCHallucination_Insert(vector, vector);
|
||||
|
||||
struct
|
||||
{
|
||||
bool m_bInputGren1;
|
||||
bool m_bInputGren2;
|
||||
} g_seats_tfc[4], *pSeatTFC;
|
||||
void TFCHallucination_Insert(vector, vector);
|
|
@ -42,7 +42,7 @@ ClientGame_PreDraw(void)
|
|||
void
|
||||
ClientGame_PostDraw(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)pSeat->m_ePlayer;
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
if (serverkeyfloat("areadefs") == 1) {
|
||||
string strArea = getplayerkeyvalue(player_localnum, "*areadef");
|
||||
|
|
|
@ -18,12 +18,6 @@ int
|
|||
ClientGame_EntityUpdate(float id, float new)
|
||||
{
|
||||
switch (id) {
|
||||
case ENT_PLAYER:
|
||||
NSENTITY_READENTITY(TFPlayer, new)
|
||||
break;
|
||||
case ENT_WEAPON:
|
||||
NSENTITY_READENTITY(HLWeapon, new)
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,20 @@ ClientGame_EventParse(float fHeader)
|
|||
case EV_OBITUARY:
|
||||
Obituary_Parse();
|
||||
break;
|
||||
case EV_BLOOD:
|
||||
vector vBloodPos;
|
||||
vector vBloodColor;
|
||||
|
||||
vBloodPos[0] = readcoord();
|
||||
vBloodPos[1] = readcoord();
|
||||
vBloodPos[2] = readcoord();
|
||||
|
||||
vBloodColor[0] = readbyte() / 255;
|
||||
vBloodColor[1] = readbyte() / 255;
|
||||
vBloodColor[2] = readbyte() / 255;
|
||||
|
||||
FX_Blood(vBloodPos, vBloodColor);
|
||||
break;
|
||||
case EV_CHAT:
|
||||
float fSender = readbyte();
|
||||
float fTeam = readbyte();
|
||||
|
@ -41,6 +55,15 @@ ClientGame_EventParse(float fHeader)
|
|||
case EV_VIEWMODEL:
|
||||
View_PlayAnimation(readbyte());
|
||||
break;
|
||||
case EV_WEAPON_PICKUP:
|
||||
int w = readbyte();
|
||||
|
||||
if (autocvar_cl_autoweaponswitch == 1) {
|
||||
sendevent("PlayerSwitchWeapon", "i", w);
|
||||
}
|
||||
|
||||
HUD_WeaponPickupNotify(w);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class
|
||||
TFCHallucination:ncEntity
|
||||
TFCHallucination:NSEntity
|
||||
{
|
||||
|
||||
};
|
||||
|
@ -28,8 +28,7 @@ TFCHallucination_Insert(vector viewPosition, vector viewDirection)
|
|||
halluPos += v_forward * random(8, 64);
|
||||
halluPos += v_up * random(-64, 64);
|
||||
halluPos += v_right * random(-64, 64);
|
||||
#warning FIX THE BLOOD CALL!
|
||||
//FX_Blood(halluPos, [1,0,0]);
|
||||
FX_Blood(halluPos, [1,0,0]);
|
||||
}
|
||||
pointsound(viewPosition, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
|
@ -68,7 +67,7 @@ TFCHallucination_Insert(vector viewPosition, vector viewDirection)
|
|||
break;
|
||||
case 7: /* nade thrown about */
|
||||
int nadeSelection = (int)floor(random(0, 8));
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
|
||||
switch (nadeSelection) {
|
||||
case 1:
|
||||
|
@ -108,7 +107,7 @@ TFCHallucination_Insert(vector viewPosition, vector viewDirection)
|
|||
break;
|
||||
case 8: /* nail shot around */
|
||||
halluPos = viewPosition + (v_forward * -32) + (v_right * random(-64, 64));
|
||||
ncRenderableEntity eNail = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNail = spawn(NSRenderableEntity);
|
||||
eNail.SetModel("models/nail.mdl");
|
||||
eNail.SetOrigin(halluPos);
|
||||
eNail.SetMovetype(MOVETYPE_NOCLIP);
|
||||
|
|
|
@ -76,10 +76,10 @@ HUD_AmmoNotify_Insert(int type, int count)
|
|||
|
||||
/* called whenever we should check for pickup updates */
|
||||
void
|
||||
HUD_AmmoNotify_Check(ncPlayer pl)
|
||||
HUD_AmmoNotify_Check(player 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[3] - pl.m_iAmmoTypes_net[3]);
|
||||
HUD_AmmoNotify_Insert(3, pl.m_iAmmoTypes[4] - pl.m_iAmmoTypes_net[4]);
|
||||
}
|
||||
HUD_AmmoNotify_Insert(0, pl.m_iAmmoRockets - pl.m_iAmmoRockets_net);
|
||||
HUD_AmmoNotify_Insert(1, pl.m_iAmmoNails - pl.m_iAmmoNails_net);
|
||||
HUD_AmmoNotify_Insert(2, pl.m_iAmmoCells - pl.m_iAmmoCells_net);
|
||||
HUD_AmmoNotify_Insert(3, pl.m_iAmmoShells - pl.m_iAmmoShells_net);
|
||||
}
|
|
@ -76,7 +76,7 @@ HUD_ItemNotify_Insert(int type, int count)
|
|||
|
||||
/* called whenever we should check for pickup updates */
|
||||
void
|
||||
HUD_ItemNotify_Check(ncPlayer pl)
|
||||
HUD_ItemNotify_Check(player pl)
|
||||
{
|
||||
int healthdiff = bound(0, pl.health - pl.health_net, 100);
|
||||
int armordiff = bound(0, pl.armor - pl.armor_net, 100);
|
||||
|
|
|
@ -30,19 +30,11 @@ ClientGame_Init(float apilevel, string enginename, float engineversion)
|
|||
registercommand("-gren1");
|
||||
registercommand("+gren2");
|
||||
registercommand("-gren2");
|
||||
registercommand("chooseclass");
|
||||
registercommand("changeclass");
|
||||
registercommand("changeteam");
|
||||
registercommand("chooseteam");
|
||||
|
||||
registercommand("lastinv");
|
||||
registercommand("invnext");
|
||||
registercommand("invprev");
|
||||
|
||||
registercommand("changeteam");
|
||||
Obituary_Init();
|
||||
|
||||
pSeatTFC = &g_seats_tfc[0];
|
||||
|
||||
pSeatLocal->weaponSelectionHUD = spawn(HLWeaponSelect);
|
||||
}
|
||||
|
||||
void VGUI_ChooseTeam(void);
|
||||
|
@ -58,6 +50,8 @@ ClientGame_RendererRestart(string rstr)
|
|||
Obituary_Precache();
|
||||
Damage_Precache();
|
||||
|
||||
FX_Blood_Init();
|
||||
|
||||
/* HUD selection icons */
|
||||
g_dmsg_spr = spriteframe("sprites/tfc_dmsg.spr", 0, 0.0f);
|
||||
g_tfchud1_spr = spriteframe("sprites/tfchud01.spr", 0, 0.0f);
|
||||
|
@ -73,5 +67,4 @@ ClientGame_RendererRestart(string rstr)
|
|||
MUZZLE_SMALL = (int)getmodelindex("sprites/muzzleflash2.spr");
|
||||
MUZZLE_WEIRD = (int)getmodelindex("sprites/muzzleflash3.spr");
|
||||
MUZZLE_ROUND = (int)getmodelindex("sprites/muzzleflash.spr");
|
||||
HLSprite_Init();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma target fte_5768
|
||||
//#pragma flag enable assumeint
|
||||
#pragma progs_dat "../../csprogs.dat"
|
||||
#pragma forcecrc 54730
|
||||
|
||||
#define CSQC
|
||||
#define CLIENT
|
||||
|
@ -21,6 +20,8 @@ defs.h
|
|||
../../../src/gs-entbase/shared.src
|
||||
../shared/include.src
|
||||
|
||||
vox.qc
|
||||
|
||||
../../../valve/src/client/damage.qc
|
||||
draw.qc
|
||||
init.qc
|
||||
|
@ -37,13 +38,11 @@ hud_itemnotify.qc
|
|||
hud_ammonotify.qc
|
||||
../../../valve/src/client/hud_sprite.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_chooseteam.qc
|
||||
../../../valve/src/client/vgui_changeclass.qc
|
||||
vgui_chooseteam.qc
|
||||
vgui_changeclass.qc
|
||||
../../../src/shared/include.src
|
||||
#endlist
|
||||
|
||||
|
|
232
src/client/vgui_changeclass.qc
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
static string g_classDescrScout;
|
||||
static string g_classDescrSniper;
|
||||
static string g_classDescrSoldier;
|
||||
static string g_classDescrDemoman;
|
||||
static string g_classDescrMedic;
|
||||
static string g_classDescrHWGuy;
|
||||
static string g_classDescrPyro;
|
||||
static string g_classDescrSpy;
|
||||
static string g_classDescrEngineer;
|
||||
static string g_classDescrRandomPC;
|
||||
|
||||
static void
|
||||
TFCClass_Init(void)
|
||||
{
|
||||
g_classDescrScout = textfile_to_string("classes/short_scout.txt");
|
||||
g_classDescrSniper = textfile_to_string("classes/short_sniper.txt");
|
||||
g_classDescrSoldier = textfile_to_string("classes/short_soldier.txt");
|
||||
g_classDescrDemoman = textfile_to_string("classes/short_demoman.txt");
|
||||
g_classDescrMedic = textfile_to_string("classes/short_medic.txt");
|
||||
g_classDescrHWGuy = textfile_to_string("classes/short_hwguy.txt");
|
||||
g_classDescrPyro = textfile_to_string("classes/short_pyro.txt");
|
||||
g_classDescrSpy = textfile_to_string("classes/short_spy.txt");
|
||||
g_classDescrEngineer = textfile_to_string("classes/short_engineer.txt");
|
||||
g_classDescrRandomPC = textfile_to_string("classes/short_randompc.txt");
|
||||
}
|
||||
|
||||
static VGUIWindow winClassSelection;
|
||||
static VGUIPic imgClassPreview;
|
||||
static VGUILabel lblClassTitle;
|
||||
static VGUILabel lblClassDescription;
|
||||
static VGUILabel lblClassCounter;
|
||||
|
||||
class TFClassButton:VGUIButton
|
||||
{
|
||||
void TFClassButton(void);
|
||||
|
||||
virtual void OnMouseUp(void);
|
||||
virtual void OnMouseEntered(void);
|
||||
};
|
||||
|
||||
void
|
||||
TFClassButton::TFClassButton(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TFClassButton::OnMouseUp(void)
|
||||
{
|
||||
int classSelection = GetTag();
|
||||
sendevent("ClassJoin", "f", (float)classSelection);
|
||||
winClassSelection.Hide();
|
||||
}
|
||||
|
||||
void
|
||||
TFClassButton::OnMouseEntered(void)
|
||||
{
|
||||
int classSelection = GetTag();
|
||||
string teamName = "blue";
|
||||
|
||||
switch (getplayerkeyfloat(player_localnum, "*team")) {
|
||||
case 1:
|
||||
teamName = "blue";
|
||||
break;
|
||||
case 2:
|
||||
teamName = "red";
|
||||
break;
|
||||
case 3:
|
||||
teamName = "blue"; /* TFC doesn't ship with a real green. */
|
||||
break;
|
||||
case 4:
|
||||
teamName = "red"; /* TFC doesn't ship with a real yellow either. */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (classSelection) {
|
||||
case 1:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_scout"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_scout", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrScout);
|
||||
break;
|
||||
case 2:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_sniper"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_sniper", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrSniper);
|
||||
break;
|
||||
case 3:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_soldier"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_soldier", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrSoldier);
|
||||
break;
|
||||
case 4:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_demoman"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_demoman", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrDemoman);
|
||||
break;
|
||||
case 5:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_medic"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_medic", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrMedic);
|
||||
break;
|
||||
case 6:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_hwguy"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_hwguy", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrHWGuy);
|
||||
break;
|
||||
case 7:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_pyro"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_pyro", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrPyro);
|
||||
break;
|
||||
case 8:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_spy"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_spy", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrSpy);
|
||||
break;
|
||||
case 9:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("Title_engineer"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_engineer", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrEngineer);
|
||||
break;
|
||||
case 0:
|
||||
lblClassTitle.SetTitle(Titles_GetTextBody("RandomPC"));
|
||||
imgClassPreview.SetImage(strcat("gfx/vgui/640_randompc", teamName));
|
||||
lblClassDescription.SetTitle(g_classDescrRandomPC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string g_classnames [] = {
|
||||
"Scout",
|
||||
"Sniper",
|
||||
"Soldier",
|
||||
"Demoman",
|
||||
"Medic",
|
||||
"HWGuy",
|
||||
"Pyro",
|
||||
"Spy",
|
||||
"Engineer",
|
||||
"Random"
|
||||
};
|
||||
|
||||
void
|
||||
VGUI_ChooseClass(void)
|
||||
{
|
||||
static int initialized;
|
||||
static TFClassButton *btns;
|
||||
static VGUILabel lblSelectClass;
|
||||
static VGUIFrame frmClassInfo;
|
||||
|
||||
if (!initialized) {
|
||||
vector btnpos = [40,80];
|
||||
initialized = TRUE;
|
||||
|
||||
TFCClass_Init();
|
||||
|
||||
winClassSelection = spawn(VGUIWindow);
|
||||
winClassSelection.SetSize([640, 480]);
|
||||
winClassSelection.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen);
|
||||
|
||||
lblSelectClass = spawn(VGUILabel);
|
||||
lblSelectClass.SetTitle(Titles_GetTextBody("Title_SelectYourClass"));
|
||||
lblSelectClass.SetTextSize(19);
|
||||
lblSelectClass.SetPos([40, 38]);
|
||||
lblSelectClass.SetSize([400, 24]);
|
||||
|
||||
frmClassInfo = spawn(VGUIFrame);
|
||||
frmClassInfo.SetPos([176, 80]);
|
||||
frmClassInfo.SetSize([424, 312]);
|
||||
|
||||
imgClassPreview = spawn(VGUIPic);
|
||||
imgClassPreview.SetPos([190, 90]);
|
||||
|
||||
lblClassTitle = spawn(VGUILabel);
|
||||
lblClassTitle.SetPos([338, 90]);
|
||||
lblClassTitle.SetTextSize(19);
|
||||
lblClassTitle.SetSize([320, 24]);
|
||||
|
||||
lblClassCounter = spawn(VGUILabel);
|
||||
lblClassCounter.SetPos([338, 90 + 32]);
|
||||
lblClassCounter.SetSize([320, 18]);
|
||||
|
||||
lblClassDescription = spawn(VGUILabel);
|
||||
lblClassDescription.SetPos([338, 90 + 32 + 32]);
|
||||
lblClassDescription.SetSize([250, 240]);
|
||||
|
||||
g_uiDesktop.Add(winClassSelection);
|
||||
winClassSelection.Add(lblSelectClass);
|
||||
winClassSelection.Add(frmClassInfo);
|
||||
winClassSelection.Add(imgClassPreview);
|
||||
winClassSelection.Add(lblClassTitle);
|
||||
winClassSelection.Add(lblClassCounter);
|
||||
winClassSelection.Add(lblClassDescription);
|
||||
|
||||
btns = memalloc(sizeof(TFClassButton) * g_classnames.length);
|
||||
for (int i = 0; i < g_classnames.length; i++) {
|
||||
btns[i] = spawn(TFClassButton);
|
||||
btns[i].SetTitle(Titles_GetTextBody(g_classnames[i]));
|
||||
btns[i].SetSize([124, 24]);
|
||||
btns[i].SetPos(btnpos);
|
||||
|
||||
if (i == 9) {
|
||||
btns[i].SetKeyEquivalent("0");
|
||||
btns[i].SetTag(0);
|
||||
} else {
|
||||
btns[i].SetKeyEquivalent(ftos((float)i+1));
|
||||
btns[i].SetTag(i+1i);
|
||||
}
|
||||
|
||||
winClassSelection.Add(btns[i]);
|
||||
btnpos[1] += 32;
|
||||
}
|
||||
}
|
||||
|
||||
winClassSelection.Show();
|
||||
winClassSelection.SetPos((video_res / 2) - (winClassSelection.GetSize() / 2));
|
||||
}
|
159
src/client/vgui_chooseteam.qc
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
static VGUIWindow winChooseTeam;
|
||||
|
||||
class TFTeamButton:VGUIButton
|
||||
{
|
||||
void TFTeamButton(void);
|
||||
|
||||
virtual void OnMouseUp(void);
|
||||
};
|
||||
|
||||
void
|
||||
TFTeamButton::TFTeamButton(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TFTeamButton::OnMouseUp(void)
|
||||
{
|
||||
int tag = GetTag();
|
||||
|
||||
localcmd("changeclass\n");
|
||||
sendevent("TeamJoin", "f", (float)tag);
|
||||
winChooseTeam.Hide();
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
VGUI_ChooseTeam_MapInfo(void)
|
||||
{
|
||||
static string mapinfo = __NULL__;
|
||||
|
||||
if (mapinfo != __NULL__)
|
||||
return mapinfo;
|
||||
|
||||
filestream fileMap = fopen(strcat("maps/", mapname, ".txt"), FILE_READ);
|
||||
string temp;
|
||||
|
||||
if (fileMap != -1) {
|
||||
while ((temp = fgets(fileMap))) {
|
||||
mapinfo = strcat(mapinfo, temp, "\n");
|
||||
}
|
||||
} else {
|
||||
mapinfo = Titles_GetTextBody("Map_Description_not_available");
|
||||
}
|
||||
|
||||
return mapinfo;
|
||||
}
|
||||
|
||||
void
|
||||
VGUI_ChooseTeam(void)
|
||||
{
|
||||
static int initialized;
|
||||
static VGUIButton btnAutoAssign;
|
||||
static VGUIButton btnGoSpectator;
|
||||
static VGUIFrame frmMapInfo;
|
||||
static VGUILabel lblSelectTeam;
|
||||
static VGUILabel lblMapName;
|
||||
static VGUILabel lblMapInfo;
|
||||
|
||||
if (!initialized) {
|
||||
vector btnpos = [40,80];
|
||||
|
||||
initialized = TRUE;
|
||||
winChooseTeam = spawn(VGUIWindow);
|
||||
winChooseTeam.SetSize('640 480');
|
||||
winChooseTeam.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen);
|
||||
|
||||
lblSelectTeam = spawn(VGUILabel);
|
||||
lblSelectTeam.SetTitle(Titles_GetTextBody("Title_SelectYourTeam"));
|
||||
lblSelectTeam.SetTextSize(19);
|
||||
lblSelectTeam.SetPos([40, 38]);
|
||||
lblSelectTeam.SetSize('400 24');
|
||||
|
||||
frmMapInfo = spawn(VGUIFrame);
|
||||
frmMapInfo.SetPos('176 80');
|
||||
frmMapInfo.SetSize('424 312');
|
||||
|
||||
lblMapName = spawn(VGUILabel);
|
||||
lblMapName.SetTitle(mapname);
|
||||
lblMapName.SetTextSize(19);
|
||||
lblMapName.SetPos('194 105');
|
||||
lblMapName.SetSize('250 312');
|
||||
|
||||
lblMapInfo = spawn(VGUILabel);
|
||||
lblMapInfo.SetTitle(VGUI_ChooseTeam_MapInfo());
|
||||
lblMapInfo.SetPos('194 129');
|
||||
lblMapInfo.SetSize('375 250');
|
||||
|
||||
for (int t = 1; t <= serverkeyfloat("teams"); t++) {
|
||||
TFTeamButton btnForTeam;
|
||||
string team_name = serverkey(sprintf("team_%i", t));
|
||||
|
||||
btnForTeam = spawn(TFTeamButton);
|
||||
btnForTeam.SetTitle(strtoupper(team_name));
|
||||
btnForTeam.SetPos(btnpos);
|
||||
btnForTeam.SetKeyEquivalent(ftos((float)t));
|
||||
btnForTeam.SetSize('124 24');
|
||||
|
||||
switch (team_name) {
|
||||
case "Blue":
|
||||
btnForTeam.SetTag(1);
|
||||
break;
|
||||
case "Red":
|
||||
btnForTeam.SetTag(2);
|
||||
break;
|
||||
case "Green":
|
||||
btnForTeam.SetTag(3);
|
||||
break;
|
||||
case "Yellow":
|
||||
btnForTeam.SetTag(4);
|
||||
break;
|
||||
}
|
||||
|
||||
winChooseTeam.Add(btnForTeam);
|
||||
btnpos[1] += 32;
|
||||
}
|
||||
|
||||
btnAutoAssign = spawn(VGUIButton);
|
||||
btnAutoAssign.SetTitle(Titles_GetTextBody("Team_AutoAssign"));
|
||||
btnAutoAssign.SetPos(btnpos);
|
||||
btnAutoAssign.SetSize('124 24');
|
||||
btnAutoAssign.SetKeyEquivalent("5");
|
||||
//btnAutoAssign.SetFunc(VGUI_AutoAssign);
|
||||
btnpos[1] += 32;
|
||||
|
||||
btnGoSpectator = spawn(VGUIButton);
|
||||
btnGoSpectator.SetTitle(Titles_GetTextBody("Menu_Spectate"));
|
||||
btnGoSpectator.SetPos(btnpos);
|
||||
btnGoSpectator.SetSize('124 24');
|
||||
btnGoSpectator.SetKeyEquivalent("6");
|
||||
//btnGoSpectator.SetFunc(VGUI_GoSpectator);
|
||||
|
||||
g_uiDesktop.Add(winChooseTeam);
|
||||
winChooseTeam.Add(frmMapInfo);
|
||||
winChooseTeam.Add(lblSelectTeam);
|
||||
winChooseTeam.Add(lblMapName);
|
||||
winChooseTeam.Add(lblMapInfo);
|
||||
winChooseTeam.Add(btnAutoAssign);
|
||||
winChooseTeam.Add(btnGoSpectator);
|
||||
}
|
||||
|
||||
winChooseTeam.Show();
|
||||
winChooseTeam.SetPos((video_res / 2) - (winChooseTeam.GetSize() / 2));
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2025 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -14,65 +14,35 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
class
|
||||
VOX:ncTalkMonster
|
||||
TFCVox:NSTalkMonster
|
||||
{
|
||||
public:
|
||||
void(void) VOX;
|
||||
void(void) TFCVox;
|
||||
virtual void(string) SentenceSample;
|
||||
};
|
||||
|
||||
TFCVox g_vox;
|
||||
|
||||
void
|
||||
VOX::SentenceSample(string sample)
|
||||
TFCVox::SentenceSample(string sample)
|
||||
{
|
||||
sound(this, CHAN_VOICE, sample, 1.0, ATTN_NONE, 100, SOUNDFLAG_FOLLOW | SOUNDFLAG_NOSPACIALISE);
|
||||
}
|
||||
|
||||
void
|
||||
VOX:: VOX(void)
|
||||
TFCVox::TFCVox(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Vox_Parse(void)
|
||||
{
|
||||
static VOX voxDelegate;
|
||||
string msg = readstring();
|
||||
|
||||
if (!voxDelegate) {
|
||||
voxDelegate = spawn(VOX);
|
||||
}
|
||||
if (!g_vox)
|
||||
g_vox = spawn(TFCVox);
|
||||
|
||||
voxDelegate.Sentence(msg);
|
||||
print(msg);
|
||||
print("\n");
|
||||
g_vox.Sentence(msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
Vox_Sentence_Broadcast(string wordsToBroadcast)
|
||||
{
|
||||
if (!STRING_SET(wordsToBroadcast)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_TFC_VOXMSG);
|
||||
WriteString(MSG_MULTICAST, wordsToBroadcast);
|
||||
multicast(g_vec_null, MULTICAST_ALL_R);
|
||||
}
|
||||
|
||||
void
|
||||
Vox_Sentence_Single(entity targetClient, string wordsToVOX)
|
||||
{
|
||||
if (!STRING_SET(wordsToVOX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_TFC_VOXMSG);
|
||||
WriteString(MSG_MULTICAST, wordsToVOX);
|
||||
msg_entity = targetClient;
|
||||
multicast(g_vec_null, MULTICAST_ONE_R);
|
||||
}
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
63
|
||||
1 cfg/skill.cfg
|
||||
1 cfg/skill_manifest.cfg
|
||||
1 data/avanti.way
|
||||
1 data/badlands.way
|
||||
1 data/casbah.way
|
||||
1 data/crossover2.way
|
||||
1 data/cz2.way
|
||||
1 data/dustbowl.way
|
||||
1 data/epicenter.way
|
||||
1 data/flagrun.way
|
||||
1 data/hunted.way
|
||||
1 data/push.way
|
||||
1 data/rock2.way
|
||||
1 data/warpath.way
|
||||
1 data/well.way
|
||||
1 decls/def/ammo.def
|
||||
1 decls/def/armor.def
|
||||
1 decls/def/items.def
|
||||
1 decls/def/monsters.def
|
||||
1 decls/def/player.def
|
||||
1 decls/def/weapons.def
|
||||
1 decls/def/weapons/ac.def
|
||||
1 decls/def/weapons/autorifle.def
|
||||
1 decls/def/weapons/axe.def
|
||||
1 decls/def/weapons/flamethrower.def
|
||||
1 decls/def/weapons/gl.def
|
||||
1 decls/def/weapons/ic.def
|
||||
1 decls/def/weapons/knife.def
|
||||
1 decls/def/weapons/medikit.def
|
||||
1 decls/def/weapons/ng.def
|
||||
1 decls/def/weapons/pl.def
|
||||
1 decls/def/weapons/railgun.def
|
||||
1 decls/def/weapons/rpg.def
|
||||
1 decls/def/weapons/shotgun.def
|
||||
1 decls/def/weapons/sniperrifle.def
|
||||
1 decls/def/weapons/spanner.def
|
||||
1 decls/def/weapons/superng.def
|
||||
1 decls/def/weapons/supershotgun.def
|
||||
1 decls/def/weapons/tranq.def
|
||||
1 decls/def/weapons/umbrella.def
|
||||
1 decls/sound/items_tfc.sndshd
|
||||
1 decls/sound/player_tfc.sndshd
|
||||
1 decls/sound/turret_tfc.sndshd
|
||||
1 decls/sound/weapons_tfc.sndshd
|
||||
1 default_tfc.cfg
|
||||
1 maps/2fort.jpg
|
||||
1 maps/avanti.jpg
|
||||
1 maps/badlands.jpg
|
||||
1 maps/casbah.jpg
|
||||
1 maps/crossover2.jpg
|
||||
1 maps/cz2.jpg
|
||||
1 maps/dustbowl.jpg
|
||||
1 maps/epicenter.jpg
|
||||
1 maps/flagrun.jpg
|
||||
1 maps/hunted.jpg
|
||||
1 maps/push.jpg
|
||||
1 maps/rock2.jpg
|
||||
1 maps/warpath.jpg
|
||||
1 maps/well.jpg
|
||||
1 particles/weapon_railgun.cfg
|
||||
1 progs/default.dat
|
||||
1 quake.rc
|
||||
1 scripts/constants.txt
|
|
@ -1,3 +1,2 @@
|
|||
#pragma sourcefile client/progs.src
|
||||
#pragma sourcefile server/progs.src
|
||||
#pragma sourcefile rules/default.qc
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
QCC=fteqcc
|
||||
|
||||
all:
|
||||
mkdir -pv ../../progs/
|
||||
$(QCC) $(CFLAGS) -I../../../src/server default.qc
|
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024-2025 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.
|
||||
*/
|
||||
|
||||
#pragma PROGS_DAT "../../progs/default.dat"
|
||||
|
||||
#include "../../../src/server/api.h"
|
||||
|
||||
static string g_tfClasses[] = {
|
||||
"player_scout",
|
||||
"player_sniper",
|
||||
"player_soldier",
|
||||
"player_demo",
|
||||
"player_medic",
|
||||
"player_heavy",
|
||||
"player_pyro",
|
||||
"player_spy",
|
||||
"player_engineer",
|
||||
};
|
||||
|
||||
static string g_tfHelp[] = {
|
||||
"HELP_SCOUT",
|
||||
"HELP_SNIPER",
|
||||
"HELP_SOLDIER",
|
||||
"HELP_DEMO",
|
||||
"HELP_MEDIC",
|
||||
"HELP_HEAVY",
|
||||
"HELP_PYRO",
|
||||
"HELP_SPY",
|
||||
"HELP_ENGINEER",
|
||||
};
|
||||
|
||||
static string g_tfPlayerColor[5] = {
|
||||
"0xffffff",
|
||||
"0x9aff",
|
||||
"0xff1800"
|
||||
"0xffca00",
|
||||
"0x3bff00"
|
||||
};
|
||||
|
||||
bool
|
||||
AllowFlashlight(void)
|
||||
{
|
||||
return cvars.GetBool("mp_flashlight");
|
||||
}
|
||||
|
||||
void
|
||||
TF_SwitchClass(entity targetPlayer, int classID)
|
||||
{
|
||||
ents.ChangeToClass(targetPlayer, g_tfClasses[classID]);
|
||||
game.TeleportToSpawn(targetPlayer);
|
||||
ents.Input(targetPlayer, "Message", g_tfHelp[classID], targetPlayer);
|
||||
userinfo.SetString(targetPlayer, "topcolor", g_tfPlayerColor[targetPlayer.team]);
|
||||
userinfo.SetString(targetPlayer, "bottomcolor", g_tfPlayerColor[targetPlayer.team]);
|
||||
}
|
||||
|
||||
void
|
||||
TF_GoSpectator(entity targetPlayer)
|
||||
{
|
||||
if (!targetPlayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
ents.ChangeToClass(targetPlayer, "spectator");
|
||||
game.TeleportToSpawn(targetPlayer);
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_Precache(void)
|
||||
{
|
||||
for (int i = 0i; i < g_tfClasses.length; i++) {
|
||||
precache.Entity(g_tfClasses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_StartGameType(void)
|
||||
{
|
||||
motd.LoadDefault();
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||
{
|
||||
/* first course of action is to kick players into spectator cam */
|
||||
TF_GoSpectator(playerEntity);
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_PlayerDisconnect(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||
{
|
||||
CodeCallback_PlayerSpawn(playerEntity);
|
||||
return (true);
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_PlayerDamage(entity inflictor, entity attacker)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||
{
|
||||
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||
|
||||
/* death-counter */
|
||||
playerEntity.deaths++;
|
||||
|
||||
/* update score-counter */
|
||||
if (ents.isPlayer(attacker)) {
|
||||
if (self == attacker) {
|
||||
attacker.frags--;
|
||||
} else {
|
||||
attacker.frags++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
|
||||
{
|
||||
ents.Input(playerEntity, "SetTeam", itos(teamNum), playerEntity);
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
CodeCallback_ClientCommand(entity targetPlayer, string command)
|
||||
{
|
||||
float commandArgs = tokenize(command);
|
||||
|
||||
switch (argv(0)) {
|
||||
case "random":
|
||||
int classID = (int)floor(random(0, g_tfClasses.length));
|
||||
TF_SwitchClass(targetPlayer, classID);
|
||||
break;
|
||||
case "scout":
|
||||
TF_SwitchClass(targetPlayer, 0);
|
||||
break;
|
||||
case "sniper":
|
||||
TF_SwitchClass(targetPlayer, 1);
|
||||
break;
|
||||
case "soldier":
|
||||
TF_SwitchClass(targetPlayer, 2);
|
||||
break;
|
||||
case "demo":
|
||||
TF_SwitchClass(targetPlayer, 3);
|
||||
break;
|
||||
case "medic":
|
||||
TF_SwitchClass(targetPlayer, 4);
|
||||
break;
|
||||
case "heavy":
|
||||
TF_SwitchClass(targetPlayer, 5);
|
||||
break;
|
||||
case "pyro":
|
||||
TF_SwitchClass(targetPlayer, 6);
|
||||
break;
|
||||
case "spy":
|
||||
TF_SwitchClass(targetPlayer, 7);
|
||||
break;
|
||||
case "engineer":
|
||||
TF_SwitchClass(targetPlayer, 8);
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
CodeCallback_ImpulseCommand(entity clientEntity, float impulseNum)
|
||||
{
|
||||
switch (impulseNum) {
|
||||
case 100:
|
||||
if (AllowFlashlight() == true) {
|
||||
ents.Input(clientEntity, "UseItem", "item_suit", clientEntity);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
QCC=fteqcc
|
||||
CC=fteqcc
|
||||
|
||||
all:
|
||||
$(QCC) $(CFLAGS) -I../../../valve/src/shared/ progs.src
|
||||
$(CC) progs.src
|
||||
|
|
25
src/server/bot.qc
Normal file
|
@ -0,0 +1,25 @@
|
|||
class
|
||||
TFCBot:NSBot
|
||||
{
|
||||
void TFCBot(void);
|
||||
|
||||
//virtual void CreateObjective(void);
|
||||
};
|
||||
|
||||
void CSEv_TeamJoin_f(float f);
|
||||
void CSEv_ClassJoin_f(float f);
|
||||
|
||||
void
|
||||
TFCBot::TFCBot(void)
|
||||
{
|
||||
CSEv_TeamJoin_f(0);
|
||||
CSEv_ClassJoin_f(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
TFCBot::CreateObjective(void)
|
||||
{
|
||||
super:: CreateObjective();
|
||||
}
|
||||
#endif
|
48
src/server/client.qc
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 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.
|
||||
*/
|
||||
|
||||
/* called every input frame */
|
||||
void
|
||||
Game_RunClientCommand(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
|
||||
/* clear map triggers */
|
||||
pl.gflags &= ~GF_NOBUILDZONE;
|
||||
pl.gflags &= ~GF_NOGRENADEZONE;
|
||||
|
||||
pl.Physics_Run();
|
||||
}
|
||||
|
||||
/* client cmd overrides happen here */
|
||||
void
|
||||
Game_ParseClientCommand(string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
if (argv(1) == "timeleft") {
|
||||
string msg;
|
||||
string timestring;
|
||||
float timeleft;
|
||||
timeleft = cvar("timelimit") - (time / 60);
|
||||
timestring = Util_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
bprint(PRINT_CHAT, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
clientcommand(self, cmd);
|
||||
}
|
|
@ -14,7 +14,9 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../../../valve/src/shared/defs.h"
|
||||
#include "gamerules.h"
|
||||
#include "../../../valve/src/server/items.h"
|
||||
#include "../../../valve/src/server/flashlight.h"
|
||||
#include "sentry.h"
|
||||
|
||||
var bool g_tfcHasBlueTeam = false;
|
||||
|
@ -47,7 +49,7 @@ TFC_DetonateTypeForPlayer(entity pl, string cname)
|
|||
if (e.real_owner != pl)
|
||||
continue;
|
||||
|
||||
ncSurfacePropEntity targ = (ncSurfacePropEntity)e;
|
||||
NSSurfacePropEntity targ = (NSSurfacePropEntity)e;
|
||||
targ.Destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/* The unit has 150 health and can hold up to 400 shells, 600 nails, 300 rockets, 400 cells, and 500 armor points. */
|
||||
|
||||
class
|
||||
TFCDispenser:ncSurfacePropEntity
|
||||
TFCDispenser:NSSurfacePropEntity
|
||||
{
|
||||
float m_flNextDispense;
|
||||
|
||||
|
@ -28,28 +28,28 @@ TFCDispenser:ncSurfacePropEntity
|
|||
int m_iRockets;
|
||||
int m_iCells;
|
||||
int m_iArmor;
|
||||
|
||||
void(void) TFCDispenser;
|
||||
|
||||
void TFCDispenser(void);
|
||||
virtual void(player) Place;
|
||||
virtual void(void) FinishPlacing;
|
||||
|
||||
virtual void Place(TFPlayer);
|
||||
virtual void FinishPlacing(void);
|
||||
virtual void(entity) Touch;
|
||||
|
||||
virtual void Touch(entity);
|
||||
virtual void(void) Replenish;
|
||||
virtual void(void) ClampValues;
|
||||
|
||||
virtual void Replenish(void);
|
||||
virtual void ClampValues(void);
|
||||
virtual int(void) GrabShells;
|
||||
virtual int(void) GrabNails;
|
||||
virtual int(void) GrabRockets;
|
||||
virtual int(void) GrabCells;
|
||||
virtual int(void) GrabArmor;
|
||||
|
||||
virtual int GrabShells(void);
|
||||
virtual int GrabNails(void);
|
||||
virtual int GrabRockets(void);
|
||||
virtual int GrabCells(void);
|
||||
virtual int GrabArmor(void);
|
||||
|
||||
virtual void Death(entity, entity, int, vector, vector, int);
|
||||
virtual void(void) Death;
|
||||
};
|
||||
|
||||
void
|
||||
TFCDispenser::Death(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
|
||||
TFCDispenser::Death(void)
|
||||
{
|
||||
env_message_single(real_owner, "#Dispenser_destroyed");
|
||||
pointparticles(particleeffectnum("fx_explosion.main"), origin, [0,0,0], 1);
|
||||
|
@ -171,25 +171,21 @@ TFCDispenser::Touch(entity eToucher)
|
|||
if (m_flNextDispense > time)
|
||||
return;
|
||||
|
||||
TFPlayer pl = (TFPlayer)eToucher;
|
||||
int rocketType = ammoNumForName("ammo_rockets");
|
||||
int nailType = ammoNumForName("ammo_nails");
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
int shellType = ammoNumForName("ammo_shells");
|
||||
player pl = (player)eToucher;
|
||||
|
||||
int r, n, c, s, a, sum;
|
||||
r = n = c = s = a = sum = 0;
|
||||
|
||||
/* only subtract what if we need anything */
|
||||
if (pl.GetReserveAmmo(rocketType) < pl.MaxAmmo(rocketType))
|
||||
if (pl.m_iAmmoRockets < pl.m_iMaxRockets)
|
||||
r = GrabRockets();
|
||||
if (pl.GetReserveAmmo(nailType) < pl.MaxAmmo(nailType))
|
||||
if (pl.m_iAmmoNails < pl.m_iMaxNails)
|
||||
n = GrabNails();
|
||||
if (pl.GetReserveAmmo(cellType) < pl.MaxAmmo(cellType))
|
||||
if (pl.m_iAmmoCells < pl.m_iMaxCells)
|
||||
c = GrabCells();
|
||||
if (pl.GetReserveAmmo(shellType) < pl.MaxAmmo(shellType))
|
||||
if (pl.m_iAmmoShells < pl.m_iMaxShells)
|
||||
s = GrabShells();
|
||||
if (pl.armor < pl.GetMaxArmor())
|
||||
if (pl.armor < pl.m_iMaxArmor)
|
||||
a = GrabArmor();
|
||||
|
||||
/* see the sum of what we picked up to determine if we'll register as a pickup */
|
||||
|
@ -202,20 +198,29 @@ TFCDispenser::Touch(entity eToucher)
|
|||
sound(this, CHAN_ITEM, "weapons/scock1.wav", 1.0, ATTN_NORM);
|
||||
|
||||
/* add whatever it is we can get */
|
||||
pl.GiveAmmo(rocketType, r);
|
||||
pl.GiveAmmo(nailType, n);
|
||||
pl.GiveAmmo(cellType, c);
|
||||
pl.GiveAmmo(shellType, s);
|
||||
pl.m_iAmmoRockets += r;
|
||||
pl.m_iAmmoNails += n;
|
||||
pl.m_iAmmoCells += c;
|
||||
pl.m_iAmmoShells += s;
|
||||
pl.armor += a;
|
||||
|
||||
if (pl.armor > pl.GetMaxArmor())
|
||||
pl.armor = pl.GetMaxArmor();
|
||||
/* clamp player values */
|
||||
if (pl.m_iAmmoRockets > pl.m_iMaxRockets)
|
||||
pl.m_iAmmoRockets = pl.m_iMaxRockets;
|
||||
if (pl.m_iAmmoNails > pl.m_iMaxNails)
|
||||
pl.m_iAmmoNails = pl.m_iMaxNails;
|
||||
if (pl.m_iAmmoCells > pl.m_iMaxCells)
|
||||
pl.m_iAmmoCells = pl.m_iMaxCells;
|
||||
if (pl.m_iAmmoShells > pl.m_iMaxShells)
|
||||
pl.m_iAmmoShells = pl.m_iMaxShells;
|
||||
if (pl.armor > pl.m_iMaxArmor)
|
||||
pl.armor = pl. m_iMaxArmor;
|
||||
|
||||
m_flNextDispense = time + 2.0f;
|
||||
}
|
||||
|
||||
void
|
||||
TFCDispenser::Place(TFPlayer pl)
|
||||
TFCDispenser::Place(player pl)
|
||||
{
|
||||
vector newAngles = pl.GetAngles();
|
||||
newAngles[0] = newAngles[2] = 0;
|
||||
|
@ -249,21 +254,20 @@ TFCDispenser::TFCDispenser(void)
|
|||
SetMovetype(MOVETYPE_NONE);
|
||||
SetSize([-16,-16,0], [16,16,48]);
|
||||
SetHealth(150);
|
||||
MakeVulnerable();
|
||||
SetTakedamage(DAMAGE_YES);
|
||||
}
|
||||
|
||||
void
|
||||
TFCDispenser_Build(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)self;
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
player pl = (player)self;
|
||||
|
||||
/* only engineers can do this */
|
||||
if (pl.classtype != CLASS_ENGINEER)
|
||||
return;
|
||||
|
||||
/* it costs cells to build these things */
|
||||
if (pl.UseAmmo(cellType, TFC_DISPENSER_COST) == false) {
|
||||
/* it costs */
|
||||
if (pl.m_iAmmoCells < TFC_DISPENSER_COST) {
|
||||
env_message_single(pl, "#Build_nometal");
|
||||
return;
|
||||
}
|
||||
|
@ -279,6 +283,8 @@ TFCDispenser_Build(void)
|
|||
return;
|
||||
}
|
||||
|
||||
pl.m_iAmmoCells -= TFC_DISPENSER_COST;
|
||||
|
||||
/* deploy */
|
||||
TFCDispenser dispenser = spawn(TFCDispenser);
|
||||
dispenser.Place(pl);
|
||||
|
@ -287,5 +293,5 @@ TFCDispenser_Build(void)
|
|||
void
|
||||
TFCDispenser_Dismantle(void)
|
||||
{
|
||||
TFC_DetonateTypeForPlayer((TFPlayer)self, "TFCDispenser");
|
||||
TFC_DetonateTypeForPlayer((player)self, "TFCDispenser");
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#includelist
|
||||
dispenser.qc
|
||||
sentry.qc
|
||||
teleporter.qc
|
||||
func_nobuild.qc
|
||||
func_nogrenades.qc
|
||||
info_player_teamspawn.qc
|
||||
item_tfgoal.qc
|
||||
info_tfgoal.qc
|
||||
info_areadef.qc
|
||||
info_tfdetect.qc
|
||||
item_armor.qc
|
||||
item_healthkit.qc
|
||||
#endlist
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2025 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2022 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
|
||||
|
@ -23,20 +23,24 @@ Brush volume that when entered, will not allow you to deploy anything as an engi
|
|||
-------- KEYS --------
|
||||
"targetname" Name
|
||||
*/
|
||||
class
|
||||
func_nobuild:ncBrushTrigger
|
||||
{
|
||||
public:
|
||||
void func_nobuild(void);
|
||||
|
||||
virtual void Respawn(void);
|
||||
virtual void Touch(entity);
|
||||
class
|
||||
func_nobuild:NSBrushTrigger
|
||||
{
|
||||
void(void) func_nobuild;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual void(entity) Touch;
|
||||
};
|
||||
|
||||
void
|
||||
func_nobuild::func_nobuild(void)
|
||||
func_nobuild::Touch(entity eToucher)
|
||||
{
|
||||
player pl = (player)eToucher;
|
||||
if (!(eToucher.flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
pl.gflags |= GF_NOBUILDZONE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -46,13 +50,7 @@ func_nobuild::Respawn(void)
|
|||
}
|
||||
|
||||
void
|
||||
func_nobuild::Touch(entity eToucher)
|
||||
func_nobuild::func_nobuild(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)eToucher;
|
||||
|
||||
if (isPlayer(eToucher) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
pl.gflags |= GF_NOBUILDZONE;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2025 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2022 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
|
||||
|
@ -23,20 +23,24 @@ Brush volume that when entered, will not allow you to deploy any grenades.
|
|||
-------- KEYS --------
|
||||
"targetname" Name
|
||||
*/
|
||||
class
|
||||
func_nogrenades:ncBrushTrigger
|
||||
{
|
||||
public:
|
||||
void func_nogrenades(void);
|
||||
|
||||
virtual void Respawn(void);
|
||||
virtual void Touch(entity);
|
||||
class
|
||||
func_nogrenades:NSBrushTrigger
|
||||
{
|
||||
void(void) func_nogrenades;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual void(entity) Touch;
|
||||
};
|
||||
|
||||
void
|
||||
func_nogrenades::func_nogrenades(void)
|
||||
func_nogrenades::Touch(entity eToucher)
|
||||
{
|
||||
player pl = (player)eToucher;
|
||||
if (!(eToucher.flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
pl.gflags |= GF_NOGRENADEZONE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -46,13 +50,7 @@ func_nogrenades::Respawn(void)
|
|||
}
|
||||
|
||||
void
|
||||
func_nogrenades::Touch(entity eToucher)
|
||||
func_nogrenades::func_nogrenades(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)eToucher;
|
||||
|
||||
if (isPlayer(eToucher) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
pl.gflags |= GF_NOGRENADEZONE;
|
||||
}
|
||||
}
|
35
src/server/gamerules.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
class TFCGameRules:CGameRules
|
||||
{
|
||||
void(void) TFCGameRules;
|
||||
|
||||
virtual bool ConsoleCommand(NSClientPlayer, string);
|
||||
virtual bool IsTeamplay(void);
|
||||
|
||||
virtual void PlayerConnect(NSClientPlayer);
|
||||
virtual void PlayerDisconnect(NSClientPlayer);
|
||||
virtual void PlayerPostFrame(NSClientPlayer);
|
||||
virtual void PlayerSpawn(NSClientPlayer);
|
||||
virtual void PlayerKill(NSClientPlayer);
|
||||
virtual void PlayerRespawn(NSClientPlayer);
|
||||
virtual void PlayerDeath(NSClientPlayer);
|
||||
virtual void DropGoalItem(NSClientPlayer);
|
||||
virtual float ImpulseCommand(NSClient, float);
|
||||
virtual void LevelNewParms(void);
|
||||
virtual void InitPostEnts(void);
|
||||
};
|
207
src/server/gamerules.qc
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2023 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
|
||||
TFCGameRules::TFCGameRules(void)
|
||||
{
|
||||
/* wipe the serverinfo clean */
|
||||
forceinfokey(world, "teams", "0");
|
||||
forceinfokey(world, "team_1", "");
|
||||
forceinfokey(world, "team_2", "");
|
||||
forceinfokey(world, "team_3", "");
|
||||
forceinfokey(world, "team_4", "");
|
||||
forceinfokey(world, "teamscore_1", "");
|
||||
forceinfokey(world, "teamscore_2", "");
|
||||
forceinfokey(world, "teamscore_3", "");
|
||||
forceinfokey(world, "teamscore_4", "");
|
||||
}
|
||||
|
||||
bool
|
||||
TFCGameRules::ConsoleCommand(NSClientPlayer pp, string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
switch (argv(0)) {
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
TFCGameRules::IsTeamplay(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::DropGoalItem(NSClientPlayer pp)
|
||||
{
|
||||
/* skip normal players */
|
||||
if (!(pp.g_items & ITEM_GOALITEM))
|
||||
return;
|
||||
|
||||
item_tfgoal target;
|
||||
|
||||
for (entity e = world; (e = find(e, ::classname, "item_tfgoal"));) {
|
||||
target = (item_tfgoal)e;
|
||||
|
||||
/* item is still pick-upable */
|
||||
if (target.solid != SOLID_NOT) {
|
||||
print("the item is not picked up. \n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* that's us, yup */
|
||||
if (target.m_eActivator == pp) {
|
||||
target.DropReturnable(pp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
print("^1WARNING: ^7Player marked as having impossible goal-item\n");
|
||||
}
|
||||
|
||||
/* we check what fields have changed over the course of the frame and network
|
||||
* only the ones that have actually changed */
|
||||
void
|
||||
TFCGameRules::PlayerPostFrame(NSClientPlayer pp)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::LevelNewParms(void)
|
||||
{
|
||||
parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 =
|
||||
parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 =
|
||||
parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 =
|
||||
parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 =
|
||||
parm29 = parm30 = 0;
|
||||
parm64 = FL_CLIENT;
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerConnect(NSClientPlayer pl)
|
||||
{
|
||||
if (Plugin_PlayerConnect(pl) == FALSE)
|
||||
bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname));
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerDisconnect(NSClientPlayer pl)
|
||||
{
|
||||
bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname));
|
||||
|
||||
/* Make this unusable */
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.modelindex = 0;
|
||||
pl.health = 0;
|
||||
pl.takedamage = 0;
|
||||
pl.SendFlags = PLAYER_MODELINDEX;
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules_PlayerRespawn(void)
|
||||
{
|
||||
TFCGameRules rule = (TFCGameRules)g_grMode;
|
||||
rule.PlayerRespawn((NSClientPlayer)self);
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerDeath(NSClientPlayer pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
|
||||
DropGoalItem(pp);
|
||||
pl.SetSolid(SOLID_NOT);
|
||||
pl.SetMovetype(MOVETYPE_NONE);
|
||||
|
||||
pl.ScheduleThink(TFCGameRules_PlayerRespawn, 4.0f);
|
||||
|
||||
/* play the iconic death sound */
|
||||
Sound_Play(pl, CHAN_VOICE, "player_tfc.death");
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerKill(NSClientPlayer pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR);
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerRespawn(NSClientPlayer pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
pl.MakeClass(pl.classtype);
|
||||
pl.SpawnIntoGame();
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::PlayerSpawn(NSClientPlayer pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
pl.MakeTempSpectator(); /* replace this with a non-spectator ghost */
|
||||
Spawn_ObserverCam(pl);
|
||||
}
|
||||
|
||||
bool
|
||||
TFCGameRules::ImpulseCommand(NSClient bp, float num)
|
||||
{
|
||||
switch (num) {
|
||||
case 101:
|
||||
player pl = (player)bp;
|
||||
if (cvar("sv_cheats") > 0) {
|
||||
Weapons_AddItem(pl, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(pl, WEAPON_MEDKIT, -1);
|
||||
Weapons_AddItem(pl, WEAPON_KNIFE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_WRENCH, -1);
|
||||
Weapons_AddItem(pl, WEAPON_UMBRELLA, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SNIPER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_TRANQUIL, -1);
|
||||
Weapons_AddItem(pl, WEAPON_RAILGUN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_AUTORIFLE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_NAILGUN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GLAUNCHER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SUPERNAIL, -1);
|
||||
Weapons_AddItem(pl, WEAPON_FLAMER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_RPG, -1);
|
||||
Weapons_AddItem(pl, WEAPON_PIPEBOMB, -1);
|
||||
Weapons_AddItem(pl, WEAPON_ASSCAN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_INCENDIARY, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GRAPPLE, -1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return super::ImpulseCommand(bp, num);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::InitPostEnts(void)
|
||||
{
|
||||
super::InitPostEnts();
|
||||
|
||||
/* rename the team spawns. */
|
||||
info_player_teamspawn::RenameTeamSpawns();
|
||||
info_tfdetect::Setup();
|
||||
}
|
|
@ -28,33 +28,26 @@ Describes an area's bounds and description/name.
|
|||
*/
|
||||
|
||||
class
|
||||
info_areadef:ncPointTrigger
|
||||
info_areadef:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void info_areadef(void);
|
||||
|
||||
virtual void Respawn(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Touch(entity);
|
||||
|
||||
private:
|
||||
string m_strDescription;
|
||||
vector m_vecMins;
|
||||
vector m_vecMaxs;
|
||||
|
||||
void(void) info_areadef;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string,string) SpawnKey;
|
||||
virtual void(entity) Touch;
|
||||
};
|
||||
|
||||
void
|
||||
info_areadef::info_areadef(void)
|
||||
info_areadef::Touch(entity eToucher)
|
||||
{
|
||||
serverinfo.SetBool("areadefs", true);
|
||||
}
|
||||
|
||||
void
|
||||
info_areadef::Touch(entity touchingEntity)
|
||||
{
|
||||
if (isPlayer(touchingEntity) == false) {
|
||||
if (!(eToucher.flags & FL_CLIENT))
|
||||
return;
|
||||
}
|
||||
|
||||
userinfo.SetString(touchingEntity, "*areadef", m_strDescription);
|
||||
forceinfokey(eToucher, "*areadef", m_strDescription);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,6 +61,12 @@ info_areadef::SpawnKey(string strKey, string strValue)
|
|||
m_strDescription = strreplace("GREEN", "^x4F4GREEN^7", m_strDescription);
|
||||
m_strDescription = strreplace("YELLOW", "^xFF4YELLOW^7", m_strDescription);
|
||||
break;
|
||||
case "mins":
|
||||
m_vecMins = stov(strValue);
|
||||
break;
|
||||
case "maxs":
|
||||
m_vecMaxs = stov(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
}
|
||||
|
@ -76,9 +75,15 @@ info_areadef::SpawnKey(string strKey, string strValue)
|
|||
void
|
||||
info_areadef::Respawn(void)
|
||||
{
|
||||
super::Respawn();
|
||||
|
||||
/* set up our volume */
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetSize(GetSpawnFloat("mins"), GetSpawnFloat("maxs"));
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
SetSize(m_vecMins, m_vecMaxs);
|
||||
}
|
||||
|
||||
void
|
||||
info_areadef::info_areadef(void)
|
||||
{
|
||||
forceinfokey(world, "areadefs", "1");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2025 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -14,38 +14,53 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
class
|
||||
info_player_teamspawn:ncSpawnPoint
|
||||
class info_player_teamspawn:NSSpawnPoint
|
||||
{
|
||||
public:
|
||||
void(void) info_player_teamspawn;
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void SpawnKey(string, string);
|
||||
|
||||
nonvirtual void RenameTeamSpawns(void);
|
||||
};
|
||||
|
||||
void
|
||||
info_player_teamspawn::info_player_teamspawn(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
info_player_teamspawn::Spawned(void)
|
||||
info_player_teamspawn::SpawnKey(string keyName, string setValue)
|
||||
{
|
||||
team = GetSpawnInt ("team_no");
|
||||
switch (keyName) {
|
||||
case "team_no":
|
||||
team = ReadInt(setValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
switch (team) {
|
||||
case 1:
|
||||
classname = "info_teamspawn_blue";
|
||||
break;
|
||||
case 2:
|
||||
classname = "info_teamspawn_red";
|
||||
break;
|
||||
case 4:
|
||||
classname = "info_teamspawn_yellow";
|
||||
break;
|
||||
case 3:
|
||||
classname = "info_teamspawn_green";
|
||||
break;
|
||||
void
|
||||
info_player_teamspawn::RenameTeamSpawns(void)
|
||||
{
|
||||
for (entity e = world; (e = find(e, ::classname, "info_player_teamspawn"));) {
|
||||
info_player_teamspawn findSpawn = (info_player_teamspawn)e;
|
||||
|
||||
switch (findSpawn.team) {
|
||||
case 1:
|
||||
e.classname = "info_teamspawn_blue";
|
||||
break;
|
||||
case 2:
|
||||
e.classname = "info_teamspawn_red";
|
||||
break;
|
||||
case 3:
|
||||
e.classname = "info_teamspawn_yellow";
|
||||
break;
|
||||
case 4:
|
||||
e.classname = "info_teamspawn_green";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
botinfo = BOTINFO_SPAWNPOINT;
|
||||
|
|
|
@ -57,35 +57,20 @@ typedef enum
|
|||
|
||||
# NOTES
|
||||
|
||||
The `maxammo_` keys sets the limits regarding available team classes.
|
||||
|
||||
The following flags can be combined:
|
||||
|
||||
- ONLY_CIVILLIAN (-1) : Not a bitflag, but when set this team only allows the civillian class.
|
||||
- SCOUT (1) : No Scout class.
|
||||
- SNIPER (2) : No Sniper class.
|
||||
- SOLDIER (4) : No Soldier class.
|
||||
- DEMO (8) : No Demoman class.
|
||||
- MEDIC (16) : No Medic class.
|
||||
- HEAVY (32) : No Heavy Weapons Guy class.
|
||||
- PYRO (64) : No Pyro class.
|
||||
- NO_RANDOM_CLASS (128) : No random class in menus.
|
||||
- SPY (256) : No Spy class.
|
||||
- ENGINEER (512) : No Engineer class.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Team Fortress (1996).
|
||||
*/
|
||||
class
|
||||
info_tfdetect:ncPointTrigger
|
||||
info_tfdetect:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void info_tfdetect(void);
|
||||
|
||||
virtual void SpawnKey(string, string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Respawn(void);
|
||||
|
||||
nonvirtual void Setup(void);
|
||||
nonvirtual void SetupClass(int teamID, tfdetectTeamFlags_t classFlags);
|
||||
|
||||
private:
|
||||
string m_strTeam1Name;
|
||||
|
@ -151,99 +136,74 @@ info_tfdetect::SpawnKey(string keyName, string setValue)
|
|||
}
|
||||
|
||||
void
|
||||
info_tfdetect::Spawned(void)
|
||||
info_tfdetect::Respawn(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
ScheduleThink(Setup, 0.0f);
|
||||
}
|
||||
|
||||
void
|
||||
info_tfdetect::SetupClass(int teamID, tfdetectTeamFlags_t classFlags)
|
||||
{
|
||||
if (classFlags == TFDFL_CIVILIANONLY) {
|
||||
teams.AddClass(teamID, "civilian");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOSCOUNT)) {
|
||||
teams.AddClass(teamID, "scout");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOSNIPER)) {
|
||||
teams.AddClass(teamID, "sniper");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOSOLDIER)) {
|
||||
teams.AddClass(teamID, "soldier");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NODEMOMAN)) {
|
||||
teams.AddClass(teamID, "demo");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOMEDIC)) {
|
||||
teams.AddClass(teamID, "medic");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOHEAVY)) {
|
||||
teams.AddClass(teamID, "heavy");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOPYRO)) {
|
||||
teams.AddClass(teamID, "pyro");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOSPY)) {
|
||||
teams.AddClass(teamID, "spy");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NOENGINEER)) {
|
||||
teams.AddClass(teamID, "engineer");
|
||||
}
|
||||
|
||||
if (!(classFlags & TFDFL_NORANDOM)) {
|
||||
teams.AddClass(teamID, "random");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
info_tfdetect::Setup(void)
|
||||
{
|
||||
int team_count = 0i;
|
||||
entity e = __NULL__;
|
||||
info_tfdetect globalTFD = (info_tfdetect)find(world, ::classname, "info_tfdetect");
|
||||
|
||||
/* populate the serverinfo field with the teams we have on the map */
|
||||
if (exists.InMap("info_teamspawn_blue")) {
|
||||
teams.SetUp(1, m_strTeam1Name, [153, 204, 255], true);
|
||||
SetupClass(1, m_bfTeam1Flags);
|
||||
teams.SetSpawnPoint(1, "info_teamspawn_blue");
|
||||
e = find(world, ::classname, "info_teamspawn_blue");
|
||||
if (e) {
|
||||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Blue");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasBlueTeam = true;
|
||||
}
|
||||
|
||||
if (exists.InMap("info_teamspawn_red")) {
|
||||
teams.SetUp(2, m_strTeam2Name, [255, 63, 63], true);
|
||||
SetupClass(2, m_bfTeam2Flags);
|
||||
teams.SetSpawnPoint(2, "info_teamspawn_red");
|
||||
e = find(world, ::classname, "info_teamspawn_red");
|
||||
if (e) {
|
||||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Red");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasRedTeam = true;
|
||||
}
|
||||
|
||||
if (exists.InMap("info_teamspawn_green")) {
|
||||
teams.SetUp(3, m_strTeam3Name, [153, 255, 204], true);
|
||||
SetupClass(3, m_bfTeam3Flags);
|
||||
teams.SetSpawnPoint(3, "info_teamspawn_green");
|
||||
e = find(world, ::classname, "info_teamspawn_green");
|
||||
if (e) {
|
||||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Green");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasGreenTeam = true;
|
||||
}
|
||||
|
||||
if (exists.InMap("info_teamspawn_yellow")) {
|
||||
teams.SetUp(4, m_strTeam4Name, [255, 255, 153], true);
|
||||
SetupClass(4, m_bfTeam4Flags);
|
||||
teams.SetSpawnPoint(4, "info_teamspawn_yellow");
|
||||
e = find(world, ::classname, "info_teamspawn_yellow");
|
||||
if (e) {
|
||||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Yellow");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasYellowTeam = true;
|
||||
}
|
||||
forceinfokey(world, "teams", itos(team_count));
|
||||
|
||||
if (!globalTFD) {
|
||||
NSLog("No info_tfdetect in level.");
|
||||
forceinfokey(world, "teamflags_1", "0");
|
||||
forceinfokey(world, "teamflags_2", "0");
|
||||
forceinfokey(world, "teamflags_3", "0");
|
||||
forceinfokey(world, "teamflags_4", "0");
|
||||
return;
|
||||
}
|
||||
|
||||
forceinfokey(world, "team_1", globalTFD.m_strTeam1Name);
|
||||
forceinfokey(world, "team_2", globalTFD.m_strTeam2Name);
|
||||
forceinfokey(world, "team_3", globalTFD.m_strTeam3Name);
|
||||
forceinfokey(world, "team_4", globalTFD.m_strTeam4Name);
|
||||
|
||||
forceinfokey(world, "teamflags_1", ftos(globalTFD.m_bfTeam1Flags));
|
||||
forceinfokey(world, "teamflags_2", ftos(globalTFD.m_bfTeam1Flags));
|
||||
forceinfokey(world, "teamflags_3", ftos(globalTFD.m_bfTeam1Flags));
|
||||
forceinfokey(world, "teamflags_4", ftos(globalTFD.m_bfTeam1Flags));
|
||||
|
||||
/* the evil localcmd feature of this entity. */
|
||||
if (STRING_SET(m_strLocalCommand)) {
|
||||
if (m_strLocalCommand) {
|
||||
localcmd(m_strLocalCommand);
|
||||
localcmd("\n");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2025 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -59,16 +59,8 @@ typedef enumflags
|
|||
} tfgoal_result;
|
||||
|
||||
/* point entity version */
|
||||
class info_tfgoal:ncRenderableEntity
|
||||
class info_tfgoal:NSRenderableEntity
|
||||
{
|
||||
public:
|
||||
void(void) info_tfgoal;
|
||||
virtual void(entity) Touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
virtual void Spawned(void);
|
||||
|
||||
private:
|
||||
string m_strName;
|
||||
string m_strActivatedSound;
|
||||
|
||||
|
@ -79,7 +71,7 @@ private:
|
|||
tfgoal_activation m_tfgActivation;
|
||||
tfgoal_effects m_tfgEffects;
|
||||
tfgoal_result m_tfgResult;
|
||||
TFPlayer m_Activator;
|
||||
player m_Activator;
|
||||
|
||||
float m_dMustCarry; /* player must carry item of this ID */
|
||||
float m_dRespawn; /* respawn after num seconds on TFRESULT_REMOVE */
|
||||
|
@ -116,80 +108,33 @@ private:
|
|||
string m_voxOwnerTeam; /* owner team */
|
||||
string m_voxNonOwnerTeams; /* non-owner team */
|
||||
|
||||
string m_strSpawnModel; /* because we mangle it */
|
||||
void(void) info_tfgoal;
|
||||
virtual void(entity) Touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
virtual void Spawned(void);
|
||||
};
|
||||
|
||||
void
|
||||
info_tfgoal::info_tfgoal(void)
|
||||
{
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_REMOVE;
|
||||
m_strName = __NULL__;
|
||||
m_strActivatedSound = __NULL__;
|
||||
m_iGoalID = 0i;
|
||||
m_iGoalGroupID = 0i;
|
||||
m_tfgActivation = 0;
|
||||
m_tfgEffects = 0;
|
||||
m_Activator = __NULL__;
|
||||
m_dMustCarry = 0.0f;
|
||||
m_dRespawn = 0.0f;
|
||||
m_dTeamBlueGain = 0.0f;
|
||||
m_dTeamRedGain = 0.0f;
|
||||
m_dTeamYellowGain = 0.0f;
|
||||
m_dTeamGreenGain = 0.0f;
|
||||
m_dScore = 0.0f;
|
||||
m_iTeamUses = 0i;
|
||||
m_iTeamOwner = 0i;
|
||||
m_iHealth = 0i;
|
||||
m_iArmor = 0i;
|
||||
m_iShells = 0i;
|
||||
m_iNails = 0i;
|
||||
m_iCells = 0i;
|
||||
m_iMedikit = 0i;
|
||||
m_iRockets = 0i;
|
||||
m_iDetpack = 0i;
|
||||
m_msgAll = __NULL__;
|
||||
m_msgActivator = __NULL__;
|
||||
m_msgActTeam = __NULL__;
|
||||
m_msgNonActTeam = __NULL__;
|
||||
m_msgOwnerTeam = __NULL__;
|
||||
m_msgNonOwnerTeams = __NULL__;
|
||||
m_voxAll = __NULL__;
|
||||
m_voxActivator = __NULL__;
|
||||
m_voxActTeam = __NULL__;
|
||||
m_voxNonActTeam = __NULL__;
|
||||
m_voxOwnerTeam = __NULL__;
|
||||
m_voxNonOwnerTeams = __NULL__;
|
||||
m_strSpawnModel = __NULL__;
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
/* HACK: goals without a targetname and TFGOAL_REMOVED can't work */
|
||||
if (m_tfgState == TFGOAL_REMOVED && HasTargetname() == false) {
|
||||
if (m_tfgState == TFGOAL_REMOVED && !targetname) {
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::Touch(entity touchingEntity)
|
||||
info_tfgoal::Touch(entity eToucher)
|
||||
{
|
||||
item_tfgoal findme = __NULL__;
|
||||
int rocketType = ammoNumForName("ammo_rockets");
|
||||
int nailType = ammoNumForName("ammo_nails");
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
int shellType = ammoNumForName("ammo_shells");
|
||||
int medikitType = ammoNumForName("ammo_medkit");
|
||||
int detpackType = ammoNumForName("ammo_detpack");
|
||||
|
||||
if (isPlayer(touchingEntity) == false) {
|
||||
if (eToucher.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
TFPlayer pl = (TFPlayer)touchingEntity;
|
||||
player pl = (player)eToucher;
|
||||
|
||||
/* check for state */
|
||||
if (m_tfgState != TFGOAL_INACTIVE) {
|
||||
|
@ -199,7 +144,7 @@ info_tfgoal::Touch(entity touchingEntity)
|
|||
|
||||
/* check for team eligibility */
|
||||
if (m_iTeamUses)
|
||||
if (touchingEntity.team != m_iTeamUses) {
|
||||
if (eToucher.team != m_iTeamUses) {
|
||||
print("not eligble\n");
|
||||
return;
|
||||
}
|
||||
|
@ -210,9 +155,8 @@ info_tfgoal::Touch(entity touchingEntity)
|
|||
for (entity e = world; (e = find(e, ::classname, "item_tfgoal"));) {
|
||||
item_tfgoal a = (item_tfgoal)e;
|
||||
|
||||
if (a.m_dItemID == m_dMustCarry) {
|
||||
if (a.m_dItemID == m_dMustCarry)
|
||||
findme = a;
|
||||
}
|
||||
}
|
||||
|
||||
if (!findme) {
|
||||
|
@ -235,53 +179,57 @@ info_tfgoal::Touch(entity touchingEntity)
|
|||
|
||||
/* mark as removed on the player end, too. */
|
||||
pl.g_items &= ~ITEM_GOALITEM;
|
||||
pl.RemoveVFlags(VFL_GOALITEM);
|
||||
pl.flags &= ~FL_GOALITEM;
|
||||
forceinfokey(pl, "*goalitem_t", "");
|
||||
}
|
||||
|
||||
sound(this, CHAN_ITEM, m_strActivatedSound, 1.0f, ATTN_NORM);
|
||||
Logging_Pickup(touchingEntity, this, m_strName);
|
||||
Logging_Pickup(eToucher, this, m_strName);
|
||||
|
||||
/* here we increase/decrease funstuff */
|
||||
pl.health += m_iHealth;
|
||||
pl.armor += m_iArmor;
|
||||
pl.GiveAmmo(rocketType, m_iRockets);
|
||||
pl.GiveAmmo(nailType, m_iNails);
|
||||
pl.GiveAmmo(cellType, m_iCells);
|
||||
pl.GiveAmmo(shellType, m_iShells);
|
||||
pl.GiveAmmo(medikitType, m_iMedikit);
|
||||
pl.GiveAmmo(detpackType, m_iDetpack);
|
||||
pl.m_iAmmoShells += m_iShells;
|
||||
pl.m_iAmmoNails += m_iNails;
|
||||
pl.m_iAmmoCells += m_iCells;
|
||||
pl.m_iAmmoRockets += m_iRockets;
|
||||
pl.m_iAmmoMedikit += m_iMedikit;
|
||||
pl.m_iAmmoDetpack += m_iDetpack;
|
||||
|
||||
/* clamp */
|
||||
pl.SetHealth(bound(0, pl.GetHealth(), pl.GetMaxHealth()));
|
||||
pl.SetArmor(bound(0, pl.GetArmor(), pl.GetMaxArmor()));
|
||||
pl.health = bound(0, pl.health, pl.m_iMaxHealth);
|
||||
pl.armor = bound(0, pl.armor, pl.m_iMaxArmor);
|
||||
pl.m_iAmmoShells = bound(0, pl.m_iAmmoShells, pl.m_iMaxShells);
|
||||
pl.m_iAmmoNails = bound(0, pl.m_iAmmoNails, pl.m_iMaxNails);
|
||||
pl.m_iAmmoCells = bound(0, pl.m_iAmmoCells, pl.m_iMaxCells);
|
||||
pl.m_iAmmoRockets = bound(0, pl.m_iAmmoRockets, pl.m_iMaxRockets);
|
||||
|
||||
pl.frags += frags;
|
||||
|
||||
string ts;
|
||||
if (m_dScore) {
|
||||
ts = sprintf("teamscore_%i", m_iTeamUses);
|
||||
serverinfo.SetFloat(ts, serverkeyfloat(ts) + m_dScore);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dScore));
|
||||
}
|
||||
if (m_dTeamBlueGain) {
|
||||
ts = "teamscore_1";
|
||||
serverinfo.SetFloat(ts, serverkeyfloat(ts) + m_dTeamBlueGain);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamBlueGain));
|
||||
}
|
||||
if (m_dTeamRedGain) {
|
||||
ts = "teamscore_2";
|
||||
serverinfo.SetFloat(ts, serverkeyfloat(ts) + m_dTeamRedGain);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamRedGain));
|
||||
}
|
||||
if (m_dTeamYellowGain) {
|
||||
ts = "teamscore_3";
|
||||
serverinfo.SetFloat(ts, serverkeyfloat(ts) + m_dTeamYellowGain);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamYellowGain));
|
||||
}
|
||||
if (m_dTeamGreenGain) {
|
||||
ts = "teamscore_4";
|
||||
serverinfo.SetFloat(ts, serverkeyfloat(ts) + m_dTeamGreenGain);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamGreenGain));
|
||||
}
|
||||
|
||||
/* message broadcaster */
|
||||
if (STRING_SET(m_msgAll)) {
|
||||
if (m_msgAll) {
|
||||
env_message_broadcast(m_msgAll);
|
||||
} else {
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
|
@ -290,21 +238,20 @@ info_tfgoal::Touch(entity touchingEntity)
|
|||
} else if (e.team == pl.team ) {
|
||||
env_message_single(e, m_msgActTeam);
|
||||
} else if (e.team != pl.team) {
|
||||
if (e.team == m_iTeamOwner && STRING_SET(m_msgOwnerTeam)) {
|
||||
if (e.team == m_iTeamOwner && m_msgOwnerTeam)
|
||||
env_message_single(e, m_msgOwnerTeam);
|
||||
} else {
|
||||
if (STRING_SET(m_msgNonOwnerTeams)) {
|
||||
else {
|
||||
if (m_msgNonOwnerTeams)
|
||||
env_message_single(e, m_msgNonOwnerTeams);
|
||||
} else {
|
||||
else
|
||||
env_message_single(e, m_msgNonActTeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vox speaker */
|
||||
if (STRING_SET(m_voxAll)) {
|
||||
if (m_voxAll) {
|
||||
Vox_Sentence_Broadcast(m_voxAll);
|
||||
} else {
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
|
@ -313,14 +260,13 @@ info_tfgoal::Touch(entity touchingEntity)
|
|||
} else if (e.team == pl.team ) {
|
||||
Vox_Sentence_Single(e, m_voxActTeam);
|
||||
} else if (e.team != pl.team) {
|
||||
if (e.team == m_iTeamOwner && m_voxOwnerTeam) {
|
||||
if (e.team == m_iTeamOwner && m_voxOwnerTeam)
|
||||
Vox_Sentence_Single(e, m_voxOwnerTeam);
|
||||
} else {
|
||||
if (STRING_SET(m_voxNonOwnerTeams)) {
|
||||
else {
|
||||
if (m_voxNonOwnerTeams)
|
||||
Vox_Sentence_Single(e, m_voxNonOwnerTeams);
|
||||
} else {
|
||||
else
|
||||
Vox_Sentence_Single(e, m_voxNonActTeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -338,172 +284,193 @@ info_tfgoal::Respawn(void)
|
|||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
SetModel(m_strSpawnModel);
|
||||
SetModel(GetSpawnModel());
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetOrigin(GetSpawnVector("origin"));
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
team = m_iTeamUses;
|
||||
|
||||
if (frags > 0) {
|
||||
if (frags > 0)
|
||||
botinfo = BOTINFO_TEAM_GOALCAPTURE;
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "netname":
|
||||
netname = strValue;
|
||||
break;
|
||||
case "noise":
|
||||
m_strActivatedSound = strValue;
|
||||
break;
|
||||
case "mdl":
|
||||
model = strValue;
|
||||
|
||||
if (serverkeyfloat("*bspversion") == 0) {
|
||||
model = strreplace("progs", "models", model);
|
||||
model = strreplace("tf_stan", "flag", model);
|
||||
}
|
||||
|
||||
break;
|
||||
case "goal_state":
|
||||
m_tfgState = stof(strValue);
|
||||
break;
|
||||
case "g_a":
|
||||
m_tfgActivation = stof(strValue);
|
||||
break;
|
||||
case "g_e":
|
||||
m_tfgEffects = stof(strValue);
|
||||
break;
|
||||
case "goal_result":
|
||||
m_tfgResult = stof(strValue);
|
||||
break;
|
||||
case "items_allowed":
|
||||
m_dMustCarry = stof(strValue);
|
||||
break;
|
||||
case "team_no":
|
||||
m_iTeamUses = stoi(strValue);
|
||||
break;
|
||||
case "owned_by":
|
||||
m_iTeamOwner = stoi(strValue);
|
||||
break;
|
||||
case "count":
|
||||
m_dScore = stof(strValue);
|
||||
break;
|
||||
case "wait":
|
||||
m_dRespawn = stof(strValue);
|
||||
break;
|
||||
case "increase_team1":
|
||||
m_dTeamBlueGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team2":
|
||||
m_dTeamRedGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team3":
|
||||
m_dTeamYellowGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team4":
|
||||
m_dTeamGreenGain = stof(strValue);
|
||||
break;
|
||||
/* messages that get sent */
|
||||
case "b_b":
|
||||
m_msgAll = strValue; /* global */
|
||||
break;
|
||||
case "message":
|
||||
m_msgActivator = strValue; /* AP */
|
||||
break;
|
||||
case "b_t":
|
||||
case "team_broadcast":
|
||||
m_msgActTeam = strValue; /* AP team */
|
||||
break;
|
||||
case "b_n":
|
||||
case "netname_non_team_broadcast":
|
||||
m_msgNonActTeam = strValue; /* non-AP team */
|
||||
break;
|
||||
case "b_o":
|
||||
case "owners_team_broadcast":
|
||||
m_msgOwnerTeam = strValue; /* owner team */
|
||||
break;
|
||||
case "non_owners_team_broadcast":
|
||||
m_msgNonOwnerTeams = strValue; /* non-owner team */
|
||||
break;
|
||||
/* sentences that get played */
|
||||
case "speak":
|
||||
m_voxAll = strValue; /* global */
|
||||
break;
|
||||
case "AP_speak":
|
||||
m_voxActivator = strValue; /* AP */
|
||||
break;
|
||||
case "team_speak":
|
||||
m_voxActTeam = strValue; /* AP team */
|
||||
break;
|
||||
case "non_team_speak":
|
||||
m_voxNonActTeam = strValue; /* non-AP team */
|
||||
break;
|
||||
case "owners_team_speak":
|
||||
m_voxOwnerTeam = strValue; /* owner team */
|
||||
break;
|
||||
case "non_owners_team_speak":
|
||||
m_voxNonOwnerTeams = strValue; /* non-owner team */
|
||||
break;
|
||||
/* AP manipulators */
|
||||
case "health":
|
||||
m_iHealth = stoi(strValue);
|
||||
break;
|
||||
case "armor":
|
||||
m_iArmor = stoi(strValue);
|
||||
break;
|
||||
case "ammo_shells":
|
||||
m_iShells = stoi(strValue);
|
||||
break;
|
||||
case "ammo_nails":
|
||||
m_iNails = stoi(strValue);
|
||||
break;
|
||||
case "ammo_rockets":
|
||||
m_iRockets = stoi(strValue);
|
||||
break;
|
||||
case "ammo_cells":
|
||||
m_iCells = stoi(strValue);
|
||||
break;
|
||||
case "ammo_medikit":
|
||||
m_iMedikit = stoi(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::SpawnKey(string keyName, string setValue)
|
||||
info_tfgoal::info_tfgoal(void)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "netname":
|
||||
netname = ReadString(setValue);
|
||||
break;
|
||||
case "noise":
|
||||
m_strActivatedSound = ReadString(setValue);
|
||||
break;
|
||||
case "model":
|
||||
case "mdl":
|
||||
m_strSpawnModel = ReadString(setValue);
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_REMOVE;
|
||||
|
||||
if (serverinfo.GetInteger("*bspversion") == 0i) {
|
||||
m_strSpawnModel = strreplace("progs", "models", model);
|
||||
m_strSpawnModel = strreplace("tf_stan", "flag", model);
|
||||
}
|
||||
break;
|
||||
case "goal_state":
|
||||
m_tfgState = ReadFloat(setValue);
|
||||
break;
|
||||
case "g_a":
|
||||
m_tfgActivation = ReadFloat(setValue);
|
||||
break;
|
||||
case "g_e":
|
||||
m_tfgEffects = ReadFloat(setValue);
|
||||
break;
|
||||
case "goal_result":
|
||||
m_tfgResult = ReadFloat(setValue);
|
||||
break;
|
||||
case "items_allowed":
|
||||
m_dMustCarry = ReadFloat(setValue);
|
||||
break;
|
||||
case "team_no":
|
||||
m_iTeamUses = ReadInt(setValue);
|
||||
break;
|
||||
case "owned_by":
|
||||
m_iTeamOwner = ReadInt(setValue);
|
||||
break;
|
||||
case "count":
|
||||
m_dScore = ReadFloat(setValue);
|
||||
break;
|
||||
case "wait":
|
||||
m_dRespawn = ReadFloat(setValue);
|
||||
break;
|
||||
case "increase_team1":
|
||||
m_dTeamBlueGain = ReadFloat(setValue);
|
||||
break;
|
||||
case "increase_team2":
|
||||
m_dTeamRedGain = ReadFloat(setValue);
|
||||
break;
|
||||
case "increase_team3":
|
||||
m_dTeamYellowGain = ReadFloat(setValue);
|
||||
break;
|
||||
case "increase_team4":
|
||||
m_dTeamGreenGain = ReadFloat(setValue);
|
||||
break;
|
||||
/* messages that get sent */
|
||||
case "b_b":
|
||||
m_msgAll = ReadString(setValue); /* global */
|
||||
break;
|
||||
case "message":
|
||||
m_msgActivator = ReadString(setValue); /* AP */
|
||||
break;
|
||||
case "b_t":
|
||||
case "team_broadcast":
|
||||
m_msgActTeam = ReadString(setValue); /* AP team */
|
||||
break;
|
||||
case "b_n":
|
||||
case "netname_non_team_broadcast":
|
||||
m_msgNonActTeam = ReadString(setValue); /* non-AP team */
|
||||
break;
|
||||
case "b_o":
|
||||
case "owners_team_broadcast":
|
||||
m_msgOwnerTeam = ReadString(setValue); /* owner team */
|
||||
break;
|
||||
case "non_owners_team_broadcast":
|
||||
m_msgNonOwnerTeams = ReadString(setValue); /* non-owner team */
|
||||
break;
|
||||
/* sentences that get played */
|
||||
case "speak":
|
||||
m_voxAll = ReadString(setValue); /* global */
|
||||
break;
|
||||
case "AP_speak":
|
||||
m_voxActivator = ReadString(setValue); /* AP */
|
||||
break;
|
||||
case "team_speak":
|
||||
m_voxActTeam = ReadString(setValue); /* AP team */
|
||||
break;
|
||||
case "non_team_speak":
|
||||
m_voxNonActTeam = ReadString(setValue); /* non-AP team */
|
||||
break;
|
||||
case "owners_team_speak":
|
||||
m_voxOwnerTeam = ReadString(setValue); /* owner team */
|
||||
break;
|
||||
case "non_owners_team_speak":
|
||||
m_voxNonOwnerTeams = ReadString(setValue); /* non-owner team */
|
||||
break;
|
||||
/* AP manipulators */
|
||||
case "health":
|
||||
m_iHealth = ReadInt(setValue);
|
||||
break;
|
||||
case "armor":
|
||||
m_iArmor = ReadInt(setValue);
|
||||
break;
|
||||
case "ammo_shells":
|
||||
m_iShells = ReadInt(setValue);
|
||||
break;
|
||||
case "ammo_nails":
|
||||
m_iNails = ReadInt(setValue);
|
||||
break;
|
||||
case "ammo_rockets":
|
||||
m_iRockets = ReadInt(setValue);
|
||||
break;
|
||||
case "ammo_cells":
|
||||
m_iCells = ReadInt(setValue);
|
||||
break;
|
||||
case "ammo_medikit":
|
||||
m_iMedikit = ReadInt(setValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(keyName, setValue);
|
||||
break;
|
||||
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
|
||||
SpawnKey(argv(i), argv(i+1));
|
||||
}
|
||||
|
||||
precache_sound(m_strActivatedSound);
|
||||
|
||||
super::NSRenderableEntity();
|
||||
info_tfgoal::Respawn();
|
||||
}
|
||||
|
||||
/* the brush based version of tfgoal */
|
||||
class i_t_g:info_tfgoal
|
||||
{
|
||||
public:
|
||||
void(void) i_t_g;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
i_t_g::i_t_g(void)
|
||||
{
|
||||
classname = "info_tfgoal";
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
i_t_g::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_BSPTRIGGER);
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
SetModel(m_strSpawnModel);
|
||||
SetOrigin(GetSpawnVector("origin"));
|
||||
SetModel(GetSpawnModel());
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
Hide();
|
||||
|
||||
team = m_iTeamUses;
|
||||
|
||||
if (frags > 0) {
|
||||
if (frags > 0)
|
||||
botinfo = BOTINFO_TEAM_GOALCAPTURE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
i_t_g::i_t_g(void)
|
||||
{
|
||||
classname = "info_tfgoal";
|
||||
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_NONE;
|
||||
|
||||
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
|
||||
SpawnKey(argv(i), argv(i+1));
|
||||
}
|
||||
|
||||
super::NSRenderableEntity();
|
||||
|
||||
precache_sound(m_strActivatedSound);
|
||||
Respawn();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
class
|
||||
TFCArmor:ncRenderableEntity
|
||||
TFCArmor:NSRenderableEntity
|
||||
{
|
||||
float m_flRespawnDelay;
|
||||
int m_iTeamUses;
|
||||
|
@ -65,10 +65,10 @@ TFCArmor::Spawned(void)
|
|||
void
|
||||
TFCArmor::Respawn(void)
|
||||
{
|
||||
SetModel(GetSpawnString("model"));
|
||||
SetModel(GetSpawnModel());
|
||||
SetSize([-16,-16,0], [16,16,56]);
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnVector("origin"));
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
DropToFloor();
|
||||
botinfo = BOTINFO_ARMOR;
|
||||
}
|
||||
|
@ -79,9 +79,7 @@ TFCArmor::Touch(entity eToucher)
|
|||
if (eToucher.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
TFPlayer pl = (TFPlayer)eToucher;
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
player pl = (player)eToucher;
|
||||
|
||||
/* check for team eligibility */
|
||||
if (m_iTeamUses)
|
||||
|
@ -89,14 +87,14 @@ TFCArmor::Touch(entity eToucher)
|
|||
return;
|
||||
|
||||
/* if we can't add anything, don't bother */
|
||||
if (pl.armor >= pl.GetMaxArmor() && pl.GetReserveAmmo(cellType) >= pl.MaxAmmo(cellType))
|
||||
if (pl.armor >= pl.m_iMaxArmor && pl.m_iAmmoCells >= pl.m_iMaxCells)
|
||||
return;
|
||||
|
||||
int ap;
|
||||
int tp = 0;
|
||||
|
||||
/* get remaining points */
|
||||
ap = pl.GetMaxArmor() - pl.armor;
|
||||
ap = pl.m_iMaxArmor - pl.armor;
|
||||
tp = m_iArmorValue;
|
||||
|
||||
/* if that's all we can give... */
|
||||
|
@ -108,7 +106,7 @@ TFCArmor::Touch(entity eToucher)
|
|||
|
||||
/* give the remaining as metal... engineers only!*/
|
||||
if (pl.classtype == CLASS_ENGINEER) {
|
||||
pl.GiveAmmo(cellType, (tp - ap));
|
||||
pl. m_iAmmoCells = bound(0, pl.m_iAmmoCells + (tp - ap), pl.m_iMaxCells);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ Health pickup. Unlike Team Fortress, this is the only one and it provides
|
|||
*/
|
||||
|
||||
class
|
||||
item_healthkit:ncRenderableEntity
|
||||
item_healthkit:NSRenderableEntity
|
||||
{
|
||||
int m_iTeamUses;
|
||||
float m_flRespawnDelay;
|
||||
|
@ -47,7 +47,7 @@ item_healthkit::Touch(entity eToucher)
|
|||
if (eToucher.classname != "player") {
|
||||
return;
|
||||
}
|
||||
TFPlayer pl = (TFPlayer)eToucher;
|
||||
player pl = (player)eToucher;
|
||||
|
||||
/* check for team eligibility */
|
||||
if (m_iTeamUses)
|
||||
|
@ -55,10 +55,10 @@ item_healthkit::Touch(entity eToucher)
|
|||
return;
|
||||
|
||||
/* leave when full */
|
||||
if (pl.health >= pl.GetMaxHealth())
|
||||
if (pl.health >= pl.m_iMaxHealth)
|
||||
return;
|
||||
|
||||
pl.SetHealth(bound(0, pl.GetHealth() + 25, pl.GetMaxHealth()));
|
||||
pl.health = bound(0, pl.health + 25, pl.m_iMaxHealth);
|
||||
|
||||
Sound_Play(this, CHAN_ITEM, "item_healthkit_tfc.pickup");
|
||||
|
||||
|
@ -88,7 +88,7 @@ item_healthkit::Respawn(void)
|
|||
SetModel("models/w_medkit.mdl");
|
||||
SetSize([-16,-16,0], [16,16,56]);
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnVector("origin"));
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
DropToFloor();
|
||||
botinfo = BOTINFO_HEALTH;
|
||||
}
|
||||
|
@ -98,4 +98,4 @@ item_healthkit::item_healthkit(void)
|
|||
{
|
||||
Sound_Precache("item_healthkit_tfc.pickup");
|
||||
m_flRespawnDelay = 30.0f;
|
||||
}
|
||||
}
|
|
@ -54,29 +54,19 @@ Duplicate keys:
|
|||
|
||||
typedef enum
|
||||
{
|
||||
GISTATUS_HOME, /*<< The item is at its home base. */
|
||||
GISTATUS_DROPPED /*<< The item is at neither on a player, nor at its base. */
|
||||
GISTATUS_HOME,
|
||||
GISTATUS_DROPPED
|
||||
} goalitem_status_e;
|
||||
|
||||
class item_tfgoal:ncRenderableEntity
|
||||
class item_tfgoal:NSRenderableEntity
|
||||
{
|
||||
public:
|
||||
void(void) item_tfgoal;
|
||||
virtual void(entity) Touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
virtual void(ncPlayer) DropReturnable;
|
||||
virtual void(void) TeamOwnerReturns;
|
||||
virtual void(void) Spawned;
|
||||
|
||||
private:
|
||||
float m_dItemID;
|
||||
|
||||
int m_iTeamUses;
|
||||
int m_iTeamOwner;
|
||||
|
||||
string m_strSound;
|
||||
TFPlayer m_eActivator;
|
||||
player m_eActivator;
|
||||
|
||||
goalitem_status_e m_status;
|
||||
|
||||
|
@ -99,28 +89,20 @@ private:
|
|||
string m_returnOwner;
|
||||
|
||||
float m_flPausetime;
|
||||
string m_strSpawnModel; /* because we mangle it */
|
||||
|
||||
void(void) item_tfgoal;
|
||||
virtual void(entity) Touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
virtual void(NSClientPlayer) DropReturnable;
|
||||
virtual void(void) TeamOwnerReturns;
|
||||
virtual void(void) Spawned;
|
||||
};
|
||||
|
||||
void
|
||||
item_tfgoal::item_tfgoal(void)
|
||||
item_tfgoal::DropReturnable(NSClientPlayer pp)
|
||||
{
|
||||
m_status = GISTATUS_HOME;
|
||||
m_returnOwner = m_returnTeam = __NULL__;
|
||||
m_flPausetime = 0;
|
||||
}
|
||||
|
||||
void
|
||||
item_tfgoal::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
precache_sound(m_strSound);
|
||||
}
|
||||
|
||||
void
|
||||
item_tfgoal::DropReturnable(ncPlayer pp)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)pp;
|
||||
player pl = (player)pp;
|
||||
|
||||
/* make it available again, put it exactly where we died */
|
||||
Respawn();
|
||||
|
@ -141,22 +123,21 @@ item_tfgoal::TeamOwnerReturns(void)
|
|||
Respawn();
|
||||
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
if (e.team == m_iTeamUses) {
|
||||
if (e.team == m_iTeamUses)
|
||||
env_message_single(e, m_returnTeam);
|
||||
} else if (e.team == m_iTeamOwner) {
|
||||
else if (e.team == m_iTeamOwner)
|
||||
env_message_single(e, m_returnOwner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_tfgoal::Touch(entity touchingEntity)
|
||||
item_tfgoal::Touch(entity eToucher)
|
||||
{
|
||||
if (isPlayer(touchingEntity) == false) {
|
||||
if (eToucher.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
TFPlayer pl = (TFPlayer)touchingEntity;
|
||||
player pl = (player)eToucher;
|
||||
|
||||
/* not in standard TFC, make cvar? */
|
||||
#if 0
|
||||
|
@ -177,7 +158,7 @@ item_tfgoal::Touch(entity touchingEntity)
|
|||
|
||||
Disappear();
|
||||
pl.g_items |= ITEM_GOALITEM;
|
||||
pl.AddVFlags(VFL_GOALITEM);
|
||||
pl.flags |= FL_GOALITEM;
|
||||
forceinfokey(pl, "*goalitem_t", itos(m_iTeamOwner));
|
||||
|
||||
m_eActivator = pl;
|
||||
|
@ -186,7 +167,7 @@ item_tfgoal::Touch(entity touchingEntity)
|
|||
sound(this, CHAN_ITEM, m_strSound, 1.0f, ATTN_NONE);
|
||||
|
||||
/* message broadcaster */
|
||||
if (STRING_SET(m_msgAll)) {
|
||||
if (m_msgAll) {
|
||||
env_message_broadcast(m_msgAll);
|
||||
} else {
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
|
@ -208,7 +189,7 @@ item_tfgoal::Touch(entity touchingEntity)
|
|||
}
|
||||
|
||||
/* vox speaker */
|
||||
if (STRING_SET(m_voxAll)) {
|
||||
if (m_voxAll) {
|
||||
Vox_Sentence_Broadcast(m_voxAll);
|
||||
} else {
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
|
@ -217,14 +198,13 @@ item_tfgoal::Touch(entity touchingEntity)
|
|||
} else if (e.team == pl.team ) {
|
||||
Vox_Sentence_Single(e, m_voxActTeam);
|
||||
} else if (e.team != pl.team) {
|
||||
if (e.team == m_iTeamOwner && STRING_SET(m_voxOwnerTeam)) {
|
||||
if (e.team == m_iTeamOwner && m_voxOwnerTeam)
|
||||
Vox_Sentence_Single(e, m_voxOwnerTeam);
|
||||
} else {
|
||||
if (STRING_SET(m_voxNonOwnerTeams)) {
|
||||
else {
|
||||
if (m_voxNonOwnerTeams)
|
||||
Vox_Sentence_Single(e, m_voxNonOwnerTeams);
|
||||
} else {
|
||||
else
|
||||
Vox_Sentence_Single(e, m_voxNonActTeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,14 +214,13 @@ item_tfgoal::Touch(entity touchingEntity)
|
|||
void
|
||||
item_tfgoal::Respawn(void)
|
||||
{
|
||||
SetModel(m_strSpawnModel);
|
||||
SetModel(GetSpawnModel());
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnVector("origin"));
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
m_eActivator = __NULL__;
|
||||
ReleaseThink();
|
||||
m_status = GISTATUS_HOME;
|
||||
SetRenderMode(RM_NORMAL);
|
||||
|
||||
/* helps with bots */
|
||||
team = m_iTeamOwner;
|
||||
|
@ -254,25 +233,24 @@ item_tfgoal::Respawn(void)
|
|||
}
|
||||
|
||||
if (m_iTeamOwner) {
|
||||
SetRenderAmt(1);
|
||||
SetRenderAmt(1.0f);
|
||||
SetRenderFX(RFX_GLOWSHELL);
|
||||
} else {
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
/* spawn into the world */
|
||||
switch (m_iTeamOwner) {
|
||||
case 1:
|
||||
SetRenderColor([0,0,255]);
|
||||
SetRenderColor([0,0,1]);
|
||||
break;
|
||||
case 2:
|
||||
SetRenderColor([255,0,0]);
|
||||
SetRenderColor([1,0,0]);
|
||||
break;
|
||||
case 3:
|
||||
SetRenderColor([255, 255,0]);
|
||||
SetRenderColor([1,1,0]);
|
||||
break;
|
||||
case 4:
|
||||
SetRenderColor([0,255,0]);
|
||||
SetRenderColor([0,1,0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -284,15 +262,13 @@ item_tfgoal::SpawnKey(string strKey, string strValue)
|
|||
case "noise":
|
||||
m_strSound = strValue;
|
||||
break;
|
||||
case "model":
|
||||
case "mdl":
|
||||
m_strSpawnModel = strValue;
|
||||
model = strValue;
|
||||
|
||||
if (serverkeyfloat("*bspversion") == 0) {
|
||||
m_strSpawnModel = strreplace("progs", "models", model);
|
||||
m_strSpawnModel = strreplace("tf_stan", "flag", model);
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_Q1) {
|
||||
model = strreplace("progs", "models", model);
|
||||
model = strreplace("tf_stan", "flag", model);
|
||||
}
|
||||
|
||||
break;
|
||||
case "goal_no":
|
||||
m_dItemID = stof(strValue);
|
||||
|
@ -358,3 +334,18 @@ item_tfgoal::SpawnKey(string strKey, string strValue)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_tfgoal::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
precache_sound(m_strSound);
|
||||
}
|
||||
|
||||
void
|
||||
item_tfgoal::item_tfgoal(void)
|
||||
{
|
||||
m_status = GISTATUS_HOME;
|
||||
m_returnOwner = m_returnTeam = __NULL__;
|
||||
m_flPausetime = 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
void
|
||||
TFCNade_ThrowCaltrop(TFPlayer pl)
|
||||
TFCNade_ThrowCaltrop(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
|
||||
static void TFCNade_ThrowHandGrenade_Touch(void) {
|
||||
|
@ -15,14 +14,14 @@ TFCNade_ThrowCaltrop(TFPlayer pl)
|
|||
pointparticles(particleeffectnum("fx_explosion.main"), self.origin, [0,0,0], 1);
|
||||
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
makevectors([0, random() * 360, 0]);
|
||||
vecNadeVelocity = v_forward * 50 + v_up * 150 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/caltrop.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -35,13 +34,11 @@ TFCNade_ThrowCaltrop(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowHandGrenade_Touch;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowHandGrenade(TFPlayer pl)
|
||||
TFCNade_ThrowHandGrenade(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -57,14 +54,14 @@ TFCNade_ThrowHandGrenade(TFPlayer pl)
|
|||
pointparticles(particleeffectnum("fx_explosion.main"), self.origin, [0,0,0], 1);
|
||||
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl. gren1.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/w_grenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -77,13 +74,11 @@ TFCNade_ThrowHandGrenade(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowHandGrenade_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowHandGrenade_Explode, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowConcussion(TFPlayer pl)
|
||||
TFCNade_ThrowConcussion(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -95,7 +90,7 @@ TFCNade_ThrowConcussion(TFPlayer pl)
|
|||
}
|
||||
|
||||
static void TFCNade_ThrowConcussion_Explode(void) {
|
||||
for (TFPlayer f = world; (f = (TFPlayer)find(f, ::classname, "player"));) {
|
||||
for (player f = world; (f = (player)find(f, ::classname, "player"));) {
|
||||
float dist = vlen(f.origin - self.origin);
|
||||
|
||||
if (dist < 256) {
|
||||
|
@ -130,14 +125,14 @@ TFCNade_ThrowConcussion(TFPlayer pl)
|
|||
msg_entity = self;
|
||||
multicast(self.origin, MULTICAST_PVS);
|
||||
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/conc_grenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -149,13 +144,11 @@ TFCNade_ThrowConcussion(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowConcussion_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowConcussion_Explode, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowNail(TFPlayer pl)
|
||||
TFCNade_ThrowNail(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -170,7 +163,7 @@ TFCNade_ThrowNail(TFPlayer pl)
|
|||
pointparticles(particleeffectnum("fx_explosion.main"), self.origin, [0,0,0], 1);
|
||||
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
static void TFCNade_ThrowNail_Shoot(entity source, vector euler_dir) {
|
||||
|
||||
|
@ -229,7 +222,7 @@ TFCNade_ThrowNail(TFPlayer pl)
|
|||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/ngrenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -242,13 +235,11 @@ TFCNade_ThrowNail(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowNail_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowNail_Deploy, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowMIRVBomblet(ncEntity bomb)
|
||||
TFCNade_ThrowMIRVBomblet(NSEntity bomb)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
|
||||
static void TFCNade_ThrowMIRVBomblet_Touch(void) {
|
||||
|
@ -262,15 +253,15 @@ TFCNade_ThrowMIRVBomblet(ncEntity bomb)
|
|||
pointparticles(particleeffectnum("fx_explosion.main"), self.origin, [0,0,0], 1);
|
||||
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
TFPlayer pl = (TFPlayer)bomb.owner;
|
||||
player pl = (player)bomb.owner;
|
||||
|
||||
makevectors([0, random() * 360, 0]);
|
||||
vecNadeVelocity = v_forward * 100 + v_up * 350 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/bomblet.mdl");
|
||||
eNade.SetOrigin(bomb.origin + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -284,13 +275,11 @@ TFCNade_ThrowMIRVBomblet(ncEntity bomb)
|
|||
|
||||
eNade.touch = TFCNade_ThrowMIRVBomblet_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowMIRVBomblet_Explode, 1.5f + random());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowMIRV(TFPlayer pl)
|
||||
TFCNade_ThrowMIRV(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -308,10 +297,10 @@ TFCNade_ThrowMIRV(TFPlayer pl)
|
|||
sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
TFCNade_ThrowMIRVBomblet((ncEntity)self);
|
||||
TFCNade_ThrowMIRVBomblet((NSEntity)self);
|
||||
}
|
||||
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
|
@ -319,7 +308,7 @@ TFCNade_ThrowMIRV(TFPlayer pl)
|
|||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl. gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/mirv_grenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -330,13 +319,11 @@ TFCNade_ThrowMIRV(TFPlayer pl)
|
|||
eNade.SetSkin(1);
|
||||
eNade.ScheduleThink(TFCNade_ThrowMIRV_Explode, flTimer);
|
||||
eNade.touch = TFCNade_ThrowMIRV_Touch;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowNapalm(TFPlayer pl)
|
||||
TFCNade_ThrowNapalm(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -348,14 +335,14 @@ TFCNade_ThrowNapalm(TFPlayer pl)
|
|||
}
|
||||
|
||||
static void TFCNade_ThrowConcussion_Explode(void) {
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/napalm.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -367,13 +354,11 @@ TFCNade_ThrowNapalm(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowConcussion_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowConcussion_Explode, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowHallucination(TFPlayer pl)
|
||||
TFCNade_ThrowHallucination(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -385,21 +370,21 @@ TFCNade_ThrowHallucination(TFPlayer pl)
|
|||
}
|
||||
|
||||
static void TFCNade_ThrowConcussion_Explode(void) {
|
||||
for (TFPlayer f = world; (f = (TFPlayer)find(f, ::classname, "player"));) {
|
||||
for (player f = world; (f = (player)find(f, ::classname, "player"));) {
|
||||
float dist = vlen(f.origin - self.origin);
|
||||
|
||||
if (dist < 192) {
|
||||
f.m_flHallucination = 15.0f;
|
||||
}
|
||||
}
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/spy_grenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -411,13 +396,11 @@ TFCNade_ThrowHallucination(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowConcussion_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowConcussion_Explode, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowEMP(TFPlayer pl)
|
||||
TFCNade_ThrowEMP(player pl)
|
||||
{
|
||||
#if 0
|
||||
vector vecNadeVelocity;
|
||||
float flTimer;
|
||||
|
||||
|
@ -429,14 +412,14 @@ TFCNade_ThrowEMP(TFPlayer pl)
|
|||
}
|
||||
|
||||
static void TFCNade_ThrowEMP_Explode(void) {
|
||||
ncEntity::Destroy();
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
Weapons_MakeVectors(pl);
|
||||
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
|
||||
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
|
||||
|
||||
ncRenderableEntity eNade = spawn(ncRenderableEntity);
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/emp_grenade.mdl");
|
||||
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
|
||||
eNade.SetOwner(pl);
|
||||
|
@ -448,11 +431,10 @@ TFCNade_ThrowEMP(TFPlayer pl)
|
|||
|
||||
eNade.touch = TFCNade_ThrowEMP_Touch;
|
||||
eNade.ScheduleThink(TFCNade_ThrowEMP_Explode, flTimer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
TFCNade_ThrowSecondary(TFPlayer pl)
|
||||
TFCNade_ThrowSecondary(player pl)
|
||||
{
|
||||
switch (pl.classtype) {
|
||||
case CLASS_SCOUT:
|
||||
|
@ -482,10 +464,10 @@ TFCNade_ThrowSecondary(TFPlayer pl)
|
|||
}
|
||||
|
||||
void
|
||||
TFCNade_SelfExplode(TFPlayer pl)
|
||||
TFCNade_SelfExplode(player pl)
|
||||
{
|
||||
float dmg = 100;
|
||||
pointparticles(particleeffectnum("fx_explosion.main"), pl.origin, [0,0,0], 1);
|
||||
//Damage_Radius(pl.origin, pl, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
Damage_Radius(pl.origin, pl, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER);
|
||||
sound(pl, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
#pragma target fte_5768
|
||||
//#pragma flag enable assumeint
|
||||
#pragma progs_dat "../../progs.dat"
|
||||
#pragma forcecrc 54730
|
||||
|
||||
#define QWSSQC
|
||||
#define SERVER
|
||||
|
@ -13,14 +12,46 @@
|
|||
../../../src/shared/defs.h
|
||||
../../../src/server/defs.h
|
||||
../../../src/botlib/botinfo.h
|
||||
|
||||
../../../src/gs-entbase/server.src
|
||||
../../../src/gs-entbase/shared.src
|
||||
|
||||
defs.h
|
||||
|
||||
../shared/include.src
|
||||
entities.src
|
||||
|
||||
../../../valve/src/server/player.qc
|
||||
|
||||
dispenser.qc
|
||||
sentry.qc
|
||||
teleporter.qc
|
||||
|
||||
func_nobuild.qc
|
||||
func_nogrenades.qc
|
||||
|
||||
vox.qc
|
||||
../../../valve/src/server/items.qc
|
||||
../../../src/botlib/include.src
|
||||
bot.qc
|
||||
|
||||
info_player_teamspawn.qc
|
||||
item_tfgoal.qc
|
||||
info_tfgoal.qc
|
||||
info_areadef.qc
|
||||
info_tfdetect.qc
|
||||
item_armor.qc
|
||||
item_healthkit.qc
|
||||
nades.qc
|
||||
|
||||
gamerules.qc
|
||||
client.qc
|
||||
server.qc
|
||||
../../../valve/src/server/damage.qc
|
||||
../../../valve/src/server/flashlight.qc
|
||||
../../../valve/src/server/modelevent.qc
|
||||
|
||||
spawn.qc
|
||||
|
||||
../../../src/server/include.src
|
||||
../../../src/shared/include.src
|
||||
#endlist
|
||||
|
|
|
@ -25,9 +25,9 @@ typedef enum
|
|||
} sentrystate_e;
|
||||
|
||||
class
|
||||
TFCSentry:ncSurfacePropEntity
|
||||
TFCSentry:NSSurfacePropEntity
|
||||
{
|
||||
ncSurfacePropEntity m_eHead;
|
||||
NSSurfacePropEntity m_eHead;
|
||||
sentrystate_e m_state;
|
||||
float m_flNextIdleSound;
|
||||
|
||||
|
@ -37,7 +37,7 @@ TFCSentry:ncSurfacePropEntity
|
|||
|
||||
void(void) TFCSentry;
|
||||
|
||||
virtual void(ncPlayer) Place;
|
||||
virtual void(NSClientPlayer) Place;
|
||||
virtual void(void) FinishPlacing;
|
||||
virtual void(void) Think;
|
||||
};
|
|
@ -64,19 +64,19 @@ TFCSentry::Think(void)
|
|||
else {
|
||||
makevectors([0, angles[1], 0]);
|
||||
m_flWantAngle = dotproduct((origin - t.origin), v_right);
|
||||
m_flCurrAngle = lerpAngle(m_flCurrAngle, m_flWantAngle, 0.25f);
|
||||
m_flCurrAngle = Math_Lerp(m_flCurrAngle, m_flWantAngle, 0.25f);
|
||||
m_eHead.SetBoneControl1(m_flCurrAngle);
|
||||
print(sprintf("head: %f; want: %f\n", m_flCurrAngle, m_flWantAngle));
|
||||
|
||||
/* fire bullets */
|
||||
input_angles = v_angle = vectoangles(origin - t.origin);
|
||||
//TraceAttack_FireBullets(1, origin, 5, [0.025,0.025], WEAPON_NONE);
|
||||
TraceAttack_FireBullets(1, origin, 5, [0.025,0.025], WEAPON_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFCSentry::Place(ncPlayer pl)
|
||||
TFCSentry::Place(NSClientPlayer pl)
|
||||
{
|
||||
vector newAngles = pl.GetAngles();
|
||||
newAngles[0] = newAngles[2] = 0;
|
||||
|
@ -118,31 +118,30 @@ TFCSentry::FinishPlacing(void)
|
|||
void
|
||||
TFCSentry::TFCSentry(void)
|
||||
{
|
||||
m_eHead = spawn(ncSurfacePropEntity);
|
||||
m_eHead = spawn(NSSurfacePropEntity);
|
||||
SetModel("models/base.mdl");
|
||||
SetSolid(SOLID_BBOX);
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
SetSize([-16,-16,0], [16,16,20]);
|
||||
|
||||
SetTakedamage(DAMAGE_YES);
|
||||
SetHealth(100);
|
||||
MakeVulnerable();
|
||||
m_eHead.SetTakedamage(DAMAGE_YES);
|
||||
m_eHead.SetHealth(100);
|
||||
m_eHead.MakeVulnerable();
|
||||
m_state = SENTRY_IDLE;
|
||||
}
|
||||
|
||||
void
|
||||
TFCSentry_Build(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)self;
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
player pl = (player)self;
|
||||
|
||||
/* only engineers can do this */
|
||||
if (pl.classtype != CLASS_ENGINEER)
|
||||
return;
|
||||
|
||||
/* it costs cells to build these things */
|
||||
if (pl.UseAmmo(cellType, TFC_SENTRY_COST) == false) {
|
||||
/* it costs */
|
||||
if (pl.m_iAmmoCells < TFC_SENTRY_COST) {
|
||||
env_message_single(pl, "#Build_nometal");
|
||||
return;
|
||||
}
|
||||
|
@ -158,6 +157,8 @@ TFCSentry_Build(void)
|
|||
return;
|
||||
}
|
||||
|
||||
pl.m_iAmmoCells -= TFC_SENTRY_COST;
|
||||
|
||||
/* deploy */
|
||||
TFCSentry sentry = spawn(TFCSentry);
|
||||
sentry.Place(pl);
|
||||
|
@ -166,5 +167,5 @@ TFCSentry_Build(void)
|
|||
void
|
||||
TFCSentry_Dismantle(void)
|
||||
{
|
||||
TFC_DetonateTypeForPlayer((TFPlayer)self, "TFCSentry");
|
||||
TFC_DetonateTypeForPlayer((player)self, "TFCSentry");
|
||||
}
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
void
|
||||
Game_InitRules(void)
|
||||
{
|
||||
g_grMode = spawn(TFCGameRules);
|
||||
}
|
||||
|
||||
void
|
||||
Game_Worldspawn(void)
|
||||
{
|
||||
|
@ -36,16 +42,19 @@ Game_Worldspawn(void)
|
|||
precache_model("models/sentry3.mdl");
|
||||
precache_model("models/player.mdl");
|
||||
precache_model("models/w_weaponbox.mdl");
|
||||
Weapons_Init();
|
||||
Player_Precache();
|
||||
FX_Corpse_Init();
|
||||
}
|
||||
|
||||
void weaponbox_spawn(TFPlayer pl)
|
||||
void weaponbox_spawn(player pl)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CSEv_TFCBuild_i(int type)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)self;
|
||||
player pl = (player)self;
|
||||
|
||||
if (pl.gflags & GF_NOBUILDZONE) {
|
||||
env_message_single(pl, "#Build_nobuild");
|
||||
|
|
163
src/server/spawn.qc
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
float
|
||||
TFCTeamJoin_SmallestTeam(int blue, int red, int yellow, int green)
|
||||
{
|
||||
while (blue > 0i || red > 0i || yellow > 0i || green > 0i) {
|
||||
/* the first team that goes to 0, gets picked. */
|
||||
if (blue <= 0i)
|
||||
return 1;
|
||||
else if (red <= 0i)
|
||||
return 2;
|
||||
else if (yellow <= 0i)
|
||||
return 3;
|
||||
else if (green <= 0i)
|
||||
return 4;
|
||||
|
||||
blue--;
|
||||
red--;
|
||||
yellow--;
|
||||
green--;
|
||||
}
|
||||
|
||||
/* the first team that goes to 0, gets picked. */
|
||||
if (blue == 0i)
|
||||
return 1;
|
||||
else if (red == 0i)
|
||||
return 2;
|
||||
else if (yellow == 0i)
|
||||
return 3;
|
||||
else if (green == 0i)
|
||||
return 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CSEv_TeamJoin_f(float f)
|
||||
{
|
||||
player pl = (player)self;
|
||||
|
||||
/* random... */
|
||||
if (f == 0) {
|
||||
int bluePlayers = 0i;
|
||||
int redPlayers = 0i;
|
||||
int yellowPlayers = 0i;
|
||||
int greenPlayers = 0i;
|
||||
|
||||
/* hack to get it to never pick this team */
|
||||
if (g_tfcHasBlueTeam == false)
|
||||
bluePlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasRedTeam == false)
|
||||
redPlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasYellowTeam == false)
|
||||
yellowPlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasGreenTeam == false)
|
||||
greenPlayers = (int)cvar("sv_playerslots");
|
||||
|
||||
/* count all valid players within each team */
|
||||
for (entity e = world; (e = find(e, ::classname, "player"));) {
|
||||
if (e.team == 1)
|
||||
bluePlayers++;
|
||||
else if (e.team == 2)
|
||||
redPlayers++;
|
||||
else if (e.team == 3)
|
||||
yellowPlayers++;
|
||||
else if (e.team == 4)
|
||||
greenPlayers++;
|
||||
}
|
||||
|
||||
/* assign us to the team with the lowest amount of players */
|
||||
f = TFCTeamJoin_SmallestTeam(bluePlayers, redPlayers, yellowPlayers, greenPlayers);
|
||||
}
|
||||
|
||||
/* mess, do it better */
|
||||
if (f == 1) {
|
||||
pl.team = 1; /* Blue */
|
||||
forceinfokey(pl, "topcolor", "0x9aff");
|
||||
forceinfokey(pl, "bottomcolor", "0x9aff");
|
||||
} else if (f == 2) {
|
||||
pl.team = 2; /* Red */
|
||||
f -= 10;
|
||||
forceinfokey(pl, "topcolor", "0xff1800");
|
||||
forceinfokey(pl, "bottomcolor", "0xff1800");
|
||||
} else if (f == 3) {
|
||||
pl.team = 3; /* Yellow */
|
||||
f -= 20;
|
||||
forceinfokey(pl, "topcolor", "0xffca00");
|
||||
forceinfokey(pl, "bottomcolor", "0xffca00");
|
||||
} else if (f == 4) {
|
||||
pl.team = 4; /* Green */
|
||||
f -= 30;
|
||||
forceinfokey(pl, "topcolor", "0x3bff00");
|
||||
forceinfokey(pl, "bottomcolor", "0x3bff00");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.health > 0) {
|
||||
ClientKill();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Called by the client-side VGUI menu when we choose a class. */
|
||||
void
|
||||
CSEv_ClassJoin_f(float f)
|
||||
{
|
||||
|
||||
player pl = (player)self;
|
||||
|
||||
/* choose a random class. */
|
||||
if (f == 0) {
|
||||
float newClass = 0;
|
||||
|
||||
while (newClass == 0 || newClass == pl.classtype)
|
||||
newClass = floor(random(CLASS_SCOUT, CLASS_ENGINEER + 1));
|
||||
|
||||
f = newClass;
|
||||
}
|
||||
|
||||
/* invalid */
|
||||
if (pl.team == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.classname != "player") {
|
||||
spawnfunc_player();
|
||||
}
|
||||
|
||||
/* invalid */
|
||||
if (pl.classtype == f)
|
||||
return;
|
||||
|
||||
/* if we're still alive... */
|
||||
if (pl.health > 0) {
|
||||
pl.classtype = f;
|
||||
pl.MakeClass(f);
|
||||
ClientKill();
|
||||
} else {
|
||||
/* insta spawn */
|
||||
|
||||
/* assign our class type for safe keeping */
|
||||
pl.classtype = f;
|
||||
|
||||
/* turn the player into the class of his choice */
|
||||
pl.MakeClass(f);
|
||||
pl.SpawnIntoGame();
|
||||
}
|
||||
}
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
/* main teleporter */
|
||||
class
|
||||
TFCTeleporter:ncSurfacePropEntity
|
||||
TFCTeleporter:NSSurfacePropEntity
|
||||
{
|
||||
float m_flNextTeleport;
|
||||
|
||||
void(void) TFCTeleporter;
|
||||
|
||||
virtual void(TFPlayer) Place;
|
||||
virtual void(player) Place;
|
||||
virtual void(void) FinishPlacing;
|
||||
virtual void(entity) Touch;
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ TFCTeleporter::Touch(entity eToucher)
|
|||
}
|
||||
|
||||
void
|
||||
TFCTeleporter::Place(TFPlayer pl)
|
||||
TFCTeleporter::Place(player pl)
|
||||
{
|
||||
SetAngles(pl.GetAngles());
|
||||
|
||||
|
@ -128,15 +128,14 @@ TFCTeleporterExit::TFCTeleporterExit(void)
|
|||
void
|
||||
TFCTeleporter_Build(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)self;
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
player pl = (player)self;
|
||||
|
||||
/* only engineers can do this */
|
||||
if (pl.classtype != CLASS_ENGINEER)
|
||||
return;
|
||||
|
||||
/* it costs */
|
||||
if (pl.UseAmmo(cellType, TFC_TELEPORTER_COST) == false) {
|
||||
if (pl.m_iAmmoCells < TFC_TELEPORTER_COST) {
|
||||
env_message_single(pl, "#Build_nometal");
|
||||
return;
|
||||
}
|
||||
|
@ -152,6 +151,8 @@ TFCTeleporter_Build(void)
|
|||
return;
|
||||
}
|
||||
|
||||
pl.m_iAmmoCells -= TFC_TELEPORTER_COST;
|
||||
|
||||
/* deploy */
|
||||
TFCTeleporter start = spawn(TFCTeleporter);
|
||||
start.Place(pl);
|
||||
|
@ -160,15 +161,14 @@ TFCTeleporter_Build(void)
|
|||
void
|
||||
TFCTeleporterExit_Build(void)
|
||||
{
|
||||
TFPlayer pl = (TFPlayer)self;
|
||||
int cellType = ammoNumForName("ammo_cells");
|
||||
player pl = (player)self;
|
||||
|
||||
/* only engineers can do this */
|
||||
if (pl.classtype != CLASS_ENGINEER)
|
||||
return;
|
||||
|
||||
/* it costs */
|
||||
if (pl.UseAmmo(cellType, TFC_TELEPORTER_COST) == false) {
|
||||
if (pl.m_iAmmoCells < TFC_TELEPORTER_COST) {
|
||||
env_message_single(pl, "#Build_nometal");
|
||||
return;
|
||||
}
|
||||
|
@ -184,6 +184,8 @@ TFCTeleporterExit_Build(void)
|
|||
return;
|
||||
}
|
||||
|
||||
pl.m_iAmmoCells -= TFC_TELEPORTER_COST;
|
||||
|
||||
/* deploy */
|
||||
TFCTeleporterExit end = spawn(TFCTeleporterExit);
|
||||
end.Place(pl);
|
||||
|
@ -192,10 +194,10 @@ TFCTeleporterExit_Build(void)
|
|||
void
|
||||
TFCTeleporter_Dismantle(void)
|
||||
{
|
||||
TFC_DetonateTypeForPlayer((TFPlayer)self, "TFCTeleporter");
|
||||
TFC_DetonateTypeForPlayer((player)self, "TFCTeleporter");
|
||||
}
|
||||
void
|
||||
TFCTeleporterExit_Dismantle(void)
|
||||
{
|
||||
TFC_DetonateTypeForPlayer((TFPlayer)self, "TFCTeleporterExit");
|
||||
TFC_DetonateTypeForPlayer((player)self, "TFCTeleporterExit");
|
||||
}
|
||||
|
|
40
src/server/vox.qc
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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
|
||||
Vox_Sentence_Broadcast(string msg)
|
||||
{
|
||||
if (!msg || msg == "")
|
||||
return;
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_TFC_VOXMSG);
|
||||
WriteString(MSG_MULTICAST, msg);
|
||||
multicast([0,0,0], MULTICAST_ALL_R);
|
||||
}
|
||||
|
||||
void
|
||||
Vox_Sentence_Single(entity targ, string msg)
|
||||
{
|
||||
if (!msg || msg == "")
|
||||
return;
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_TFC_VOXMSG);
|
||||
WriteString(MSG_MULTICAST, msg);
|
||||
msg_entity = targ;
|
||||
multicast([0,0,0], MULTICAST_ONE_R);
|
||||
}
|
|
@ -52,3 +52,26 @@ string g_teammodels_hd[] = {
|
|||
"models/player/spy/spy2.mdl",
|
||||
"models/player/engineer/engineer2.mdl"
|
||||
};
|
||||
|
||||
/* are we using a later build of TF? */
|
||||
bool
|
||||
TFC_IsLaterBuild(void)
|
||||
{
|
||||
if (whichpack(g_teammodels_hd[1]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* stuff */
|
||||
string
|
||||
TFC_GetModelForClasstype(classtype_e type)
|
||||
{
|
||||
if (TFC_IsLaterBuild() == true)
|
||||
if (autocvar(tfc_newmodels, 0) == 1)
|
||||
return g_teammodels[type]; /* on later versions, the old names are the HD ones */
|
||||
else
|
||||
return g_teammodels_hd[type];
|
||||
|
||||
return g_teammodels[type];
|
||||
}
|
|
@ -5,13 +5,42 @@ weapons.h
|
|||
|
||||
flags.h
|
||||
events.h
|
||||
../../../valve/src/shared/skeleton.h
|
||||
../../../valve/src/shared/player.qc
|
||||
player.qc
|
||||
../../../valve/src/shared/weapon_common.h
|
||||
../../../valve/src/shared/animations.h
|
||||
animations_tfc.h
|
||||
../../../valve/src/shared/animations.qc
|
||||
pmove.qc
|
||||
vox.qc
|
||||
../../../valve/src/shared/HLWeapon.qc
|
||||
|
||||
../../../valve/src/shared/fx_blood.qc
|
||||
../../../valve/src/shared/fx_corpse.qc
|
||||
|
||||
weapon_basesemi.qc
|
||||
weapon_basemelee.qc
|
||||
weapon_baseshotgun.qc
|
||||
weapon_baseprojectile.qc
|
||||
weapon_baseautomatic.qc
|
||||
|
||||
w_asscan.qc
|
||||
w_autorifle.qc
|
||||
w_crowbar.qc
|
||||
w_dbs.qc
|
||||
w_flamer.qc
|
||||
w_glauncher.qc
|
||||
w_grapple.qc
|
||||
w_incendiary.qc
|
||||
w_knife.qc
|
||||
w_medkit.qc
|
||||
w_nailgun.qc
|
||||
w_pipebomb.qc
|
||||
w_railgun.qc
|
||||
w_rpg.qc
|
||||
w_sbs.qc
|
||||
w_sniper.qc
|
||||
w_supernail.qc
|
||||
w_tranquil.qc
|
||||
w_umbrella.qc
|
||||
w_wrench.qc
|
||||
weapons.qc
|
||||
../../../valve/src/shared/weapon_common.qc
|
||||
#endlist
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2024AAAAAA Marco Cawthorne <marco@icculus.org>
|
||||
* 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
|
||||
|
@ -14,12 +14,23 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
class
|
||||
TFPlayer:HLPlayer
|
||||
#include "../../../valve/src/shared/skeleton.h"
|
||||
|
||||
/* all potential SendFlags bits we can possibly send */
|
||||
enumflags
|
||||
{
|
||||
PLAYER_TOPFRAME = PLAYER_CUSTOMFIELDSTART,
|
||||
PLAYER_BOTTOMFRAME,
|
||||
PLAYER_AMMO1,
|
||||
PLAYER_AMMO2,
|
||||
PLAYER_AMMO3,
|
||||
PLAYER_UNUSED5,
|
||||
PLAYER_UNUSED6,
|
||||
PLAYER_UNUSED7
|
||||
};
|
||||
|
||||
void TFPlayer(void);
|
||||
|
||||
class player:NSClientPlayer
|
||||
{
|
||||
/* class info */
|
||||
PREDICTED_INT(classtype)
|
||||
|
||||
|
@ -30,15 +41,28 @@ TFPlayer:HLPlayer
|
|||
PREDICTED_INT(anim_bottom)
|
||||
PREDICTED_FLOAT(anim_bottom_time)
|
||||
|
||||
/* ammo 1 */
|
||||
PREDICTED_INT(mag_sbs)
|
||||
PREDICTED_INT(mag_dbs)
|
||||
PREDICTED_INT(mag_rpg)
|
||||
PREDICTED_INT(mag_glauncher)
|
||||
|
||||
/* ammo 2 */
|
||||
PREDICTED_INT(m_iAmmoRockets)
|
||||
PREDICTED_INT(m_iAmmoNails)
|
||||
PREDICTED_INT(m_iAmmoCells)
|
||||
PREDICTED_INT(m_iAmmoShells)
|
||||
PREDICTED_INT(m_iAmmoDetpack)
|
||||
PREDICTED_INT(m_iAmmoMedikit)
|
||||
|
||||
/* ammo 3 */
|
||||
PREDICTED_INT(mode_tempstate)
|
||||
|
||||
PREDICTED_FLOAT(m_flIdleScale)
|
||||
PREDICTED_FLOAT(m_flHallucination)
|
||||
|
||||
virtual bool CanSprint(void);
|
||||
virtual bool CanCrouch(void);
|
||||
virtual bool CanProne(void);
|
||||
virtual bool CanLean(void);
|
||||
|
||||
virtual void Physics_Jump(void);
|
||||
virtual float Physics_MaxSpeed(void);
|
||||
|
||||
virtual void ProcessInput(void);
|
||||
|
||||
|
@ -47,22 +71,35 @@ TFPlayer:HLPlayer
|
|||
nonvirtual void TFC_ReleaseGren1(void);
|
||||
nonvirtual void TFC_ReleaseGren2(void);
|
||||
virtual void UpdatePlayerAnimation(float);
|
||||
virtual void Physics_InputPreMove(void);
|
||||
|
||||
#ifdef CLIENT
|
||||
virtual void ReceiveEntity(float,float);
|
||||
virtual void PredictPreFrame(void);
|
||||
virtual void PredictPostFrame(void);
|
||||
virtual void ClientInputFrame(void);
|
||||
virtual void UpdateAliveCam(void);
|
||||
virtual void UpdatePlayerAttachments(bool);
|
||||
|
||||
float m_flNextHallucination;
|
||||
|
||||
#else
|
||||
ncTimer gren1;
|
||||
ncTimer gren2;
|
||||
NSTimer gren1;
|
||||
NSTimer gren2;
|
||||
|
||||
int m_iMaxHealth;
|
||||
int m_iMaxArmor;
|
||||
|
||||
int m_iMaxShells;
|
||||
int m_iMaxNails;
|
||||
int m_iMaxRockets;
|
||||
int m_iMaxCells;
|
||||
int m_iMaxDetpack;
|
||||
int m_iMaxMedikit;
|
||||
|
||||
virtual void EvaluateEntity(void);
|
||||
virtual float SendEntity(entity, float);
|
||||
|
||||
virtual void SpawnIntoGame(void);
|
||||
virtual void MakeClass(classtype_e);
|
||||
virtual void ServerInputFrame(void);
|
||||
|
||||
nonvirtual void TFC_FragSelf(void);
|
||||
|
@ -70,24 +107,11 @@ TFPlayer:HLPlayer
|
|||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
TFPlayer::TFPlayer(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Animation_PlayerUpdate(player);
|
||||
void Animation_TimerUpdate(player, float);
|
||||
|
||||
void
|
||||
TFPlayer::Physics_InputPreMove(void)
|
||||
{
|
||||
super::Physics_InputPreMove();
|
||||
|
||||
gflags &= ~GF_NOBUILDZONE;
|
||||
gflags &= ~GF_NOGRENADEZONE;
|
||||
}
|
||||
|
||||
void
|
||||
TFPlayer::UpdatePlayerAnimation(float timelength)
|
||||
player::UpdatePlayerAnimation(float timelength)
|
||||
{
|
||||
/* calculate our skeletal progression */
|
||||
Animation_PlayerUpdate(this);
|
||||
|
@ -95,46 +119,22 @@ TFPlayer::UpdatePlayerAnimation(float timelength)
|
|||
Animation_TimerUpdate(this, timelength);
|
||||
}
|
||||
|
||||
/* we invalidate the next two so we can use their input_ bits, INPUT_SPRINT & PRONE */
|
||||
bool
|
||||
TFPlayer::CanSprint(void)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
bool
|
||||
TFPlayer::CanProne(void)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool
|
||||
TFPlayer::CanCrouch(void)
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
TFPlayer::CanLean(void)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
|
||||
void TFCNade_ThrowCaltrop(TFPlayer);
|
||||
void TFCNade_ThrowHandGrenade(TFPlayer);
|
||||
void TFCNade_ThrowSecondary(TFPlayer);
|
||||
void TFCNade_SelfExplode(TFPlayer);
|
||||
void TFCNade_ThrowCaltrop(player);
|
||||
void TFCNade_ThrowHandGrenade(player);
|
||||
void TFCNade_ThrowSecondary(player);
|
||||
void TFCNade_SelfExplode(player);
|
||||
|
||||
void
|
||||
TFPlayer::TFC_FragSelf(void)
|
||||
player::TFC_FragSelf(void)
|
||||
{
|
||||
print("Primary exploded in your hand!\n");
|
||||
TFCNade_SelfExplode(this);
|
||||
}
|
||||
|
||||
void
|
||||
TFPlayer::TFC_ThrowSecondary(void)
|
||||
player::TFC_ThrowSecondary(void)
|
||||
{
|
||||
print("Secondary exploded in your hand!\n");
|
||||
TFCNade_ThrowSecondary(this);
|
||||
|
@ -142,7 +142,7 @@ TFPlayer::TFC_ThrowSecondary(void)
|
|||
#endif
|
||||
|
||||
void
|
||||
TFPlayer::TFC_CookGren1(void)
|
||||
player::TFC_CookGren1(void)
|
||||
{
|
||||
/* we're already cooking it */
|
||||
if (gflags & GF_GREN1COOK)
|
||||
|
@ -166,7 +166,7 @@ TFPlayer::TFC_CookGren1(void)
|
|||
}
|
||||
|
||||
void
|
||||
TFPlayer::TFC_ReleaseGren1(void)
|
||||
player::TFC_ReleaseGren1(void)
|
||||
{
|
||||
if (!(gflags & GF_GREN1COOK))
|
||||
return;
|
||||
|
@ -188,7 +188,7 @@ TFPlayer::TFC_ReleaseGren1(void)
|
|||
}
|
||||
|
||||
void
|
||||
TFPlayer::TFC_CookGren2(void)
|
||||
player::TFC_CookGren2(void)
|
||||
{
|
||||
if (gflags & GF_GREN2COOK)
|
||||
return;
|
||||
|
@ -206,7 +206,7 @@ TFPlayer::TFC_CookGren2(void)
|
|||
}
|
||||
|
||||
void
|
||||
TFPlayer::TFC_ReleaseGren2(void)
|
||||
player::TFC_ReleaseGren2(void)
|
||||
{
|
||||
if (!(gflags & GF_GREN2COOK))
|
||||
return;
|
||||
|
@ -220,24 +220,113 @@ TFPlayer::TFC_ReleaseGren2(void)
|
|||
}
|
||||
|
||||
void
|
||||
TFPlayer::ProcessInput(void)
|
||||
player::ProcessInput(void)
|
||||
{
|
||||
super::ProcessInput();
|
||||
|
||||
if (input_buttons & INPUT_SPRINT)
|
||||
if (input_buttons & INPUT_BUTTON6)
|
||||
TFC_CookGren1();
|
||||
else
|
||||
TFC_ReleaseGren1();
|
||||
|
||||
if (input_buttons & INPUT_PRONE)
|
||||
if (input_buttons & INPUT_BUTTON7)
|
||||
TFC_CookGren2();
|
||||
else
|
||||
TFC_ReleaseGren2();
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
|
||||
.string oldmodel;
|
||||
string Weapons_GetPlayermodel(player, int);
|
||||
|
||||
void
|
||||
TFPlayer::UpdateAliveCam(void)
|
||||
player::UpdatePlayerAttachments(bool visible)
|
||||
{
|
||||
/* draw the flashlight */
|
||||
if (gflags & GF_FLASHLIGHT) {
|
||||
vector src;
|
||||
vector ang;
|
||||
|
||||
if (entnum != player_localentnum) {
|
||||
src = origin + view_ofs;
|
||||
ang = v_angle;
|
||||
} else {
|
||||
src = pSeat->m_vecPredictedOrigin + [0,0,-8];
|
||||
ang = view_angles;
|
||||
}
|
||||
|
||||
makevectors(ang);
|
||||
traceline(src, src + (v_forward * 8096), MOVE_NORMAL, this);
|
||||
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
|
||||
dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]);
|
||||
} else {
|
||||
float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight");
|
||||
dynamiclight_set(p, LFIELD_ANGLES, ang);
|
||||
dynamiclight_set(p, LFIELD_FLAGS, 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: this needs to be incorporated and simplified, now that we can handle it all in-class */
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
/* what's the current weapon model supposed to be anyway? */
|
||||
p_model.oldmodel = Weapons_GetPlayermodel(this, activeweapon);
|
||||
|
||||
/* we changed weapons, update skeletonindex */
|
||||
if (p_model.model != p_model.oldmodel) {
|
||||
/* free memory */
|
||||
if (p_model.skeletonindex)
|
||||
skel_delete(p_model.skeletonindex);
|
||||
|
||||
/* set the new model and mark us updated */
|
||||
setmodel(p_model, p_model.oldmodel);
|
||||
p_model.model = p_model.oldmodel;
|
||||
|
||||
/* set the new skeletonindex */
|
||||
p_model.skeletonindex = skel_create(p_model.modelindex);
|
||||
|
||||
/* hack this thing in here FIXME: this should be done when popping in/out of a pvs */
|
||||
if (autocvar(cl_himodels, 1, "Use high-quality thisayer models over lower-definition ones"))
|
||||
setcustomskin(this, "", "geomset 0 2\n");
|
||||
else
|
||||
setcustomskin(this, "", "geomset 0 1\n");
|
||||
}
|
||||
|
||||
/* follow thisayer at all times */
|
||||
setorigin(p_model, origin);
|
||||
p_model.angles = angles;
|
||||
skel_build(p_model.skeletonindex, p_model, p_model.modelindex,0, 0, -1);
|
||||
|
||||
/* we have to loop through all valid bones of the weapon model and match them
|
||||
* to the thisayer one */
|
||||
for (float i = 0; i < g_pbones.length; i++) {
|
||||
vector bpos;
|
||||
float pbone = gettagindex(this, g_pbones[i]);
|
||||
float wbone = gettagindex(p_model, g_pbones[i]);
|
||||
|
||||
/* if the bone doesn't ignore in either skeletal mesh, ignore */
|
||||
if (wbone <= 0 || pbone <= 0)
|
||||
continue;
|
||||
|
||||
bpos = gettaginfo(this, pbone);
|
||||
|
||||
/* the most expensive bit */
|
||||
skel_set_bone_world(p_model, wbone, bpos, v_forward, v_right, v_up);
|
||||
}
|
||||
}
|
||||
|
||||
void Weapons_AmmoUpdate(entity);
|
||||
void HUD_AmmoNotify_Check(player pl);
|
||||
void HUD_ItemNotify_Check(player pl);
|
||||
void Camera_RunPosBob(vector angles, __inout vector camera_pos);
|
||||
void Camera_StrafeRoll(__inout vector camera_angle);
|
||||
void Shake_Update(NSClientPlayer);
|
||||
|
||||
void
|
||||
player::UpdateAliveCam(void)
|
||||
{
|
||||
vector cam_pos = GetEyePos();
|
||||
Camera_RunPosBob(view_angles, cam_pos);
|
||||
|
@ -254,7 +343,7 @@ TFPlayer::UpdateAliveCam(void)
|
|||
g_view.SetCameraAngle(view_angles);
|
||||
|
||||
if (vehicle) {
|
||||
ncVehicle veh = (ncVehicle)vehicle;
|
||||
NSVehicle veh = (NSVehicle)vehicle;
|
||||
|
||||
if (veh.UpdateView)
|
||||
veh.UpdateView();
|
||||
|
@ -272,25 +361,16 @@ TFPlayer::UpdateAliveCam(void)
|
|||
g_view.AddPunchAngle(punchangle);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::ReceiveEntity
|
||||
=================
|
||||
*/
|
||||
void
|
||||
TFPlayer::ClientInputFrame(void)
|
||||
{
|
||||
super::ClientInputFrame();
|
||||
|
||||
/* we need to make sure those aren't actually handled by the server */
|
||||
if (pSeatTFC->m_bInputGren1 == true) {
|
||||
input_buttons |= INPUT_PRONE;
|
||||
}
|
||||
if (pSeatTFC->m_bInputGren2 == true) {
|
||||
input_buttons |= INPUT_SPRINT;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFPlayer::ReceiveEntity(float new, float flChanged)
|
||||
player::ReceiveEntity(float new, float flChanged)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
ncPlayer::ReceiveEntity(new, flChanged);
|
||||
super::ReceiveEntity(new, flChanged);
|
||||
|
||||
/* animation */
|
||||
READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
||||
|
@ -299,9 +379,22 @@ TFPlayer::ReceiveEntity(float new, float flChanged)
|
|||
READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
|
||||
READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
|
||||
|
||||
READENTITY_BYTE(classtype, PLAYER_AMMOTYPES)
|
||||
READENTITY_FLOAT(m_flIdleScale, PLAYER_AMMOTYPES)
|
||||
READENTITY_FLOAT(m_flHallucination, PLAYER_AMMOTYPES)
|
||||
READENTITY_BYTE(mag_sbs, PLAYER_AMMO1)
|
||||
READENTITY_BYTE(mag_dbs, PLAYER_AMMO1)
|
||||
READENTITY_BYTE(mag_rpg, PLAYER_AMMO1)
|
||||
READENTITY_BYTE(mag_glauncher, PLAYER_AMMO1)
|
||||
|
||||
READENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2)
|
||||
READENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2)
|
||||
READENTITY_BYTE(m_iAmmoCells, PLAYER_AMMO2)
|
||||
READENTITY_BYTE(m_iAmmoShells, PLAYER_AMMO2)
|
||||
READENTITY_BYTE(m_iAmmoDetpack, PLAYER_AMMO2)
|
||||
READENTITY_BYTE(m_iAmmoMedikit, PLAYER_AMMO2)
|
||||
|
||||
READENTITY_BYTE(mode_tempstate, PLAYER_AMMO3)
|
||||
READENTITY_BYTE(classtype, PLAYER_AMMO3)
|
||||
READENTITY_FLOAT(m_flIdleScale, PLAYER_AMMO3)
|
||||
READENTITY_FLOAT(m_flHallucination, PLAYER_AMMO3)
|
||||
|
||||
setorigin(this, origin);
|
||||
|
||||
|
@ -314,52 +407,93 @@ TFPlayer::ReceiveEntity(float new, float flChanged)
|
|||
if (flChanged == UPDATE_ALL)
|
||||
PredictPreFrame();
|
||||
|
||||
if (flChanged & PLAYER_AMMOTYPES) {
|
||||
//Weapons_AmmoUpdate(this);
|
||||
if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3) {
|
||||
Weapons_AmmoUpdate(this);
|
||||
HUD_AmmoNotify_Check(this);
|
||||
}
|
||||
|
||||
if (flChanged & PLAYER_ITEMS || flChanged & PLAYER_HEALTH) {
|
||||
if (flChanged & PLAYER_ITEMS || flChanged & PLAYER_HEALTH)
|
||||
HUD_ItemNotify_Check(this);
|
||||
}
|
||||
|
||||
if (m_flHallucination > 0.0) {
|
||||
if (m_flNextHallucination > time) {
|
||||
if (m_flNextHallucination > time)
|
||||
return;
|
||||
}
|
||||
|
||||
TFCHallucination_Insert(origin, v_angle);
|
||||
m_flNextHallucination = time + 0.25f + random(0.25,0.75);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::PredictPostFrame
|
||||
|
||||
Save the last valid server values away in the _net variants of each field
|
||||
so we can roll them back later.
|
||||
=================
|
||||
*/
|
||||
void
|
||||
TFPlayer::PredictPreFrame(void)
|
||||
player::PredictPreFrame(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
ncPlayer::PredictPreFrame();
|
||||
NSClientPlayer::PredictPreFrame();
|
||||
|
||||
SAVE_STATE(anim_top)
|
||||
SAVE_STATE(anim_top_delay)
|
||||
SAVE_STATE(anim_top_time)
|
||||
SAVE_STATE(anim_bottom)
|
||||
SAVE_STATE(anim_bottom_time)
|
||||
|
||||
SAVE_STATE(mag_sbs)
|
||||
SAVE_STATE(mag_dbs)
|
||||
SAVE_STATE(mag_rpg)
|
||||
SAVE_STATE(mag_glauncher)
|
||||
|
||||
SAVE_STATE(m_iAmmoRockets)
|
||||
SAVE_STATE(m_iAmmoNails)
|
||||
SAVE_STATE(m_iAmmoCells)
|
||||
SAVE_STATE(m_iAmmoShells)
|
||||
SAVE_STATE(m_iAmmoDetpack)
|
||||
SAVE_STATE(m_iAmmoMedikit)
|
||||
|
||||
SAVE_STATE(mode_tempstate)
|
||||
SAVE_STATE(classtype)
|
||||
SAVE_STATE(m_flIdleScale)
|
||||
SAVE_STATE(m_flHallucination)
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::PredictPostFrame
|
||||
|
||||
Where we roll back our values to the ones last sent/verified by the server.
|
||||
=================
|
||||
*/
|
||||
void
|
||||
TFPlayer::PredictPostFrame(void)
|
||||
player::PredictPostFrame(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
ncPlayer::PredictPostFrame();
|
||||
NSClientPlayer::PredictPostFrame();
|
||||
|
||||
ROLL_BACK(anim_top)
|
||||
ROLL_BACK(anim_top_delay)
|
||||
ROLL_BACK(anim_top_time)
|
||||
ROLL_BACK(anim_bottom)
|
||||
ROLL_BACK(anim_bottom_time)
|
||||
|
||||
ROLL_BACK(mag_sbs)
|
||||
ROLL_BACK(mag_dbs)
|
||||
ROLL_BACK(mag_rpg)
|
||||
ROLL_BACK(mag_glauncher)
|
||||
|
||||
ROLL_BACK(m_iAmmoRockets)
|
||||
ROLL_BACK(m_iAmmoNails)
|
||||
ROLL_BACK(m_iAmmoCells)
|
||||
ROLL_BACK(m_iAmmoShells)
|
||||
ROLL_BACK(m_iAmmoDetpack)
|
||||
ROLL_BACK(m_iAmmoMedikit)
|
||||
|
||||
ROLL_BACK(mode_tempstate)
|
||||
ROLL_BACK(classtype)
|
||||
ROLL_BACK(m_flIdleScale)
|
||||
ROLL_BACK(m_flHallucination)
|
||||
|
@ -367,7 +501,7 @@ TFPlayer::PredictPostFrame(void)
|
|||
|
||||
#else
|
||||
void
|
||||
TFPlayer::ServerInputFrame(void)
|
||||
player::ServerInputFrame(void)
|
||||
{
|
||||
super::ServerInputFrame();
|
||||
gflags &= ~GF_NOBUILDZONE;
|
||||
|
@ -381,10 +515,10 @@ TFPlayer::ServerInputFrame(void)
|
|||
}
|
||||
|
||||
void
|
||||
TFPlayer::EvaluateEntity(void)
|
||||
player::EvaluateEntity(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
ncPlayer::EvaluateEntity();
|
||||
NSClientPlayer::EvaluateEntity();
|
||||
|
||||
/* animation */
|
||||
EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME)
|
||||
|
@ -393,13 +527,255 @@ TFPlayer::EvaluateEntity(void)
|
|||
EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME)
|
||||
EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME)
|
||||
|
||||
EVALUATE_FIELD(classtype, PLAYER_AMMOTYPES)
|
||||
EVALUATE_FIELD(m_flIdleScale, PLAYER_AMMOTYPES)
|
||||
EVALUATE_FIELD(m_flHallucination, PLAYER_AMMOTYPES)
|
||||
EVALUATE_FIELD(mag_sbs, PLAYER_AMMO1)
|
||||
EVALUATE_FIELD(mag_dbs, PLAYER_AMMO1)
|
||||
EVALUATE_FIELD(mag_rpg, PLAYER_AMMO1)
|
||||
EVALUATE_FIELD(mag_glauncher, PLAYER_AMMO1)
|
||||
|
||||
EVALUATE_FIELD(m_iAmmoRockets, PLAYER_AMMO2)
|
||||
EVALUATE_FIELD(m_iAmmoNails, PLAYER_AMMO2)
|
||||
EVALUATE_FIELD(m_iAmmoCells, PLAYER_AMMO2)
|
||||
EVALUATE_FIELD(m_iAmmoShells, PLAYER_AMMO2)
|
||||
EVALUATE_FIELD(m_iAmmoDetpack, PLAYER_AMMO2)
|
||||
EVALUATE_FIELD(m_iAmmoMedikit, PLAYER_AMMO2)
|
||||
|
||||
EVALUATE_FIELD(mode_tempstate, PLAYER_AMMO3)
|
||||
EVALUATE_FIELD(classtype, PLAYER_AMMO3)
|
||||
EVALUATE_FIELD(m_flIdleScale, PLAYER_AMMO3)
|
||||
EVALUATE_FIELD(m_flHallucination, PLAYER_AMMO3)
|
||||
}
|
||||
|
||||
void
|
||||
player::SpawnIntoGame(void)
|
||||
{
|
||||
entity spot = world;
|
||||
|
||||
/* spawn into the world */
|
||||
switch (team) {
|
||||
case 1:
|
||||
spot = Spawn_SelectRandom("info_teamspawn_blue");
|
||||
break;
|
||||
case 2:
|
||||
spot = Spawn_SelectRandom("info_teamspawn_red");
|
||||
break;
|
||||
case 3:
|
||||
spot = Spawn_SelectRandom("info_teamspawn_yellow");
|
||||
break;
|
||||
case 4:
|
||||
spot = Spawn_SelectRandom("info_teamspawn_green");
|
||||
break;
|
||||
}
|
||||
|
||||
setorigin(this, spot.origin);
|
||||
angles = spot.angles;
|
||||
fixangle = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
player::MakeClass(classtype_e class)
|
||||
{
|
||||
health = self.max_health = 100;
|
||||
takedamage = DAMAGE_YES;
|
||||
solid = SOLID_SLIDEBOX;
|
||||
movetype = MOVETYPE_WALK;
|
||||
flags = FL_CLIENT;
|
||||
viewzoom = 1.0;
|
||||
|
||||
/* select our class model */
|
||||
model = TFC_GetModelForClasstype(classtype);
|
||||
setmodel(this, model);
|
||||
setsize(this, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
velocity = [0,0,0];
|
||||
gravity = __NULL__;
|
||||
|
||||
armor = activeweapon = g_items = 0;
|
||||
iBleeds = TRUE;
|
||||
forceinfokey(this, "*spec", "0");
|
||||
forceinfokey(this, "*team", ftos(team));
|
||||
|
||||
switch (classtype) {
|
||||
case CLASS_SCOUT:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_NAILGUN, -1);
|
||||
m_iAmmoShells = 17;
|
||||
m_iAmmoNails = 100;
|
||||
|
||||
m_iMaxHealth = 75;
|
||||
m_iMaxArmor = 50;
|
||||
health = m_iMaxHealth;
|
||||
armor = 25;
|
||||
|
||||
m_iMaxShells = 50;
|
||||
m_iMaxNails = 200;
|
||||
m_iMaxCells = 100;
|
||||
m_iMaxRockets = 25;
|
||||
env_message_single(this, "HELP_SCOUT");
|
||||
break;
|
||||
case CLASS_SNIPER:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SNIPER, -1);
|
||||
Weapons_AddItem(this, WEAPON_AUTORIFLE, -1);
|
||||
Weapons_AddItem(this, WEAPON_NAILGUN, -1);
|
||||
m_iAmmoShells = 60; /* sniper rifles use shells */
|
||||
m_iAmmoNails = 50;
|
||||
|
||||
m_iMaxHealth = 90;
|
||||
m_iMaxArmor = 50;
|
||||
health = m_iMaxHealth;
|
||||
armor = 0;
|
||||
|
||||
m_iMaxShells = 75;
|
||||
m_iMaxNails = 100;
|
||||
m_iMaxCells = 50;
|
||||
m_iMaxRockets = 25;
|
||||
env_message_single(this, "HELP_SNIPER");
|
||||
break;
|
||||
case CLASS_SOLDIER:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_RPG, -1);
|
||||
m_iAmmoShells = 26;
|
||||
m_iAmmoRockets = 6;
|
||||
|
||||
m_iMaxHealth = 100;
|
||||
m_iMaxArmor = 200;
|
||||
health = m_iMaxHealth;
|
||||
armor = 100;
|
||||
|
||||
m_iMaxShells = 100;
|
||||
m_iMaxNails = 100;
|
||||
m_iMaxCells = 50;
|
||||
m_iMaxRockets = 50;
|
||||
env_message_single(this, "HELP_SOLDIER");
|
||||
break;
|
||||
case CLASS_DEMO:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_GLAUNCHER, -1);
|
||||
Weapons_AddItem(this, WEAPON_PIPEBOMB, -1);
|
||||
m_iAmmoShells = 22;
|
||||
m_iAmmoRockets = 14;
|
||||
|
||||
m_iMaxHealth = 90;
|
||||
m_iMaxArmor = 100;
|
||||
health = m_iMaxHealth;
|
||||
armor = 50;
|
||||
|
||||
m_iMaxShells = 75;
|
||||
m_iMaxNails = 50;
|
||||
m_iMaxCells = 50;
|
||||
m_iMaxRockets = 50;
|
||||
env_message_single(this, "HELP_DEMOMAN");
|
||||
break;
|
||||
case CLASS_MEDIC:
|
||||
Weapons_AddItem(this, WEAPON_MEDKIT, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_SUPERNAIL, -1);
|
||||
m_iAmmoShells = 26;
|
||||
m_iAmmoNails = 50;
|
||||
|
||||
m_iMaxHealth = 90;
|
||||
m_iMaxArmor = 100;
|
||||
health = m_iMaxHealth;
|
||||
armor = 50;
|
||||
|
||||
m_iMaxShells = 75;
|
||||
m_iMaxNails = 150;
|
||||
m_iMaxCells = 50;
|
||||
m_iMaxRockets = 25;
|
||||
env_message_single(this, "HELP_MEDIC");
|
||||
break;
|
||||
case CLASS_HVYWEAPON:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_ASSCAN, -1);
|
||||
m_iAmmoShells = 176; /* all of the heavy's weapons use shells */
|
||||
|
||||
m_iMaxHealth = 100;
|
||||
m_iMaxArmor = 300;
|
||||
health = m_iMaxHealth;
|
||||
armor = 150;
|
||||
|
||||
m_iMaxShells = 200;
|
||||
m_iMaxNails = 200;
|
||||
m_iMaxCells = 50;
|
||||
m_iMaxRockets = 25;
|
||||
env_message_single(this, "HELP_HWGUY");
|
||||
break;
|
||||
case CLASS_PYRO:
|
||||
Weapons_AddItem(this, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(this, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_FLAMER, -1);
|
||||
Weapons_AddItem(this, WEAPON_INCENDIARY, -1);
|
||||
m_iAmmoShells = 12;
|
||||
m_iAmmoCells = 120;
|
||||
m_iAmmoRockets = 5;
|
||||
|
||||
m_iMaxHealth = 100;
|
||||
m_iMaxArmor = 150;
|
||||
health = m_iMaxHealth;
|
||||
armor = 50;
|
||||
|
||||
m_iMaxShells = 40;
|
||||
m_iMaxNails = 50;
|
||||
m_iMaxCells = 200;
|
||||
m_iMaxRockets = 60;
|
||||
env_message_single(this, "HELP_PYRO");
|
||||
break;
|
||||
case CLASS_SPY:
|
||||
Weapons_AddItem(this, WEAPON_KNIFE, -1);
|
||||
Weapons_AddItem(this, WEAPON_TRANQUIL, -1);
|
||||
Weapons_AddItem(this, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(this, WEAPON_NAILGUN, -1);
|
||||
m_iAmmoShells = 24; /* tranquil and dbs use shells */
|
||||
m_iAmmoNails = 50;
|
||||
|
||||
m_iMaxHealth = 90;
|
||||
m_iMaxArmor = 100;
|
||||
health = m_iMaxHealth;
|
||||
armor = 25;
|
||||
|
||||
m_iMaxShells = 40;
|
||||
m_iMaxNails = 50;
|
||||
m_iMaxCells = 30;
|
||||
m_iMaxRockets = 15;
|
||||
env_message_single(this, "HELP_SPY");
|
||||
break;
|
||||
case CLASS_ENGINEER:
|
||||
Weapons_AddItem(this, WEAPON_WRENCH, -1);
|
||||
Weapons_AddItem(this, WEAPON_RAILGUN, -1);
|
||||
Weapons_AddItem(this, WEAPON_DBS, -1);
|
||||
m_iAmmoCells = 100;
|
||||
m_iAmmoNails = 25;
|
||||
m_iAmmoShells = 4;
|
||||
|
||||
m_iMaxHealth = 80;
|
||||
m_iMaxArmor = 50;
|
||||
health = m_iMaxHealth;
|
||||
armor = 25;
|
||||
|
||||
m_iMaxShells = 50;
|
||||
m_iMaxNails = 50;
|
||||
m_iMaxCells = 200;
|
||||
m_iMaxRockets = 30;
|
||||
env_message_single(this, "HELP_ENGINEER");
|
||||
break;
|
||||
}
|
||||
|
||||
g_items |= ITEM_SUIT;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::SendEntity
|
||||
=================
|
||||
*/
|
||||
float
|
||||
TFPlayer::SendEntity(entity ePEnt, float flChanged)
|
||||
player::SendEntity(entity ePEnt, float flChanged)
|
||||
{
|
||||
/* don't broadcast invisible players */
|
||||
if (IsFakeSpectator() && ePEnt != this)
|
||||
|
@ -409,8 +785,11 @@ TFPlayer::SendEntity(entity ePEnt, float flChanged)
|
|||
|
||||
flChanged = OptimiseChangedFlags(ePEnt, flChanged);
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_PLAYER);
|
||||
WriteFloat(MSG_ENTITY, flChanged);
|
||||
|
||||
/* the generic client attributes */
|
||||
ncPlayer::SendEntity(ePEnt, flChanged);
|
||||
NSClientPlayer::SendEntity(ePEnt, flChanged);
|
||||
|
||||
SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
||||
SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
|
||||
|
@ -418,9 +797,22 @@ TFPlayer::SendEntity(entity ePEnt, float flChanged)
|
|||
SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
|
||||
SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
|
||||
|
||||
SENDENTITY_BYTE(classtype, PLAYER_AMMOTYPES)
|
||||
SENDENTITY_FLOAT(m_flIdleScale, PLAYER_AMMOTYPES)
|
||||
SENDENTITY_FLOAT(m_flHallucination, PLAYER_AMMOTYPES)
|
||||
SENDENTITY_BYTE(mag_sbs, PLAYER_AMMO1)
|
||||
SENDENTITY_BYTE(mag_dbs, PLAYER_AMMO1)
|
||||
SENDENTITY_BYTE(mag_rpg, PLAYER_AMMO1)
|
||||
SENDENTITY_BYTE(mag_glauncher, PLAYER_AMMO1)
|
||||
|
||||
SENDENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2)
|
||||
SENDENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2)
|
||||
SENDENTITY_BYTE(m_iAmmoCells, PLAYER_AMMO2)
|
||||
SENDENTITY_BYTE(m_iAmmoShells, PLAYER_AMMO2)
|
||||
SENDENTITY_BYTE(m_iAmmoDetpack, PLAYER_AMMO2)
|
||||
SENDENTITY_BYTE(m_iAmmoMedikit, PLAYER_AMMO2)
|
||||
|
||||
SENDENTITY_BYTE(mode_tempstate, PLAYER_AMMO3)
|
||||
SENDENTITY_BYTE(classtype, PLAYER_AMMO3)
|
||||
SENDENTITY_FLOAT(m_flIdleScale, PLAYER_AMMO3)
|
||||
SENDENTITY_FLOAT(m_flHallucination, PLAYER_AMMO3)
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define PHY_VIEWPOS_CROUCHED [0,0,12]
|
||||
|
||||
void
|
||||
TFPlayer::Physics_Jump(void)
|
||||
player::Physics_Jump(void)
|
||||
{
|
||||
if (waterlevel >= 2) {
|
||||
if (watertype == CONTENT_WATER) {
|
||||
|
@ -49,3 +49,47 @@ TFPlayer::Physics_Jump(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
player::Physics_MaxSpeed(void)
|
||||
{
|
||||
float desiredspeed = 300.0f;
|
||||
|
||||
/* values courtesy of https://wiki.teamfortress.com/ */
|
||||
switch (classtype) {
|
||||
case CLASS_SCOUT:
|
||||
desiredspeed = 400.0f;
|
||||
break;
|
||||
case CLASS_SNIPER:
|
||||
desiredspeed = 300.0f;
|
||||
break;
|
||||
case CLASS_SOLDIER:
|
||||
desiredspeed = 240.0f;
|
||||
break;
|
||||
case CLASS_DEMO:
|
||||
desiredspeed = 280.0f;
|
||||
break;
|
||||
case CLASS_MEDIC:
|
||||
desiredspeed = 320.0f;
|
||||
break;
|
||||
case CLASS_HVYWEAPON:
|
||||
desiredspeed = 228.0f;
|
||||
break;
|
||||
case CLASS_PYRO:
|
||||
desiredspeed = 300.0f;
|
||||
break;
|
||||
case CLASS_SPY:
|
||||
desiredspeed = 300.0f;
|
||||
break;
|
||||
case CLASS_ENGINEER:
|
||||
desiredspeed = 300.0f;
|
||||
break;
|
||||
default:
|
||||
desiredspeed = 300.0f;
|
||||
}
|
||||
|
||||
if (GetFlags() & FL_CROUCHING)
|
||||
desiredspeed /= 3;
|
||||
|
||||
return desiredspeed;
|
||||
}
|
296
src/shared/w_asscan.qc
Normal file
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2019-2020 Gethyn ThomasQuail <xylemon@posteo.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Animations */
|
||||
enum
|
||||
{
|
||||
ASSCAN_IDLE1,
|
||||
ASSCAN_IDLE2,
|
||||
ASSCAN_SPINUP,
|
||||
ASSCAN_SPINDOWN,
|
||||
ASSCAN_FIRE,
|
||||
ASSCAN_DRAW,
|
||||
ASSCAN_HOLSTER
|
||||
};
|
||||
|
||||
#ifdef CLIENT
|
||||
void w_asscan_ejectshell(void)
|
||||
{
|
||||
static void w_asscan_ejectshell_death(void) {
|
||||
remove(self);
|
||||
}
|
||||
static void w_asscan_ejectshell_touch(void) {
|
||||
if (other == world)
|
||||
Sound_Play(self, CHAN_BODY, "modelevent_shell.land");
|
||||
}
|
||||
entity eShell = spawn();
|
||||
setmodel(eShell, "models/shell.mdl");
|
||||
eShell.solid = SOLID_BBOX;
|
||||
eShell.movetype = MOVETYPE_BOUNCE;
|
||||
eShell.drawmask = MASK_ENGINE;
|
||||
eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0];
|
||||
eShell.velocity = pSeat->m_vecPredictedVelocity;
|
||||
|
||||
makevectors(pSeat->m_eViewModel.angles);
|
||||
eShell.velocity += (v_forward * 0);
|
||||
eShell.velocity += (v_right * -80);
|
||||
eShell.velocity += (v_up * 100);
|
||||
eShell.touch = w_asscan_ejectshell_touch;
|
||||
|
||||
eShell.avelocity = [0,45,900];
|
||||
eShell.think = w_asscan_ejectshell_death;
|
||||
eShell.nextthink = time + 2.5f;
|
||||
setsize(eShell, [0,0,0], [0,0,0]);
|
||||
setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 26) + (v_up * -15));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
w_asscan_precache(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Sound_Precache("weapon_asscan.fire");
|
||||
Sound_Precache("weapon_asscan.reload");
|
||||
Sound_Precache("weapon_asscan.spindown");
|
||||
Sound_Precache("weapon_asscan.spinup");
|
||||
precache_model("models/w_tfac.mdl");
|
||||
precache_model("models/p_tfac.mdl");
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
precache_model("models/v_tfac.mdl");
|
||||
Sound_Precache("modelevent_shell.land");
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
w_asscan_pickup(player pl, int new, int startammo)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_updateammo(player pl)
|
||||
{
|
||||
Weapons_UpdateAmmo(pl, -1, pl.m_iAmmoShells, -1);
|
||||
}
|
||||
|
||||
string
|
||||
w_asscan_wmodel(void)
|
||||
{
|
||||
return "models/w_tfac.mdl";
|
||||
}
|
||||
|
||||
string
|
||||
w_asscan_pmodel(player pl)
|
||||
{
|
||||
return "models/p_mini2.mdl";
|
||||
}
|
||||
|
||||
string
|
||||
w_asscan_deathmsg(void)
|
||||
{
|
||||
return "%s was rolled over by %s' Chaingun.";
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_draw(player pl)
|
||||
{
|
||||
pl.mode_tempstate = 0;
|
||||
Weapons_SetModel("models/v_tfac.mdl");
|
||||
Weapons_ViewAnimation(pl, ASSCAN_DRAW);
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_holster(player pl)
|
||||
{
|
||||
Weapons_ViewAnimation(pl, ASSCAN_HOLSTER);
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_release(player pl)
|
||||
{
|
||||
/* end firing */
|
||||
if (pl.mode_tempstate == 1) {
|
||||
pl.mode_tempstate = 0;
|
||||
Weapons_Sound(pl, CHAN_WEAPON, "weapon_asscan.spindown");
|
||||
Weapons_ViewAnimation(pl, ASSCAN_SPINDOWN);
|
||||
pl.w_attack_next = 1.0f;
|
||||
pl.w_idle_next = 4.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl.w_idle_next > 0.0)
|
||||
return;
|
||||
|
||||
int r = (float)input_sequence % 2;
|
||||
if (r) {
|
||||
Weapons_ViewAnimation(pl, ASSCAN_IDLE1);
|
||||
} else {
|
||||
Weapons_ViewAnimation(pl, ASSCAN_IDLE2);
|
||||
}
|
||||
|
||||
pl.w_idle_next = 15.0f;
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_primary(player pl)
|
||||
{
|
||||
/* rate check */
|
||||
if (pl.w_attack_next > 0.0)
|
||||
return;
|
||||
|
||||
/* ammo check */
|
||||
if (pl.m_iAmmoShells <= 0) {
|
||||
w_asscan_release(pl);
|
||||
return;
|
||||
}
|
||||
|
||||
/* spin up first */
|
||||
if (pl.mode_tempstate == 0) {
|
||||
pl.mode_tempstate = 1;
|
||||
Weapons_ViewAnimation(pl, ASSCAN_SPINUP);
|
||||
Weapons_Sound(pl, CHAN_WEAPON, "weapon_asscan.spinup");
|
||||
pl.w_attack_next = 0.5f;
|
||||
pl.w_idle_next = pl.w_attack_next;
|
||||
return;
|
||||
}
|
||||
|
||||
/* from now on we're just going rambo */
|
||||
pl.m_iAmmoShells--;
|
||||
|
||||
Weapons_ViewAnimation(pl, ASSCAN_FIRE);
|
||||
Weapons_ViewPunchAngle(pl, [random(-2, 2),0,0]);
|
||||
Weapons_Sound(pl, CHAN_WEAPON, "weapon_asscan.fire");
|
||||
|
||||
if (pl.flags & FL_CROUCHING)
|
||||
Animation_PlayerTop(pl, TFCANIM_CR_SHOOTASSCAN, 0.1f);
|
||||
else
|
||||
Animation_PlayerTop(pl, TFCANIM_SHOOTASSCAN, 0.1f);
|
||||
|
||||
#ifdef CLIENT
|
||||
View_AddEvent(w_asscan_ejectshell, 0.0f);
|
||||
View_SetMuzzleflash(MUZZLE_WEIRD);
|
||||
#else
|
||||
TraceAttack_FireBullets(1, Weapons_GetCameraPos(pl), 8, [0.15,0.15], WEAPON_ASSCAN);
|
||||
#endif
|
||||
|
||||
pl.w_attack_next = 0.1f;
|
||||
pl.w_idle_next = 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_hud(player pl)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
vector aicon_pos;
|
||||
|
||||
aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
|
||||
|
||||
Cross_DrawSub(g_cross_spr, [24,24], [48/128,24/128], [0.1875, 0.1875]);
|
||||
|
||||
HUD_DrawAmmo2();
|
||||
|
||||
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,72/128], [24/256, 24/128], g_hud_color, pSeatLocal->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
|
||||
#endif
|
||||
}
|
||||
|
||||
float
|
||||
w_asscan_aimanim(player pl)
|
||||
{
|
||||
return pl.flags & FL_CROUCHING ? TFCANIM_CR_AIMASSCAN : TFCANIM_AIMASSCAN;
|
||||
}
|
||||
|
||||
void
|
||||
w_asscan_hudpic(player pl, int selected, vector pos, float a)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
vector hud_col;
|
||||
|
||||
if (pl.m_iAmmoShells == 0)
|
||||
hud_col = [1,0,0];
|
||||
else
|
||||
hud_col = g_hud_color;
|
||||
|
||||
HUD_DrawAmmoBar(pos, pl.m_iAmmoShells, 200, a);
|
||||
|
||||
if (selected) {
|
||||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
g_tfchud4_spr,
|
||||
[0,90/256],
|
||||
[170/256,45/256],
|
||||
hud_col,
|
||||
a,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
} else {
|
||||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
g_tfchud3_spr,
|
||||
[0,45/256],
|
||||
[170/256,45/256],
|
||||
hud_col,
|
||||
a,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
w_asscan_isempty(player pl)
|
||||
{
|
||||
if (pl.m_iAmmoShells <= 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
weapontype_t
|
||||
w_asscan_type(player pl)
|
||||
{
|
||||
return WPNTYPE_RANGED;
|
||||
}
|
||||
|
||||
weapon_t w_asscan =
|
||||
{
|
||||
.name = "asscan",
|
||||
.id = ITEM_ASSCAN,
|
||||
.slot = 3,
|
||||
.slot_pos = 3,
|
||||
.weight = WEIGHT_ASSCAN,
|
||||
.draw = w_asscan_draw,
|
||||
.holster = w_asscan_holster,
|
||||
.primary = w_asscan_primary,
|
||||
.secondary = w_asscan_release,
|
||||
.reload = __NULL__,
|
||||
.release = w_asscan_release,
|
||||
.postdraw = w_asscan_hud,
|
||||
.precache = w_asscan_precache,
|
||||
.pickup = w_asscan_pickup,
|
||||
.updateammo = w_asscan_updateammo,
|
||||
.wmodel = w_asscan_wmodel,
|
||||
.pmodel = w_asscan_pmodel,
|
||||
.deathmsg = w_asscan_deathmsg,
|
||||
.aimanim = w_asscan_aimanim,
|
||||
.isempty = w_asscan_isempty,
|
||||
.type = w_asscan_type,
|
||||
.hudpic = w_asscan_hudpic
|
||||
};
|