as released 2002-07-15

This commit is contained in:
archive 2002-07-15 00:00:00 +00:00
parent 930d214707
commit d5bbdc0fb0
122 changed files with 54493 additions and 1178 deletions

BIN
UK-PC-EULA Level Editor.doc Normal file

Binary file not shown.

3768
base/maps/heli.map Normal file

File diff suppressed because it is too large Load diff

45507
base/maps/kam6.map Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
//Generated by BehavEd
rem ( "ambush once the player crashes train, guards shoot out windows on train" );
rem ( "sarge takes out first window" );
affect ( "ambush_one_sarge", /*@AFFECT_TYPE*/ FLUSH )
{
set ( /*@SET_TYPES*/ "SET_RELEASE_ONCONTACT", /*@BOOL_TYPES_REL*/ "ON" );
set ( /*@SET_TYPES*/ "SET_FACE_TARGET", "window_one_shoot" );
set ( /*@SET_TYPES*/ "SET_ENEMY", "window_one_shoot" );
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "Attack" );
wait ( 700.000 );
set ( /*@SET_TYPES*/ "SET_ENEMY", "NULL" );
}
affect ( "ambush_one_guy1", /*@AFFECT_TYPE*/ FLUSH )
{
set ( /*@SET_TYPES*/ "SET_RELEASE_ONCONTACT", /*@BOOL_TYPES_REL*/ "ON" );
set ( /*@SET_TYPES*/ "SET_FACE_TARGET", "window_two_shoot" );
set ( /*@SET_TYPES*/ "SET_ENEMY", "window_two_shoot" );
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "Attack" );
wait ( 700.000 );
set ( /*@SET_TYPES*/ "SET_ENEMY", "NULL" );
}
affect ( "ambush_one_guy2", /*@AFFECT_TYPE*/ FLUSH )
{
set ( /*@SET_TYPES*/ "SET_RELEASE_ONCONTACT", /*@BOOL_TYPES_REL*/ "ON" );
set ( /*@SET_TYPES*/ "SET_FACE_TARGET", "window_three_shoot" );
set ( /*@SET_TYPES*/ "SET_ENEMY", "window_three_shoot" );
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "Attack" );
wait ( 700.000 );
set ( /*@SET_TYPES*/ "SET_ENEMY", "NULL" );
}
affect ( "ambush_one_guy3", /*@AFFECT_TYPE*/ FLUSH )
{
set ( /*@SET_TYPES*/ "SET_RELEASE_ONCONTACT", /*@BOOL_TYPES_REL*/ "ON" );
set ( /*@SET_TYPES*/ "SET_FACE_TARGET", "window_four_shoot" );
set ( /*@SET_TYPES*/ "SET_ENEMY", "window_four_shoot" );
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "Attack" );
wait ( 700.000 );
set ( /*@SET_TYPES*/ "SET_ENEMY", "NULL" );
}

View file

@ -0,0 +1,9 @@
//Generated by BehavEd
rem ( "this is the roff of the ceiling cart going by during the beginning" );
affect ( "ceiling_cart", /*@AFFECT_TYPE*/ FLUSH )
{
play ( /*@PLAY_TYPES*/ "PLAY_ROFF", "scripts/kam6/roffs/cart/car_thing_cart.rof" );
}

View file

@ -0,0 +1,10 @@
//Generated by BehavEd
rem ( "when the player is on the second tier the front door opens and guys ambush" );
affect ( "player", /*@AFFECT_TYPE*/ FLUSH )
{
use ( "front_door" );
use ( "main_door_guys" );
}

View file

@ -0,0 +1,72 @@
//Generated by BehavEd
rem ( "opens elevator doors and lowers the elevator" );
affect ( "door_left1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second half of left door moving out and down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "24.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 1000.0" );
}
affect ( "door_left2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "left2 moving out and down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "56.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 1000.0" );
}
affect ( "door_right1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second half of right door moving out and down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "24.0 0.0 0.0 1000.0" );
}
affect ( "door_right2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "right2 moving out and down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "56.0 0.0 0.0 1000.0" );
}
affect ( "elevator", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "elevator, below is a func wall to block the player from leaving" );
use ( "dont_leave_elev" );
sound ( /*@CHANNELS*/ CHAN_AUTO, "sound/misc/events/elevator_run.mp3" );
//$"moveBy"@4
wait ( 500.000 );
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
use ( "dont_leave_elev" );
}

View file

@ -0,0 +1,69 @@
//Generated by BehavEd
rem ( "opens elevator doors and lowers the elevator" );
affect ( "door_left2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "left2 moving out and down" );
//$"moveBy"@4
set ( "SET_MOVE_BY", "56.0 0.0 0.0 1000.0" );
wait ( 1000.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 1000.0" );
affect ( "door_left1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second half of left door moving out and down" );
//$"moveBy"@4
set ( "SET_MOVE_BY", "24.0 0.0 0.0 1000.0" );
wait ( 1000.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 1000.0" );
affect ( "door_right2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "right2 moving out and down" );
//$"moveBy"@4
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 1000.0" );
wait ( 1000.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "56.0 0.0 0.0 1000.0" );
affect ( "door_right1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second half of right door moving out and down" );
//$"moveBy"@4
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 1000.0" );
wait ( 1000.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
wait ( 19000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "24.0 0.0 0.0 1000.0" );
affect ( "elevator", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "elevator moving" );
sound ( /*@CHANNELS*/ CHAN_AUTO, "sound/misc/events/elevator_run.mp3" );
//$"moveBy"@2
wait ( 1000.000 );
set ( "SET_MOVE_BY", "0.0 0.0 -1760.0 19000.0" );
}
}
}
}
}

View file

@ -0,0 +1,73 @@
//Generated by BehavEd
rem ( "opens elevator doors and lowers the elevator" );
affect ( "door_left1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second part opening and moving down" );
sound ( /*@CHANNELS*/ CHAN_AUTO, "sound/misc/events/elevator_run.mp3" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "24.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 1760.0 18000.0" );
wait ( 18000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 1000.0" );
}
affect ( "door_left2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "left one opening and moving down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "56.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 1760.0 18000.0" );
wait ( 18000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 1000.0" );
}
affect ( "door_right1", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "second right one opening and moving down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "-24.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 1760.0 18000.0" );
wait ( 18000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "24.0 0.0 0.0 1000.0" );
}
affect ( "door_right2", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "right one opening and moving down" );
//$"moveBy"@3
set ( "SET_MOVE_BY", "-56.0 0.0 0.0 500.0" );
wait ( 500.000 );
//$"moveBy"@3
set ( "SET_MOVE_BY", "0.0 0.0 1760.0 18000.0" );
wait ( 18000.000 );
//$"moveBy"@1
set ( "SET_MOVE_BY", "56.0 0.0 0.0 1000.0" );
}
affect ( "elevator", /*@AFFECT_TYPE*/ FLUSH )
{
rem ( "actual elevator moving down" );
use ( "el_sound" );
use ( "dont_leave_elev" );
//$"moveBy"@4
wait ( 500.000 );
set ( "SET_MOVE_BY", "0.0 0.0 1760.0 18000.0" );
wait ( 18000.000 );
use ( "dont_leave_elev" );
}

View file

@ -0,0 +1,29 @@
//Generated by BehavEd
rem ( "two guys runing out of view when they see the player" );
affect ( "elev_sci_guy", /*@AFFECT_TYPE*/ FLUSH )
{
task ( "sci guy run" )
{
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "MoveToEnt" );
set ( /*@SET_TYPES*/ "SET_ENTGOAL", "elev_sci_guy_spot" );
}
dowait ( "sci guy run" );
}
affect ( "elev_sci_guy", /*@AFFECT_TYPE*/ FLUSH )
{
task ( "chem guy run" )
{
set ( /*@SET_TYPES*/ "SET_TASK", /*@TASK_TYPES*/ "MoveToEnt" );
set ( /*@SET_TYPES*/ "SET_ENTGOAL", "chem_sci_guy_spot" );
}
dowait ( "chem guy run" );
}

536
bin/BehavEd.bhc Normal file
View file

@ -0,0 +1,536 @@
/*
BehavEd Command List
(Note that anything involving floats must be (eg) "1.0", not just "1")
*/
//=== TYPES ================================================================
//header file type includes
// SOF2SPECIFIC: this typeset now MUST be present for BehavEd to present GET-helper combos!
<%s="SET_TYPES">
{
#include "IGInterface.h" setType_e
}
<%s="BOOL_TYPES">
{
"OFF"
"ON"
}
<%s="BOOL_TYPES_REL">
{
"OFF"
"ON"
"NULL"
}
<%s="GOAL_REL">
{
"STOP"
"PAUSE"
"GO"
}
<%s="LOOK_TYPES">
{
"HEAD"
"EYES"
"FULL"
"NULL"
}
<%s="HITLOC">
{
"Head"
"Right Leg"
"Neck"
"Left Leg"
"Chest"
"Right Foot"
"Left Shoulder"
"Left Arm"
"Left Hand"
"Right Shoulder"
"Right Arm"
"Right Hand"
"Gut"
"Groin"
"Left Thigh"
"Left Foot"
"Right Thigh"
"NULL"
}
<%s="SPEED">
{
"1 - None"
"2 - Slow"
"3 - TakeYourTime"
"4 - Jog"
"5 - NoRush"
"6 - FastJog"
"7 - HurryUp"
"8 - Run"
"9 - FastRun"
"10 - Emergency"
}
<%s="TASK_TYPES">
{
"WALK"//# uses finite state for walking
"RUN"//# uses finite state for running
"Path"//# plans path to navpoint using Lich
"PathCrouch"//# plans path to navpoint using Lich, once there- goes to crouch spot
"Move"//# moves to a specific point on map (NOT finite state driven)
"MoveToEnt"//# moves to a specific entity on map
"MoveToDeadEnt"//# movesto dead entity without stepping on it (do NOT use me if your name is not FOWLOR)
"Teleport"//# teleports to point (NOT finite state driven)
"Attack"//# fires weapon (might need to set Focus first)
"Focus"//# focus on target (use SET_ENEMY to specify one, default is closest member of enemy team)
"Use"//# Walk to this entity, then use it (use entgoal for name of entity)
"Pickup"//# Walk to the closest pickup, and pick it up
"Inventory"//# For inventory actions
}
<%s="GOAL_TYPES">
{
"HoldArea"//# SQUAD: Move to this area using leapfrog and hold it (use areagoal)
"FastAdvance"//# SQUAD: Move to this area quickly and hold it (use areagoal)_
"Surround"//# SQUAD: Surround this opponent (use entgoal)
"TakePosition"//# FIRETEAM/INDIVIDUAL: leap frog to this position (use vecgoal)
"Recon"// # FIRETEAM/INDIVIDUAL: Proceed to this area then recon/explore it (use areagoal)
"Guard"// # FIRETEAM/INDIVIDUAL: Patrol in this area (use areagoal)
"Wander"// # FIRETEAM/INDIVIDUAL: Wander this area (use areagoal)
"Follow"// # FIRETEAM/INDIVIDUAL: Follow this entity (use entgoal)
}
<%s="GOAL_MODES">
{
"Stealth"//# Execute your teams goals all stealth-like (send out scouts first)
"Rambo"//# Disregard stealth
"Flank"//# Send 1/2 of the team to flank area. (use areagoal2)
}
<%s="INVENTORY_ACTION">
{
"Draw"
"Hold" //# Will also draw if not currently drawn, then hold
"Examine" //# Will also draw if not currently drawn, then examine
"Use"//# Will also draw if not currently drawn, then use
"Throw"//# Will also draw if not currently drawn, then throw
"Holster"
"Toss"//# Only for gun, tosses it out
}
<%i="DECLARE_TYPE">
{
FLOAT//## %s="" # A number
STRING//## %s="" # A string
VECTOR//## %s="" # A vector
}
<%i="CHANNELS">
{
#include "channels.h" soundChannel_e
}
<%s="SKEL">
{
"Arms" // # set animation arms
"Torso" // # set animation torso
"Body" // # set animation body
"Left Arm" // # set animation left arm
"Eyes" // # set eye animations
}
<%s="PRIM">
{
"Attack" // # use Attack primitive
"Damage" // # use Damage primitive
"HMove" // # use HMOVE primitive
"VMove" // # use VMOVE primitive
"Stationary" // # use Stationary primitive
"Inventory" // # use Inventory primitive
"Interaction" // # use Interaction primitive
"Communication" // # use Communication primitive
}
<%s="HEALTH">
{
"Dead" // # use Dead Animations
"Low" // # use Low HP Animations
"Medium" // # use Med HP Animations
"Full" // # use Full HP Animations
}
<%s="MOOD">
{
"Bored"
"Happy"
"Sad"
"Alert"
"Afraid"
"Stealth"
"Soldier"
"Normal"
"AfraidFace"
"NULL"
}
<%s="ITEM">
{
"Hold Rifle"
"None" // # not holding anything
"Hold Pistol"
}
<%s="STANCE">
{
"Stand"
"Crouch"
"Prone"
"Sit"
"Jump"
"Swim"
"NULL"
}
<%s="HANDSIGNAL">
{
"Advance"
"Danger"
"Disperse"
"Follow"
"Halt"
"Point"
"Rush"
"Sight"
"Slow"
"Terrorist Point"
}
<%s="TEAM_TYPES">
{
"Team_None"
"Team_TheShop"
"Team_Prometheus"
"Team_ColombianRebels"
"Team_Finca"
"Team_Czech"
"Team_HongKongGang"
}
<%s="ANIMNAME">
{
"Fire M4" // # name of Animation to use
"Breathe"
"Jog"
"Jog Back"
"Run"
"Run Back"
"Walk"
"Swim"
"Walk Back"
"Walk030"
"Walk060"
"Walk090"
"Walk150"
"Walk210"
"Walk240"
"Walk270"
"Walk300"
"Walk330"
"Crouch Fast Walk"
"Crouch Run"
"Crouch Slow Walk"
"Crouch Walk"
"Crouch Walk Back"
"Advance"
"Danger"
"Disperse"
"Follow"
"Halt"
"Point"
"Rush"
"Sight"
"Slow"
"Heli Piloting"
"Heli Turning"
"Fire"
"ShootM60"
"Hold"
"Hold Death"
"Neck Death"
"Pain"
"Left Leg Death"
"Left Shoulder Death"
"R Shoulder"
"Right Thigh Death"
"Left Thigh Death"
"Groin Death"
"Foot Death"
"Front Death"
"HeadPain"
"Front Pain"
}
<%i="AFFECT_TYPE">
{
FLUSH//# clears out affected entity's prior commands first
INSERT//# inserts command into affected entity's current list
}
<%i="CAMERA_COMMANDS">
{
ENABLE//## %% # Puts game in camera mode // no more parms
DISABLE//## %% # Takes game out of camera mode //no more parms
ZOOM//## %f="0.0" %d="0" # Normal is 80, 10 is zoomed in, max is 120. Second value is time in ms to take to zoom to the new FOV
MOVE//## %v="0.0 0.0 0.0" %d="0" # Move to a absolute vector origin or TAG("targetname", ORIGIN) over time over number of milliseconds
PAN//## %v="0.0 0.0 0.0" %v="0.0 0.0 0.0" %d="0" # Pan to absolute angle from current angle in dir (no dir will use shortest) over number of milliseconds
ROLL//## %f="0.0" %d="0" # Roll to relative angle offsets of current angle over number of milliseconds
TRACK//## %s="trackName" %f="0.0" %d="0" # Get on track and move at speed, last number is whether or not to lerp to the start pos
FOLLOW//## %s="cameraGroup" %f="0.0" %d="0" # Follow ents with matching cameraGroup at angleSpeed, last number is whether or not to lerp to the start angle
DISTANCE//## %f="0.0" %d="0" # Keep this distance from cameraGroup (if any), last number is whether or not to lerp to the start angle
FADE//## %v="0.0 0.0 0.0" %f="0.0" %v="0.0 0.0 0.0" %f="0.0" %d="0" # Fade from [start Red Green Blue], [Opacity] to [end Red Green Blue], [Opacity] (all fields valid ranges are 0 to 1) over [number of milliseconds]
SHAKE//## %f="0.0" %d="0" # Intensity (0-16) and duration, in milliseconds
PATH//## %s="filename" !!"S:\base\!!scripts\*.rof" # Play a ROFF on a camera
}
<%i="TAG_TYPE">
{
ORIGIN
ANGLES
}
<%s="PLAY_TYPES">
{
#include "IGInterface.h" playType_e
}
// these must be left in this order, since they mirror the order of icons in res/bitmap1.bmp
//
<%i="ICON_OVERRIDES">
{
I_BRACE
I_EVENT
I_MACRO
I_SPACE
//
I_SOUND
I_CAMERA
I_ROTATE
I_REMOVE
I_SET
I_MOVE
I_IF
I_LOOP
I_DO
I_WAIT
I_DOWAIT
I_SIGNAL
I_WAITSIGNAL
I_FLUSH
I_WAITCLOCK
}
//#=== Flow control commands ============================================
[I_FLUSH] flush();//# clear all previous script commands on ent
[I_IF] if ( $test expression =,<,>,! xxx$ ) {} //# if condition true, execute block of commands
[I_IF] else () {} //# must immediately follow and else, will execute if the if condition is false
[I_LOOP] loop ( %d=-1 ) {} //# execute block of commands any number of times (-1 = forever)
affect( %s="DEFAULT", %t="AFFECT_TYPE" ) {}//# switch script affect to ent with specified name, flush old commands or insert the new block of commands into current commands
run ( %s="DEFAULT" ); //# ent runs specified script
//#=== Standard commands ================================================
[I_WAITCLOCK] wait( %f=1000.0 );//# script will wait specified number of milliseconds
[I_WAITSIGNAL] waitsignal( %s="signalname" );//# wait until a signal() command is given with the name name - only one ent can wait for a particular signal
[I_SIGNAL] signal( %s="signalname" );//# The ent waiting for this signal will continue with it's script
//action( %s="DEFAULT", %s="DEFAULT" );//# no longer valid, but I'll leave it in for the moment for testing
[I_SOUND] sound( %t="CHANNELS", %s="DEFAULT" );//# play sound on specified channel of ent
[I_MOVE] move ( %v=<0.0 0.0 0.0>, %f=1000.0 );//# Move ent from current location to <x,y,z> over time in milliseconds #Moves absolute to location
[I_MOVE] "moveBy"
{
set( %s="SET_MOVE_BY" %s="0.0 0.0 0.0 1000.0"); //# Move ent from current location by <x,y,z> over time in milliseconds #Moves relative to location
}
[I_MOVE] "moveDir"
{
set( %s="SET_MOVE" %s="0.0 0.0 0.0 500.0 1000.0"); //# Move ent from current location in direction of <x,y,z> with distance d over time in milliseconds #Moves relative to location
}
//[I_MOVE] move ( %v=<0.0 0.0 0.0>, %v=<0.0 0.0 0.0>, %f=1000.0 );//move ent from point to point at speed
//move ( $default$, $default$, %f=1000.0 );//move ent from point to point at speed
//[I_MOVE] move ( $default$, %f=1000.0 );//move ent from point to point at speed
[I_ROTATE] rotate( %v=<0.0 0.0 0.0>, %f=1000.0 );//# rotate ent to target angles at speed
use ( %s="DEFAULT" );//# uses specified ent
//use ( $get(STRING,"targetname")$ );//# uses specified ent from a get(STRING) command
//kill ( %s="DEFAULT" );//# kills ent with specified name
[I_REMOVE] remove ( %s="DEFAULT" ); //# removes ent with specified name from game
print( %s="DEFAULT" );//# Prints text to center of screen
rem(%s="comment");//# Just a comment for script, no actual effect in-game
//#=== Variable Handling ===============================================
declare( %t="DECLARE_TYPE", %s="variablename" ); //# declare a global variable here, limit of 16 per map
free( %s="variablename" ); //# free a global variable so you can make more
//get( %t="DECLARE_TYPE", %s="variablename" ); //# OF NO USE BY ITSELF - this will be removed soon, but is still usable inside other commands
random( %f=0.0, %f=0.0 );//# use a random float between 2 specified values. OF NO USE BY ITSELF - this will be removed soon, but is still usable inside other commands
//#=== Set commands =====================================================
//# standard strings
[I_SET] set( %t="SET_TYPES", %s="DEFAULT" );//# standard set commands
[I_SET] set( %s="variablename", %s="value" );//# set for variables
//[I_SET] set_anim_arms( %t="PRIM", %t="HEALTH", %t="ITEM", %t="MOOD", %t="STANCE", %t="ANIMNAME"); # set animation arms
//[I_SET] set_anim_torso( %t="PRIM", %t="HEALTH", %t="MOOD", %t="STANCE", %t="ANIMNAME"); # set animation torso
//[I_SET] set_anim_body( %t="PRIM", %t="HEALTH", %t="MOOD", %t="STANCE", %t="ANIMNAME"); # set animation body
//#Camera functions
[I_CAMERA] camera( %t="CAMERA_COMMANDS" );
//#Task functions
task( %s="DEFAULT" ) {}
[I_DO] do( %s="DEFAULT" )
[I_WAIT] wait( %s="DEFAULT" ) //# wait until task "taskname" is complete
wait( $random( 0, 1 )$ ) //# wait a specified amount of time
[I_DOWAIT] dowait( %s="DEFAULT" ); //# shorthand form of: do("taskname"); wait("taskname")
play (%t="PLAY_TYPES", %s="default");
//#=== Macros ===========================================================
"WalkTo"
{
set( %s="SET_TASK", %s="WALK" );
set( %s="SET_NAVGOAL", %s="DEFAULT" );
}
"RunTo"
{
set( %s="SET_TASK", %s="RUN" );
set( %s="SET_NAVGOAL", %s="DEFAULT" );
}
"Path"
{
set( %s="SET_TASK", %s="Path" ); //# Use Path for getting around corners
set( %s="SET_NAVGOAL", %s="DEFAULT" );
}
"Crouch"
{
set ( %s="SET_MOOD", %s="Stealth" );
set ( %s="SET_STANCE", %s="Crouch" );
}
"Halt Hand Signal"
{
set ( %s="SET_HAND_SIGNAL", %s="Halt" );
}
// Old 1st parm locked set commands, not needed any more:
/*
//# vectors
set( %r%s="SET_ORIGIN", %v=<0.0 0.0 0.0>);
set( %r%s="SET_ANGLES", %v=<0.0 0.0 0.0>);
set( %r%s="SET_COPY_ORIGIN", %v=<0.0 0.0 0.0>);
//# floats
set( %r%s="SET_VELOCITY",%f=0.0);
set( %r%s="SET_XVELOCITY",%f=0.0);
set( %r%s="SET_YVELOCITY",%f=0.0);
set( %r%s="SET_ZVELOCITY",%f=0.0);
set( %r%s="SET_AVELOCITY",%f=0.0);
set( %r%s="SET_DPITCH",%f=0.0);
set( %r%s="SET_DYAW",%f=0.0);
set( %r%s="SET_TIMESCALE",%f=0.0);
set( %r%s="SET_VISRANGE",%f=0.0);
set( %r%s="SET_EARSHOT",%f=0.0);
set( %r%s="SET_VIGILANCE",%f=0.0);
//# ints
set( %r%s="SET_ANIM_HOLDTIME_LOWER",%d=0);
set( %r%s="SET_ANIM_HOLDTIME_UPPER",%d=0);
set( %r%s="SET_HEALTH",%d=0);
set( %r%s="SET_WALKSPEED",%d=0);
set( %r%s="SET_RUNSPEED",%d=0);
set( %r%s="SET_YAWSPEED",%d=0);
set( %r%s="SET_FRICTION",%d=0);
set( %r%s="SET_SHOOTDIST",%d=0);
set( %r%s="SET_HFOV",%d=0);
set( %r%s="SET_VFOV",%d=0);
set( %r%s="SET_DELAYSCRIPTTIME",%d=0);
set( %r%s="SET_FORWARDMOVE",%d=0);
set( %r%s="SET_RIGHTMOVE",%d=0);
set( %r%s="SET_AGGRESSION",%d=0);//# 1 - 5
set( %r%s="SET_AIM",%d=0);//# 1 - 5
//# booleans and simple calls
set( %r%s="SET_SCRIPTED",%t="BOOL_TYPES");
set( %r%s="SET_HIDING",%t="BOOL_TYPES");
set( %r%s="SET_IGNOREPAIN",%t="BOOL_TYPES");
set( %r%s="SET_IGNOREENEMIES",%t="BOOL_TYPES");
set( %r%s="SET_STRAIGHTTOGOAL",%t="BOOL_TYPES");
set( %r%s="SET_DONTSHOOT",%t="BOOL_TYPES");
set( %r%s="SET_NOTARGET",%t="BOOL_TYPES");
set( %r%s="SET_CROUCHED",%t="BOOL_TYPES");
set( %r%s="SET_WALKING",%t="BOOL_TYPES");
set( %r%s="SET_CAREFUL",%t="BOOL_TYPES");
set( %r%s="SET_UNDYING",%t="BOOL_TYPES");
set( %r%s="SET_NOAVOID",%t="BOOL_TYPES");
set( %r%s="SET_BEAM",%t="BOOL_TYPES");
set( %r%s="SET_CREATEFORMATION",%t="BOOL_TYPES");
//# Behavior state settings
set( %r%s="BSTATE", %t="BSTATE_STRINGS" );
set( %r%s="defaultBState", %t="BSTATE_STRINGS" );
set( %r%s="tempBehavior", %t="BSTATE_STRINGS" );
//# Animation settings
set( %r%s="anim_upper", %t="ANIM_NAMES" );
set( %r%s="anim_lower", %t="ANIM_NAMES" );
set( %r%s="anim_both", %t="ANIM_NAMES" );
//#Enemy team table
set( %r%s="playerTeam", %t="TEAM_NAMES" );
set( %r%s="enemyTeam", %t="TEAM_NAMES" );
//#Weapon table
set( %r%s="weapon", %t="WEAPON_NAMES" );
//#Lean side table
set( %r%s="LEAN", %t="LEAN_TYPES" );//# left, right, or none
//#Event/effect table
set( %r%s="event", %s="default" );//# not implemented
//Old hardcoded camera commands
camera( %r%s="ORIGIN", %v=<0.0 0.0 0.0> );
camera( %r%s="ANGLES", %v=<0.0 0.0 0.0> );
camera( %r%s="FOV", %f=0.0 );
camera( %r%s="MOVE", %v=<0.0 0.0 0.0>, %f=0.0 );
camera( %r%s="PAN", %v=<0.0 0.0 0.0>, %f=0.0 );
camera( %r%s="ZOOM", %f=0.0, %f=0.0 );
camera( %r%s="FADE", %v=<0.0 0.0 0.0>, %f=0.0, %v=<0.0 0.0 0.0>, %f=0.0, %f=0.0 );
camera( %r%s="ENABLE" );
camera( %r%s="DISABLE" );
*/

BIN
bin/BehavEd.exe Normal file

Binary file not shown.

BIN
bin/ConfusEditor.exe Normal file

Binary file not shown.

BIN
bin/IBIze.exe Normal file

Binary file not shown.

BIN
bin/MD3View.exe Normal file

Binary file not shown.

BIN
bin/SklView.exe Normal file

Binary file not shown.

View file

@ -96,31 +96,11 @@ Grenade Launcher, uses 40mm rounds
*/ */
/*QUAKED pickup_weapon_M67 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
/*QUAKED pickup_weapon_M84 (0 .6 .6) (-15 -15 -15) (15 15 15) /*QUAKED pickup_weapon_M84 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade Grenade
*/ */
/*QUAKED pickup_weapon_F1 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
/*QUAKED pickup_weapon_L2A2 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
/*QUAKED pickup_weapon_MDN11 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
/*QUAKED pickup_weapon_SMOHG92 (0 .6 .6) (-15 -15 -15) (15 15 15) /*QUAKED pickup_weapon_SMOHG92 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade Grenade
*/ */
@ -136,6 +116,11 @@ White Phosphorus Grenade
*/ */
/*QUAKED pickup_weapon_MP5 (0 .6 .6) (-15 -15 -15) (15 15 15)
Sub-Machinegun, uses 9mm rounds
*/
/*QUAKED pickup_ammo_45 (0 .6 .6) (-15 -15 -15) (15 15 15) /*QUAKED pickup_ammo_45 (0 .6 .6) (-15 -15 -15) (15 15 15)
*/ */
@ -339,6 +324,11 @@ A bmodel that just sits there, doing nothing. Can be used for conditional walls
*/ */
/*QUAKED func_wall (0 .5 .8) ? START_OFF
A func wall can be turned off and on by targetting it.
*/
/*QUAKED func_rotating (0 .5 .8) ? START_ON - X_AXIS Y_AXIS /*QUAKED func_rotating (0 .5 .8) ? START_ON - X_AXIS Y_AXIS
You need to have an origin brush as part of this entity. The center of that brush will be You need to have an origin brush as part of this entity. The center of that brush will be
the point around which it is rotated. It will rotate around the Z axis by default. You can the point around which it is rotated. It will rotate around the Z axis by default. You can
@ -467,6 +457,14 @@ in site, closest in distance
*/ */
/*QUAKED target_effect (0 0.5 0) (-8 -8 -8) (8 8 8)
Plays an effect each time its targetted
"effect" effect to play
"delay" delay in milliseconds before the effect plays
*/
/*QUAKED trigger_multiple (.5 .5 .5) ? /*QUAKED trigger_multiple (.5 .5 .5) ?
"wait" : Seconds between triggerings, 0.5 default, -1 = one time only. "wait" : Seconds between triggerings, 0.5 default, -1 = one time only.
"random" wait variance, default is 0 "random" wait variance, default is 0
@ -537,4 +535,34 @@ so, the basic time between firing is a random time between
*/ */
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay.
*/
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) nonlinear angle negative_spot negative_point q3map_non-dynamic
Non-displayed light.
"light" overrides the default 300 intensity.
Nonlinear checkbox gives inverse square falloff instead of linear
Lights pointed at a target will be spotlights.
"radius" overrides the default 64 unit radius of a spotlight at the target point.
"scale" light falloff, 4.5 was used in the example map.
"_color" rgb percentage - red is 1 0 0, decimals are allowed.
"target" the targetname of the info_null the light is pointing to
"targetname" for switching, the name of the light, switch would have same target.
"style" the style or appearance of the light given off.
0 normal
1 FLICKER (first variety)
2 SLOW STRONG PULSE
3 CANDLE (first variety)
4 FAST STROBE
5 GENTLE PULSE 1
6 FLICKER (second variety)
7 CANDLE (second variety)
8 CANDLE (third variety)
9 SLOW STROBE (fourth variety)
10 FLUORESCENT FLICKER
11 SLOW PULSE NOT FADE TO BLACK
12 FAST PULSE
13 Test Blending
*/

42
bin/sof2.qe4 Normal file
View file

@ -0,0 +1,42 @@
{
"basepath" "S:\base"
"remotebasepath" "S:\base"
"texturepath" "S:\base\textures"
"entitypath" "S:\gamecode\*.cpp"
"mapspath" "S:\base\maps"
"rshcmd" "ts S:\bin\"
"autosave" "C:\ravenlocal\sof2\autosave.map"
"bsp FullVis (patchshadows)" "!sof2map -bsp $ -class 4 && !sof2map -vis $ -class 2 && !sof2map -light -patchshadows $"
"bsp FullVis (visible lighting)" "!sof2map -bsp $ -class 4 && !sof2map -vis -saveprt $ -class 2 && !sof2map -vlight $ -class 2"
"bsp FullVis (vertex lighting)" "!sof2map -bsp $ -class 4 && !sof2map -vis $ -class 2 && !sof2map -light -vertexlighting $ -class 2"
"bsp FullVis (extra)" "!sof2map -bsp $ -class 4 && !sof2map -vis $ -class 2 && !sof2map -light -extra $"
"bsp FullVis (1/2 LMs)" "!sof2map -bsp -samplesize 32 $ -class 4 && !sof2map -vis $ -class 2 && !sof2map -light -extra -samplesize 32 $"
"bsp FullVis" "!sof2map -bsp $ -class 4 && !sof2map -vis $ -class 2 && !sof2map -light $"
"bsp FullVis (nolight)" "!sof2map -bsp $ -class 4 && !sof2map -vis $ -class 2"
"bsp FullVis (lowmem)" "!sof2map -bsp $ -class 4 && !sof2map -vis -nopassage $ -class 2 && !sof2map -light $"
"bsp FullVis (lesmem)" "!sof2map -bsp $ -class 4 && !sof2map -vis -passageOnly $ -class 2 && !sof2map -light $"
"bsp FastVis" "!sof2map -bsp $ -class 4 && !sof2map -vis -fast $ -class 3 && !sof2map -light $"
"bsp FastVis (nolight)" "!sof2map -bsp $ -class 4 && !sof2map -vis -fast $ -class 3"
"bsp Instance" "!sof2map -bsp -rename $ -class 4 && !sof2map -light $"
"bsp Instance (extra)" "!sof2map -bsp -rename $ -class 4 && !sof2map -light -extra $"
"bsp Novis Showseams (nolight)" "!sof2map -bsp -showseams $ -class 4"
"bsp Novis (nolight)" "!sof2map -bsp $ -class 4"
"bsp Relight" "s:\bin\sof2map -bsp -onlyents $ -class 4 && !sof2map -light $"
"bsp Relight (extra)" "s:\bin\sof2map -bsp -onlyents $ -class 4 && !sof2map -light -extra $"
"bsp Relight (extra wide)" "s:\bin\sof2map -bsp -onlyents $ -class 4 && !sof2map -light -extrawide $"
"bsp Relight (1/2 LM)" "s:\bin\sof2map -bsp -onlyents $ && !sof2map -light -extra -samplesize 32 $"
"bsp [LOCAL] FullVis" "s:\bin\sof2map -all $"
"bsp [LOCAL] FullVis (extra)" "S:\bin\sof2map -bsp $ && S:\bin\sof2map -vis $ && S:\bin\sof2map -light -extra $"
"bsp [LOCAL] FullVis (1/2 LMs)" "s:\bin\sof2map -bsp -samplesize 32 $ && s:\bin\sof2map -vis $ && s:\bin\sof2map -light -extra -samplesize 32 $"
"bsp [LOCAL] FullVis (nolight)" "S:\bin\sof2map -bsp $ && S:\bin\sof2map -vis $"
"bsp [LOCAL] FastVis (nolight)" "S:\bin\sof2map -bsp $ && S:\bin\sof2map -vis -fast $"
"bsp [LOCAL] FastVis" "S:\bin\sof2map -bsp $ && S:\bin\sof2map -vis -fast $ && S:\bin\sof2map -light $"
"bsp [LOCAL] Instance" "S:\bin\sof2map -bsp -rename $ && s:\bin\sof2map -light $"
"bsp [LOCAL] Instance (extra)" "S:\bin\sof2map -bsp -rename $ && s:\bin\sof2map -light -extra $"
"bsp [LOCAL] NoVis" "S:\bin\sof2map -bsp $"
"bsp [LOCAL] OnlyEnts" "S:\bin\sof2map -bsp -onlyents $"
"bsp [LOCAL] Info" "S:\bin\sof2map -info $"
"bsp [LOCAL] Relight (extra)" "s:\bin\sof2map -bsp -onlyents $ && s:\bin\sof2map -light -extra $"
"bsp [LOCAL] Relight (1/2 LM)" "s:\bin\sof2map -bsp -onlyents $ && s:\bin\sof2map -light -extra -samplesize 32 $"
"brush_primit" "0"
}

View file

@ -1,23 +0,0 @@
{
"basepath" "..\base"
"rshcmd" ""
"remotebasepath" "..\base"
"entitypath" "__QERPATH*.def"
"texturepath" "..\base\textures"
"autosave" "..\base\maps\autosave.map"
"bsp FullVis (1/2 LMs)" "__QERPATHsof2map -bsp -rename -samplesize 32 $ -class 4 && __QERPATHsof2map -vis $ -class 2 && __QERPATHsof2map -light -extra -samplesize 32 $"
"bsp FullVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light $"
"bsp FullVis (extra)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light -extra $"
"bsp FullVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $"
"bsp FastVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $"
"bsp FastVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $ && __QERPATHsof2map -light $"
"bsp NoVis" "__QERPATHlocalbatch\novis.bat $"
"bsp OnlyEnts" "__QERPATHsof2map -bsp -rename -onlyents $"
"bsp Info" "__QERPATHsof2map -info $"
"bsp Relight (extra)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra $"
"bsp Relight (1/2 LM)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra -samplesize 32 $"
"brush_primit" "0"
}

BIN
bin/striped.exe Normal file

Binary file not shown.

View file

@ -87,6 +87,22 @@ Package=<4>
############################################################################### ###############################################################################
Project: "gt_dem"=.\gametype\gt_dem\gt_dem.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SoF2/code/gametype/gt_dem", ZRDAAAAA
.\gametype\gt_dem
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "gt_dm"=.\gametype\gt_dm\gt_dm.dsp - Package Owner=<4> Project: "gt_dm"=.\gametype\gt_dm\gt_dm.dsp - Package Owner=<4>
Package=<5> Package=<5>

View file

@ -1,5 +1,5 @@
@set include= @set include=
@del /q ..\base\vm @del /q debug\base\mp\vm
@cd game @cd game
call game.bat call game.bat
@cd ..\cgame @cd ..\cgame
@ -12,6 +12,8 @@ call gt_ctf.bat
call gt_inf.bat call gt_inf.bat
@cd ..\gt_elim @cd ..\gt_elim
call gt_elim.bat call gt_elim.bat
@cd ..\gt_dem
call gt_dem.bat
@cd ..\gt_dm @cd ..\gt_dm
call gt_dm.bat call gt_dm.bat
@cd ..\gt_tdm @cd ..\gt_tdm
@ -36,6 +38,8 @@ if not exist "gametype\gt_tdm\vm\gt_tdm.qvm" goto badTDM
if not exist "gametype\gt_ctf\vm\gt_ctf.qvm" goto badCTF if not exist "gametype\gt_ctf\vm\gt_ctf.qvm" goto badCTF
:testinf :testinf
if not exist "gametype\gt_inf\vm\gt_inf.qvm" goto badINF if not exist "gametype\gt_inf\vm\gt_inf.qvm" goto badINF
:testdem
if not exist "gametype\gt_dem\vm\gt_dem.qvm" goto badDEM
:testelim :testelim
if not exist "gametype\gt_elim\vm\gt_elim.qvm" goto badELIM if not exist "gametype\gt_elim\vm\gt_elim.qvm" goto badELIM
if %bad == "0" goto goodBuild if %bad == "0" goto goodBuild
@ -81,6 +85,11 @@ echo ***** gt_elim.qvm did not build!
set bad = 1 set bad = 1
goto end goto end
:badDEM
echo ***** gt_dem.qvm did not build!
set bad = 1
goto end
:goodBuild :goodBuild
echo VMs were built successfully! echo VMs were built successfully!

View file

@ -112,6 +112,8 @@ stringID_table_t bg_animTable [MAX_ANIMATIONS+1] =
ENUM2STRING(TORSO_RELOAD_MM1_SHELL), ENUM2STRING(TORSO_RELOAD_MM1_SHELL),
ENUM2STRING(TORSO_RELOAD_MM1_END), ENUM2STRING(TORSO_RELOAD_MM1_END),
ENUM2STRING(TORSO_USE),
//must be terminated //must be terminated
NULL,-1 NULL,-1
}; };

View file

@ -244,7 +244,7 @@ void CG_Drop_f ( void )
// Go to next weapon before the current drops // Go to next weapon before the current drops
exclude = cg.weaponSelect; exclude = cg.weaponSelect;
cg.weaponSelect = WP_M67_GRENADE; cg.weaponSelect = WP_M84_GRENADE;
CG_PrevWeapon ( qfalse, exclude ); CG_PrevWeapon ( qfalse, exclude );
// Send server comand // Send server comand
@ -300,6 +300,27 @@ static void CG_WeaponToggle_f ( void )
gitem_t* item; gitem_t* item;
int i; int i;
if ( !cg.snap )
{
return;
}
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
return;
}
if ( cg.snap->ps.pm_flags & PMF_FOLLOW )
{
return;
}
if ( cg.predictedPlayerState.weaponstate == WEAPON_CHARGING ||
cg.predictedPlayerState.weaponstate == WEAPON_CHARGING_ALT )
{
return;
}
// Get the toggle groups // Get the toggle groups
group1 = CG_GetOutfittingGroupFromString ( CG_Argv(1) ); group1 = CG_GetOutfittingGroupFromString ( CG_Argv(1) );
group2 = CG_GetOutfittingGroupFromString ( CG_Argv(2) ); group2 = CG_GetOutfittingGroupFromString ( CG_Argv(2) );
@ -371,6 +392,12 @@ be selected
*/ */
static void CG_NextWeapon_f ( void ) static void CG_NextWeapon_f ( void )
{ {
if ( cg_zoomWeaponChange.integer && (cg.predictedPlayerState.pm_flags & PMF_ZOOMED ) )
{
trap_SendConsoleCommand ( "+zoomin; wait; -zoomin;" );
return;
}
CG_NextWeapon ( qtrue, -1 ); CG_NextWeapon ( qtrue, -1 );
} }
@ -384,6 +411,12 @@ to be selectd
*/ */
static void CG_PrevWeapon_f ( void ) static void CG_PrevWeapon_f ( void )
{ {
if ( cg_zoomWeaponChange.integer && (cg.predictedPlayerState.pm_flags & PMF_ZOOMED) )
{
trap_SendConsoleCommand ( "+zoomout; wait; -zoomout;" );
return;
}
CG_PrevWeapon ( qtrue, -1 ); CG_PrevWeapon ( qtrue, -1 );
} }

View file

@ -273,6 +273,9 @@ void CG_DrawRadar ( void )
break; break;
case ET_PLAYER: case ET_PLAYER:
{
vec4_t color;
cl = &cgs.clientinfo[ cent->currentState.number ]; cl = &cgs.clientinfo[ cent->currentState.number ];
// not valid then dont draw it // not valid then dont draw it
@ -281,6 +284,15 @@ void CG_DrawRadar ( void )
continue; continue;
} }
if ( cent->currentState.gametypeitems )
{
VectorCopy4 ( g_color_table[ColorIndex(COLOR_YELLOW)], color );
}
else
{
VectorCopy4 ( teamColor, color );
}
if (cl->mLastChatTime+RADAR_CHAT_DURATION > cg.time) if (cl->mLastChatTime+RADAR_CHAT_DURATION > cg.time)
{ {
vec3_t finalColor; vec3_t finalColor;
@ -288,16 +300,16 @@ void CG_DrawRadar ( void )
scale = ((cg.time - cl->mLastChatTime) / (float)RADAR_CHAT_DURATION); scale = ((cg.time - cl->mLastChatTime) / (float)RADAR_CHAT_DURATION);
scale *= scale; scale *= scale;
finalColor[0] = (teamColor[0] * (scale)) + (colorWhite[0] * (1.0-scale)); finalColor[0] = (color[0] * (scale)) + (colorWhite[0] * (1.0-scale));
finalColor[1] = (teamColor[1] * (scale)) + (colorWhite[1] * (1.0-scale)); finalColor[1] = (color[1] * (scale)) + (colorWhite[1] * (1.0-scale));
finalColor[2] = (teamColor[2] * (scale)) + (colorWhite[2] * (1.0-scale)); finalColor[2] = (color[2] * (scale)) + (colorWhite[2] * (1.0-scale));
finalColor[3] = teamColor[3]; finalColor[3] = color[3];
trap_R_SetColor ( finalColor ); trap_R_SetColor ( finalColor );
scale += 1.0; scale += 1.0;
} }
else else
{ {
trap_R_SetColor ( teamColor ); trap_R_SetColor ( color );
scale = 1.0; scale = 1.0;
} }
@ -308,6 +320,7 @@ void CG_DrawRadar ( void )
break; break;
} }
} }
}
trap_R_SetColor ( colorWhite ); trap_R_SetColor ( colorWhite );
CG_DrawRotatePic2( RADAR_X + RADAR_RADIUS, RADAR_Y + RADAR_RADIUS, arrow_w, arrow_h, CG_DrawRotatePic2( RADAR_X + RADAR_RADIUS, RADAR_Y + RADAR_RADIUS, arrow_w, arrow_h,
@ -950,6 +963,7 @@ CG_DrawCenterText
static void CG_DrawCenterText ( void ) static void CG_DrawCenterText ( void )
{ {
int w; int w;
int h;
if ( cgs.gametypeMessageTime < cg.time ) if ( cgs.gametypeMessageTime < cg.time )
{ {
@ -958,7 +972,8 @@ static void CG_DrawCenterText ( void )
} }
w = trap_R_GetTextWidth( cgs.gametypeMessage, cgs.media.hudFont, 0.43f, 0 ); w = trap_R_GetTextWidth( cgs.gametypeMessage, cgs.media.hudFont, 0.43f, 0 );
CG_DrawText ( (SCREEN_WIDTH - w) / 2, cg_centerY.integer, cgs.media.hudFont, 0.43f, colorWhite, cgs.gametypeMessage, 0, DT_OUTLINE ); h = trap_R_GetTextHeight( cgs.gametypeMessage, cgs.media.hudFont, 0.43f, 0 );
CG_DrawText ( (SCREEN_WIDTH - w) / 2, cg_centerY.integer + h, cgs.media.hudFont, 0.43f, colorWhite, cgs.gametypeMessage, 0, DT_OUTLINE );
} }
@ -983,6 +998,11 @@ static void CG_DrawCrosshair(void)
return; return;
} }
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
return;
}
// If zoomed or unzoomed with the sniper rifle dont draw the standard crosshair // If zoomed or unzoomed with the sniper rifle dont draw the standard crosshair
zoomed = (cg.predictedPlayerState.pm_flags&PMF_ZOOMED); zoomed = (cg.predictedPlayerState.pm_flags&PMF_ZOOMED);
if ( zoomed || (cg.predictedPlayerState.weapon==WP_MSG90A1 && !zoomed) ) if ( zoomed || (cg.predictedPlayerState.weapon==WP_MSG90A1 && !zoomed) )
@ -1016,8 +1036,15 @@ static void CG_DrawCrosshair(void)
w = h = cg_crosshairSize.value; w = h = cg_crosshairSize.value;
// Determine the // Determine the
if ( cg_crosshairGrow.integer )
{
scale = ((float)cg.predictedPlayerState.inaccuracy / ((float)weaponData[cg.predictedPlayerState.weapon].attack[ATTACK_NORMAL].maxInaccuracy+1)); scale = ((float)cg.predictedPlayerState.inaccuracy / ((float)weaponData[cg.predictedPlayerState.weapon].attack[ATTACK_NORMAL].maxInaccuracy+1));
scale = 1 + scale * 1; scale = 1 + scale * 1;
}
else
{
scale = 1;
}
w = w * scale; w = w * scale;
h = h * scale; h = h * scale;
@ -1248,6 +1275,11 @@ static void CG_DrawSpectator(void)
else else
s = "SPECTATOR"; s = "SPECTATOR";
if ( (cg.snap->ps.pm_flags & PMF_FOLLOW) )
{
y = 65;
}
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.45f, 0 ) / 2, CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.45f, 0 ) / 2,
y, cgs.media.hudFont, 0.45f, colorWhite, s, 0, DT_OUTLINE ); y, cgs.media.hudFont, 0.45f, colorWhite, s, 0, DT_OUTLINE );
@ -1381,7 +1413,7 @@ static void CG_DrawWarmup( void )
} }
w = trap_R_GetTextWidth(s, cgs.media.hudFont, 0.53f, 0 ); w = trap_R_GetTextWidth(s, cgs.media.hudFont, 0.53f, 0 );
CG_DrawText (320 - w / 2, 105, cgs.media.hudFont, 0.53f, colorWhite, s, 0, DT_OUTLINE ); CG_DrawText (320 - w / 2, 155, cgs.media.hudFont, 0.53f, colorWhite, s, 0, DT_OUTLINE );
} }
/* /*
@ -1443,7 +1475,7 @@ static void CG_DrawChat ( void )
} }
else else
{ {
y = 395; y = 380;
x = 35; x = 35;
} }
@ -1590,6 +1622,39 @@ static void CG_DrawFlashBang ( void )
CG_FillRect ( 0, 0, 640, 480, color ); CG_FillRect ( 0, 0, 640, 480, color );
} }
/*
=================
CG_DrawHUDIcons
draws the currnet list of hud icons in the bottom left corner
=================
*/
static void CG_DrawHUDIcons ( void )
{
int i;
float x;
// User turn off hud icons?
if ( !cg_drawHUDIcons.integer )
{
return;
}
x = 25;
for ( i = 0; i < MAX_HUDICONS; i ++ )
{
// No hud icon? skip it
if ( !cgs.hudIcons[i] )
{
continue;
}
CG_DrawPic ( x, 425, 32, 32, cgs.gameIcons[ cgs.hudIcons[i] ] );
x += 40;
}
}
/* /*
================= =================
@ -1643,6 +1708,7 @@ static void CG_Draw2D( void )
CG_DrawSpectator(); CG_DrawSpectator();
CG_DrawCrosshair(); CG_DrawCrosshair();
CG_DrawCrosshairNames(); CG_DrawCrosshairNames();
CG_DrawHUDIcons();
} }
else else
{ {
@ -1653,6 +1719,7 @@ static void CG_Draw2D( void )
if ( !cg.showScores ) if ( !cg.showScores )
{ {
CG_DrawHUDIcons();
CG_DrawTimedMenus(); CG_DrawTimedMenus();
CG_DrawCrosshair(); CG_DrawCrosshair();
CG_DrawCrosshairNames(); CG_DrawCrosshairNames();
@ -1726,7 +1793,7 @@ void CG_DrawActive( stereoFrame_t stereoView )
} }
// Popup the objectives scren if we need to // Popup the objectives scren if we need to
if( cg.popupObjectives ) if( cg.popupObjectives && !cg.demoPlayback)
{ {
char temp[MAX_INFO_STRING]; char temp[MAX_INFO_STRING];
char lastobjectives[MAX_INFO_STRING]; char lastobjectives[MAX_INFO_STRING];

View file

@ -884,6 +884,7 @@ static void CG_AddCEntity( centity_t *cent )
break; break;
case ET_MOVER: case ET_MOVER:
case ET_WALL:
CG_Mover( cent ); CG_Mover( cent );
break; break;

View file

@ -229,6 +229,7 @@ static void CG_Obituary( entityState_t *ent )
message = "saw the light"; message = "saw the light";
break; break;
case MOD_TRIGGER_HURT: case MOD_TRIGGER_HURT:
case MOD_TRIGGER_HURT_NOSUICIDE:
message = "was in the wrong place"; message = "was in the wrong place";
break; break;
case MOD_TEAMCHANGE: case MOD_TEAMCHANGE:
@ -246,11 +247,7 @@ static void CG_Obituary( entityState_t *ent )
{ {
case MOD_MM1_GRENADE_LAUNCHER: case MOD_MM1_GRENADE_LAUNCHER:
case MOD_RPG7_LAUNCHER: case MOD_RPG7_LAUNCHER:
case MOD_M67_GRENADE:
case MOD_M84_GRENADE: case MOD_M84_GRENADE:
case MOD_F1_GRENADE:
case MOD_L2A2_GRENADE:
case MOD_MDN11_GRENADE:
case MOD_SMOHG92_GRENADE: case MOD_SMOHG92_GRENADE:
case MOD_ANM14_GRENADE: case MOD_ANM14_GRENADE:
case MOD_M15_GRENADE: case MOD_M15_GRENADE:
@ -345,10 +342,12 @@ static void CG_Obituary( entityState_t *ent )
if ( attack == ATTACK_ALTERNATE ) if ( attack == ATTACK_ALTERNATE )
{ {
message = "was bludgeoned by"; message = "was bludgeoned by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
} }
else else
{ {
message = "was pumped full of lead by"; message = "was pumped full of lead by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
} }
break; break;
@ -357,10 +356,12 @@ static void CG_Obituary( entityState_t *ent )
if ( attack == ATTACK_ALTERNATE ) if ( attack == ATTACK_ALTERNATE )
{ {
message = "was pistol whipped by"; message = "was pistol whipped by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
} }
else else
{ {
message = "was shot by"; message = "was shot by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
} }
break; break;
@ -372,31 +373,32 @@ static void CG_Obituary( entityState_t *ent )
else else
{ {
message = "was shot by"; message = "was shot by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
} }
break; break;
case MOD_M60_MACHINEGUN: case MOD_M60_MACHINEGUN:
case MOD_MICRO_UZI_SUBMACHINEGUN: case MOD_MICRO_UZI_SUBMACHINEGUN:
case MOD_MP5:
case MOD_M3A1_SUBMACHINEGUN: case MOD_M3A1_SUBMACHINEGUN:
case MOD_M4_ASSAULT_RIFLE: case MOD_M4_ASSAULT_RIFLE:
message = "was shot by"; message = "was shot by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
break; break;
case MOD_MSG90A1_SNIPER_RIFLE: case MOD_MSG90A1_SNIPER_RIFLE:
message = "was sniped by"; message = "was sniped by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
break; break;
case MOD_MM1_GRENADE_LAUNCHER: case MOD_MM1_GRENADE_LAUNCHER:
case MOD_RPG7_LAUNCHER: case MOD_RPG7_LAUNCHER:
case MOD_M67_GRENADE:
case MOD_M84_GRENADE: case MOD_M84_GRENADE:
case MOD_F1_GRENADE:
case MOD_L2A2_GRENADE:
case MOD_MDN11_GRENADE:
case MOD_SMOHG92_GRENADE: case MOD_SMOHG92_GRENADE:
case MOD_ANM14_GRENADE: case MOD_ANM14_GRENADE:
case MOD_M15_GRENADE: case MOD_M15_GRENADE:
message = "was detonated by"; message = "was detonated by";
message2 = va("'s %s", weaponParseInfo[mod].mName );
break; break;
case MOD_TELEFRAG: case MOD_TELEFRAG:
@ -550,6 +552,11 @@ static void CG_BodyQueueCopy(centity_t *cent, int clientNum, int hitLocation, ve
trap_G2API_DuplicateGhoul2Instance(source->ghoul2, &cent->ghoul2); trap_G2API_DuplicateGhoul2Instance(source->ghoul2, &cent->ghoul2);
if ( !cent->ghoul2 )
{
return;
}
// Reset all mision bolt positions // Reset all mision bolt positions
for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ ) for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ )
{ {

View file

@ -39,9 +39,18 @@ qboolean CG_ParseGametypeItems ( TGPGroup itemsGroup )
trap_GPG_FindPairValue ( itemGroup, "model", "", temp ); trap_GPG_FindPairValue ( itemGroup, "model", "", temp );
bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ].world_model[0] = (char *)trap_VM_LocalStringAlloc ( temp ); bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ].world_model[0] = (char *)trap_VM_LocalStringAlloc ( temp );
trap_GPG_FindPairValue ( itemGroup, "usemodel", "", temp );
if ( *temp )
{
trap_G2API_InitGhoul2Model(&cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].useModel, temp, 0 , 0, 0, 0, 0);
}
// Parse bolt model file // Parse bolt model file
trap_GPG_FindPairValue ( itemGroup, "boltmodel", "", temp ); trap_GPG_FindPairValue ( itemGroup, "boltmodel", "", temp );
if ( *temp )
{
trap_G2API_InitGhoul2Model(&cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].boltModel, temp, 0 , 0, 0, 0, 0); trap_G2API_InitGhoul2Model(&cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].boltModel, temp, 0 , 0, 0, 0, 0);
}
cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].radius[0] = 60; cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].radius[0] = 60;
CG_RegisterItemVisuals ( MODELINDEX_GAMETYPE_ITEM+itemCount ); CG_RegisterItemVisuals ( MODELINDEX_GAMETYPE_ITEM+itemCount );

View file

@ -292,6 +292,7 @@ void CG_DoGoreFromWeapon( int weaponnum, int attack, vec3_t hitloc, vec3_t hitdi
// Medium guns // Medium guns
case WP_M3A1_SUBMACHINEGUN: case WP_M3A1_SUBMACHINEGUN:
case WP_MP5:
CG_AddGore(irand(PGORE_BULLET_E, PGORE_BULLET_G), flrand( 5.25f, 7.5f), CG_AddGore(irand(PGORE_BULLET_E, PGORE_BULLET_G), flrand( 5.25f, 7.5f),
hitloc, hitdirection, entnum, entposition, entangle, ghoul2); hitloc, hitdirection, entnum, entposition, entangle, ghoul2);
if (cg_goreDetail.integer>0) if (cg_goreDetail.integer>0)
@ -380,10 +381,7 @@ void CG_DoGoreFromWeapon( int weaponnum, int attack, vec3_t hitloc, vec3_t hitdi
// Explosions // Explosions
case WP_MM1_GRENADE_LAUNCHER: case WP_MM1_GRENADE_LAUNCHER:
case WP_RPG7_LAUNCHER: case WP_RPG7_LAUNCHER:
case WP_M67_GRENADE: case WP_SMOHG92_GRENADE:
case WP_F1_GRENADE:
case WP_L2A2_GRENADE:
case WP_MDN11_GRENADE:
CG_AddGore(PGORE_SHRAPNEL, flrand( 14.0f, 17.0f), CG_AddGore(PGORE_SHRAPNEL, flrand( 14.0f, 17.0f),
hitloc, hitdirection, entnum, entposition, entangle, ghoul2); hitloc, hitdirection, entnum, entposition, entangle, ghoul2);
if (cg_goreDetail.integer>1) if (cg_goreDetail.integer>1)
@ -396,7 +394,6 @@ void CG_DoGoreFromWeapon( int weaponnum, int attack, vec3_t hitloc, vec3_t hitdi
// Stun/char // Stun/char
case WP_M84_GRENADE: case WP_M84_GRENADE:
case WP_M15_GRENADE: case WP_M15_GRENADE:
case WP_SMOHG92_GRENADE:
CG_AddGore(PGORE_BURN, flrand( 14.0f, 18.0f), CG_AddGore(PGORE_BURN, flrand( 14.0f, 18.0f),
hitloc, hitdirection, entnum, entposition, entangle, ghoul2); hitloc, hitdirection, entnum, entposition, entangle, ghoul2);
break; break;
@ -1183,14 +1180,16 @@ static void CG_ProcessChunk(int clientNum, centity_t *cent, TGoreChunk *chunk, v
{ {
Com_Error(ERR_DROP, "CG_ProcessChunk invalid g2 pointer for client %d\n", clientNum); Com_Error(ERR_DROP, "CG_ProcessChunk invalid g2 pointer for client %d\n", clientNum);
} }
trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, &re->ghoul2); trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, &re->ghoul2);
trap_G2API_SetRootSurface(&re->ghoul2, 0, CreateFinalName(chunk->mRoot, &Primary, &Opposite, qfalse));
if (!re->ghoul2) if (!re->ghoul2)
{ // whoa, that surface caused our model to go away??? { // whoa, that surface caused our model to go away???
CG_FreeLocalEntity(le); CG_FreeLocalEntity(le);
return; return;
} }
trap_G2API_SetRootSurface(&re->ghoul2, 0, CreateFinalName(chunk->mRoot, &Primary, &Opposite, qfalse));
bolt = trap_G2API_AddBolt(cent->ghoul2, 0, CreateFinalName(chunk->mBone, &Primary, &Opposite, qfalse)); bolt = trap_G2API_AddBolt(cent->ghoul2, 0, CreateFinalName(chunk->mBone, &Primary, &Opposite, qfalse));
if (bolt != -1) if (bolt != -1)
{ {
@ -1217,8 +1216,7 @@ static void CG_ProcessChunk(int clientNum, centity_t *cent, TGoreChunk *chunk, v
ci = &cgs.clientinfo[clientNum]; ci = &cgs.clientinfo[clientNum];
anim = &ci->animations[cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT]; anim = &ci->animations[cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT];
animSpeed = 50.0f / anim->frameLerp; animSpeed = 50.0f / anim->frameLerp;
// trap_G2API_SetBoneAnim(re->ghoul2, 0, "model_root", 0, 0, flags, animSpeed, cg.time, -1, 0);
// trap_G2API_SetBoneAnim(re->ghoul2, 0, "lower_lumbar", 0, 0, flags, animSpeed, cg.time, -1, 0);
trap_G2API_SetBoneAnim(re->ghoul2, 0, "model_root", anim->firstFrame + anim->numFrames - 1, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, -1, 0); trap_G2API_SetBoneAnim(re->ghoul2, 0, "model_root", anim->firstFrame + anim->numFrames - 1, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, -1, 0);
trap_G2API_SetBoneAnim(re->ghoul2, 0, "lower_lumbar", anim->firstFrame + anim->numFrames - 1, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, -1, 0); trap_G2API_SetBoneAnim(re->ghoul2, 0, "lower_lumbar", anim->firstFrame + anim->numFrames - 1, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, -1, 0);

View file

@ -302,6 +302,8 @@ typedef struct
animation_t animations[MAX_ANIMATIONS]; animation_t animations[MAX_ANIMATIONS];
sfxHandle_t sounds[MAX_CUSTOM_SOUNDS]; sfxHandle_t sounds[MAX_CUSTOM_SOUNDS];
qboolean voice;
} clientInfo_t; } clientInfo_t;
// Each weapon can have multiple attacsk. SOF2 by default has 2 attacks // Each weapon can have multiple attacsk. SOF2 by default has 2 attacks
@ -373,6 +375,7 @@ typedef struct
float radius[MAX_ITEM_MODELS]; float radius[MAX_ITEM_MODELS];
void* boltModel; void* boltModel;
void* useModel;
} itemInfo_t; } itemInfo_t;
@ -762,6 +765,8 @@ typedef struct
float mIRDist; float mIRDist;
float mIRSeeThrough; float mIRSeeThrough;
int hudIcons[MAX_HUDICONS];
} cgs_t; } cgs_t;
//============================================================================== //==============================================================================
@ -787,9 +792,11 @@ extern vmCvar_t cg_drawCrosshair;
extern vmCvar_t cg_drawCrosshairNames; extern vmCvar_t cg_drawCrosshairNames;
extern vmCvar_t cg_drawRadar; extern vmCvar_t cg_drawRadar;
extern vmCvar_t cg_drawTeamScores; extern vmCvar_t cg_drawTeamScores;
extern vmCvar_t cg_drawHUDIcons;
extern vmCvar_t cg_crosshairX; extern vmCvar_t cg_crosshairX;
extern vmCvar_t cg_crosshairY; extern vmCvar_t cg_crosshairY;
extern vmCvar_t cg_crosshairSize; extern vmCvar_t cg_crosshairSize;
extern vmCvar_t cg_crosshairGrow;
extern vmCvar_t cg_crosshairRGBA; extern vmCvar_t cg_crosshairRGBA;
extern vmCvar_t cg_crosshairFriendRGBA; extern vmCvar_t cg_crosshairFriendRGBA;
extern vmCvar_t cg_draw2D; extern vmCvar_t cg_draw2D;
@ -881,6 +888,8 @@ extern vmCvar_t cg_bodyTime;
extern vmCvar_t rw_enabled; extern vmCvar_t rw_enabled;
extern vmCvar_t cg_zoomWeaponChange;
// //
// cg_main.c // cg_main.c
// //

View file

@ -137,6 +137,29 @@ int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int a
trap_UI_CloseAll ( ); trap_UI_CloseAll ( );
return 0; return 0;
case CG_VOICE_EVENT:
Com_Printf ( "voice: event %d\n", arg0 );
switch ( arg0 )
{
case VEV_TALKSTART:
if ( arg1 != cg.predictedPlayerState.clientNum )
{
trap_S_StartLocalSound ( trap_S_RegisterSound ( "sound/radiostart.wav" ), CHAN_AUTO );
}
cgs.clientinfo[arg1].voice = qtrue;
break;
case VEV_TALKSTOP:
if ( arg1 != cg.predictedPlayerState.clientNum )
{
trap_S_StartLocalSound ( trap_S_RegisterSound ( "sound/radiostart.wav" ), CHAN_AUTO );
}
cgs.clientinfo[arg1].voice = qfalse;
break;
}
return 0;
default: default:
Com_Error( ERR_FATAL, "vmMain: unknown command %i", command ); Com_Error( ERR_FATAL, "vmMain: unknown command %i", command );
break; break;
@ -195,7 +218,6 @@ int cg_numpermanents = 0;
weaponInfo_t cg_weapons[MAX_WEAPONS]; weaponInfo_t cg_weapons[MAX_WEAPONS];
itemInfo_t cg_items[MAX_ITEMS]; itemInfo_t cg_items[MAX_ITEMS];
vmCvar_t con_notifyTime;
vmCvar_t cg_centertime; vmCvar_t cg_centertime;
vmCvar_t cg_centerY; vmCvar_t cg_centerY;
vmCvar_t cg_runpitch; vmCvar_t cg_runpitch;
@ -211,7 +233,9 @@ vmCvar_t cg_drawCrosshair;
vmCvar_t cg_drawCrosshairNames; vmCvar_t cg_drawCrosshairNames;
vmCvar_t cg_drawRadar; vmCvar_t cg_drawRadar;
vmCvar_t cg_drawTeamScores; vmCvar_t cg_drawTeamScores;
vmCvar_t cg_drawHUDIcons;
vmCvar_t cg_crosshairSize; vmCvar_t cg_crosshairSize;
vmCvar_t cg_crosshairGrow;
vmCvar_t cg_crosshairX; vmCvar_t cg_crosshairX;
vmCvar_t cg_crosshairY; vmCvar_t cg_crosshairY;
vmCvar_t cg_crosshairRGBA; vmCvar_t cg_crosshairRGBA;
@ -302,6 +326,8 @@ vmCvar_t cg_weaponMenuFast;
vmCvar_t cg_bodyTime; vmCvar_t cg_bodyTime;
vmCvar_t cg_zoomWeaponChange;
vmCvar_t rw_enabled; vmCvar_t rw_enabled;
typedef struct typedef struct
@ -320,8 +346,6 @@ static cvarTable_t cvarTable[] =
{ &cg_lockDeaths, "lock_deaths", "1", 0 }, { &cg_lockDeaths, "lock_deaths", "1", 0 },
{ &rw_enabled, "rw_enabled", "0", 0 }, { &rw_enabled, "rw_enabled", "0", 0 },
{ &con_notifyTime, "con_notifyTime", "3", 0 },
{ &cg_shellEjection, "cg_shellEjection", "1", CVAR_ARCHIVE }, { &cg_shellEjection, "cg_shellEjection", "1", CVAR_ARCHIVE },
{ &cg_ignore, "cg_ignore", "0", 0 }, { &cg_ignore, "cg_ignore", "0", 0 },
{ &cg_autoswitch, "cg_autoswitch", "2", CVAR_ARCHIVE }, { &cg_autoswitch, "cg_autoswitch", "2", CVAR_ARCHIVE },
@ -335,7 +359,9 @@ static cvarTable_t cvarTable[] =
{ &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE }, { &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE },
{ &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
{ &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
{ &cg_drawHUDIcons, "cg_drawHUDIcons", "1", CVAR_ARCHIVE },
{ &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE }, { &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE },
{ &cg_crosshairGrow, "cg_crosshairGrow", "1", CVAR_ARCHIVE },
{ &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE }, { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE },
{ &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE }, { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE },
{ &cg_crosshairRGBA, "cg_crosshairRGBA", "1,1,1,1", CVAR_ARCHIVE }, { &cg_crosshairRGBA, "cg_crosshairRGBA", "1,1,1,1", CVAR_ARCHIVE },
@ -438,6 +464,8 @@ static cvarTable_t cvarTable[] =
{ &cg_weaponMenuFast, "cg_weaponMenuFast", "0", CVAR_ARCHIVE }, { &cg_weaponMenuFast, "cg_weaponMenuFast", "0", CVAR_ARCHIVE },
{ &cg_bodyTime, "cg_bodyTime", "0", CVAR_ARCHIVE, 0.0f, 0.0f }, { &cg_bodyTime, "cg_bodyTime", "0", CVAR_ARCHIVE, 0.0f, 0.0f },
{ &cg_zoomWeaponChange, "cg_zoomWeaponChange", "1", CVAR_ARCHIVE, 0.0f, 0.0f },
}; };
static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
@ -1853,7 +1881,7 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
CG_InitHitModel( ); CG_InitHitModel( );
CG_LoadingString( "graphics" ); CG_LoadingString( "graphics" );
BG_ParseInviewFile ( ); BG_ParseInviewFile ( cgs.pickupsDisabled );
CG_RegisterGraphics ( ); CG_RegisterGraphics ( );
// CG_RegisterMission ( ); // CG_RegisterMission ( );
@ -1889,6 +1917,7 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
trap_Cvar_Set ( "ui_info_gametype", va("%i",cgs.gametype ) ); trap_Cvar_Set ( "ui_info_gametype", va("%i",cgs.gametype ) );
trap_Cvar_Set ( "ui_info_objectives", cgs.gametypeData->description ); trap_Cvar_Set ( "ui_info_objectives", cgs.gametypeData->description );
trap_Cvar_Set ( "con_draw", cg.scoreBoardShowing?"0":"1" );
// remove the last loading update // remove the last loading update
cg.infoScreenText[0] = 0; cg.infoScreenText[0] = 0;

View file

@ -305,7 +305,15 @@ void CG_DrawUseIcon ( rectDef_t* rect )
} }
CG_DrawStretchPic ( rect->x, rect->y, rect->w, rect->h,0, 0, 1, 1, NULL, CG_DrawStretchPic ( rect->x, rect->y, rect->w, rect->h,0, 0, 1, 1, NULL,
cgs.gameIcons [ cg.predictedPlayerState.generic1 ] ); cgs.gameIcons [ cg.predictedPlayerState.stats[STAT_USEICON] ] );
if ( cg.predictedPlayerState.stats[STAT_USETIME] )
{
float w = 98.0f * (float)cg.predictedPlayerState.stats[STAT_USETIME] / (float)cg.predictedPlayerState.stats[STAT_USETIME_MAX];
CG_DrawRect ( rect->x + rect->h + 10, rect->y + 9, 100, rect->h - 18, 1, colorWhite );
CG_FillRect ( rect->x + rect->h + 11, rect->y + 10, w, rect->h - 20, colorRed );
CG_DrawRect ( rect->x + rect->h + 11, rect->y + 10, w, rect->h - 20, 1, colorBlack );
}
} }
//============================================================================== //==============================================================================
@ -316,6 +324,12 @@ void CG_DrawPlayerGametypeItems ( rectDef_t* rect )
float x; float x;
int i; int i;
// If not in a use zone then dont bother
if ( cg.predictedPlayerState.pm_flags & PMF_CAN_USE )
{
return;
}
x = rect->x; x = rect->x;
for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ ) for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ )

View file

@ -1,119 +0,0 @@
#include "cg_local.h"
#include "animtable.h"
/*
======================
CG_ParseAnimationFile
Read a configuration file containing animation counts and rates
models/players/visor/animation.cfg, etc
======================
*/
qboolean CG_ParseAnimationFile ( const char *filename, clientInfo_t *ci)
{
const char *text_p;
int len;
int i;
char *token;
float fps;
int skip;
char text[20000];
fileHandle_t f;
int animNum;
animation_t *animations;
animations = ci->animations;
// load the file
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( len <= 0 || len >= sizeof( text ) - 1 )
{
return qfalse;
}
trap_FS_Read( text, len, f );
text[len] = 0;
trap_FS_FCloseFile( f );
// parse the text
text_p = text;
skip = 0; // quiet the compiler warning
//FIXME: have some way of playing anims backwards... negative numFrames?
//initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
for(i = 0; i < MAX_ANIMATIONS; i++)
{
animations[i].firstFrame = 0;
animations[i].numFrames = 0;
animations[i].loopFrames = -1;
animations[i].frameLerp = 100;
animations[i].initialLerp = 100;
}
// read information for each frame
while(1)
{
token = COM_Parse( &text_p );
if ( !token || !token[0])
{
break;
}
animNum = GetIDForString(animTable, token);
if(animNum == -1)
{
//#ifndef FINAL_BUILD
#ifdef _DEBUG
Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
#endif
continue;
}
token = COM_Parse( &text_p );
if ( !token )
{
break;
}
animations[animNum].firstFrame = atoi( token );
token = COM_Parse( &text_p );
if ( !token )
{
break;
}
animations[animNum].numFrames = atoi( token );
token = COM_Parse( &text_p );
if ( !token )
{
break;
}
animations[animNum].loopFrames = atoi( token );
token = COM_Parse( &text_p );
if ( !token )
{
break;
}
fps = atof( token );
if ( fps == 0 )
{
fps = 1;//Don't allow divide by zero error
}
if ( fps < 0 )
{//backwards
animations[animNum].frameLerp = floor(1000.0f / fps);
}
else
{
animations[animNum].frameLerp = ceil(1000.0f / fps);
}
animations[animNum].initialLerp = ceil(1000.0f / fabs(fps));
}
return qtrue;
}

View file

@ -284,32 +284,22 @@ static void CG_SetDeferredClientInfo( clientInfo_t *ci )
int i; int i;
clientInfo_t *match; clientInfo_t *match;
/* // spectators can use any skin
// If someone else is already the same models and skins we if ( ci->team == TEAM_SPECTATOR )
// can just load the client info {
for ( i = 0 ; i < cgs.maxclients ; i++ ) for ( i = 0; i < cgs.maxclients; i ++ )
{ {
match = &cgs.clientinfo[ i ]; match = &cgs.clientinfo[ i ];
if ( !match->infoValid )
// Cant steal the model from invalid or deferred clients
if ( !match->infoValid || match->deferred )
{ {
continue; continue;
} }
// If the model, skin, and team match then we have a match ci->deferred = qtrue;
if ( Q_stricmp( ci->identityName, match->identityName) || CG_CopyClientInfoModel( match, ci );
(ci->team != match->team) )
{
continue;
}
// just load the real info cause it uses the same models and skins
CG_LoadClientInfo( ci );
return; return;
} }
*/ }
// Try to use any skin from the team they are joining // Try to use any skin from the team they are joining
if ( cgs.gametypeData->teams ) if ( cgs.gametypeData->teams )
@ -948,19 +938,40 @@ CG_UpdatePlayerWeaponModel
void CG_UpdatePlayerWeaponModel ( centity_t* cent, qboolean force ) void CG_UpdatePlayerWeaponModel ( centity_t* cent, qboolean force )
{ {
clientInfo_t *ci = &cgs.clientinfo[cent->currentState.clientNum]; clientInfo_t *ci = &cgs.clientinfo[cent->currentState.clientNum];
void *model;
model = NULL;
if ( (cent->pe.torso.anim&~ANIM_TOGGLEBIT) == TORSO_USE )
{
int item;
cent->pe.weapon = -1;
for ( item = 0; item < MAX_GAMETYPE_ITEMS; item ++ )
{
if ( cent->currentState.gametypeitems & (1<<item) )
{
model = cg_items[MODELINDEX_GAMETYPE_ITEM+item].useModel;
break;
}
}
}
// If the weapon model hasnt changed then dont update it // If the weapon model hasnt changed then dont update it
if ( !force && cent->currentState.weapon == cent->pe.weapon ) else if ( !force && cent->currentState.weapon == cent->pe.weapon )
{ {
return; return;
} }
else
{
// Ensure the weapon is registered // Ensure the weapon is registered
CG_RegisterWeapon ( cent->currentState.weapon ); CG_RegisterWeapon ( cent->currentState.weapon );
// If we have a ghoul model then we can attach it to the right hand of the player model model = cg_weapons[cent->currentState.weapon].weaponG2Model;
if (cg_weapons[cent->currentState.weapon].weaponG2Model)
{ cent->pe.weapon = cent->currentState.weapon;
}
// Get rid of whats in their hand
if ( cent->pe.weaponModelSpot ) if ( cent->pe.weaponModelSpot )
{ {
trap_G2API_DetachG2Model ( cent->ghoul2, cent->pe.weaponModelSpot ); trap_G2API_DetachG2Model ( cent->ghoul2, cent->pe.weaponModelSpot );
@ -968,8 +979,10 @@ void CG_UpdatePlayerWeaponModel ( centity_t* cent, qboolean force )
cent->pe.weaponModelSpot = 0; cent->pe.weaponModelSpot = 0;
} }
cent->pe.weaponModelSpot = trap_G2API_CopySpecificGhoul2Model(cg_weapons[cent->currentState.weapon].weaponG2Model, 0, cent->ghoul2, -1 ); // If we have a ghoul model then we can attach it to the right hand of the player model
// trap_G2API_CopySpecificGhoul2Model(cg_weapons[cent->currentState.weapon].weaponG2Model, 0, cent->ghoul2, cent->pe.weaponModelSpot ); if (model)
{
cent->pe.weaponModelSpot = trap_G2API_CopySpecificGhoul2Model(model, 0, cent->ghoul2, -1 );
trap_G2API_SetBoltInfo(cent->ghoul2, cent->pe.weaponModelSpot, ci->boltWorldWeapon ); trap_G2API_SetBoltInfo(cent->ghoul2, cent->pe.weaponModelSpot, ci->boltWorldWeapon );
trap_G2API_AttachG2Model(cent->ghoul2, cent->pe.weaponModelSpot, cent->ghoul2, ci->boltWorldWeapon, 0); trap_G2API_AttachG2Model(cent->ghoul2, cent->pe.weaponModelSpot, cent->ghoul2, ci->boltWorldWeapon, 0);
@ -985,9 +998,6 @@ void CG_UpdatePlayerWeaponModel ( centity_t* cent, qboolean force )
break; break;
} }
} }
// Update the weapon in the player entity
cent->pe.weapon = cent->currentState.weapon;
} }
/* /*

View file

@ -344,6 +344,8 @@ typedef enum
CG_MAP_CHANGE, CG_MAP_CHANGE,
CG_VOICE_EVENT,
} cgameExport_t; } cgameExport_t;
// CG_POINT_CONTENTS // CG_POINT_CONTENTS

View file

@ -217,6 +217,8 @@ Called on load to set the initial values from configure strings
*/ */
void CG_SetConfigValues( void ) void CG_SetConfigValues( void )
{ {
int i;
cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) ); cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) );
cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) ); cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) );
cgs.pickupsDisabled = atoi( CG_ConfigString( CS_PICKUPSDISABLED ) ); cgs.pickupsDisabled = atoi( CG_ConfigString( CS_PICKUPSDISABLED ) );
@ -227,6 +229,11 @@ void CG_SetConfigValues( void )
CG_ParseGametypeTimer ( ); CG_ParseGametypeTimer ( );
CG_ParseGametypeMessage ( ); CG_ParseGametypeMessage ( );
CG_ParseVoteTime ( ); CG_ParseVoteTime ( );
for ( i = 0; i < MAX_HUDICONS; i ++ )
{
cgs.hudIcons[i] = atoi ( CG_ConfigString ( CS_HUDICONS + i ) );
}
} }
/* /*
@ -369,6 +376,10 @@ static void CG_ConfigStringModified( void )
{ {
cgs.gameIcons[ num - CS_ICONS ] = trap_R_RegisterShaderNoMip ( str ); cgs.gameIcons[ num - CS_ICONS ] = trap_R_RegisterShaderNoMip ( str );
} }
else if ( num >= CS_HUDICONS && num < CS_HUDICONS + MAX_HUDICONS )
{
cgs.hudIcons[ num - CS_HUDICONS ] = atoi ( str );
}
} }
@ -669,8 +680,6 @@ void CG_LoadVoiceChats( void )
size = trap_MemoryRemaining(); size = trap_MemoryRemaining();
CG_ParseVoiceChats( "scripts/female1.voice", &voiceChatLists[0], MAX_VOICECHATS ); CG_ParseVoiceChats( "scripts/female1.voice", &voiceChatLists[0], MAX_VOICECHATS );
CG_ParseVoiceChats( "scripts/male1.voice", &voiceChatLists[1], MAX_VOICECHATS ); CG_ParseVoiceChats( "scripts/male1.voice", &voiceChatLists[1], MAX_VOICECHATS );
Com_Printf("voice chat memory size = %d\n", size - trap_MemoryRemaining());
} }
/* /*

View file

@ -1305,6 +1305,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
if ( cg.deferredPlayerLoading > 10 ) if ( cg.deferredPlayerLoading > 10 )
{ {
CG_LoadDeferredPlayers(); CG_LoadDeferredPlayers();
cg.deferredPlayerLoading = 0;
} }
// build the render lists // build the render lists

View file

@ -224,7 +224,7 @@ void CG_PlayerWeaponEffects ( refEntity_t *parent, centity_t *cent, int team, ve
} }
// Add a dlight to the scene if it has a muzzle effect // Add a dlight to the scene if it has a muzzle effect
if ( attackInfo->muzzleEffect ) if ( attackInfo->muzzleEffect && weaponNum != WP_MP5 )
{ {
trap_R_AddLightToScene( flash.origin, 200, 0.6f, 0.4f, 0.2f ); trap_R_AddLightToScene( flash.origin, 200, 0.6f, 0.4f, 0.2f );
} }
@ -503,6 +503,12 @@ void CG_AddViewWeapon(playerState_t *ps)
VectorCopy ( cg.refdef.vieworg, gun.origin ); VectorCopy ( cg.refdef.vieworg, gun.origin );
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
VectorMA ( gun.origin, (-20.0f * (float)cg.predictedPlayerState.stats[STAT_USEWEAPONDROP]/300.0f), cg.refdef.viewaxis[0], gun.origin );
VectorMA ( gun.origin, (-20.0f * (float)cg.predictedPlayerState.stats[STAT_USEWEAPONDROP]/300.0f), cg.refdef.viewaxis[2], gun.origin );
}
// Add movement bobbing // Add movement bobbing
gun.origin[2] += cg.xyspeed * cg.bobfracsin * 0.0015f; gun.origin[2] += cg.xyspeed * cg.bobfracsin * 0.0015f;
@ -650,7 +656,7 @@ void CG_AddViewWeapon(playerState_t *ps)
} }
// Add a dlight when there is a muzzle effect // Add a dlight when there is a muzzle effect
if ( attackInfo->muzzleEffect ) if ( attackInfo->muzzleEffect && ps->weapon != WP_MP5 )
{ {
trap_R_AddLightToScene( flash.origin, 200, 0.6f, 0.4f, 0.2f ); trap_R_AddLightToScene( flash.origin, 200, 0.6f, 0.4f, 0.2f );
} }
@ -723,6 +729,11 @@ void CG_NextWeapon ( qboolean allowEmpty, int exclude )
return; return;
} }
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
return;
}
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) if ( cg.snap->ps.pm_flags & PMF_FOLLOW )
{ {
return; return;
@ -793,6 +804,11 @@ void CG_PrevWeapon ( qboolean allowEmpty, int exclude )
return; return;
} }
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
return;
}
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) if ( cg.snap->ps.pm_flags & PMF_FOLLOW )
{ {
return; return;
@ -861,6 +877,11 @@ void CG_Weapon_f( void )
return; return;
} }
if ( cg.predictedPlayerState.stats[STAT_USEWEAPONDROP] )
{
return;
}
if ( (cg.snap->ps.pm_flags & PMF_FOLLOW) ) if ( (cg.snap->ps.pm_flags & PMF_FOLLOW) )
{ {
return; return;
@ -951,7 +972,7 @@ The current weapon has just run out of ammo
void CG_OutOfAmmoChange( int weapon ) void CG_OutOfAmmoChange( int weapon )
{ {
// Get the best weapon thats not a grenade // Get the best weapon thats not a grenade
cg.weaponSelect = WP_M67_GRENADE; cg.weaponSelect = WP_M84_GRENADE;
CG_PrevWeapon ( qfalse, weapon ); CG_PrevWeapon ( qfalse, weapon );
} }
@ -1131,12 +1152,19 @@ void CG_FireWeapon( centity_t *cent, attackType_t attack )
c = rand() % c; c = rand() % c;
if ( attackInfo->flashSound[c] ) if ( attackInfo->flashSound[c] )
{ {
trap_S_StartSound( NULL, ent->number, CHAN_WEAPON, attackInfo->flashSound[c], -1, 2000 ); int radius = 2000;
if ( ent->weapon == WP_MP5 && cent->currentState.number != cg.snap->ps.clientNum)
{
radius = 1250;
}
trap_S_StartSound( NULL, ent->number, CHAN_WEAPON, attackInfo->flashSound[c], -1, radius );
} }
} }
// Handle dissapearing bullets if this is the main guy firing // Handle dissapearing bullets if this is the main guy firing
if ( cent->currentState.number == cg.snap->ps.clientNum ) if ( cent->currentState.number == cg.snap->ps.clientNum && cg.hitModel )
{ {
CG_PredictedBullet ( cent, attack ); CG_PredictedBullet ( cent, attack );
} }
@ -1329,12 +1357,8 @@ void CG_MissileHitWall (
case AMMO_40: case AMMO_40:
case AMMO_M15: case AMMO_M15:
case AMMO_M67:
case AMMO_M84: case AMMO_M84:
case AMMO_F1:
case AMMO_RPG7: case AMMO_RPG7:
case AMMO_L2A2:
case AMMO_MDN11:
case AMMO_SMOHG92: case AMMO_SMOHG92:
case AMMO_ANM14: case AMMO_ANM14:
@ -1403,11 +1427,7 @@ void CG_MissileHitPlayer (
case AMMO_RPG7: case AMMO_RPG7:
case AMMO_40: case AMMO_40:
case AMMO_M15: case AMMO_M15:
case AMMO_M67:
case AMMO_M84: case AMMO_M84:
case AMMO_F1:
case AMMO_L2A2:
case AMMO_MDN11:
case AMMO_SMOHG92: case AMMO_SMOHG92:
case AMMO_ANM14: case AMMO_ANM14:
if (cg_lockBlood.integer) if (cg_lockBlood.integer)
@ -1521,9 +1541,15 @@ void CG_Tracer(int tracerEffectID, vec3_t source, vec3_t dest )
{ {
vec3_t forward; vec3_t forward;
float len; float len;
float chance;
if ( !tracerEffectID )
{
return;
}
// Lower the amount of tracers // Lower the amount of tracers
float chance = cg_tracerChance.value * 100.0f; chance = cg_tracerChance.value * 100.0f;
if ( rand()%100 > chance ) if ( rand()%100 > chance )
{ {
return; return;
@ -1591,6 +1617,7 @@ void CG_Bullet(
// Tracers on enemies only // Tracers on enemies only
if ( sourceEntityNum != cg.snap->ps.clientNum || cg.renderingThirdPerson ) if ( sourceEntityNum != cg.snap->ps.clientNum || cg.renderingThirdPerson )
{ {
// MP5's have no tracers
CG_Tracer(tracerEffectID, start, end ); CG_Tracer(tracerEffectID, start, end );
} }
} }

View file

@ -737,14 +737,11 @@ int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean resta
bs->botWeaponWeights[WP_M590_SHOTGUN] = 13; bs->botWeaponWeights[WP_M590_SHOTGUN] = 13;
bs->botWeaponWeights[WP_MM1_GRENADE_LAUNCHER] = 8; bs->botWeaponWeights[WP_MM1_GRENADE_LAUNCHER] = 8;
bs->botWeaponWeights[WP_RPG7_LAUNCHER] = 16; bs->botWeaponWeights[WP_RPG7_LAUNCHER] = 16;
bs->botWeaponWeights[WP_M67_GRENADE] = 6;
bs->botWeaponWeights[WP_M84_GRENADE] = 6; bs->botWeaponWeights[WP_M84_GRENADE] = 6;
bs->botWeaponWeights[WP_F1_GRENADE] = 6;
bs->botWeaponWeights[WP_L2A2_GRENADE] = 5;
bs->botWeaponWeights[WP_MDN11_GRENADE] = 5;
bs->botWeaponWeights[WP_SMOHG92_GRENADE] = 2; bs->botWeaponWeights[WP_SMOHG92_GRENADE] = 2;
bs->botWeaponWeights[WP_ANM14_GRENADE] = 2; bs->botWeaponWeights[WP_ANM14_GRENADE] = 2;
bs->botWeaponWeights[WP_M15_GRENADE] = 2; bs->botWeaponWeights[WP_M15_GRENADE] = 2;
bs->botWeaponWeights[WP_MP5] = 7;
BotUtilizePersonality(bs); BotUtilizePersonality(bs);
@ -3498,6 +3495,7 @@ float BotWeaponCanLead(bot_state_t *bs)
case WP_M60_MACHINEGUN: case WP_M60_MACHINEGUN:
case WP_MICRO_UZI_SUBMACHINEGUN: case WP_MICRO_UZI_SUBMACHINEGUN:
case WP_M3A1_SUBMACHINEGUN: case WP_M3A1_SUBMACHINEGUN:
case WP_MP5:
case WP_MSG90A1: case WP_MSG90A1:
case WP_USAS_12_SHOTGUN: case WP_USAS_12_SHOTGUN:
case WP_M590_SHOTGUN: case WP_M590_SHOTGUN:
@ -3507,11 +3505,7 @@ float BotWeaponCanLead(bot_state_t *bs)
return 0.5; return 0.5;
case WP_RPG7_LAUNCHER: case WP_RPG7_LAUNCHER:
return 0.5; return 0.5;
case WP_M67_GRENADE:
case WP_M84_GRENADE: case WP_M84_GRENADE:
case WP_F1_GRENADE:
case WP_L2A2_GRENADE:
case WP_MDN11_GRENADE:
case WP_SMOHG92_GRENADE: case WP_SMOHG92_GRENADE:
case WP_ANM14_GRENADE: case WP_ANM14_GRENADE:
case WP_M15_GRENADE: case WP_M15_GRENADE:

View file

@ -1345,16 +1345,14 @@ float botGlobalNavWeaponWeights[WP_NUM_WEAPONS] =
9,//WP_M60_MACHINEGUN, 9,//WP_M60_MACHINEGUN,
7,//WP_MM1_GRENADE_LAUNCHER, 7,//WP_MM1_GRENADE_LAUNCHER,
7,//WP_RPG7_LAUNCHER, 7,//WP_RPG7_LAUNCHER,
7,//WP_M67_GRENADE,
6,//WP_M84_GRENADE, 6,//WP_M84_GRENADE,
6,//WP_F1_GRENADE,
6,//WP_L2A2_GRENADE,
6,//WP_MDN11_GRENADE,
6,//WP_SMOHG92_GRENADE, 6,//WP_SMOHG92_GRENADE,
6,//WP_ANM14_GRENADE, 6,//WP_ANM14_GRENADE,
6//WP_M15_GRENADE, 6,//WP_M15_GRENADE,
6,//WP_MP5
}; };
int GetNearestVisibleWPToItem(vec3_t org, int ignore) int GetNearestVisibleWPToItem(vec3_t org, int ignore)

View file

@ -138,6 +138,13 @@ static qboolean BG_ParseGametypeInfo ( int gametypeIndex )
gametype->respawnType = RT_NORMAL; gametype->respawnType = RT_NORMAL;
} }
// A gametype can be based off another gametype which means it uses all the gametypes entities
trap_GPG_FindPairValue ( gtGroup, "basegametype", "", temp );
if ( temp[0] )
{
gametype->basegametype = trap_VM_LocalStringAlloc ( temp );
}
// What percentage doest he backpack replenish? // What percentage doest he backpack replenish?
trap_GPG_FindPairValue ( gtGroup, "backpack", "0", temp ); trap_GPG_FindPairValue ( gtGroup, "backpack", "0", temp );
gametype->backpack = atoi(temp); gametype->backpack = atoi(temp);

View file

@ -434,27 +434,6 @@ Grenade Launcher, uses 40mm rounds
OUTFITTING_GROUP_PRIMARY, OUTFITTING_GROUP_PRIMARY,
}, },
/*QUAKED pickup_weapon_M67 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
{
"pickup_weapon_M67",
"sound/player/pickup/weapon.wav",
{ "models/weapons/m67/world/m67world.glm",
0, 0, 0},
/* icon */ "gfx/menus/hud/weapon_icons/m67_icon",
"*gfx/menus/weapon_renders/m67",
"a",
/* pickup */ "M67 grenade",
5,
IT_WEAPON,
WP_M67_GRENADE,
/* precache */ "",
/* sounds */ "",
OUTFITTING_GROUP_GRENADE,
},
/*QUAKED pickup_weapon_M84 (0 .6 .6) (-15 -15 -15) (15 15 15) /*QUAKED pickup_weapon_M84 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade Grenade
*/ */
@ -476,69 +455,6 @@ Grenade
OUTFITTING_GROUP_GRENADE, OUTFITTING_GROUP_GRENADE,
}, },
/*QUAKED pickup_weapon_F1 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
{
"pickup_weapon_F1",
"sound/player/pickup/weapon.wav",
{ "models/weapons/f1/world/f1world.glm",
0, 0, 0},
/* icon */ "gfx/menus/hud/weapon_icons/f1_icon",
"*gfx/menus/weapon_renders/m84",
"a",
/* pickup */ "F1 Frag",
5,
IT_WEAPON,
WP_F1_GRENADE,
/* precache */ "",
/* sounds */ "",
OUTFITTING_GROUP_GRENADE,
},
/*QUAKED pickup_weapon_L2A2 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
{
"pickup_weapon_L2A2",
"sound/player/pickup/weapon.wav",
{ "models/weapons/l2a2/world/l2a2world.glm",
0, 0, 0},
/* icon */ "gfx/menus/hud/weapon_icons/l2a2_icon",
"*gfx/menus/weapon_renders/m84",
"a",
/* pickup */ "L2A2 grenade",
5,
IT_WEAPON,
WP_L2A2_GRENADE,
/* precache */ "",
/* sounds */ "",
OUTFITTING_GROUP_GRENADE,
},
/*QUAKED pickup_weapon_MDN11 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade
*/
{
"pickup_weapon_MDN11",
"sound/player/pickup/weapon.wav",
{ "models/weapons/mdn11/world/mdn11world.glm",
0, 0, 0},
/* icon */ "gfx/menus/hud/weapon_icons/mdn11_icon",
"*gfx/menus/weapon_renders/mdn11",
"a",
/* pickup */ "MDN11 grenade",
5,
IT_WEAPON,
WP_MDN11_GRENADE,
/* precache */ "",
/* sounds */ "",
OUTFITTING_GROUP_GRENADE,
},
/*QUAKED pickup_weapon_SMOHG92 (0 .6 .6) (-15 -15 -15) (15 15 15) /*QUAKED pickup_weapon_SMOHG92 (0 .6 .6) (-15 -15 -15) (15 15 15)
Grenade Grenade
*/ */
@ -602,6 +518,27 @@ White Phosphorus Grenade
OUTFITTING_GROUP_GRENADE, OUTFITTING_GROUP_GRENADE,
}, },
/*QUAKED pickup_weapon_MP5 (0 .6 .6) (-15 -15 -15) (15 15 15)
Sub-Machinegun, uses 9mm rounds
*/
{
"pickup_weapon_MP5",
"sound/player/pickup/weapon.wav",
{ "models/weapons/mp5/world/mp5world.glm",
0, 0, 0},
/* icon */ "gfx/menus/hud/weapon_icons/mp5_icon",
"gfx/menus/weapon_renders/mp5",
"a",
/* pickup */ "MP5 Sub-machinegun",
30,
IT_WEAPON,
WP_MP5,
/* precache */ "",
/* sounds */ "",
OUTFITTING_GROUP_PRIMARY,
},
// //
// AMMO ITEMS // AMMO ITEMS
// //

View file

@ -36,7 +36,7 @@ char bg_availableOutfitting[WP_NUM_WEAPONS] = {-1};
int bg_outfittingGroups[OUTFITTING_GROUP_MAX][MAX_OUTFITTING_GROUPITEM] = int bg_outfittingGroups[OUTFITTING_GROUP_MAX][MAX_OUTFITTING_GROUPITEM] =
{ {
{ MODELINDEX_WEAPON_AK74, MODELINDEX_WEAPON_M4, MODELINDEX_WEAPON_USAS12, MODELINDEX_WEAPON_MSG90A1, MODELINDEX_WEAPON_M60, MODELINDEX_WEAPON_RPG7, MODELINDEX_WEAPON_MM1, -1, -1, -1 }, { MODELINDEX_WEAPON_AK74, MODELINDEX_WEAPON_M4, MODELINDEX_WEAPON_USAS12, MODELINDEX_WEAPON_MSG90A1, MODELINDEX_WEAPON_M60, MODELINDEX_WEAPON_MP5, MODELINDEX_WEAPON_RPG7, MODELINDEX_WEAPON_MM1, -1, -1 },
{ MODELINDEX_WEAPON_M590, MODELINDEX_WEAPON_MICROUZI, MODELINDEX_WEAPON_M3A1, -1, -1, -1, -1, -1, -1, - 1 }, { MODELINDEX_WEAPON_M590, MODELINDEX_WEAPON_MICROUZI, MODELINDEX_WEAPON_M3A1, -1, -1, -1, -1, -1, -1, - 1 },
{ MODELINDEX_WEAPON_M19, MODELINDEX_WEAPON_SOCOM, -1, -1, -1, -1, -1, -1, -1, -1 }, { MODELINDEX_WEAPON_M19, MODELINDEX_WEAPON_SOCOM, -1, -1, -1, -1, -1, -1, -1, -1 },
{ MODELINDEX_WEAPON_SMOHG92, MODELINDEX_WEAPON_M84, MODELINDEX_WEAPON_M15, MODELINDEX_WEAPON_ANM14, -1, -1, -1, -1, -1, -1 }, { MODELINDEX_WEAPON_SMOHG92, MODELINDEX_WEAPON_M84, MODELINDEX_WEAPON_M15, MODELINDEX_WEAPON_ANM14, -1, -1, -1, -1, -1, -1 },
@ -143,7 +143,12 @@ void PM_TorsoAnimation( playerState_t* ps )
{ {
case WEAPON_SPAWNING: case WEAPON_SPAWNING:
case WEAPON_READY: case WEAPON_READY:
if ( (ps->pm_flags & PMF_ZOOMED) && weaponData[ps->weapon].animIdleZoomed )
if ( ps->stats[STAT_USEWEAPONDROP] )
{
PM_ContinueTorsoAnim ( ps, TORSO_USE );
}
else if ( (ps->pm_flags & PMF_ZOOMED) && weaponData[ps->weapon].animIdleZoomed )
{ {
PM_ContinueTorsoAnim ( ps, weaponData[ps->weapon].animIdleZoomed ); PM_ContinueTorsoAnim ( ps, weaponData[ps->weapon].animIdleZoomed );
} }
@ -1257,7 +1262,7 @@ void BG_PlayerAngles (
AnglesSubtract( headAngles, lowerTorsoAngles, headAngles ); AnglesSubtract( headAngles, lowerTorsoAngles, headAngles );
AnglesSubtract( lowerTorsoAngles, legsAngles, lowerTorsoAngles ); AnglesSubtract( lowerTorsoAngles, legsAngles, lowerTorsoAngles );
if ( legs ) if ( legs && ghoul2 )
{ {
AnglesToAxis( legsAngles, legs ); AnglesToAxis( legsAngles, legs );

View file

@ -183,7 +183,7 @@ static void PM_Friction( void )
drop += control*pm_ladderfriction*pml.frametime; drop += control*pm_ladderfriction*pml.frametime;
} }
} }
else if ( pm->waterlevel ) else if ( pm->waterlevel > 1 )
{ {
drop += speed*pm_waterfriction*pm->waterlevel*pml.frametime; drop += speed*pm_waterfriction*pm->waterlevel*pml.frametime;
} }
@ -993,6 +993,97 @@ static void PM_NoclipMove( void ) {
//============================================================================ //============================================================================
/*
==============
PM_Use
Generates a use event
==============
*/
#define USE_DELAY 2000
void PM_Use( void )
{
int useTime = 0;
// don't allow attack until all buttons are up
if ( pm->ps->pm_flags & PMF_RESPAWNED )
{
return;
}
// ignore if not a normal player
if ( pm->ps->pm_type != PM_NORMAL )
{
return;
}
// check for dead player
if ( pm->ps->stats[STAT_HEALTH] <= 0 )
{
pm->ps->weapon = WP_NONE;
return;
}
// Cant use so dont bother letting them try
if ( !(pm->ps->pm_flags & PMF_CAN_USE ) || !(pm->cmd.buttons & BUTTON_USE ) )
{
if ( pm->ps->stats[STAT_USEWEAPONDROP] )
{
pm->ps->stats[STAT_USEWEAPONDROP] -= pml.msec;
if ( pm->ps->stats[STAT_USEWEAPONDROP] < 0 )
{
pm->ps->stats[STAT_USEWEAPONDROP] = 0;
}
}
if ( pm->ps->pm_debounce & PMD_USE )
{
pm->ps->pm_debounce &= ~PMD_USE;
pm->ps->stats[STAT_USETIME] = 0;
}
return;
}
pm->ps->pm_debounce |= PMD_USE;
useTime = pm->ps->stats[STAT_USETIME_MAX];
if ( useTime )
{
int elapsedTime = pm->ps->stats[STAT_USETIME];
if ( elapsedTime < useTime )
{
elapsedTime += pml.msec;
}
pm->ps->stats[STAT_USEWEAPONDROP] += pml.msec;
if ( pm->ps->stats[STAT_USEWEAPONDROP] > 300 )
{
pm->ps->stats[STAT_USEWEAPONDROP] = 300;
}
if ( elapsedTime >= useTime )
{
pm->ps->stats[STAT_USETIME] = 0;
PM_AddEvent ( EV_USE );
}
else
{
pm->ps->stats[STAT_USETIME] = elapsedTime;
}
return;
}
if ( !(pm->ps->pm_debounce & PMD_USE) )
{
PM_AddEvent ( EV_USE );
}
}
/* /*
================ ================
PM_FootstepForSurface PM_FootstepForSurface
@ -2014,11 +2105,7 @@ TAnimWeapon* PM_GetAnimFromName ( char *animName, playerState_t *ps, int *animIn
PM_SetWeaponAnimChoice(aW); PM_SetWeaponAnimChoice(aW);
break; break;
case WP_M67_GRENADE:
case WP_M84_GRENADE: case WP_M84_GRENADE:
case WP_F1_GRENADE:
case WP_L2A2_GRENADE:
case WP_MDN11_GRENADE:
case WP_SMOHG92_GRENADE: case WP_SMOHG92_GRENADE:
case WP_ANM14_GRENADE: case WP_ANM14_GRENADE:
case WP_M15_GRENADE: case WP_M15_GRENADE:
@ -2230,12 +2317,9 @@ static void PM_BeginWeaponChange(int weapon)
} }
// turn off any kind of zooming when weapon switching. // turn off any kind of zooming when weapon switching.
if( pm->ps->pm_flags & PMF_ZOOMED )
{
pm->ps->zoomFov = 0; pm->ps->zoomFov = 0;
pm->ps->zoomTime = pm->ps->commandTime; pm->ps->zoomTime = 0;
pm->ps->pm_flags &= ~(PMF_ZOOM_FLAGS); pm->ps->pm_flags &= ~(PMF_ZOOM_FLAGS);
}
// Clear the weapon time // Clear the weapon time
pm->ps->weaponTime = 0; pm->ps->weaponTime = 0;
@ -2245,7 +2329,7 @@ static void PM_BeginWeaponChange(int weapon)
PM_AddEvent(EV_CHANGE_WEAPON); PM_AddEvent(EV_CHANGE_WEAPON);
pm->ps->weaponstate = WEAPON_DROPPING; pm->ps->weaponstate = WEAPON_DROPPING;
if( pm->ps->weapon >= WP_M67_GRENADE && pm->ps->weapon <= WP_M15_GRENADE && pm->ps->clip[ATTACK_NORMAL][pm->ps->weapon] <= 0 ) if( pm->ps->weapon >= WP_M84_GRENADE && pm->ps->weapon <= WP_M15_GRENADE && pm->ps->clip[ATTACK_NORMAL][pm->ps->weapon] <= 0 )
{ {
// We don't want to play the 'putaway' anim for the grenades if we are out of grenades! // We don't want to play the 'putaway' anim for the grenades if we are out of grenades!
return; return;
@ -2291,7 +2375,7 @@ static void PM_FinishWeaponChange( void )
} }
// We don't want to play the 'takeout' anim for the grenades if we are about to reload anyway // We don't want to play the 'takeout' anim for the grenades if we are about to reload anyway
if( pm->ps->weapon >= WP_M67_GRENADE && pm->ps->weapon <= WP_M15_GRENADE && pm->ps->clip[ATTACK_NORMAL][pm->ps->weapon] <=0 ) if( pm->ps->weapon >= WP_M84_GRENADE && pm->ps->weapon <= WP_M15_GRENADE && pm->ps->clip[ATTACK_NORMAL][pm->ps->weapon] <=0 )
{ {
return; return;
} }
@ -2387,6 +2471,7 @@ PM_EndRefillClip
void PM_EndRefillClip(void) void PM_EndRefillClip(void)
{ {
pm->ps->weaponstate=WEAPON_READY; pm->ps->weaponstate=WEAPON_READY;
pm->ps->weaponFireBurstCount = 0;
} }
/* /*
@ -2742,6 +2827,12 @@ static void PM_Weapon( void )
// Get modifed attack buttons. // Get modifed attack buttons.
attackButtons = PM_GetAttackButtons(); attackButtons = PM_GetAttackButtons();
// Gun goes away when using something
if ( pm->ps->stats[STAT_USEWEAPONDROP] )
{
return;
}
// don't allow attack until all buttons are up // don't allow attack until all buttons are up
if ( pm->ps->pm_flags & PMF_RESPAWNED ) if ( pm->ps->pm_flags & PMF_RESPAWNED )
{ {
@ -2873,11 +2964,7 @@ static void PM_Weapon( void )
{ {
switch(pm->ps->weapon) switch(pm->ps->weapon)
{ {
case WP_M67_GRENADE:
case WP_M84_GRENADE: case WP_M84_GRENADE:
case WP_F1_GRENADE:
case WP_L2A2_GRENADE:
case WP_MDN11_GRENADE:
case WP_SMOHG92_GRENADE: case WP_SMOHG92_GRENADE:
case WP_ANM14_GRENADE: case WP_ANM14_GRENADE:
case WP_M15_GRENADE: case WP_M15_GRENADE:
@ -2994,7 +3081,7 @@ static void PM_Weapon( void )
default: default:
PM_EndRefillClip(); PM_EndRefillClip();
break; return;
} }
} }
else if(pm->ps->pm_flags & PMF_ZOOM_DEFER_RELOAD ) else if(pm->ps->pm_flags & PMF_ZOOM_DEFER_RELOAD )
@ -3203,11 +3290,7 @@ static void PM_Weapon( void )
break; break;
case WP_M67_GRENADE:
case WP_M84_GRENADE: case WP_M84_GRENADE:
case WP_F1_GRENADE:
case WP_L2A2_GRENADE:
case WP_MDN11_GRENADE:
case WP_SMOHG92_GRENADE: case WP_SMOHG92_GRENADE:
case WP_ANM14_GRENADE: case WP_ANM14_GRENADE:
case WP_M15_GRENADE: case WP_M15_GRENADE:
@ -3551,8 +3634,11 @@ void PmoveSingle (pmove_t *pmove) {
} }
} }
// Cant run when zoomed // Cant run when zoomed, leaning, or using something that takes time
if ( (pm->ps->pm_flags&PMF_ZOOMED) || pm->ps->weaponstate == WEAPON_ZOOMIN || (pm->cmd.buttons & (BUTTON_LEAN_LEFT|BUTTON_LEAN_RIGHT)) ) if ( (pm->ps->pm_flags&PMF_ZOOMED) ||
(pm->ps->weaponstate == WEAPON_ZOOMIN) ||
(pm->cmd.buttons & (BUTTON_LEAN_LEFT|BUTTON_LEAN_RIGHT)) ||
(pm->ps->stats[STAT_USEWEAPONDROP]) )
{ {
if ( pm->cmd.forwardmove > 64 ) if ( pm->cmd.forwardmove > 64 )
{ {
@ -3758,6 +3844,9 @@ void PmoveSingle (pmove_t *pmove) {
// weapons // weapons
PM_Weapon(); PM_Weapon();
// Use
PM_Use ( );
// torso animation // torso animation
PM_TorsoAnimation( pm->ps ); PM_TorsoAnimation( pm->ps );
@ -3890,11 +3979,18 @@ int BG_FindLadder ( vec3_t pos )
float dist2 = DistanceSquared( pos, pm_ladders[ladder].origin ); float dist2 = DistanceSquared( pos, pm_ladders[ladder].origin );
if ( dist2 < dist ) if ( dist2 < dist )
{
vec3_t diff;
VectorSubtract ( pm_ladders[ladder].origin, pos, diff );
diff[2] = 0;
if ( VectorLengthSquared ( diff ) < 500 * 500 )
{ {
dist = dist2; dist = dist2;
result = ladder; result = ladder;
} }
} }
}
return result; return result;
} }

View file

@ -12,34 +12,10 @@
#include "../../ui/menudef.h" #include "../../ui/menudef.h"
#include "inv.h" #include "inv.h"
//#define GAME_VERSION "sof2mp-0.01" sent on 11/26/2001
//#define GAME_VERSION "sof2mp-0.02" sent on 12/10/2001
//#define GAME_VERSION "sof2mp-0.03" sent on 12/16/2001
//#define GAME_VERSION "sof2mp-0.081" sent on 1/15/2002
//#define GAME_VERSION "sof2mp-0.09" sent on 1/24/2002
//#define GAME_VERSION "sof2mp-0.10" sent on 1/31/2002
//#define GAME_VERSION "sof2mp-0.11" sent on 2/7/2002
//#define GAME_VERSION "sof2mp-0.12" sent on 2/14/2002
//#define GAME_VERSION "sof2mp-0.13" sent on 2/21/2002
//#define GAME_VERSION "sof2mp-0.13b" public beta #1 on 3/1/3002
//#define GAME_VERSION "sof2mp-0.14" sent on 3/4/2002
//#define GAME_VERSION "sof2mp-0.15" sent on 3/11/2002
//#define GAME_VERSION "sof2mp-0.15b" public beta #2 on 3/13/2002
//#define GAME_VERSION "sof2mp-0.16" sent on 3/18/2002
//#define GAME_VERSION "sof2mp-0.16b" public beta #3 on 3/20/2002
//#define GAME_VERSION "sof2mp-0.17" sent on 3/24/2002
//#define GAME_VERSION "sof2mp-1.01t" sent on 3/28/2002
//#define GAME_VERSION "sof2mp-0.18" sent on 4/1/2002 - April Fools!
//#define GAME_VERSION "sof2mp-1.02t" sent on 4/5/2002
//#define GAME_VERSION "sof2mp-0.19" sent on 4/8/2002
//#define GAME_VERSION "sof2mp-0.20" sent on 4/15/2002 - Tax Day!
//#define GAME_VERSION "sof2mp-0.21" sent on 4/22/2002
//#define GAME_VERSION "sof2mp-1.00.22" sent on 4/26/2002
//#define GAME_VERSION "sof2mp-1.00.23" sent on 4/27/2002
#ifdef GERMAN_BUILD #ifdef GERMAN_BUILD
#define GAME_VERSION "sof2mp-1.00g" #define GAME_VERSION "sof2mp-mod-1.01g"
#else #else
#define GAME_VERSION "sof2mp-1.00" #define GAME_VERSION "sof2mp-mod-1.01"
#endif #endif
#define DEFAULT_GRAVITY 800 #define DEFAULT_GRAVITY 800
@ -60,7 +36,7 @@
#define SCORE_NOT_PRESENT -9999 // for the CS_SCORES[12] when only one player is present #define SCORE_NOT_PRESENT -9999 // for the CS_SCORES[12] when only one player is present
#define DEFAULT_PLAYER_Z_MAX 43 #define DEFAULT_PLAYER_Z_MAX 43
#define CROUCH_PLAYER_Z_MAX 18 #define CROUCH_PLAYER_Z_MAX 26
#define PRONE_PLAYER_Z_MAX -12 #define PRONE_PLAYER_Z_MAX -12
#define DEAD_PLAYER_Z_MAX -30 #define DEAD_PLAYER_Z_MAX -30
@ -136,7 +112,9 @@ enum
CS_TEAM_INFO = CS_ICONS + MAX_ICONS, CS_TEAM_INFO = CS_ICONS + MAX_ICONS,
CS_AMBIENT_SOUNDSETS = CS_TEAM_INFO + TEAM_NUM_TEAMS, CS_AMBIENT_SOUNDSETS = CS_TEAM_INFO + TEAM_NUM_TEAMS,
CS_MAX = CS_AMBIENT_SOUNDSETS + MAX_AMBIENT_SOUNDSETS CS_HUDICONS = CS_AMBIENT_SOUNDSETS + MAX_AMBIENT_SOUNDSETS,
CS_MAX = CS_HUDICONS + MAX_HUDICONS,
}; };
/* /*
@ -318,6 +296,8 @@ typedef enum
TORSO_RELOAD_MM1_SHELL, TORSO_RELOAD_MM1_SHELL,
TORSO_RELOAD_MM1_END, TORSO_RELOAD_MM1_END,
TORSO_USE,
MAX_ANIMATIONS MAX_ANIMATIONS
} animNumber_t; } animNumber_t;
@ -499,6 +479,10 @@ typedef enum
STAT_GAMETYPE_ITEMS, // Which gametype items they have STAT_GAMETYPE_ITEMS, // Which gametype items they have
STAT_SEED, // seed used to keep weapon firing in sync STAT_SEED, // seed used to keep weapon firing in sync
STAT_OUTFIT_GRENADE, // indicates which greande is chosen in the outfitting STAT_OUTFIT_GRENADE, // indicates which greande is chosen in the outfitting
STAT_USEICON, // icon to display when able to use a trigger or item
STAT_USETIME, // elased time for using
STAT_USETIME_MAX, // total time required to use
STAT_USEWEAPONDROP, // value to drop weapon out of view when using
} statIndex_t; } statIndex_t;
@ -669,6 +653,13 @@ typedef enum
} entity_event_t; // There is a maximum of 256 events (8 bits transmission, 2 high bits for uniqueness) } entity_event_t; // There is a maximum of 256 events (8 bits transmission, 2 high bits for uniqueness)
typedef enum
{
VEV_TALKSTART,
VEV_TALKSTOP,
} voice_event_t;
typedef enum typedef enum
{ {
GAME_OVER_TIMELIMIT, GAME_OVER_TIMELIMIT,
@ -791,6 +782,10 @@ typedef enum
ET_DEBUG_CYLINDER, ET_DEBUG_CYLINDER,
ET_GAMETYPE_TRIGGER,
ET_WALL,
ET_EVENTS // any of the EV_* events can be added freestanding ET_EVENTS // any of the EV_* events can be added freestanding
// by setting eType to ET_EVENTS + eventNum // by setting eType to ET_EVENTS + eventNum
// this avoids having to set eFlags and eventNum // this avoids having to set eFlags and eventNum
@ -943,6 +938,7 @@ typedef struct gametypeData_s
const char* displayName; const char* displayName;
const char* script; const char* script;
const char* description; const char* description;
const char* basegametype;
respawnType_t respawnType; respawnType_t respawnType;
qboolean pickupsDisabled; qboolean pickupsDisabled;

View file

@ -17,6 +17,7 @@ char *bg_weaponNames[WP_NUM_WEAPONS] =
"M590", // WP_M590_SHOTGUN, "M590", // WP_M590_SHOTGUN,
"Micro Uzi", // WP_MICRO_UZI_SUBMACHINEGUN, "Micro Uzi", // WP_MICRO_UZI_SUBMACHINEGUN,
"M3A1", // WP_M3A1_SUBMACHINEGUN, "M3A1", // WP_M3A1_SUBMACHINEGUN,
"MP5", // WP_MP5
"USAS-12", // WP_USAS_12_SHOTGUN, "USAS-12", // WP_USAS_12_SHOTGUN,
"M4", // WP_M4_ASSAULT_RIFLE, "M4", // WP_M4_ASSAULT_RIFLE,
"AK74", // WP_AK74_ASSAULT_RIFLE, "AK74", // WP_AK74_ASSAULT_RIFLE,
@ -24,14 +25,10 @@ char *bg_weaponNames[WP_NUM_WEAPONS] =
"M60", // WP_M60_MACHINEGUN, "M60", // WP_M60_MACHINEGUN,
"MM1", // WP_MM1_GRENADE_LAUNCHER, "MM1", // WP_MM1_GRENADE_LAUNCHER,
"RPG7", // WP_RPG7_LAUNCHER, "RPG7", // WP_RPG7_LAUNCHER,
"M67", // WP_M67_GRENADE,
"M84", // WP_M84_GRENADE, "M84", // WP_M84_GRENADE,
"F1", // WP_F1_GRENADE,
"L2A2", // WP_L2A2_GRENADE,
"MDN11", // WP_MDN11_GRENADE,
"SMOHG92", // WP_SMOHG92_GRENADE, "SMOHG92", // WP_SMOHG92_GRENADE,
"ANM14", // WP_ANM14_GRENADE, "ANM14", // WP_ANM14_GRENADE,
"M15" // WP_M15_GRENADE, "M15", // WP_M15_GRENADE,
}; };
weaponData_t weaponData[WP_NUM_WEAPONS]; weaponData_t weaponData[WP_NUM_WEAPONS];
@ -47,17 +44,33 @@ char *ammoNames[AMMO_MAX] =
"40mm grenade", // AMMO_40, "40mm grenade", // AMMO_40,
"RPG7", // AMMO_RPG7 "RPG7", // AMMO_RPG7
"M15", // AMMO_M15, "M15", // AMMO_M15,
"M67", // AMMO_M67,
"M84", // AMMO_M84, "M84", // AMMO_M84,
"F1", // AMMO_F1,
"L2A2", // AMMO_L2A2,
"MDN11", // AMMO_MDN11,
"SMOHG92", // AMMO_SMOHG92, "SMOHG92", // AMMO_SMOHG92,
"ANM14" // AMMO_ANM14, "ANM14", // AMMO_ANM14,
"7.62mm belt", // AMMO_762_BELT,
"9mm|mp5", // AMMO_9_MP5
}; };
ammoData_t ammoData[AMMO_MAX]; ammoData_t ammoData[AMMO_MAX];
static const char* BG_GetRealAmmoName ( ammo_t ammoNum )
{
static char name[64] = "";
char* or;
or = strchr ( ammoNames[ammoNum], '|' );
if ( or )
{
Q_strncpyz ( name, ammoNames[ammoNum], or - ammoNames[ammoNum] + 1);
}
else
{
strcpy ( name, ammoNames[ammoNum] );
}
return name;
}
static qboolean BG_ParseAmmoStats(ammo_t ammoNum, void *group) static qboolean BG_ParseAmmoStats(ammo_t ammoNum, void *group)
{ {
char tmpStr[256]; char tmpStr[256];
@ -66,7 +79,7 @@ static qboolean BG_ParseAmmoStats(ammo_t ammoNum, void *group)
ammo = &ammoData[ammoNum]; ammo = &ammoData[ammoNum];
memset(ammo, 0, sizeof(ammoData_t)); memset(ammo, 0, sizeof(ammoData_t));
ammo->name = (char*)trap_VM_LocalStringAlloc ( ammoNames[ammoNum] ); ammo->name = (char*)trap_VM_LocalStringAlloc ( BG_GetRealAmmoName ( ammoNum ) );
Q_strlwr ( ammo->name ); Q_strlwr ( ammo->name );
// Get the scale of the gore for this bullet // Get the scale of the gore for this bullet
@ -80,8 +93,7 @@ static qboolean BG_ParseAmmoStats(ammo_t ammoNum, void *group)
qboolean BG_InitAmmoStats(void) qboolean BG_InitAmmoStats(void)
{ {
void *GP2, *topGroup, *topSubs; void *GP2, *topGroup;
char name[256];
int i; int i;
ammoData[AMMO_NONE].goreScale = 0.0f; ammoData[AMMO_NONE].goreScale = 0.0f;
@ -94,38 +106,45 @@ qboolean BG_InitAmmoStats(void)
} }
topGroup = trap_GP_GetBaseParseGroup(GP2); topGroup = trap_GP_GetBaseParseGroup(GP2);
for ( i = 0; i < AMMO_MAX; i ++ )
{
void* topSubs;
const char* realName;
realName = BG_GetRealAmmoName ( i );
topSubs = trap_GPG_GetSubGroups(topGroup); topSubs = trap_GPG_GetSubGroups(topGroup);
while(topSubs) while(topSubs)
{ {
char name[256];
trap_GPG_GetName(topSubs, name); trap_GPG_GetName(topSubs, name);
if (Q_stricmp(name, "ammo") == 0) if (Q_stricmp(name, "ammo") != 0)
{ {
trap_GPG_FindPairValue(topSubs, "name", "", name); continue;
for(i=0;i<AMMO_MAX;i++)
{
if (Q_stricmp(ammoNames[i], name) == 0)
{
BG_ParseAmmoStats(i, topSubs);
break;
}
} }
#ifdef _DEBUG trap_GPG_FindPairValue(topSubs, "name", "", name);
if (i == AMMO_MAX) if ( !Q_stricmp ( name, realName ) )
{ {
Com_Printf("BG_InitAmmoStats: Unknown ammo: %s\n", name); BG_ParseAmmoStats(i, topSubs );
} break;
#endif
} }
topSubs = trap_GPG_GetNext(topSubs); topSubs = trap_GPG_GetNext(topSubs);
} }
if ( !topSubs )
{
Com_Printf("BG_InitAmmoStats: Unknown ammo: %s\n", BG_GetRealAmmoName ( i ) );
}
}
trap_GP_Delete(&GP2); trap_GP_Delete(&GP2);
return qtrue; return qtrue;
} }
static qboolean BG_ParseAttackStats ( int weaponNum, attackData_t* attack, void *attacksub ) static qboolean BG_ParseAttackStats ( int weaponNum, attackData_t* attack, void *attacksub, qboolean pickupsDisabled )
{ {
void* sub; void* sub;
char tmpStr[256]; char tmpStr[256];
@ -148,7 +167,19 @@ static qboolean BG_ParseAttackStats ( int weaponNum, attackData_t* attack, void
trap_GPG_FindPairValue(attacksub, "name", "NONE", attack->name); trap_GPG_FindPairValue(attacksub, "name", "NONE", attack->name);
trap_GPG_FindPairValue(attacksub, "hudIcon", "NONE", attack->icon); trap_GPG_FindPairValue(attacksub, "hudIcon", "NONE", attack->icon);
if ( pickupsDisabled )
{
trap_GPG_FindPairValue(attacksub, "mp_ammoType_outfitting", "", tmpStr);
if ( !tmpStr[0] )
{
trap_GPG_FindPairValue(attacksub, "mp_ammoType||ammoType", "none", tmpStr); trap_GPG_FindPairValue(attacksub, "mp_ammoType||ammoType", "none", tmpStr);
}
}
else
{
trap_GPG_FindPairValue(attacksub, "mp_ammoType||ammoType", "none", tmpStr);
}
attack->ammoIndex = AMMO_NONE; attack->ammoIndex = AMMO_NONE;
for (i = 0; i < AMMO_MAX; i++) for (i = 0; i < AMMO_MAX; i++)
{ {
@ -306,7 +337,7 @@ static qboolean BG_ParseAttackStats ( int weaponNum, attackData_t* attack, void
return qtrue; return qtrue;
} }
static qboolean BG_ParseWeaponStats(weapon_t weaponNum, void *group) static qboolean BG_ParseWeaponStats(weapon_t weaponNum, void *group, qboolean pickupsDisabled )
{ {
char tmpStr[256]; char tmpStr[256];
weaponData_t *weapon; weaponData_t *weapon;
@ -342,15 +373,15 @@ static qboolean BG_ParseWeaponStats(weapon_t weaponNum, void *group)
weapon->animReloadEnd = GetIDForString ( bg_animTable, tmpStr ); weapon->animReloadEnd = GetIDForString ( bg_animTable, tmpStr );
// primary attack // primary attack
BG_ParseAttackStats ( weaponNum, &weapon->attack[ATTACK_NORMAL], trap_GPG_FindSubGroup(group, "attack") ); BG_ParseAttackStats ( weaponNum, &weapon->attack[ATTACK_NORMAL], trap_GPG_FindSubGroup(group, "attack"), pickupsDisabled );
// alternate attack // alternate attack
BG_ParseAttackStats ( weaponNum, &weapon->attack[ATTACK_ALTERNATE], trap_GPG_FindSubGroup(group, "altattack") ); BG_ParseAttackStats ( weaponNum, &weapon->attack[ATTACK_ALTERNATE], trap_GPG_FindSubGroup(group, "altattack"), pickupsDisabled );
return qtrue; return qtrue;
} }
qboolean BG_InitWeaponStats(void) qboolean BG_InitWeaponStats( qboolean pickupsDisabled )
{ {
void *GP2, *topGroup, *topSubs; void *GP2, *topGroup, *topSubs;
char name[256]; char name[256];
@ -374,7 +405,7 @@ qboolean BG_InitWeaponStats(void)
{ {
if (Q_stricmp(bg_weaponNames[i], name) == 0) if (Q_stricmp(bg_weaponNames[i], name) == 0)
{ {
BG_ParseWeaponStats(i, topSubs); BG_ParseWeaponStats(i, topSubs, pickupsDisabled );
break; break;
} }
} }
@ -924,7 +955,7 @@ static qboolean BG_ParseWeapon(weapon_t weapon, void *group)
return qtrue; return qtrue;
} }
qboolean BG_ParseInviewFile(void) qboolean BG_ParseInviewFile( qboolean pickupsDisabled )
{ {
void *GP2, *topGroup, *topSubs, *group; void *GP2, *topGroup, *topSubs, *group;
char name[256], temp[256]; char name[256], temp[256];
@ -998,7 +1029,7 @@ qboolean BG_ParseInviewFile(void)
BG_InitAmmoStats(); BG_InitAmmoStats();
return BG_InitWeaponStats(); return BG_InitWeaponStats( pickupsDisabled );
} }
TAnimWeapon *BG_GetInviewAnim(int weaponIdx,const char *animKey,int *animIndex) TAnimWeapon *BG_GetInviewAnim(int weaponIdx,const char *animKey,int *animIndex)

View file

@ -21,6 +21,7 @@ typedef enum
MOD_M590_SHOTGUN, MOD_M590_SHOTGUN,
MOD_MICRO_UZI_SUBMACHINEGUN, MOD_MICRO_UZI_SUBMACHINEGUN,
MOD_M3A1_SUBMACHINEGUN, MOD_M3A1_SUBMACHINEGUN,
MOD_MP5,
// Primaries // Primaries
MOD_USAS_12_SHOTGUN, MOD_USAS_12_SHOTGUN,
@ -32,11 +33,7 @@ typedef enum
MOD_RPG7_LAUNCHER, MOD_RPG7_LAUNCHER,
// Grenades // Grenades
MOD_M67_GRENADE,
MOD_M84_GRENADE, MOD_M84_GRENADE,
MOD_F1_GRENADE,
MOD_L2A2_GRENADE,
MOD_MDN11_GRENADE,
MOD_SMOHG92_GRENADE, MOD_SMOHG92_GRENADE,
MOD_ANM14_GRENADE, MOD_ANM14_GRENADE,
MOD_M15_GRENADE, MOD_M15_GRENADE,
@ -48,7 +45,8 @@ typedef enum
MOD_SUICIDE, MOD_SUICIDE,
MOD_TEAMCHANGE, MOD_TEAMCHANGE,
MOD_TARGET_LASER, MOD_TARGET_LASER,
MOD_TRIGGER_HURT MOD_TRIGGER_HURT,
MOD_TRIGGER_HURT_NOSUICIDE
} meansOfDeath_t; } meansOfDeath_t;
@ -67,6 +65,7 @@ typedef enum
WP_M590_SHOTGUN, WP_M590_SHOTGUN,
WP_MICRO_UZI_SUBMACHINEGUN, WP_MICRO_UZI_SUBMACHINEGUN,
WP_M3A1_SUBMACHINEGUN, WP_M3A1_SUBMACHINEGUN,
WP_MP5,
// Primaries // Primaries
WP_USAS_12_SHOTGUN, WP_USAS_12_SHOTGUN,
@ -78,11 +77,7 @@ typedef enum
WP_RPG7_LAUNCHER, WP_RPG7_LAUNCHER,
// Grenades // Grenades
WP_M67_GRENADE,
WP_M84_GRENADE, WP_M84_GRENADE,
WP_F1_GRENADE,
WP_L2A2_GRENADE,
WP_MDN11_GRENADE,
WP_SMOHG92_GRENADE, WP_SMOHG92_GRENADE,
WP_ANM14_GRENADE, WP_ANM14_GRENADE,
WP_M15_GRENADE, WP_M15_GRENADE,
@ -97,20 +92,20 @@ typedef enum
AMMO_KNIFE, AMMO_KNIFE,
AMMO_045, AMMO_045,
AMMO_556, AMMO_556,
AMMO_9 , AMMO_9,
AMMO_12 , AMMO_12 ,
AMMO_762, AMMO_762,
AMMO_40, AMMO_40,
AMMO_RPG7, AMMO_RPG7,
AMMO_M15, AMMO_M15,
AMMO_M67,
AMMO_M84, AMMO_M84,
AMMO_F1,
AMMO_L2A2,
AMMO_MDN11,
AMMO_SMOHG92, AMMO_SMOHG92,
AMMO_ANM14, AMMO_ANM14,
AMMO_762_BELT,
AMMO_MP5_9,
AMMO_MAX, AMMO_MAX,
AMMO_NONE, AMMO_NONE,
@ -355,7 +350,7 @@ extern TWeaponParseInfo weaponParseInfo[WP_NUM_WEAPONS];
extern char weaponLeftHand[MAX_QPATH]; extern char weaponLeftHand[MAX_QPATH];
extern char weaponRightHand[MAX_QPATH]; extern char weaponRightHand[MAX_QPATH];
qboolean BG_ParseInviewFile ( void); qboolean BG_ParseInviewFile ( qboolean );
TAnimWeapon* BG_GetInviewAnim ( int weaponIdx,const char *animKey,int *animIndex); TAnimWeapon* BG_GetInviewAnim ( int weaponIdx,const char *animKey,int *animIndex);
TAnimWeapon* BG_GetInviewAnimFromIndex ( int weaponIdx,int animIndex); TAnimWeapon* BG_GetInviewAnimFromIndex ( int weaponIdx,int animIndex);
TAnimInfoWeapon* BG_GetInviewModelAnim ( int weaponIdx,const char *modelKey,const char *animKey); TAnimInfoWeapon* BG_GetInviewModelAnim ( int weaponIdx,const char *modelKey,const char *animKey);

View file

@ -4,6 +4,7 @@
#include "g_local.h" #include "g_local.h"
void P_SetTwitchInfo(gclient_t *client) void P_SetTwitchInfo(gclient_t *client)
{ {
client->ps.painTime = level.time; client->ps.painTime = level.time;
@ -155,7 +156,7 @@ G_SetClientSound
*/ */
void G_SetClientSound( gentity_t *ent ) void G_SetClientSound( gentity_t *ent )
{ {
ent->client->ps.loopSound = 0; // ent->client->ps.loopSound = 0;
} }
/* /*
@ -286,6 +287,8 @@ void G_TouchTriggers( gentity_t *ent )
// Reset the players can use flag // Reset the players can use flag
ent->client->ps.pm_flags &= ~(PMF_CAN_USE); ent->client->ps.pm_flags &= ~(PMF_CAN_USE);
ent->client->useEntity = 0;
ent->client->ps.loopSound = 0;
ent->s.modelindex = 0; ent->s.modelindex = 0;
for ( i=0 ; i<num ; i++ ) for ( i=0 ; i<num ; i++ )
@ -311,6 +314,45 @@ void G_TouchTriggers( gentity_t *ent )
continue; continue;
} }
// Look for usable gametype triggers and you cant use when zoomed
if ( !(ent->client->ps.pm_flags & PMF_ZOOMED ) )
{
switch ( hit->s.eType )
{
case ET_GAMETYPE_TRIGGER:
if ( hit->use && trap_GT_SendEvent ( GTEV_TRIGGER_CANBEUSED, level.time, hit->health, ent->s.number, ent->client->sess.team, 0, 0 ) )
{
ent->client->ps.pm_flags |= PMF_CAN_USE;
ent->client->ps.stats[STAT_USEICON] = hit->delay;
ent->client->ps.stats[STAT_USETIME_MAX] = hit->soundPos1;
if ( ent->client->ps.stats[STAT_USETIME] )
{
ent->client->ps.loopSound = hit->soundLoop;
}
ent->client->useEntity = hit;
continue;
}
break;
case ET_ITEM:
if ( hit->item->giType == IT_GAMETYPE && trap_GT_SendEvent ( GTEV_ITEM_CANBEUSED, level.time, hit->item->quantity, ent->s.number, ent->client->sess.team, 0, 0 ) )
{
ent->client->ps.pm_flags |= PMF_CAN_USE;
ent->client->ps.stats[STAT_USEICON] = level.gametypeItems[hit->item->giTag].useIcon;
ent->client->ps.stats[STAT_USETIME_MAX] = level.gametypeItems[hit->item->giTag].useTime;
if ( ent->client->ps.stats[STAT_USETIME] )
{
ent->client->ps.loopSound = level.gametypeItems[hit->item->giTag].useSound;
}
ent->client->useEntity = hit;
continue;
}
break;
}
}
if ( !hit->touch && !ent->touch ) if ( !hit->touch && !ent->touch )
{ {
continue; continue;
@ -494,6 +536,7 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )
{ {
client->ps.pm_type = PM_SPECTATOR; client->ps.pm_type = PM_SPECTATOR;
client->ps.speed = 400; // faster than normal client->ps.speed = 400; // faster than normal
client->ps.loopSound = 0;
// set up for pmove // set up for pmove
memset (&pm, 0, sizeof(pm)); memset (&pm, 0, sizeof(pm));
@ -621,6 +664,10 @@ ClientIntermissionThink
*/ */
void ClientIntermissionThink( gclient_t *client ) void ClientIntermissionThink( gclient_t *client )
{ {
G_UpdatePlayerStateScores ( &g_entities[client->ps.clientNum] );
client->ps.loopSound = 0;
client->ps.eFlags &= ~EF_TALK; client->ps.eFlags &= ~EF_TALK;
client->ps.eFlags &= ~EF_FIRING; client->ps.eFlags &= ~EF_FIRING;
@ -646,48 +693,30 @@ use key pressed
*/ */
void G_Use ( gentity_t* ent ) void G_Use ( gentity_t* ent )
{ {
int i; if ( !ent->client->useEntity )
int num;
int touch[MAX_GENTITIES];
gentity_t *hit;
vec3_t mins;
vec3_t maxs;
static vec3_t range = { 20, 20, 40 };
if ( !ent->client )
{ {
return; return;
} }
// dead clients don't activate triggers! if ( ent->client->useEntity->s.eType == ET_ITEM )
if ( ent->client->ps.stats[STAT_HEALTH] <= 0 ) { {
// Make sure one last time that it can still be used
if ( !trap_GT_SendEvent ( GTEV_ITEM_CANBEUSED, level.time, ent->client->useEntity->item->quantity, ent->s.number, ent->client->sess.team, 0, 0 ) )
{
return; return;
} }
VectorSubtract( ent->client->ps.origin, range, mins ); gametype_item_use ( ent->client->useEntity, ent );
VectorAdd( ent->client->ps.origin, range, maxs ); return;
num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES );
// can't use ent->r.absmin, because that has a one unit pad
VectorAdd( ent->client->ps.origin, ent->r.mins, mins );
VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs );
for ( i=0 ; i<num ; i++ )
{
hit = &g_entities[touch[i]];
if ( !hit->use )
{
continue;
} }
// Misstion triggers can be used // Make double sure it can still be used
if ( !Q_stricmp ( hit->classname, "gametype_trigger" ) ) if ( !trap_GT_SendEvent ( GTEV_TRIGGER_CANBEUSED, level.time, ent->client->useEntity->health, ent->s.number, ent->client->sess.team, 0, 0 ) )
{ {
hit->use ( hit, ent, ent ); return;
}
} }
ent->client->useEntity->use ( ent->client->useEntity, ent, ent );
} }
/* /*
@ -976,6 +1005,7 @@ void ClientThink_real( gentity_t *ent )
pm.cmd = *ucmd; pm.cmd = *ucmd;
if ( pm.ps->pm_type == PM_DEAD ) if ( pm.ps->pm_type == PM_DEAD )
{ {
pm.ps->loopSound = 0;
pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
} }
else if ( client->siameseTwin ) else if ( client->siameseTwin )
@ -1136,6 +1166,9 @@ because they killed too many teammates
*/ */
void G_CheckClientTeamkill ( gentity_t* ent ) void G_CheckClientTeamkill ( gentity_t* ent )
{ {
char userinfo[MAX_INFO_STRING];
char *value;
if ( !g_teamkillDamageMax.integer || !level.gametypeData->teams || !ent->client->sess.teamkillDamage ) if ( !g_teamkillDamageMax.integer || !level.gametypeData->teams || !ent->client->sess.teamkillDamage )
{ {
return; return;
@ -1164,11 +1197,38 @@ void G_CheckClientTeamkill ( gentity_t* ent )
return; return;
} }
trap_GetUserinfo( ent->s.number, userinfo, sizeof( userinfo ) );
value = Info_ValueForKey (userinfo, "ip");
G_LogPrintf( "ClientKick: %i %s - auto kick for teamkilling\n", ent->s.number, value );
ent->client->sess.teamkillDamage = 0; ent->client->sess.teamkillDamage = 0;
ent->client->sess.teamkillForgiveTime = 0; ent->client->sess.teamkillForgiveTime = 0;
// Keep track of who was autokicked so we can display a list if need be
Com_sprintf ( level.autokickedIP[level.autokickedHead], sizeof(level.autokickedIP[0]), value );
Com_sprintf ( level.autokickedName[level.autokickedHead], sizeof(level.autokickedName[0]), ent->client->pers.netname );
level.autokickedCount++;
if ( level.autokickedCount >= MAX_AUTOKICKLIST )
{
level.autokickedCount = MAX_AUTOKICKLIST;
}
level.autokickedHead++;
if ( level.autokickedHead >= MAX_AUTOKICKLIST )
{
level.autokickedHead = 0;
}
// Buh bye // Buh bye
if ( g_teamkillBanTime.integer )
{
trap_SendConsoleCommand( EXEC_INSERT, va("banclient \"%d\" \"%d\" \"team killing\"\n", ent->s.number, g_teamkillBanTime.integer ) );
}
else
{
trap_SendConsoleCommand( EXEC_INSERT, va("clientkick \"%d\" \"team killing\"\n", ent->s.number ) ); trap_SendConsoleCommand( EXEC_INSERT, va("clientkick \"%d\" \"team killing\"\n", ent->s.number ) );
}
} }
/* /*
@ -1287,10 +1347,12 @@ void SpectatorClientEndFrame( gentity_t *ent )
{ {
int count; int count;
int ping; int ping;
int score;
int respawnTimer; int respawnTimer;
count = ent->client->ps.persistant[PERS_SPAWN_COUNT]; count = ent->client->ps.persistant[PERS_SPAWN_COUNT];
ping = ent->client->ps.ping; ping = ent->client->ps.ping;
score = ent->client->ps.persistant[PERS_SCORE];
flags = (cl->ps.eFlags & ~(EF_VOTED)) | (ent->client->ps.eFlags & (EF_VOTED)); flags = (cl->ps.eFlags & ~(EF_VOTED)) | (ent->client->ps.eFlags & (EF_VOTED));
respawnTimer = ent->client->ps.respawnTimer; respawnTimer = ent->client->ps.respawnTimer;
@ -1298,6 +1360,7 @@ void SpectatorClientEndFrame( gentity_t *ent )
ent->client->ps.pm_flags |= PMF_FOLLOW; ent->client->ps.pm_flags |= PMF_FOLLOW;
ent->client->ps.eFlags = flags; ent->client->ps.eFlags = flags;
ent->client->ps.persistant[PERS_SPAWN_COUNT] = count; ent->client->ps.persistant[PERS_SPAWN_COUNT] = count;
ent->client->ps.persistant[PERS_SCORE] = score;
ent->client->ps.ping = ping; ent->client->ps.ping = ping;
ent->client->ps.respawnTimer = respawnTimer; ent->client->ps.respawnTimer = respawnTimer;

View file

@ -235,10 +235,10 @@ void G_UndoAntiLag ( void )
if ( other->r.svFlags & SVF_DOUBLED_BBOX ) if ( other->r.svFlags & SVF_DOUBLED_BBOX )
{ {
// Put the hitbox back the way it was // Put the hitbox back the way it was
other->r.maxs[0] /= 2; other->r.maxs[0] = other->client->maxSave[0];
other->r.maxs[1] /= 2; other->r.maxs[1] = other->client->maxSave[1];
other->r.mins[0] /= 2; other->r.mins[0] = other->client->minSave[0];
other->r.mins[1] /= 2; other->r.mins[1] = other->client->minSave[1];
other->r.svFlags &= (~SVF_DOUBLED_BBOX); other->r.svFlags &= (~SVF_DOUBLED_BBOX);
} }
@ -304,12 +304,29 @@ void G_ApplyAntiLag ( gentity_t* ref, qboolean enlargeHitBox )
if ( enlargeHitBox ) if ( enlargeHitBox )
{ {
other->client->minSave[0] = other->r.mins[0];
other->client->minSave[1] = other->r.mins[1];
other->client->maxSave[0] = other->r.maxs[0];
other->client->maxSave[1] = other->r.maxs[1];
// Adjust the hit box to account for hands and such // Adjust the hit box to account for hands and such
// that are sticking out of the normal bounding box // that are sticking out of the normal bounding box
other->r.maxs[0] *= 2;
other->r.maxs[1] *= 2; if ( other->client->ps.pm_flags & PMF_LEANING )
other->r.mins[0] *= 2; {
other->r.mins[1] *= 2; other->r.maxs[0] *= 3.0f;
other->r.maxs[1] *= 3.0f;
other->r.mins[0] *= 3.0f;
other->r.mins[1] *= 3.0f;
}
else
{
other->r.maxs[0] *= 2.0f;
other->r.maxs[1] *= 2.0f;
other->r.mins[0] *= 2.0f;
other->r.mins[1] *= 2.0f;
}
other->r.svFlags |= SVF_DOUBLED_BBOX; other->r.svFlags |= SVF_DOUBLED_BBOX;
} }

View file

@ -736,6 +736,8 @@ void G_ClientCleanName ( const char *in, char *out, int outSize, qboolean colors
break; break;
} }
if ( *in != Q_COLOR_ESCAPE )
{
// don't allow black in a name, period // don't allow black in a name, period
if( !colors || ColorIndex(*in) == 0 ) if( !colors || ColorIndex(*in) == 0 )
{ {
@ -754,6 +756,14 @@ void G_ClientCleanName ( const char *in, char *out, int outSize, qboolean colors
len += 2; len += 2;
continue; continue;
} }
else
{
*out++ = ch;
*out++ = ch;
in++;
continue;
}
}
// don't allow too many consecutive spaces // don't allow too many consecutive spaces
if( ch == ' ' ) if( ch == ' ' )
@ -880,6 +890,11 @@ void G_UpdateOutfitting ( int clientNum )
} }
} }
// Disable zooming
client->ps.zoomFov = 0;
client->ps.zoomTime = 0;
client->ps.pm_flags &= ~(PMF_ZOOM_FLAGS);
client->ps.weapon = equipWeapon; client->ps.weapon = equipWeapon;
client->ps.weaponstate = WEAPON_READY; //WEAPON_SPAWNING; client->ps.weaponstate = WEAPON_READY; //WEAPON_SPAWNING;
client->ps.weaponTime = 0; client->ps.weaponTime = 0;
@ -923,6 +938,34 @@ void G_UpdateOutfitting ( int clientNum )
client->ps.stats[STAT_OUTFIT_GRENADE] = bg_itemlist[bg_outfittingGroups[OUTFITTING_GROUP_GRENADE][client->pers.outfitting.items[OUTFITTING_GROUP_GRENADE]]].giTag; client->ps.stats[STAT_OUTFIT_GRENADE] = bg_itemlist[bg_outfittingGroups[OUTFITTING_GROUP_GRENADE][client->pers.outfitting.items[OUTFITTING_GROUP_GRENADE]]].giTag;
} }
/*
===========
G_FindClientByName
Looks up a player by its case insensitive name
============
*/
gclient_t* G_FindClientByName ( const char* name, int ignoreNum )
{
int i;
for ( i = 0; i < level.numConnectedClients; i ++ )
{
gentity_t* ent = &g_entities[level.sortedClients[i]];
if ( level.sortedClients[i] == ignoreNum )
{
continue;
}
if ( Q_stricmp ( name, ent->client->pers.netname ) == 0 )
{
return ent->client;
}
}
return NULL;
}
/* /*
=========== ===========
@ -944,6 +987,8 @@ void ClientUserinfoChanged( int clientNum )
gclient_t *client; gclient_t *client;
char oldname[MAX_STRING_CHARS]; char oldname[MAX_STRING_CHARS];
char userinfo[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING];
char origname[MAX_NETNAME];
int namecount = 1;
TIdentity *oldidentity; TIdentity *oldidentity;
ent = g_entities + clientNum; ent = g_entities + clientNum;
@ -1004,6 +1049,14 @@ void ClientUserinfoChanged( int clientNum )
} }
} }
// See if we need to find a new name because the one they chose is taken
Q_strncpyz ( origname, client->pers.netname, MAX_NETNAME - 5 );
while ( G_FindClientByName ( client->pers.netname, clientNum ) )
{
Com_sprintf ( client->pers.netname, MAX_NETNAME, "%s(%d)", origname, namecount );
namecount++;
}
// set max health // set max health
health = atoi( Info_ValueForKey( userinfo, "handicap" ) ); health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
@ -1164,6 +1217,7 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot )
char *value; char *value;
gclient_t *client; gclient_t *client;
char userinfo[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING];
char ip[128];
gentity_t *ent; gentity_t *ent;
ent = &g_entities[ clientNum ]; ent = &g_entities[ clientNum ];
@ -1172,15 +1226,12 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot )
// check to see if they are on the banned IP list // check to see if they are on the banned IP list
value = Info_ValueForKey (userinfo, "ip"); value = Info_ValueForKey (userinfo, "ip");
if ( G_FilterPacket( value ) ) Com_sprintf ( ip, sizeof(ip), value );
{
return "Banned.";
}
// we don't check password for bots and local client // we don't check password for bots and local client
// NOTE: local client <-> "ip" "localhost" // NOTE: local client <-> "ip" "localhost"
// this means this client is not running in our current process // this means this client is not running in our current process
if ( !( isBot ) && (strcmp(value, "localhost") != 0)) if ( !( isBot ) && (strcmp(ip, "localhost") != 0))
{ {
// check for a password // check for a password
value = Info_ValueForKey (userinfo, "password"); value = Info_ValueForKey (userinfo, "password");
@ -1220,20 +1271,20 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot )
} }
// get and distribute relevent paramters // get and distribute relevent paramters
G_LogPrintf( "ClientConnect: %i\n", clientNum ); G_LogPrintf( "ClientConnect: %i - %s\n", clientNum, ip );
ClientUserinfoChanged( clientNum ); ClientUserinfoChanged( clientNum );
// don't do the "xxx connected" messages if they were caried over from previous level // don't do the "xxx connected" messages if they were caried over from previous level
if ( firstTime ) if ( firstTime )
{ {
trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " is connecting...\n\"", client->pers.netname) ); trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " is connecting...\n\"", client->pers.netname) );
}
// Broadcast team change if not going to spectator // Broadcast team change if not going to spectator
if ( level.gametypeData->teams && client->sess.team != TEAM_SPECTATOR ) if ( level.gametypeData->teams && client->sess.team != TEAM_SPECTATOR )
{ {
BroadcastTeamChange( client, -1 ); BroadcastTeamChange( client, -1 );
} }
}
// count current clients and rank for scoreboard // count current clients and rank for scoreboard
CalculateRanks(); CalculateRanks();
@ -1310,6 +1361,17 @@ void ClientBegin( int clientNum )
G_LogPrintf( "ClientBegin: %i\n", clientNum ); G_LogPrintf( "ClientBegin: %i\n", clientNum );
// See if we should spawn as a ghost
if ( client->sess.team != TEAM_SPECTATOR && level.gametypeData->respawnType == RT_NONE )
{
// If there are ghosts already then spawn as a ghost because
// the game is already in progress.
if ( (level.gametypeJoinTime && (level.time - level.gametypeJoinTime) > (g_roundjointime.integer * 1000)) )
{
G_StartGhosting ( ent );
}
}
// count current clients and rank for scoreboard // count current clients and rank for scoreboard
CalculateRanks(); CalculateRanks();
} }

View file

@ -261,6 +261,36 @@ void Cmd_Drop_f ( gentity_t* ent )
} }
} }
/*
==================
Cmd_DropItem_f
Drops the gametype items the player is carrying
==================
*/
void Cmd_DropItem_f ( gentity_t* ent )
{
// spectators cant drop anything since they dont have anything
if ( ent->client->sess.team == TEAM_SPECTATOR )
{
return;
}
// Ghosts and followers cant drop stuff
if ( ent->client->ps.pm_flags & (PMF_GHOST|PMF_FOLLOW) )
{
return;
}
// Nothing to drop
if ( !ent->client->ps.stats[STAT_GAMETYPE_ITEMS] )
{
return;
}
G_DropGametypeItems ( ent );
}
/* /*
================== ==================
Cmd_Give_f Cmd_Give_f
@ -737,7 +767,7 @@ void SetTeam( gentity_t *ent, char *s, const char* identity )
{ {
// If there are ghosts already then spawn as a ghost because // If there are ghosts already then spawn as a ghost because
// the game is already in progress. // the game is already in progress.
if ( (level.gametypeJoinTime && (level.time - level.gametypeJoinTime) > 20000) || noOutfittingChange || client->sess.noTeamChange ) if ( (level.gametypeJoinTime && (level.time - level.gametypeJoinTime) > (g_roundjointime.integer * 1000)) || noOutfittingChange || client->sess.noTeamChange )
{ {
ghost = qtrue; ghost = qtrue;
} }
@ -868,6 +898,7 @@ void G_StopFollowing( gentity_t *ent )
ent->client->sess.spectatorState = SPECTATOR_FREE; ent->client->sess.spectatorState = SPECTATOR_FREE;
ent->client->ps.clientNum = ent - g_entities; ent->client->ps.clientNum = ent - g_entities;
ent->client->ps.zoomFov = 0; ent->client->ps.zoomFov = 0;
ent->client->ps.loopSound = 0;
ent->client->ps.pm_flags &= ~(PMF_GOGGLES_ON|PMF_ZOOM_FLAGS); ent->client->ps.pm_flags &= ~(PMF_GOGGLES_ON|PMF_ZOOM_FLAGS);
ent->client->ps.persistant[PERS_TEAM] = ent->client->sess.team; ent->client->ps.persistant[PERS_TEAM] = ent->client->sess.team;
ent->r.svFlags &= ~SVF_BOT; ent->r.svFlags &= ~SVF_BOT;
@ -1005,6 +1036,16 @@ void Cmd_Follow_f( gentity_t *ent )
return; return;
} }
// Dissallow following of the enemy if the cvar is set
if ( level.gametypeData->teams && !g_followEnemy.integer && ent->client->sess.team != TEAM_SPECTATOR )
{
// Are they on the same team?
if ( level.clients[ i ].sess.team != ent->client->sess.team )
{
return;
}
}
// first set them to spectator as long as they arent a ghost // first set them to spectator as long as they arent a ghost
if ( !ent->client->sess.ghost && ent->client->sess.team != TEAM_SPECTATOR ) if ( !ent->client->sess.ghost && ent->client->sess.team != TEAM_SPECTATOR )
{ {
@ -1295,7 +1336,7 @@ void G_Say ( gentity_t *ent, gentity_t *target, int mode, const char *chatText )
int j; int j;
gentity_t *other; gentity_t *other;
char text[MAX_SAY_TEXT]; char text[MAX_SAY_TEXT];
char name[64]; char name[256];
// Logging stuff // Logging stuff
switch ( mode ) switch ( mode )
@ -1655,6 +1696,7 @@ void Cmd_CallVote_f( gentity_t *ent )
} else if ( !Q_stricmp( arg1, "kick" ) ) { } else if ( !Q_stricmp( arg1, "kick" ) ) {
} else if ( !Q_stricmp( arg1, "clientkick" ) ) { } else if ( !Q_stricmp( arg1, "clientkick" ) ) {
} else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) { } else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) {
} else if ( !Q_stricmp( arg1, "g_friendlyfire" ) ) {
} else if ( !Q_stricmp( arg1, "timelimit" ) ) { } else if ( !Q_stricmp( arg1, "timelimit" ) ) {
} else if ( !Q_stricmp( arg1, "timeextension" ) ) { } else if ( !Q_stricmp( arg1, "timeextension" ) ) {
} else if ( !Q_stricmp( arg1, "scorelimit" ) ) { } else if ( !Q_stricmp( arg1, "scorelimit" ) ) {
@ -1713,7 +1755,7 @@ void Cmd_CallVote_f( gentity_t *ent )
{ {
if (!*g_mapcycle.string || !Q_stricmp ( g_mapcycle.string, "none" ) ) if (!*g_mapcycle.string || !Q_stricmp ( g_mapcycle.string, "none" ) )
{ {
trap_SendServerCommand( ent-g_entities, "print \"there is no map cycle ccurently set up.\n\"" ); trap_SendServerCommand( ent-g_entities, "print \"there is no map cycle currently set up.\n\"" );
return; return;
} }
@ -1736,7 +1778,15 @@ void Cmd_CallVote_f( gentity_t *ent )
return; return;
} }
Com_sprintf ( level.voteString, sizeof(level.voteString ), "%s %s", arg1, arg2 ); if ( g_voteKickBanTime.integer )
{
Com_sprintf ( level.voteString, sizeof(level.voteString ), "banclient %s %d voted off server", arg2, g_voteKickBanTime.integer );
}
else
{
Com_sprintf ( level.voteString, sizeof(level.voteString ), "clientkick %s", arg2 );
}
Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[n].client->pers.netname ); Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[n].client->pers.netname );
} }
else if ( !Q_stricmp ( arg1, "kick" ) ) else if ( !Q_stricmp ( arg1, "kick" ) )
@ -1749,7 +1799,15 @@ void Cmd_CallVote_f( gentity_t *ent )
return; return;
} }
if ( g_voteKickBanTime.integer )
{
Com_sprintf ( level.voteString, sizeof(level.voteString ), "banclient %d %d voted off server", clientid, g_voteKickBanTime.integer );
}
else
{
Com_sprintf ( level.voteString, sizeof(level.voteString ), "clientkick %d", clientid ); Com_sprintf ( level.voteString, sizeof(level.voteString ), "clientkick %d", clientid );
}
Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[clientid].client->pers.netname ); Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[clientid].client->pers.netname );
} }
else if ( !Q_stricmp ( arg1, "timeextension" ) ) else if ( !Q_stricmp ( arg1, "timeextension" ) )
@ -1944,6 +2002,8 @@ void ClientCommand( int clientNum ) {
if ( Q_stricmp ( cmd, "drop" ) == 0 ) if ( Q_stricmp ( cmd, "drop" ) == 0 )
Cmd_Drop_f ( ent ); Cmd_Drop_f ( ent );
else if (Q_stricmp (cmd, "dropitem" ) == 0 )
Cmd_DropItem_f ( ent );
else if (Q_stricmp (cmd, "give") == 0) else if (Q_stricmp (cmd, "give") == 0)
Cmd_Give_f (ent); Cmd_Give_f (ent);
else if (Q_stricmp (cmd, "god") == 0) else if (Q_stricmp (cmd, "god") == 0)

View file

@ -41,11 +41,7 @@ Toss the weapon and custom gametype items for the killed player
*/ */
void TossClientItems( gentity_t *self ) void TossClientItems( gentity_t *self )
{ {
gitem_t *item;
int weapon; int weapon;
float angle;
int i;
gentity_t *drop;
// drop the weapon if not a gauntlet or machinegun // drop the weapon if not a gauntlet or machinegun
weapon = self->s.weapon; weapon = self->s.weapon;
@ -71,36 +67,7 @@ void TossClientItems( gentity_t *self )
G_DropWeapon ( self, weapon, 0 ); G_DropWeapon ( self, weapon, 0 );
} }
// drop all custom gametype items G_DropGametypeItems ( self );
angle = 45;
for ( i = 0 ; i < MAX_GAMETYPE_ITEMS ; i++ )
{
// skip this gametype item if the client doenst have it
if ( !(self->client->ps.stats[STAT_GAMETYPE_ITEMS] & (1<<i)) )
{
continue;
}
item = BG_FindGametypeItem ( i );
if ( !item )
{
continue;
}
drop = G_DropItem( self, item, angle );
drop->count = 1;
angle += 45;
// TAke it away from the client just in case
self->client->ps.stats[STAT_GAMETYPE_ITEMS] &= ~(1<<i);
if ( self->enemy && self->enemy->client && !OnSameTeam ( self->enemy, self ) )
{
trap_GT_SendEvent ( GTEV_ITEM_DEFEND, level.time, item->quantity, self->enemy->s.clientNum, self->enemy->client->sess.team, 0, 0 );
}
}
self->client->ps.stats[STAT_GAMETYPE_ITEMS] = 0;
} }
/* /*
@ -152,6 +119,7 @@ char *modNames[] =
"MOD_M590_SHOTGUN", "MOD_M590_SHOTGUN",
"MOD_MICRO_UZI_SUBMACHINEGUN", "MOD_MICRO_UZI_SUBMACHINEGUN",
"MOD_M3A1_SUBMACHINEGUN", "MOD_M3A1_SUBMACHINEGUN",
"MOD_MP5",
"MOD_USAS_12_SHOTGUN", "MOD_USAS_12_SHOTGUN",
"MOD_M4_ASSAULT_RIFLE", "MOD_M4_ASSAULT_RIFLE",
@ -161,11 +129,7 @@ char *modNames[] =
"MOD_MM1_GRENADE_LAUNCHER", "MOD_MM1_GRENADE_LAUNCHER",
"MOD_RPG7_LAUNCHER", "MOD_RPG7_LAUNCHER",
"MOD_M67_GRENADE",
"MOD_M84_GRENADE", "MOD_M84_GRENADE",
"MOD_F1_GRENADE",
"MOD_L2A2_GRENADE",
"MOD_MDN11_GRENADE",
"MOD_SMOHG92_GRENADE", "MOD_SMOHG92_GRENADE",
"MOD_ANM14_GRENADE", "MOD_ANM14_GRENADE",
"MOD_M15_GRENADE", "MOD_M15_GRENADE",
@ -177,7 +141,8 @@ char *modNames[] =
"MOD_SUICIDE", "MOD_SUICIDE",
"MOD_TEAMCHANGE", "MOD_TEAMCHANGE",
"MOD_TARGET_LASER", "MOD_TARGET_LASER",
"MOD_TRIGGER_HURT" "MOD_TRIGGER_HURT",
"MOD_TRIGGER_HURT_NOSUICIDE"
}; };
/* /*
@ -281,6 +246,7 @@ void player_die(
{ {
gentity_t* missile; gentity_t* missile;
missile = G_FireWeapon( self, ATTACK_NORMAL ); missile = G_FireWeapon( self, ATTACK_NORMAL );
missile->dflags |= DAMAGE_NO_TEAMKILL;
if ( missile ) if ( missile )
{ {
VectorClear ( missile->s.pos.trDelta ); VectorClear ( missile->s.pos.trDelta );
@ -306,14 +272,14 @@ void player_die(
if ( attacker == self ) if ( attacker == self )
{ {
if ( mod != MOD_TEAMCHANGE ) if ( mod != MOD_TEAMCHANGE && mod != MOD_TRIGGER_HURT_NOSUICIDE )
{ {
G_AddScore( attacker, g_suicidePenalty.integer ); G_AddScore( attacker, g_suicidePenalty.integer );
} }
} }
else if ( OnSameTeam ( self, attacker ) ) else if ( OnSameTeam ( self, attacker ) )
{ {
if ( mod != MOD_TELEFRAG ) if ( mod != MOD_TELEFRAG && mod != MOD_TRIGGER_HURT_NOSUICIDE )
{ {
G_AddScore( attacker, g_teamkillPenalty.integer ); G_AddScore( attacker, g_teamkillPenalty.integer );
} }
@ -326,7 +292,7 @@ void player_die(
attacker->client->lastKillTime = level.time; attacker->client->lastKillTime = level.time;
} }
} }
else if ( mod != MOD_TEAMCHANGE ) else if ( mod != MOD_TEAMCHANGE && mod != MOD_TRIGGER_HURT_NOSUICIDE )
{ {
G_AddScore( self, g_suicidePenalty.integer ); G_AddScore( self, g_suicidePenalty.integer );
} }
@ -361,7 +327,7 @@ void player_die(
// Let the gametype handle the problem, if it doenst handle it and return 1 then // Let the gametype handle the problem, if it doenst handle it and return 1 then
// just reset the gametype item // just reset the gametype item
if ( !trap_GT_SendEvent ( GTEV_ITEM_STUCK, level.time, item->quantity, 0, 0, 0, 0 ) ) if ( !trap_GT_SendEvent ( GTEV_ITEM_STUCK, level.time, level.gametypeItems[item->giTag].id, 0, 0, 0, 0 ) )
{ {
G_ResetGametypeItem ( item ); G_ResetGametypeItem ( item );
} }
@ -406,6 +372,7 @@ void player_die(
self->client->ps.zoomFov = 0; // Turn off zooming when we die self->client->ps.zoomFov = 0; // Turn off zooming when we die
self->client->ps.stats[STAT_GAMETYPE_ITEMS] = 0; self->client->ps.stats[STAT_GAMETYPE_ITEMS] = 0;
self->client->ps.pm_flags &= ~(PMF_GOGGLES_ON|PMF_ZOOM_FLAGS); self->client->ps.pm_flags &= ~(PMF_GOGGLES_ON|PMF_ZOOM_FLAGS);
self->client->ps.loopSound = 0;
self->s.angles[0] = 0; self->s.angles[0] = 0;
self->s.angles[2] = 0; self->s.angles[2] = 0;
@ -818,13 +785,6 @@ int G_Damage (
} }
} }
// the intermission has allready been qualified for, so don't
// allow any extra scoring
if ( level.intermissionQueued )
{
return 0;
}
// Cant change outfitting after being shot // Cant change outfitting after being shot
if ( targ->client ) if ( targ->client )
{ {
@ -951,15 +911,12 @@ int G_Damage (
take -= asave; take -= asave;
// Teamkill dmage thats not caused by a telefrag? // Teamkill dmage thats not caused by a telefrag?
if ( g_teamkillDamageMax.integer && mod != MOD_TELEFRAG ) if ( g_teamkillDamageMax.integer && mod != MOD_TELEFRAG && !(dflags&DAMAGE_NO_TEAMKILL) )
{ {
if ( level.gametypeData->teams && targ && attacker && targ != attacker ) if ( level.gametypeData->teams && targ && attacker && targ != attacker )
{ {
// Hurt your own team? // Hurt your own team?
if ( OnSameTeam ( targ, attacker ) ) if ( OnSameTeam ( targ, attacker ) )
{
// Dont count more than one damage call per frame (grenades!)
if ( level.time != attacker->client->sess.teamkillForgiveTime )
{ {
int actualtake = Com_Clamp ( 0, targ->health, take ); int actualtake = Com_Clamp ( 0, targ->health, take );
@ -968,7 +925,6 @@ int G_Damage (
} }
} }
} }
}
// Output hits // Output hits
if ( g_logHits.integer && attacker && targ && attacker->client && targ->client ) if ( g_logHits.integer && attacker && targ && attacker->client && targ->client )
@ -1052,9 +1008,17 @@ int G_Damage (
if ( targ->health > 0 ) if ( targ->health > 0 )
{ {
// 45 damage is full slowdown, so..
float slowdown;
slowdown = (float)damage / 20.0f;
slowdown = Com_Clampf ( 0.0f, 1.0f, slowdown );
slowdown *= 0.75f;
slowdown = 1.0f - slowdown;
// Slow down the client at bit when they get hit // Slow down the client at bit when they get hit
targ->client->ps.velocity[0] *= 0.25f; targ->client->ps.velocity[0] *= slowdown;
targ->client->ps.velocity[1] *= 0.25f; targ->client->ps.velocity[1] *= slowdown;
// figure momentum add, even if the damage won't be taken // figure momentum add, even if the damage won't be taken
if ( knockback ) if ( knockback )
@ -1277,6 +1241,7 @@ qboolean G_RadiusDamage (
float radius, float radius,
gentity_t* ignore, gentity_t* ignore,
int power, int power,
int dflags,
int mod int mod
) )
{ {
@ -1363,10 +1328,13 @@ qboolean G_RadiusDamage (
location = G_MultipleDamageLocations ( location ); location = G_MultipleDamageLocations ( location );
} }
d = G_Damage (ent, NULL, attacker, dir, origin, (int)points, DAMAGE_RADIUS|DAMAGE_NO_ARMOR, mod, location ); d = G_Damage (ent, NULL, attacker, dir, origin, (int)points, DAMAGE_RADIUS|DAMAGE_NO_ARMOR|dflags, mod, location );
if ( d && ent->client ) if ( d && ent->client )
{ {
// Only one of the grenade hits will count for tk damage
dflags |= DAMAGE_NO_TEAMKILL;
// Put some procedural gore on the target. // Put some procedural gore on the target.
tent = G_TempEntity( origin, EV_EXPLOSION_HIT_FLESH ); tent = G_TempEntity( origin, EV_EXPLOSION_HIT_FLESH );
@ -1378,7 +1346,7 @@ qboolean G_RadiusDamage (
} }
else if (points >= 10) else if (points >= 10)
{ // dangerous weapon { // dangerous weapon
weapon = WP_M67_GRENADE; weapon = WP_SMOHG92_GRENADE;
} }
else else
{ // Just a flesh wound { // Just a flesh wound

View file

@ -9,6 +9,10 @@
#define MAX_GAMETYPE_SPAWN_POINTS 32 #define MAX_GAMETYPE_SPAWN_POINTS 32
void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator );
void target_effect_delayed_use ( gentity_t* self );
int g_gametypeItemCount = 0; int g_gametypeItemCount = 0;
vec3_t g_effectOrigin; vec3_t g_effectOrigin;
@ -54,6 +58,10 @@ void SP_gametype_player ( gentity_t *ent )
{ {
team = TEAM_BLUE; team = TEAM_BLUE;
} }
else
{
team = TEAM_FREE;
}
} }
G_AddClientSpawn ( ent, team ); G_AddClientSpawn ( ent, team );
@ -68,12 +76,30 @@ void SP_mission_player ( gentity_t* ent )
SP_gametype_player ( ent ); SP_gametype_player ( ent );
} }
void gametype_item_use ( gentity_t* self, gentity_t* other )
{
if ( level.gametypeResetTime )
{
return;
}
if ( trap_GT_SendEvent ( GTEV_ITEM_USED, level.time, self->item->quantity, other->s.number, other->client->sess.team, 0, 0 ) )
{
G_UseTargets ( self, other );
}
}
void gametype_trigger_use ( gentity_t *self, gentity_t *other, gentity_t *activator ) void gametype_trigger_use ( gentity_t *self, gentity_t *other, gentity_t *activator )
{ {
if ( level.gametypeResetTime ) if ( level.gametypeResetTime )
{ {
return; return;
} }
if ( trap_GT_SendEvent ( GTEV_TRIGGER_USED, level.time, self->health, other->s.number, other->client->sess.team, 0, 0 ) )
{
G_UseTargets ( self, other );
}
} }
void gametype_trigger_touch ( gentity_t *self, gentity_t *other, trace_t *trace ) void gametype_trigger_touch ( gentity_t *self, gentity_t *other, trace_t *trace )
@ -102,44 +128,47 @@ void SP_gametype_trigger ( gentity_t* ent )
} }
InitTrigger (ent); InitTrigger (ent);
ent->s.eType = ET_GAMETYPE_TRIGGER;
} }
static gentity_t* G_RealSpawnGametypeItem ( gentity_t* ent, qboolean dropped ) static gentity_t* G_RealSpawnGametypeItem ( gitem_t* item, vec3_t origin, vec3_t angles, qboolean dropped )
{ {
gentity_t* it_ent; gentity_t* it_ent;
it_ent = G_Spawn(); it_ent = G_Spawn();
it_ent->flags |= FL_DROPPED_ITEM; it_ent->flags |= FL_DROPPED_ITEM;
it_ent->item = ent->item; it_ent->item = item;
VectorCopy( ent->r.currentOrigin, it_ent->s.origin ); VectorCopy( origin, it_ent->s.origin );
VectorCopy ( ent->s.angles, it_ent->s.apos.trBase ); VectorCopy ( angles, it_ent->s.apos.trBase );
it_ent->classname = ent->item->classname; VectorCopy ( angles, it_ent->s.angles );
it_ent->classname = item->classname;
G_SpawnItem ( it_ent, it_ent->item ); G_SpawnItem ( it_ent, it_ent->item );
FinishSpawningItem(it_ent); FinishSpawningItem(it_ent);
VectorSet( it_ent->r.mins, -ITEM_RADIUS * 4 / 3, -ITEM_RADIUS * 4 / 3, -ITEM_RADIUS ); VectorSet( it_ent->r.mins, -ITEM_RADIUS * 4 / 3, -ITEM_RADIUS * 4 / 3, -ITEM_RADIUS );
VectorSet( it_ent->r.maxs, ITEM_RADIUS * 4 / 3, ITEM_RADIUS * 4 / 3, ITEM_RADIUS ); VectorSet( it_ent->r.maxs, ITEM_RADIUS * 4 / 3, ITEM_RADIUS * 4 / 3, ITEM_RADIUS );
// Red team only
if ( ent->s.eFlags & EF_REDTEAM )
{
it_ent->s.eFlags |= EF_REDTEAM;
}
if ( ent->s.eFlags & EF_BLUETEAM )
{
it_ent->s.eFlags |= EF_BLUETEAM;
}
return it_ent; return it_ent;
} }
gentity_t* G_SpawnGametypeItem ( const char* pickup_name, qboolean dropped ) gentity_t* G_SpawnGametypeItem ( const char* pickup_name, qboolean dropped, vec3_t origin )
{ {
gentity_t* ent; gentity_t* ent;
if ( dropped )
{
gitem_t* item = BG_FindItem ( pickup_name );
if ( item )
{
return G_RealSpawnGametypeItem ( item, origin, vec3_origin, dropped );
}
return NULL;
}
// Look for the gametype item in the map // Look for the gametype item in the map
ent = NULL; ent = NULL;
while ( NULL != (ent = G_Find ( ent, FOFS(classname), "gametype_item" ) ) ) while ( NULL != (ent = G_Find ( ent, FOFS(classname), "gametype_item" ) ) )
@ -158,12 +187,12 @@ gentity_t* G_SpawnGametypeItem ( const char* pickup_name, qboolean dropped )
return NULL; return NULL;
} }
return G_RealSpawnGametypeItem ( ent, dropped ); return G_RealSpawnGametypeItem ( ent->item, ent->r.currentOrigin, ent->s.angles, dropped );
} }
void G_GametypeItemThink ( gentity_t* ent ) void G_GametypeItemThink ( gentity_t* ent )
{ {
G_RealSpawnGametypeItem ( ent, qfalse ); G_RealSpawnGametypeItem ( ent->item, ent->r.currentOrigin, ent->s.angles, qfalse );
} }
/*QUAKED gametype_item (0 0 1) (-16 -16 -16) (16 16 16) /*QUAKED gametype_item (0 0 1) (-16 -16 -16) (16 16 16)
@ -224,7 +253,7 @@ void G_ResetGametypeItem ( gitem_t* item )
continue; continue;
} }
G_RealSpawnGametypeItem ( find, qfalse ); G_RealSpawnGametypeItem ( find->item, find->r.currentOrigin, find->s.angles, qfalse );
} }
} }
@ -347,6 +376,18 @@ void G_ResetEntities ( void )
{ {
G_FreeEntity ( ent ); G_FreeEntity ( ent );
} }
// func_wall's can be toggled off/on
else if ( ent->s.eType == ET_WALL )
{
if ( ent->spawnflags & 1 )
{
trap_UnlinkEntity ( ent );
}
else
{
trap_LinkEntity ( ent );
}
}
// If the dropped flag is set then free it // If the dropped flag is set then free it
else if ( ent->flags & FL_DROPPED_ITEM ) else if ( ent->flags & FL_DROPPED_ITEM )
{ {
@ -361,6 +402,18 @@ void G_ResetEntities ( void )
{ {
G_FreeEntity ( ent ); G_FreeEntity ( ent );
} }
else if ( ent->use == hurt_use )
{
if ( ent->spawnflags & 1 )
{
trap_UnlinkEntity ( ent );
}
}
else if ( ent->think == target_effect_delayed_use )
{
ent->think = 0;
ent->nextthink = 0;
}
} }
} }
@ -543,6 +596,68 @@ qboolean G_ParseGametypeFile ( void )
return qtrue; return qtrue;
} }
/*
=================
G_EnableGametypeItemPickup
Drops all of the gametype items held by the player
=================
*/
void G_EnableGametypeItemPickup ( gentity_t* ent )
{
ent->s.eFlags &= ~EF_NOPICKUP;
}
/*
=================
G_DropGametypeItems
Drops all of the gametype items held by the player
=================
*/
void G_DropGametypeItems ( gentity_t* self )
{
float angle;
int i;
gentity_t *drop;
gitem_t *item;
// drop all custom gametype items
angle = 0;
for ( i = 0 ; i < MAX_GAMETYPE_ITEMS ; i++ )
{
// skip this gametype item if the client doenst have it
if ( !(self->client->ps.stats[STAT_GAMETYPE_ITEMS] & (1<<i)) )
{
continue;
}
item = BG_FindGametypeItem ( i );
if ( !item )
{
continue;
}
drop = G_DropItem( self, item, angle );
drop->count = 1;
angle += 45;
drop->nextthink = level.time + 3000;
drop->s.eFlags |= EF_NOPICKUP;
drop->think = G_EnableGametypeItemPickup;
// TAke it away from the client just in case
self->client->ps.stats[STAT_GAMETYPE_ITEMS] &= ~(1<<i);
if ( self->enemy && self->enemy->client && !OnSameTeam ( self->enemy, self ) )
{
trap_GT_SendEvent ( GTEV_ITEM_DEFEND, level.time, level.gametypeItems[item->giTag].id, self->enemy->s.clientNum, self->enemy->client->sess.team, 0, 0 );
}
}
self->client->ps.stats[STAT_GAMETYPE_ITEMS] = 0;
}
/* /*
================= =================
CheckGametype CheckGametype
@ -697,7 +812,7 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
G_Voice ( &g_entities[arg0], NULL, SAY_TEAM, (const char*) arg1, qfalse ); G_Voice ( &g_entities[arg0], NULL, SAY_TEAM, (const char*) arg1, qfalse );
break; break;
case GTCMD_REGISTERGLOBALSOUND: case GTCMD_REGISTERSOUND:
return G_SoundIndex ( (char*) arg0 ); return G_SoundIndex ( (char*) arg0 );
case GTCMD_STARTGLOBALSOUND: case GTCMD_STARTGLOBALSOUND:
@ -709,9 +824,20 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
break; break;
} }
case GTCMD_STARTSOUND:
G_SoundAtLoc ( (float*)arg1, CHAN_AUTO, arg0 );
break;
case GTCMD_REGISTEREFFECT: case GTCMD_REGISTEREFFECT:
return G_EffectIndex ( (char*) arg0 ); return G_EffectIndex ( (char*) arg0 );
case GTCMD_REGISTERICON:
return G_IconIndex ( (char*) arg0 );
case GTCMD_SETHUDICON:
G_SetHUDIcon ( arg0, arg1 );
break;
case GTCMD_PLAYEFFECT: case GTCMD_PLAYEFFECT:
G_PlayEffect ( arg0, (float*) arg1, (float*) arg2 ); G_PlayEffect ( arg0, (float*) arg1, (float*) arg2 );
break; break;
@ -741,6 +867,95 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
Com_sprintf ( (char*) arg1, arg2, "%s", g_entities[arg0].client->pers.netname ); Com_sprintf ( (char*) arg1, arg2, "%s", g_entities[arg0].client->pers.netname );
break; break;
case GTCMD_GETTRIGGERTARGET:
{
gentity_t *find;
Com_sprintf ( (char*) arg1, arg2, "" );
find = NULL;
while ( NULL != (find = G_Find ( find, FOFS(classname), "gametype_trigger" ) ) )
{
if ( find->health == arg0 )
{
Com_sprintf ( (char*) arg1, arg2, "%s", find->target );
break;
}
}
break;
}
case GTCMD_GETCLIENTORIGIN:
VectorCopy ( g_entities[arg0].client->ps.origin, (float*) arg1 );
break;
case GTCMD_GIVECLIENTITEM:
{
gitem_t* item;
item = BG_FindGametypeItemByID ( arg1 );
if ( item )
{
level.clients[arg0].ps.stats[STAT_GAMETYPE_ITEMS] |= (1<<item->giTag);
}
break;
}
case GTCMD_GETCLIENTLIST:
{
int i;
int count;
int *clients = (int*)arg1;
for ( i = 0, count = 0; i < level.numConnectedClients && count < arg2; i ++ )
{
gclient_t* client = &level.clients[level.sortedClients[i]];
if ( client->pers.connected != CON_CONNECTED )
{
continue;
}
if ( client->sess.team == arg0 )
{
*clients = level.sortedClients[i];
clients++;
count++;
}
}
return count;
}
case GTCMD_TAKECLIENTITEM:
{
gitem_t* item;
item = BG_FindGametypeItemByID ( arg1 );
if ( item )
{
level.clients[arg0].ps.stats[STAT_GAMETYPE_ITEMS] &= ~(1<<item->giTag);
}
break;
}
case GTCMD_SPAWNITEM:
{
gitem_t* item;
item = BG_FindGametypeItemByID ( arg0 );
if ( item )
{
gentity_t* ent = LaunchItem ( item, (float*)arg1, vec3_origin );
if ( ent )
{
VectorCopy ( (float*)arg2, ent->s.angles );
}
}
break;
}
case GTCMD_DOESCLIENTHAVEITEM: case GTCMD_DOESCLIENTHAVEITEM:
{ {
gitem_t* item; gitem_t* item;
@ -762,12 +977,29 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
case GTCMD_REGISTERITEM: case GTCMD_REGISTERITEM:
{ {
gitem_t* item; gitem_t *item;
gtItemDef_t *def;
def = (gtItemDef_t*)arg2;
item = BG_FindItem ( (const char*) arg1 ); item = BG_FindItem ( (const char*) arg1 );
if ( item ) if ( item )
{ {
gtitem_t *gtitem;
gtitem = &level.gametypeItems[item->giTag];
gtitem->id = arg0;
item->quantity = arg0; item->quantity = arg0;
// See if the trigger needs to be used.
if ( def && def->size == sizeof(gtItemDef_t) && def->use )
{
gtitem->useIcon = def->useIcon;
gtitem->useTime = def->useTime;
gtitem->useSound = def->useSound;
}
return qtrue; return qtrue;
} }
@ -776,7 +1008,10 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
case GTCMD_REGISTERTRIGGER: case GTCMD_REGISTERTRIGGER:
{ {
gentity_t* find; gentity_t *find;
gtTriggerDef_t *def;
def = (gtTriggerDef_t*)arg2;
find = NULL; find = NULL;
while ( NULL != (find = G_Find ( find, FOFS(classname), "gametype_trigger" ) ) ) while ( NULL != (find = G_Find ( find, FOFS(classname), "gametype_trigger" ) ) )
@ -789,12 +1024,26 @@ int G_GametypeCommand ( int cmd, int arg0, int arg1, int arg2, int arg3, int arg
// Assign the id to it. // Assign the id to it.
find->health = arg0; find->health = arg0;
find->touch = gametype_trigger_touch; find->touch = gametype_trigger_touch;
// See if the trigger needs to be used.
if ( def && def->size == sizeof(gtTriggerDef_t) && def->use )
{
find->use = gametype_trigger_use;
find->delay = def->useIcon;
find->soundPos1 = def->useTime;
find->soundLoop = def->useSound;
}
trap_LinkEntity (find); trap_LinkEntity (find);
} }
return 0; return 0;
} }
case GTCMD_USETARGETS:
G_UseTargetsByName ( (const char*) arg0, NULL, NULL );
break;
default: default:
break; break;
} }

View file

@ -316,7 +316,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace)
if ( ent->item->giType == IT_GAMETYPE ) if ( ent->item->giType == IT_GAMETYPE )
{ {
// Let the gametype decide if it can be picked up // Let the gametype decide if it can be picked up
if ( !trap_GT_SendEvent ( GTEV_ITEM_TOUCHED, level.time, ent->item->quantity, other->s.number, other->client->sess.team, 0, 0 ) ) if ( !trap_GT_SendEvent ( GTEV_ITEM_TOUCHED, level.time, level.gametypeItems[ent->item->giTag].id, other->s.number, other->client->sess.team, 0, 0 ) )
{ {
return; return;
} }
@ -454,7 +454,7 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity )
// Gametype items must be spawned using the spawn mission item function // Gametype items must be spawned using the spawn mission item function
if ( item->giType == IT_GAMETYPE ) if ( item->giType == IT_GAMETYPE )
{ {
dropped = G_SpawnGametypeItem ( item->pickup_name, qtrue ); dropped = G_SpawnGametypeItem ( item->pickup_name, qtrue, origin );
dropped->nextthink = 0; dropped->nextthink = 0;
} }
else else
@ -513,14 +513,14 @@ gentity_t *G_DropItem( gentity_t *ent, gitem_t *item, float angle )
angles[PITCH] = 0; // always forward angles[PITCH] = 0; // always forward
AngleVectors( angles, velocity, NULL, NULL ); AngleVectors( angles, velocity, NULL, NULL );
VectorScale( velocity, 150, velocity ); VectorScale( velocity, 100, velocity );
velocity[2] += 200 + crandom() * 50; velocity[2] += 100 + crandom() * 50;
dropped = LaunchItem( item, ent->r.currentOrigin, velocity ); dropped = LaunchItem( item, ent->r.currentOrigin, velocity );
if ( item->giType == IT_GAMETYPE ) if ( item->giType == IT_GAMETYPE )
{ {
trap_GT_SendEvent ( GTEV_ITEM_DROPPED, level.time, item->quantity, ent->s.number, 0, 0, 0 ); trap_GT_SendEvent ( GTEV_ITEM_DROPPED, level.time, level.gametypeItems[item->giTag].id, ent->s.number, 0, 0, 0 );
} }
return dropped; return dropped;
@ -734,7 +734,7 @@ void FinishSpawningItem( gentity_t *ent )
ent->s.radius = 60; ent->s.radius = 60;
} }
*/ */
if ( ent->item->giType != IT_GAMETYPE && ent->spawnflags & 1 ) if ( ent->item->giType != IT_GAMETYPE && (ent->spawnflags & 1) )
{ {
// suspended // suspended
G_SetOrigin( ent, ent->s.origin ); G_SetOrigin( ent, ent->s.origin );
@ -765,6 +765,12 @@ void FinishSpawningItem( gentity_t *ent )
return; return;
} }
// Gametype items are broadcast
if ( ent->item->giType == IT_GAMETYPE )
{
ent->r.svFlags |= SVF_BROADCAST;
}
trap_LinkEntity (ent); trap_LinkEntity (ent);
} }
@ -882,7 +888,7 @@ void G_SpawnItem (gentity_t *ent, gitem_t *item)
ent->nextthink = level.time + FRAMETIME * 2; ent->nextthink = level.time + FRAMETIME * 2;
ent->think = FinishSpawningItem; ent->think = FinishSpawningItem;
ent->physicsBounce = 0.50; // items are bouncy ent->physicsBounce = 0.2f; // items are bouncy
} }
@ -992,7 +998,7 @@ void G_RunItem( gentity_t *ent )
{ {
// Let the gametype handle the problem, if it doenst handle it and return 1 then // Let the gametype handle the problem, if it doenst handle it and return 1 then
// just reset the gametype item // just reset the gametype item
if ( !trap_GT_SendEvent ( GTEV_ITEM_STUCK, level.time, ent->item->quantity, 0, 0, 0, 0 ) ) if ( !trap_GT_SendEvent ( GTEV_ITEM_STUCK, level.time, level.gametypeItems[ent->item->giTag].id, 0, 0, 0, 0 ) )
{ {
G_ResetGametypeItem ( ent->item ); G_ResetGametypeItem ( ent->item );
} }

View file

@ -166,6 +166,15 @@ typedef struct gspawn_s
} gspawn_t; } gspawn_t;
typedef struct gtitem_s
{
int id;
int useIcon;
int useSound;
int useTime;
} gtitem_t;
typedef enum typedef enum
{ {
CON_DISCONNECTED, CON_DISCONNECTED,
@ -369,6 +378,10 @@ struct gclient_s
vec3_t ghoulHeadAngles; vec3_t ghoulHeadAngles;
gentity_t *siameseTwin; gentity_t *siameseTwin;
gentity_t *useEntity;
vec3_t maxSave;
vec3_t minSave;
}; };
@ -378,6 +391,8 @@ struct gclient_s
#define MAX_SPAWN_VARS 64 #define MAX_SPAWN_VARS 64
#define MAX_SPAWN_VARS_CHARS 4096 #define MAX_SPAWN_VARS_CHARS 4096
#define MAX_AUTOKICKLIST 32
typedef struct typedef struct
{ {
struct gclient_s *clients; // [maxclients] struct gclient_s *clients; // [maxclients]
@ -483,6 +498,7 @@ typedef struct
int gametypeRespawnTime[TEAM_NUM_TEAMS]; int gametypeRespawnTime[TEAM_NUM_TEAMS];
int gametypeDelayTime; int gametypeDelayTime;
const char* gametypeTeam[TEAM_NUM_TEAMS]; const char* gametypeTeam[TEAM_NUM_TEAMS];
gtitem_t gametypeItems[MAX_GAMETYPE_ITEMS];
void* serverGhoul2; void* serverGhoul2;
animation_t ghoulAnimations[MAX_ANIMATIONS]; animation_t ghoulAnimations[MAX_ANIMATIONS];
@ -496,6 +512,11 @@ typedef struct
int timeExtension; int timeExtension;
int autokickedCount;
int autokickedHead;
char autokickedName[MAX_AUTOKICKLIST][MAX_NETNAME];
char autokickedIP[MAX_AUTOKICKLIST][20];
} level_locals_t; } level_locals_t;
// //
@ -542,7 +563,7 @@ void RespawnItem( gentity_t *ent );
void PrecacheItem ( gitem_t *it ); void PrecacheItem ( gitem_t *it );
gentity_t* G_DropItem ( gentity_t *ent, gitem_t *item, float angle ); gentity_t* G_DropItem ( gentity_t *ent, gitem_t *item, float angle );
gentity_t* G_LaunchItem ( gitem_t *item, vec3_t origin, vec3_t velocity ); gentity_t* LaunchItem ( gitem_t *item, vec3_t origin, vec3_t velocity );
gentity_t* G_DropWeapon ( gentity_t* ent, weapon_t weapon, int pickupDelay ); gentity_t* G_DropWeapon ( gentity_t* ent, weapon_t weapon, int pickupDelay );
void SetRespawn (gentity_t *ent, float delay); void SetRespawn (gentity_t *ent, float delay);
@ -581,6 +602,7 @@ void G_InitGentity( gentity_t *e );
gentity_t *G_Spawn (void); gentity_t *G_Spawn (void);
gentity_t *G_TempEntity( vec3_t origin, int event ); gentity_t *G_TempEntity( vec3_t origin, int event );
void G_PlayEffect(int fxID, vec3_t org, vec3_t ang); void G_PlayEffect(int fxID, vec3_t org, vec3_t ang);
void G_SetHUDIcon ( int index, int icon );
void G_Sound( gentity_t *ent, int channel, int soundIndex ); void G_Sound( gentity_t *ent, int channel, int soundIndex );
void G_SoundAtLoc( vec3_t loc, int channel, int soundIndex ); void G_SoundAtLoc( vec3_t loc, int channel, int soundIndex );
void G_EntitySound( gentity_t *ent, int channel, int soundIndex ); void G_EntitySound( gentity_t *ent, int channel, int soundIndex );
@ -619,6 +641,7 @@ qboolean trap_G2API_GetAnimFileNameIndex ( void* ghoul2, qhandle_t modelIndex, c
void trap_G2_ListModelSurfaces(void *ghlInfo); void trap_G2_ListModelSurfaces(void *ghlInfo);
void trap_G2_ListModelBones(void *ghlInfo, int frame); void trap_G2_ListModelBones(void *ghlInfo, int frame);
int trap_G2API_AddBolt(void *ghoul2, const int modelIndex, const char *boneName); int trap_G2API_AddBolt(void *ghoul2, const int modelIndex, const char *boneName);
void trap_G2API_SetBoltInfo(void *ghoul2, int modelIndex, int boltInfo);
qboolean trap_G2API_RemoveBolt(void *ghlInfo, const int modelIndex, const int index); qboolean trap_G2API_RemoveBolt(void *ghlInfo, const int modelIndex, const int index);
qboolean trap_G2API_AttachG2Model(void *ghoul2From, int modelFrom, void *ghoul2To, int toBoltIndex, int toModel); qboolean trap_G2API_AttachG2Model(void *ghoul2From, int modelFrom, void *ghoul2To, int toBoltIndex, int toModel);
void trap_G2_SetGhoul2ModelIndexes(void *ghoul2, qhandle_t *modelList, qhandle_t *skinList); void trap_G2_SetGhoul2ModelIndexes(void *ghoul2, qhandle_t *modelList, qhandle_t *skinList);
@ -647,7 +670,7 @@ qboolean trap_G2API_SetBoneAnim(void *ghoul2, const int modelIndex, const char *
qboolean CanDamage ( gentity_t *targ, vec3_t origin); qboolean CanDamage ( gentity_t *targ, vec3_t origin);
int G_GetHitLocation ( gentity_t *target, vec3_t ppoint, vec3_t dir ); int G_GetHitLocation ( gentity_t *target, vec3_t ppoint, vec3_t dir );
int G_Damage ( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod, int location ); int G_Damage ( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod, int location );
qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int power, int mod); qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int power, int dflags, int mod );
void body_die ( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath, int hitLocation, vec3_t hitDir ); void body_die ( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath, int hitLocation, vec3_t hitDir );
void TossClientItems ( gentity_t *self ); void TossClientItems ( gentity_t *self );
@ -661,6 +684,7 @@ void TossClientItems ( gentity_t *self );
#define DAMAGE_AREA_DAMAGE 0x00000400 // spawn area damage #define DAMAGE_AREA_DAMAGE 0x00000400 // spawn area damage
#define DAMAGE_NO_GORE 0x00000800 // dont spawn gore pieces with this damage #define DAMAGE_NO_GORE 0x00000800 // dont spawn gore pieces with this damage
#define DAMAGE_FORCE_GORE 0x00001000 // force something to pop off #define DAMAGE_FORCE_GORE 0x00001000 // force something to pop off
#define DAMAGE_NO_TEAMKILL 0x00002000 // does not produce teamkill damage
// //
// g_missile.c // g_missile.c
@ -728,8 +752,6 @@ void G_AddClientSpawn ( gentity_t* ent, team_t team );
// g_svcmds.c // g_svcmds.c
// //
qboolean ConsoleCommand ( void ); qboolean ConsoleCommand ( void );
void G_ProcessIPBans ( void );
qboolean G_FilterPacket ( char *from );
// //
// g_weapon.c // g_weapon.c
@ -811,13 +833,15 @@ void G_LoadArenas ( void );
// g_gametype.c // g_gametype.c
// //
gentity_t* G_SelectGametypeSpawnPoint ( team_t team, vec3_t origin, vec3_t angles ); gentity_t* G_SelectGametypeSpawnPoint ( team_t team, vec3_t origin, vec3_t angles );
gentity_t* G_SpawnGametypeItem ( const char* pickup_name, qboolean dropped ); gentity_t* G_SpawnGametypeItem ( const char* pickup_name, qboolean dropped, vec3_t origin );
gentity_t* G_SelectRandomGametypeSpawnPoint ( team_t team ); gentity_t* G_SelectRandomGametypeSpawnPoint ( team_t team );
qboolean G_ParseGametypeFile ( void ); qboolean G_ParseGametypeFile ( void );
qboolean G_ExecuteGametypeScript ( gentity_t* activator, const char* name ); qboolean G_ExecuteGametypeScript ( gentity_t* activator, const char* name );
void G_ResetGametype ( void ); void G_ResetGametype ( void );
qboolean G_CanGametypeTriggerBeUsed ( gentity_t* self, gentity_t* activator ); qboolean G_CanGametypeTriggerBeUsed ( gentity_t* self, gentity_t* activator );
void G_ResetGametypeItem ( gitem_t* item ); void G_ResetGametypeItem ( gitem_t* item );
void gametype_item_use ( gentity_t* self, gentity_t* other );
void G_DropGametypeItems ( gentity_t* self );
// ai_main.c // ai_main.c
#define MAX_FILEPATH 144 #define MAX_FILEPATH 144
@ -877,11 +901,10 @@ extern vmCvar_t g_warmup;
extern vmCvar_t g_doWarmup; extern vmCvar_t g_doWarmup;
extern vmCvar_t g_allowVote; extern vmCvar_t g_allowVote;
extern vmCvar_t g_voteDuration; extern vmCvar_t g_voteDuration;
extern vmCvar_t g_voteKickBanTime;
extern vmCvar_t g_failedVoteDelay; extern vmCvar_t g_failedVoteDelay;
extern vmCvar_t g_teamAutoJoin; extern vmCvar_t g_teamAutoJoin;
extern vmCvar_t g_teamForceBalance; extern vmCvar_t g_teamForceBalance;
extern vmCvar_t g_banIPs;
extern vmCvar_t g_filterBan;
extern vmCvar_t g_smoothClients; extern vmCvar_t g_smoothClients;
extern vmCvar_t pmove_fixed; extern vmCvar_t pmove_fixed;
extern vmCvar_t pmove_msec; extern vmCvar_t pmove_msec;
@ -892,6 +915,7 @@ extern vmCvar_t RMG;
extern vmCvar_t g_debugRMG; extern vmCvar_t g_debugRMG;
extern vmCvar_t g_timeouttospec; extern vmCvar_t g_timeouttospec;
extern vmCvar_t g_roundtimelimit; extern vmCvar_t g_roundtimelimit;
extern vmCvar_t g_roundjointime;
extern vmCvar_t g_timeextension; extern vmCvar_t g_timeextension;
extern vmCvar_t g_roundstartdelay; extern vmCvar_t g_roundstartdelay;
extern vmCvar_t g_availableWeapons; extern vmCvar_t g_availableWeapons;
@ -903,8 +927,11 @@ extern vmCvar_t g_suicidePenalty;
extern vmCvar_t g_teamkillPenalty; extern vmCvar_t g_teamkillPenalty;
extern vmCvar_t g_teamkillDamageMax; extern vmCvar_t g_teamkillDamageMax;
extern vmCvar_t g_teamkillDamageForgive; extern vmCvar_t g_teamkillDamageForgive;
extern vmCvar_t g_teamkillBanTime;
extern vmCvar_t g_voiceFloodCount; extern vmCvar_t g_voiceFloodCount;
extern vmCvar_t g_voiceFloodPenalty; extern vmCvar_t g_voiceFloodPenalty;
extern vmCvar_t g_voiceTalkingGhosts;
extern vmCvar_t g_suddenDeath;
void trap_Printf( const char *fmt ); void trap_Printf( const char *fmt );
void trap_Error( const char *fmt ); void trap_Error( const char *fmt );

View file

@ -52,11 +52,10 @@ vmCvar_t g_logSync;
vmCvar_t g_logHits; vmCvar_t g_logHits;
vmCvar_t g_allowVote; vmCvar_t g_allowVote;
vmCvar_t g_voteDuration; vmCvar_t g_voteDuration;
vmCvar_t g_voteKickBanTime;
vmCvar_t g_failedVoteDelay; vmCvar_t g_failedVoteDelay;
vmCvar_t g_teamAutoJoin; vmCvar_t g_teamAutoJoin;
vmCvar_t g_teamForceBalance; vmCvar_t g_teamForceBalance;
vmCvar_t g_banIPs;
vmCvar_t g_filterBan;
vmCvar_t g_smoothClients; vmCvar_t g_smoothClients;
vmCvar_t pmove_fixed; vmCvar_t pmove_fixed;
vmCvar_t pmove_msec; vmCvar_t pmove_msec;
@ -66,6 +65,7 @@ vmCvar_t g_fps;
vmCvar_t g_respawnInterval; vmCvar_t g_respawnInterval;
vmCvar_t g_respawnInvulnerability; vmCvar_t g_respawnInvulnerability;
vmCvar_t g_roundtimelimit; vmCvar_t g_roundtimelimit;
vmCvar_t g_roundjointime;
vmCvar_t g_timeextension; vmCvar_t g_timeextension;
vmCvar_t g_timeouttospec; vmCvar_t g_timeouttospec;
vmCvar_t g_roundstartdelay; vmCvar_t g_roundstartdelay;
@ -78,8 +78,11 @@ vmCvar_t g_suicidePenalty; // Amount of score added for killing yourself (typ
vmCvar_t g_teamkillPenalty; // Amount of score added for killing a teammates (typically negative) vmCvar_t g_teamkillPenalty; // Amount of score added for killing a teammates (typically negative)
vmCvar_t g_teamkillDamageMax; // max damage one can do to teammates before being kicked vmCvar_t g_teamkillDamageMax; // max damage one can do to teammates before being kicked
vmCvar_t g_teamkillDamageForgive; // amount of teamkill damage forgiven each minute vmCvar_t g_teamkillDamageForgive; // amount of teamkill damage forgiven each minute
vmCvar_t g_teamkillBanTime; // number of minutes to ban someone for after being kicked
vmCvar_t g_voiceFloodCount; // Number of voice messages in one minute to be concidered flooding vmCvar_t g_voiceFloodCount; // Number of voice messages in one minute to be concidered flooding
vmCvar_t g_voiceFloodPenalty; // Amount of time a void flooder must wait before they can use voice again vmCvar_t g_voiceFloodPenalty; // Amount of time a void flooder must wait before they can use voice again
vmCvar_t g_suddenDeath;
vmCvar_t g_voiceTalkingGhosts; // Allow ghosts to talk to alive players
vmCvar_t RMG; vmCvar_t RMG;
vmCvar_t g_debugRMG; vmCvar_t g_debugRMG;
@ -122,9 +125,6 @@ static cvarTable_t gameCvarTable[] =
{ &g_password, "g_password", "", CVAR_USERINFO, 0.0, 0.0, 0, qfalse }, { &g_password, "g_password", "", CVAR_USERINFO, 0.0, 0.0, 0, qfalse },
{ &g_banIPs, "g_banIPs", "", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_filterBan, "g_filterBan", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_needpass, "g_needpass", "0", CVAR_SERVERINFO | CVAR_ROM, 0.0, 0.0, 0, qfalse }, { &g_needpass, "g_needpass", "0", CVAR_SERVERINFO | CVAR_ROM, 0.0, 0.0, 0, qfalse },
{ &g_dedicated, "dedicated", "0", 0, 0.0, 0.0, 0, qfalse }, { &g_dedicated, "dedicated", "0", 0, 0.0, 0.0, 0, qfalse },
@ -143,6 +143,7 @@ static cvarTable_t gameCvarTable[] =
{ &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_voteDuration, "g_voteDuration", "60", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_voteDuration, "g_voteDuration", "60", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_voteKickBanTime, "g_voteKickBanTime", "0", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_failedVoteDelay, "g_failedVoteDelay", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_failedVoteDelay, "g_failedVoteDelay", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_listEntity, "g_listEntity", "0", 0, 0.0, 0.0, 0, qfalse }, { &g_listEntity, "g_listEntity", "0", 0, 0.0, 0.0, 0, qfalse },
@ -160,11 +161,12 @@ static cvarTable_t gameCvarTable[] =
{ &g_timeouttospec, "g_timeouttospec", "15", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_timeouttospec, "g_timeouttospec", "15", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_roundtimelimit, "g_roundtimelimit", "5", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_roundtimelimit, "g_roundtimelimit", "5", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_roundjointime, "g_roundjointime", "5", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_timeextension, "g_timeextension", "15", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_timeextension, "g_timeextension", "15", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_roundstartdelay, "g_roundstartdelay", "5", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_roundstartdelay, "g_roundstartdelay", "5", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_availableWeapons, "g_availableWeapons", "2222222222211", CVAR_ARCHIVE|CVAR_SERVERINFO|CVAR_LATCH, 0.0, 0.0, 0, qfalse }, { &g_availableWeapons, "g_availableWeapons", "22222222222211", CVAR_ARCHIVE|CVAR_SERVERINFO|CVAR_LATCH, 0.0, 0.0, 0, qfalse },
{ &g_forceFollow, "g_forceFollow", "0", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_forceFollow, "g_forceFollow", "0", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
{ &g_followEnemy, "g_followEnemy", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse }, { &g_followEnemy, "g_followEnemy", "1", CVAR_ARCHIVE, 0.0, 0.0, 0, qfalse },
@ -181,6 +183,11 @@ static cvarTable_t gameCvarTable[] =
{ &g_teamkillPenalty, "g_teamkillPenalty", "-1", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse }, { &g_teamkillPenalty, "g_teamkillPenalty", "-1", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &g_teamkillDamageMax, "g_teamkillDamageMax", "300", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse }, { &g_teamkillDamageMax, "g_teamkillDamageMax", "300", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &g_teamkillDamageForgive, "g_teamkillDamageForgive", "50", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse }, { &g_teamkillDamageForgive, "g_teamkillDamageForgive", "50", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &g_teamkillBanTime, "g_teamkillBanTime", "5", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &g_suddenDeath, "g_suddenDeath", "1", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &g_voiceTalkingGhosts, "g_voiceTalkingGhosts", "1", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
}; };
// bk001129 - made static to avoid aliasing // bk001129 - made static to avoid aliasing
@ -449,6 +456,7 @@ void G_SetGametype ( const char* gametype )
gametype = bg_gametypeData[i].name; gametype = bg_gametypeData[i].name;
trap_Cvar_Set( "g_gametype", gametype ); trap_Cvar_Set( "g_gametype", gametype );
trap_Cvar_Set( "RMG_mission", gametype );
level.gametype = BG_FindGametype ( gametype ); level.gametype = BG_FindGametype ( gametype );
trap_Cvar_Update( &g_gametype ); trap_Cvar_Update( &g_gametype );
@ -494,7 +502,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
G_RegisterCvars(); G_RegisterCvars();
G_ProcessIPBans();
// Load the list of arenas // Load the list of arenas
G_LoadArenas ( ); G_LoadArenas ( );
@ -505,6 +512,9 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
// Set the current gametype // Set the current gametype
G_SetGametype(g_gametype.string); G_SetGametype(g_gametype.string);
// Set the available outfitting
BG_SetAvailableOutfitting ( g_availableWeapons.string );
// Give the game a uniqe id // Give the game a uniqe id
trap_SetConfigstring ( CS_GAME_ID, va("%d", randomSeed ) ); trap_SetConfigstring ( CS_GAME_ID, va("%d", randomSeed ) );
@ -573,8 +583,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
// reserve some spots for dead player bodies // reserve some spots for dead player bodies
G_InitBodyQueue(); G_InitBodyQueue();
BG_ParseInviewFile();
ClearRegisteredItems(); ClearRegisteredItems();
// parse the key/value pairs and spawn gentities // parse the key/value pairs and spawn gentities
@ -585,6 +593,8 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
// linked up properly // linked up properly
G_ParseGametypeFile ( ); G_ParseGametypeFile ( );
BG_ParseInviewFile( level.pickupsDisabled );
// Load in the identities // Load in the identities
BG_ParseNPCFiles ( ); BG_ParseNPCFiles ( );
@ -612,9 +622,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
G_RemapTeamShaders(); G_RemapTeamShaders();
// Set the available outfitting
BG_SetAvailableOutfitting ( g_availableWeapons.string );
// Initialize the gametype // Initialize the gametype
trap_GT_Init ( g_gametype.string, restart ); trap_GT_Init ( g_gametype.string, restart );
@ -943,8 +950,12 @@ void MoveClientToIntermission( gentity_t *ent )
G_StopFollowing( ent ); G_StopFollowing( ent );
} }
FindIntermissionPoint ( );
// move to the spot // move to the spot
VectorCopy( level.intermission_origin, ent->s.origin ); VectorCopy( level.intermission_origin, ent->s.origin );
VectorCopy( level.intermission_origin, ent->r.currentOrigin );
VectorCopy( level.intermission_origin, ent->client->ps.pvsOrigin );
VectorCopy( level.intermission_origin, ent->client->ps.origin ); VectorCopy( level.intermission_origin, ent->client->ps.origin );
VectorCopy (level.intermission_angle, ent->client->ps.viewangles); VectorCopy (level.intermission_angle, ent->client->ps.viewangles);
@ -1122,7 +1133,7 @@ void QDECL G_LogPrintf( const char *fmt, ... ) {
tens = sec / 10; tens = sec / 10;
sec -= tens * 10; sec -= tens * 10;
Com_sprintf( string, sizeof(string), "%fi:%i%i ", min, tens, sec ); Com_sprintf( string, sizeof(string), "%4i:%i%i ", min, tens, sec );
va_start( argptr, fmt ); va_start( argptr, fmt );
vsprintf( string +8 , fmt,argptr ); vsprintf( string +8 , fmt,argptr );
@ -1342,7 +1353,7 @@ void CheckExitRules( void )
} }
// check for sudden death // check for sudden death
if ( ScoreIsTied() ) if ( g_suddenDeath.integer && ScoreIsTied() )
{ {
// always wait for sudden death // always wait for sudden death
return; return;

View file

@ -123,12 +123,12 @@ void G_ExplodeMissile( gentity_t *ent ) {
// do some instant damage // do some instant damage
G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->damage, ent->splashRadius, ent, G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->damage, ent->splashRadius, ent,
1, ent->splashMethodOfDeath ); 1, ent->dflags, ent->splashMethodOfDeath );
} }
else else
{ // normal radius of effect damage { // normal radius of effect damage
G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent,
1, ent->splashMethodOfDeath ); 1, ent->dflags, ent->splashMethodOfDeath );
} }
} }
@ -228,7 +228,7 @@ G_CauseAreaDamage
*/ */
void G_CauseAreaDamage( gentity_t *ent ) void G_CauseAreaDamage( gentity_t *ent )
{ {
G_RadiusDamage ( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, 3, ent->methodOfDeath ); G_RadiusDamage ( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, 3, DAMAGE_NO_TEAMKILL, ent->methodOfDeath );
ent->s.time2--; ent->s.time2--;
@ -447,12 +447,12 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace )
// do some instant damage // do some instant damage
G_RadiusDamage( trace->endpos, ent->parent, ent->damage, ent->splashRadius, other, G_RadiusDamage( trace->endpos, ent->parent, ent->damage, ent->splashRadius, other,
1, ent->splashMethodOfDeath ); 1, ent->dflags, ent->splashMethodOfDeath );
} }
else else
{ // normal radius of effect damage { // normal radius of effect damage
G_RadiusDamage( trace->endpos, ent->parent, ent->splashDamage, ent->splashRadius, G_RadiusDamage( trace->endpos, ent->parent, ent->splashDamage, ent->splashRadius,
other, 1, ent->splashMethodOfDeath ); other, 1, ent->dflags, ent->splashMethodOfDeath );
} }
} }

View file

@ -326,12 +326,13 @@ qboolean G_MoverPush( gentity_t *pusher, vec3_t move, vec3_t amove, gentity_t **
} }
// If being blocked by an item just let it pass through it and get rid of the item // If being blocked by an item just let it pass through it and get rid of the item
if ( check->s.eType == ET_ITEM ) if ( check->s.eType == ET_ITEM && check->item->giType != IT_GAMETYPE )
{ {
G_FreeEntity ( check ); G_FreeEntity ( check );
continue; continue;
} }
// the move was blocked an entity // the move was blocked an entity
// bobbing entities are instant-kill and never get blocked // bobbing entities are instant-kill and never get blocked
@ -1407,6 +1408,47 @@ void SP_func_static( gentity_t *ent ) {
} }
} }
void G_WallUse(gentity_t *self, gentity_t *other, gentity_t *activator)
{
if ( self->r.linked )
{
trap_UnlinkEntity ( self );
}
else
{
trap_LinkEntity ( self );
}
}
/*QUAKED func_wall (0 .5 .8) ? START_OFF
A func wall can be turned off and on by targetting it.
*/
void SP_func_wall ( gentity_t* ent )
{
// Right now func walls are not supported in multiplayer
if ( RMG.integer )
{
trap_UnlinkEntity ( ent );
return;
}
trap_SetBrushModel( ent, ent->model );
InitMover( ent );
VectorCopy( ent->s.origin, ent->s.pos.trBase );
VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin );
VectorCopy( ent->s.apos.trBase, ent->r.currentAngles );
ent->s.eType = ET_WALL;
ent->use = G_WallUse;
if ( !(ent->spawnflags & 1 ) )
{
trap_LinkEntity( ent );
}
}
/* /*
=============================================================================== ===============================================================================

View file

@ -72,7 +72,6 @@ void G_InitSessionData( gclient_t *client, char *userinfo )
if ( g_teamAutoJoin.integer ) if ( g_teamAutoJoin.integer )
{ {
sess->team = PickTeam( -1 ); sess->team = PickTeam( -1 );
BroadcastTeamChange( client, -1 );
} }
else else
{ {

View file

@ -131,6 +131,7 @@ void SP_func_door (gentity_t *ent);
void SP_func_train (gentity_t *ent); void SP_func_train (gentity_t *ent);
void SP_func_timer (gentity_t *ent); void SP_func_timer (gentity_t *ent);
void SP_func_glass (gentity_t *ent); void SP_func_glass (gentity_t *ent);
void SP_func_wall (gentity_t *ent);
void SP_trigger_always (gentity_t *ent); void SP_trigger_always (gentity_t *ent);
void SP_trigger_multiple (gentity_t *ent); void SP_trigger_multiple (gentity_t *ent);
@ -192,6 +193,7 @@ spawn_t spawns[] =
{"func_train", SP_func_train}, {"func_train", SP_func_train},
{"func_timer", SP_func_timer}, {"func_timer", SP_func_timer},
{"func_glass", SP_func_glass}, {"func_glass", SP_func_glass},
{"func_wall", SP_func_wall},
// Triggers are brush objects that cause an effect when contacted // Triggers are brush objects that cause an effect when contacted
// by a living player, usually involving firing targets. // by a living player, usually involving firing targets.
@ -252,7 +254,6 @@ spawn_t spawns[] =
{"info_null", 0}, {"info_null", 0},
{"door_rotating", 0}, {"door_rotating", 0},
{"emplaced_wpn", 0}, {"emplaced_wpn", 0},
{"func_wall", 0},
{"info_NPC*", 0}, {"info_NPC*", 0},
{"info_player_start", 0}, {"info_player_start", 0},
{"NPC_*", 0}, {"NPC_*", 0},
@ -432,6 +433,35 @@ void G_ParseField( const char *key, const char *value, gentity_t *ent ) {
} }
} }
/*
===================
G_IsGametypeInList
Determines if the given gametype is in the given list.
===================
*/
qboolean G_IsGametypeInList ( const char* gametype, const char* list )
{
const char* buf = (char*) list;
char* token;
while ( 1 )
{
token = COM_Parse ( &buf );
if ( !token || !token[0] )
{
break;
}
if ( Q_stricmp ( token, gametype ) == 0 )
{
return qtrue;
}
}
return qfalse;
}
/* /*
=================== ===================
G_SpawnGEntityFromSpawnVars G_SpawnGEntityFromSpawnVars
@ -486,15 +516,25 @@ void G_SpawnGEntityFromSpawnVars( qboolean inSubBSP )
} }
// Only spawn this entity in the specified gametype // Only spawn this entity in the specified gametype
if( G_SpawnString( "gametype", NULL, &value ) ) if( G_SpawnString( "gametype", NULL, &value ) && value )
{ {
// Has to be a case match if ( !G_IsGametypeInList ( level.gametypeData->name, value ) )
if ( value && !strstr ( value, level.gametypeData->name ) ) {
if ( level.gametypeData->basegametype )
{
if ( !G_IsGametypeInList ( level.gametypeData->basegametype, value ) )
{ {
G_FreeEntity ( ent ); G_FreeEntity ( ent );
return; return;
} }
} }
else
{
G_FreeEntity ( ent );
return;
}
}
}
// move editor origin to pos // move editor origin to pos
VectorCopy( ent->s.origin, ent->s.pos.trBase ); VectorCopy( ent->s.origin, ent->s.pos.trBase );

View file

@ -5,274 +5,8 @@
#include "g_local.h" #include "g_local.h"
/*
==============================================================================
PACKET FILTERING
You can add or remove addresses from the filter list with:
addip <ip>
removeip <ip>
The ip address is specified in dot format, and any unspecified digits will match any value, so you can specify an entire class C network with "addip 192.246.40".
Removeip will only remove an address specified exactly the same way. You cannot addip a subnet, then removeip a single host.
listip
Prints the current list of filters.
g_filterban <0 or 1>
If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game. This is the default setting.
If 0, then only addresses matching the list will be allowed. This lets you easily set up a private game, or a game that only allows players from your local network.
==============================================================================
*/
// extern vmCvar_t g_banIPs;
// extern vmCvar_t g_filterBan;
typedef struct ipFilter_s
{
unsigned mask;
unsigned compare;
} ipFilter_t;
#define MAX_IPFILTERS 1024
static ipFilter_t ipFilters[MAX_IPFILTERS];
static int numIPFilters;
char *ConcatArgs( int start ); char *ConcatArgs( int start );
/*
=================
StringToFilter
=================
*/
static qboolean StringToFilter (char *s, ipFilter_t *f)
{
char num[128];
int i, j;
byte b[4];
byte m[4];
for (i=0 ; i<4 ; i++)
{
b[i] = 0;
m[i] = 0;
}
for (i=0 ; i<4 ; i++)
{
if (*s < '0' || *s > '9')
{
Com_Printf( "Bad filter address: %s\n", s );
return qfalse;
}
j = 0;
while (*s >= '0' && *s <= '9')
{
num[j++] = *s++;
}
num[j] = 0;
b[i] = atoi(num);
if (b[i] != 0)
m[i] = 255;
if (!*s)
break;
s++;
}
f->mask = *(unsigned *)m;
f->compare = *(unsigned *)b;
return qtrue;
}
/*
=================
UpdateIPBans
=================
*/
static void UpdateIPBans (void)
{
byte b[4];
int i;
char iplist[MAX_INFO_STRING];
*iplist = 0;
for (i = 0 ; i < numIPFilters ; i++)
{
if (ipFilters[i].compare == 0xffffffff)
continue;
*(unsigned *)b = ipFilters[i].compare;
Com_sprintf( iplist + strlen(iplist), sizeof(iplist) - strlen(iplist),
"%i.%i.%i.%i ", b[0], b[1], b[2], b[3]);
}
trap_Cvar_Set( "g_banIPs", iplist );
}
/*
=================
G_FilterPacket
=================
*/
qboolean G_FilterPacket (char *from)
{
int i;
unsigned in;
byte m[4];
char *p;
m[0] = m[1] = m[2] = m[3] = 0;
i = 0;
p = from;
while (*p && i < 4) {
while (*p >= '0' && *p <= '9') {
m[i] = m[i]*10 + (*p - '0');
p++;
}
if (!*p || *p == ':')
break;
i++, p++;
}
in = *(unsigned *)m;
for (i=0 ; i<numIPFilters ; i++)
if ( (in & ipFilters[i].mask) == ipFilters[i].compare)
return g_filterBan.integer != 0;
return g_filterBan.integer == 0;
}
/*
=================
AddIP
=================
*/
static void AddIP( char *str )
{
int i;
for (i = 0 ; i < numIPFilters ; i++)
{
if (ipFilters[i].compare == 0xffffffff)
{
break; // free spot
}
}
if (i == numIPFilters)
{
if (numIPFilters == MAX_IPFILTERS)
{
Com_Printf ("IP filter list is full\n");
return;
}
numIPFilters++;
}
if (!StringToFilter (str, &ipFilters[i]))
{
ipFilters[i].compare = 0xffffffffu;
}
UpdateIPBans();
}
/*
=================
G_ProcessIPBans
=================
*/
void G_ProcessIPBans(void)
{
char *s, *t;
char str[MAX_TOKEN_CHARS];
Q_strncpyz( str, g_banIPs.string, sizeof(str) );
for (t = s = g_banIPs.string; *t; /* */ ) {
s = strchr(s, ' ');
if (!s)
break;
while (*s == ' ')
*s++ = 0;
if (*t)
AddIP( t );
t = s;
}
}
/*
=================
Svcmd_AddIP_f
=================
*/
void Svcmd_AddIP_f (void)
{
char str[MAX_TOKEN_CHARS];
if ( trap_Argc() < 2 ) {
Com_Printf("Usage: addip <ip-mask>\n");
return;
}
trap_Argv( 1, str, sizeof( str ) );
AddIP( str );
}
/*
=================
Svcmd_RemoveIP_f
=================
*/
void Svcmd_RemoveIP_f (void)
{
ipFilter_t f;
int i;
char str[MAX_TOKEN_CHARS];
if ( trap_Argc() < 2 ) {
Com_Printf("Usage: sv removeip <ip-mask>\n");
return;
}
trap_Argv( 1, str, sizeof( str ) );
if (!StringToFilter (str, &f))
return;
for (i=0 ; i<numIPFilters ; i++) {
if (ipFilters[i].mask == f.mask &&
ipFilters[i].compare == f.compare) {
ipFilters[i].compare = 0xffffffffu;
Com_Printf ("Removed.\n");
UpdateIPBans();
return;
}
}
Com_Printf ( "Didn't find %s.\n", str );
}
/* /*
=================== ===================
Svcmd_EntityList_f Svcmd_EntityList_f
@ -359,6 +93,16 @@ void Svcmd_ExtendTime_f (void)
trap_SendServerCommand( -1, va("print \"timelimit extended by %d minutes\n\"", time) ); trap_SendServerCommand( -1, va("print \"timelimit extended by %d minutes\n\"", time) );
} }
void Svcmd_AutoKickList_f ( void )
{
int i;
for ( i = 0; i < level.autokickedCount; i ++ )
{
Com_Printf ( "%16s - %s\n", level.autokickedIP[i], level.autokickedName[i] );
}
}
gclient_t *ClientForString( const char *s ) { gclient_t *ClientForString( const char *s ) {
gclient_t *cl; gclient_t *cl;
int i; int i;
@ -482,24 +226,6 @@ qboolean ConsoleCommand( void )
#endif #endif
if (Q_stricmp (cmd, "addip") == 0)
{
Svcmd_AddIP_f();
return qtrue;
}
if (Q_stricmp (cmd, "removeip") == 0)
{
Svcmd_RemoveIP_f();
return qtrue;
}
if (Q_stricmp (cmd, "listip") == 0)
{
trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" );
return qtrue;
}
if (Q_stricmp (cmd, "gametype_restart" ) == 0 ) if (Q_stricmp (cmd, "gametype_restart" ) == 0 )
{ {
G_ResetGametype ( ); G_ResetGametype ( );
@ -512,6 +238,12 @@ qboolean ConsoleCommand( void )
return qtrue; return qtrue;
} }
if ( Q_stricmp ( cmd, "autokicklist" ) == 0 )
{
Svcmd_AutoKickList_f();
return qtrue;
}
if (g_dedicated.integer) if (g_dedicated.integer)
{ {
if (Q_stricmp (cmd, "say") == 0) if (Q_stricmp (cmd, "say") == 0)

View file

@ -194,6 +194,8 @@ equ trap_G2_ListModelSurfaces -586 ; G_G2_LISTSURFACES
equ trap_G2_ListModelBones -585 ; G_G2_LISTBONES equ trap_G2_ListModelBones -585 ; G_G2_LISTBONES
equ trap_G2_SetGhoul2ModelIndexes -588 ; G_G2_SETMODELS equ trap_G2_SetGhoul2ModelIndexes -588 ; G_G2_SETMODELS
equ trap_G2_HaveWeGhoul2Models -587 ; G_G2_HAVEWEGHOULMODELS equ trap_G2_HaveWeGhoul2Models -587 ; G_G2_HAVEWEGHOULMODELS
equ trap_G2API_AddBolt -591 ; G_G2_ADDBOLT
equ trap_G2API_SetBoltInfo -592 ; G_G2_SETBOLTINFO
equ trap_G2API_GetBoltMatrix -589 ; G_G2_GETBOLT equ trap_G2API_GetBoltMatrix -589 ; G_G2_GETBOLT
equ trap_G2API_InitGhoul2Model -590 ; G_G2_INITGHOUL2MODEL equ trap_G2API_InitGhoul2Model -590 ; G_G2_INITGHOUL2MODEL
equ trap_G2API_CleanGhoul2Models -600 ; G_G2_CLEANMODELS equ trap_G2API_CleanGhoul2Models -600 ; G_G2_CLEANMODELS

View file

@ -825,6 +825,16 @@ qboolean trap_G2_HaveWeGhoul2Models( void *ghoul2)
return (qboolean)(syscall(G_G2_HAVEWEGHOULMODELS, ghoul2)); return (qboolean)(syscall(G_G2_HAVEWEGHOULMODELS, ghoul2));
} }
int trap_G2API_AddBolt(void *ghoul2, const int modelIndex, const char *boneName)
{
return (int) (syscall(G_G2_ADDBOLT, ghoul2, modelIndex, boneName));
}
void trap_G2API_SetBoltInfo(void *ghoul2, int modelIndex, int boltInfo)
{
syscall(G_G2_SETBOLTINFO, ghoul2, modelIndex, boltInfo);
}
qboolean trap_G2API_GetBoltMatrix(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, qboolean trap_G2API_GetBoltMatrix(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale) const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale)
{ {

View file

@ -151,7 +151,7 @@ Team_GetLocation
Report a location for the player. Uses placed nearby target_location entities Report a location for the player. Uses placed nearby target_location entities
============ ============
*/ */
gentity_t *Team_GetLocation(gentity_t *ent) gentity_t *Team_GetLocation(gentity_t *ent, qboolean pvs )
{ {
gentity_t *eloc, *best; gentity_t *eloc, *best;
float bestlen, len; float bestlen, len;
@ -173,7 +173,7 @@ gentity_t *Team_GetLocation(gentity_t *ent)
continue; continue;
} }
if ( !trap_InPVS( origin, eloc->r.currentOrigin ) ) if ( pvs && !trap_InPVS( origin, eloc->r.currentOrigin ) )
{ {
continue; continue;
} }
@ -195,7 +195,11 @@ qboolean Team_GetLocationMsg ( gentity_t *ent, char *loc, int loclen )
{ {
gentity_t *best; gentity_t *best;
best = Team_GetLocation( ent ); best = Team_GetLocation( ent, qtrue );
if ( !best )
{
best = Team_GetLocation( ent, qfalse );
}
if (!best) if (!best)
{ {

View file

@ -8,7 +8,7 @@ const char* OtherTeamName ( team_t team );
const char* TeamColorString ( team_t team ); const char* TeamColorString ( team_t team );
void G_AddTeamScore ( team_t team, int score ); void G_AddTeamScore ( team_t team, int score );
gentity_t* Team_GetLocation ( gentity_t *ent ); gentity_t* Team_GetLocation ( gentity_t *ent, qboolean pvs );
qboolean Team_GetLocationMsg ( gentity_t *ent, char *loc, int loclen ); qboolean Team_GetLocationMsg ( gentity_t *ent, char *loc, int loclen );

View file

@ -329,9 +329,14 @@ NO_PROTECTION *nothing* stops the damage
*/ */
void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) { void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
if ( self->r.linked ) { if ( self->r.linked ) {
trap_UnlinkEntity( self ); trap_UnlinkEntity( self );
} else { } else {
// Triggers that are used to turn them on no longer cause suicide penalty
self->methodOfDeath = MOD_TRIGGER_HURT_NOSUICIDE;
trap_LinkEntity( self ); trap_LinkEntity( self );
} }
} }
@ -364,7 +369,7 @@ void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
dflags = DAMAGE_NO_PROTECTION; dflags = DAMAGE_NO_PROTECTION;
else else
dflags = 0; dflags = 0;
G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT, HL_NONE ); G_Damage (other, self, self, NULL, NULL, self->damage, dflags, self->methodOfDeath, HL_NONE );
} }
void SP_trigger_hurt( gentity_t *self ) { void SP_trigger_hurt( gentity_t *self ) {
@ -377,14 +382,13 @@ void SP_trigger_hurt( gentity_t *self ) {
self->damage = 5; self->damage = 5;
} }
self->methodOfDeath = MOD_TRIGGER_HURT;
self->r.contents = CONTENTS_TRIGGER; self->r.contents = CONTENTS_TRIGGER;
if ( self->spawnflags & 2 ) {
self->use = hurt_use; self->use = hurt_use;
}
// link in to the world if starting active // link in to the world if starting active
if ( ! (self->spawnflags & 1) ) { if ( ! (self->spawnflags & 1) )
{
trap_LinkEntity (self); trap_LinkEntity (self);
} }
} }
@ -398,6 +402,7 @@ void SP_trigger_ladder ( gentity_t* self )
{ {
vec3_t fwd; vec3_t fwd;
trap_SetBrushModel( self, self->model );
trap_LinkEntity ( self ); trap_LinkEntity ( self );
trap_SetConfigstring( CS_LADDERS + level.ladderCount++, trap_SetConfigstring( CS_LADDERS + level.ladderCount++,

View file

@ -252,7 +252,7 @@ void G_UseTargetsByName( const char* name, gentity_t* other, gentity_t *activato
} }
} }
if ( !other->inuse ) if ( other && !other->inuse )
{ {
Com_Printf("entity was removed while using targets\n"); Com_Printf("entity was removed while using targets\n");
return; return;
@ -662,6 +662,16 @@ void G_PlayEffect(int fxID, vec3_t org, vec3_t ang)
te->s.eventParm = fxID; te->s.eventParm = fxID;
} }
/*
=============
G_SetHUDIcon
=============
*/
void G_SetHUDIcon ( int index, int icon )
{
trap_SetConfigstring ( CS_HUDICONS + index, va("%i", icon ) );
}
/* /*
============= =============
G_Sound G_Sound

View file

@ -549,12 +549,6 @@ void G_FireBullet ( gentity_t* ent, int weapon, int attack )
for ( h = 0; h < hitcount; h ++ ) for ( h = 0; h < hitcount; h ++ )
{ {
// We wann all pellets counting towards team damage
if ( ent->client )
{
ent->client->sess.teamkillForgiveTime = 0;
}
G_Damage( hit[h].ent, ent, ent, fwd, hit[h].origin, hit[h].damage, flags, attackDat->mod + (attack<<8), hit[h].location ); G_Damage( hit[h].ent, ent, ent, fwd, hit[h].origin, hit[h].damage, flags, attackDat->mod + (attack<<8), hit[h].location );
} }
} }
@ -588,7 +582,7 @@ gentity_t* G_FireProjectile ( gentity_t *ent, weapon_t weapon, attackType_t atta
muzzlePoint[2] += ent->client->ps.viewheight; muzzlePoint[2] += ent->client->ps.viewheight;
// Inform of the grenade toss if its a timed grenade // Inform of the grenade toss if its a timed grenade
if ( weapon >= WP_M67_GRENADE && weapon < WP_M15_GRENADE && (flags&PROJECTILE_TIMED) && (ent->client->ps.pm_type == PM_NORMAL) ) if ( weapon >= WP_M84_GRENADE && weapon < WP_M15_GRENADE && (flags&PROJECTILE_TIMED) && (ent->client->ps.pm_type == PM_NORMAL) )
{ {
gentity_t* nearby; gentity_t* nearby;

View file

@ -66,33 +66,30 @@ typedef enum
MODELINDEX_WEAPON_M60, // 16 MODELINDEX_WEAPON_M60, // 16
MODELINDEX_WEAPON_RPG7, MODELINDEX_WEAPON_RPG7,
MODELINDEX_WEAPON_MM1, MODELINDEX_WEAPON_MM1,
MODELINDEX_WEAPON_M67,
MODELINDEX_WEAPON_M84, MODELINDEX_WEAPON_M84,
MODELINDEX_WEAPON_F1, // 21
MODELINDEX_WEAPON_L2A2,
MODELINDEX_WEAPON_MDN11,
MODELINDEX_WEAPON_SMOHG92, MODELINDEX_WEAPON_SMOHG92,
MODELINDEX_WEAPON_ANM14,
MODELINDEX_WEAPON_M15, // 26 MODELINDEX_WEAPON_ANM14, // 21
MODELINDEX_WEAPON_M15,
MODELINDEX_WEAPON_MP5,
MODELINDEX_AMMO_045, MODELINDEX_AMMO_045,
MODELINDEX_AMMO_9MM, MODELINDEX_AMMO_9MM,
MODELINDEX_AMMO_12GAUGE, MODELINDEX_AMMO_12GAUGE,
MODELINDEX_AMMO_762,
MODELINDEX_AMMO_556, // 31 MODELINDEX_AMMO_762, // 26
MODELINDEX_AMMO_556,
MODELINDEX_AMMO_40MM, MODELINDEX_AMMO_40MM,
MODELINDEX_AMMO_RPG7, MODELINDEX_AMMO_RPG7,
MODELINDEX_BACKPACK, MODELINDEX_BACKPACK,
MODELINDEX_GAMETYPE_ITEM, MODELINDEX_GAMETYPE_ITEM, // 31
MODELINDEX_GAMETYPE_ITEM_2, MODELINDEX_GAMETYPE_ITEM_2,
MODELINDEX_GAMETYPE_ITEM_3, MODELINDEX_GAMETYPE_ITEM_3,
MODELINDEX_GAMETYPE_ITEM_4, MODELINDEX_GAMETYPE_ITEM_4,
MODELINDEX_GAMETYPE_ITEM_5, MODELINDEX_GAMETYPE_ITEM_5,
MODELINDEX_ARMOR, MODELINDEX_ARMOR, // 36
MODELINDEX_NIGHTVISION, MODELINDEX_NIGHTVISION,
MODELINDEX_THERMAL, MODELINDEX_THERMAL,

View file

@ -877,11 +877,17 @@ int Q_PrintStrlen( const char *string ) {
len = 0; len = 0;
p = string; p = string;
while( *p ) { while( *p )
if( Q_IsColorString( p ) ) { {
p += 2; if( *p == '^' )
{
p++;
if ( *p != '^' )
{
p ++;
continue; continue;
} }
}
p++; p++;
len++; len++;
} }
@ -898,10 +904,18 @@ char *Q_CleanStr( char *string ) {
s = string; s = string;
d = string; d = string;
while ((c = *s) != 0 ) { while ((c = *s) != 0 ) {
if ( Q_IsColorString( s ) ) {
if( *s == '^' )
{
s++; s++;
if( *s == '^' )
{
*d++ = '^';
*d++ = '^';
} }
else if ( c >= 0x20 && c <= 0x7E ) { }
else if ( c >= 0x20 && c <= 0x7E )
{
*d++ = c; *d++ = c;
} }
s++; s++;

View file

@ -6,36 +6,12 @@
// q_shared.h -- included first by ALL program modules. // q_shared.h -- included first by ALL program modules.
// A user mod should never modify this file // A user mod should never modify this file
//#define Q3_VERSION "SOF2MP V0.01" sent on 11/26/2001
//#define Q3_VERSION "SOF2MP V0.02" sent on 12/10/2001
//#define Q3_VERSION "SOF2MP V0.03" sent on 12/16/2001
//#define Q3_VERSION "SOF2MP V0.081" sent on 1/15/2002
//#define Q3_VERSION "SOF2MP V0.09" sent on 1/24/2002
//#define Q3_VERSION "SOF2MP V0.10" sent on 1/31/2002
//#define Q3_VERSION "SOF2MP V0.11" sent on 2/7/2002
//#define Q3_VERSION "SOF2MP V0.12" sent on 2/14/2002
//#define Q3_VERSION "SOF2MP V0.13" sent on 2/21/2002
//#define Q3_VERSION "SOF2MP V0.13b" public beta #1 on 3/1/3002
//#define Q3_VERSION "SOF2MP V0.14" sent on 3/4/2002
//#define Q3_VERSION "SOF2MP V0.15" sent on 3/11/2002
//#define Q3_VERSION "SOF2MP V0.15b" public beta #2 on 3/13/2002
//#define Q3_VERSION "SOF2MP V0.16" sent on 3/18/2002
//#define Q3_VERSION "SOF2MP V0.16b" public beta #3 on 3/20/2002
//#define Q3_VERSION "SOF2MP V0.17" sent on 3/24/2002
//#define Q3_VERSION "SOF2MP TEST V1.01t" sent on 3/28/2002
//#define Q3_VERSION "SOF2MP V0.18" sent on 4/1/2002 - April Fools!
//#define Q3_VERSION "SOF2MP V1.02t" sent on 4/5/2002
//#define Q3_VERSION "SOF2MP V0.19" sent on 4/8/2002
//#define Q3_VERSION "SOF2MP V0.20" sent on 4/15/2002 - Tax Day!
//#define Q3_VERSION "SOF2MP V0.21" sent on 4/22/2002
//#define Q3_VERSION "SOF2MP V1.00.22" sent on 4/26/2002
//#define Q3_VERSION "SOF2MP V1.00.23" sent on 4/27/2002
#ifdef GERMAN_BUILD #ifdef GERMAN_BUILD
#define Q3_VERSION "SOF2MP V1.00g" #define Q3_VERSION "SOF2MP V1.01g" // sent on 6/10/2002
#define SOF2_VERSION_ID "1.00g" #define SOF2_VERSION_ID "1.01g" // sent on 6/10/2002
#else #else
#define Q3_VERSION "SOF2MP V1.00" #define Q3_VERSION "SOF2MP V1.01" // sent on 6/10/2002
#define SOF2_VERSION_ID "1.00" #define SOF2_VERSION_ID "1.01" // sent on 6/10/2002
#endif #endif
//#define SPECIAL_PRE_CACHE 1 //#define SPECIAL_PRE_CACHE 1
@ -1340,6 +1316,7 @@ typedef enum {
#define MAX_SUB_BSP 32 #define MAX_SUB_BSP 32
#define MAX_ICONS 32 #define MAX_ICONS 32
#define MAX_CHARSKINS 64 // character skins #define MAX_CHARSKINS 64 // character skins
#define MAX_HUDICONS 16 // icons on hud
#define MAX_CONFIGSTRINGS 1400 #define MAX_CONFIGSTRINGS 1400

View file

@ -20,6 +20,13 @@ typedef struct gametypeLocals_s
int redCaptureEffect; int redCaptureEffect;
int blueCaptureEffect; int blueCaptureEffect;
int iconRedFlag;
int iconBlueFlag;
int iconRedFlagDropped;
int iconBlueFlagDropped;
int iconRedFlagCarried;
int iconBlueFlagCarried;
} gametypeLocals_t; } gametypeLocals_t;
extern gametypeLocals_t gametype; extern gametypeLocals_t gametype;

View file

@ -57,6 +57,8 @@ int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int a
return 0; return 0;
case GAMETYPE_START: case GAMETYPE_START:
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlag );
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlag );
return 0; return 0;
case GAMETYPE_RUN_FRAME: case GAMETYPE_RUN_FRAME:
@ -131,9 +133,18 @@ void GT_Init ( void )
memset ( &gametype, 0, sizeof(gametype) ); memset ( &gametype, 0, sizeof(gametype) );
// Register the global sounds // Register the global sounds
gametype.flagReturnSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_return.mp3" ); gametype.flagReturnSound = trap_Cmd_RegisterSound ( "sound/ctf_return.mp3" );
gametype.flagTakenSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_flag.mp3" ); gametype.flagTakenSound = trap_Cmd_RegisterSound ( "sound/ctf_flag.mp3" );
gametype.flagCaptureSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_win.mp3" ); gametype.flagCaptureSound = trap_Cmd_RegisterSound ( "sound/ctf_win.mp3" );
gametype.iconRedFlag = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_red" );
gametype.iconBlueFlag = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_blue" );
gametype.iconRedFlagDropped = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_red_dropped" );
gametype.iconBlueFlagDropped = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_blue_dropped" );
gametype.iconRedFlagCarried = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_red_carried" );
gametype.iconBlueFlagCarried = trap_Cmd_RegisterIcon ( "gfx/menus/hud/ctf_blue_carried" );
// Register all cvars for this gametype // Register all cvars for this gametype
GT_RegisterCvars ( ); GT_RegisterCvars ( );
@ -165,6 +176,7 @@ void GT_RunFrame ( int time )
{ {
trap_Cmd_ResetItem ( ITEM_REDFLAG ); trap_Cmd_ResetItem ( ITEM_REDFLAG );
trap_Cmd_TextMessage ( -1, "The Red Flag has returned!" ); trap_Cmd_TextMessage ( -1, "The Red Flag has returned!" );
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlag );
trap_Cmd_StartGlobalSound ( gametype.flagReturnSound ); trap_Cmd_StartGlobalSound ( gametype.flagReturnSound );
gametype.redFlagDropTime = 0; gametype.redFlagDropTime = 0;
} }
@ -174,6 +186,7 @@ void GT_RunFrame ( int time )
{ {
trap_Cmd_ResetItem ( ITEM_BLUEFLAG ); trap_Cmd_ResetItem ( ITEM_BLUEFLAG );
trap_Cmd_TextMessage ( -1, "The Blue Flag has returned!" ); trap_Cmd_TextMessage ( -1, "The Blue Flag has returned!" );
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlag );
trap_Cmd_StartGlobalSound ( gametype.flagReturnSound ); trap_Cmd_StartGlobalSound ( gametype.flagReturnSound );
gametype.blueFlagDropTime = 0; gametype.blueFlagDropTime = 0;
} }
@ -207,6 +220,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_TextMessage ( -1, "The Red Flag has returned!" ); trap_Cmd_TextMessage ( -1, "The Red Flag has returned!" );
trap_Cmd_StartGlobalSound ( gametype.flagReturnSound ); trap_Cmd_StartGlobalSound ( gametype.flagReturnSound );
gametype.redFlagDropTime = 0; gametype.redFlagDropTime = 0;
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlag );
return 1; return 1;
case ITEM_BLUEFLAG: case ITEM_BLUEFLAG:
@ -214,6 +228,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_TextMessage ( -1, "The Blue Flag has returned!" ); trap_Cmd_TextMessage ( -1, "The Blue Flag has returned!" );
trap_Cmd_StartGlobalSound ( gametype.flagReturnSound ); trap_Cmd_StartGlobalSound ( gametype.flagReturnSound );
gametype.blueFlagDropTime = 0; gametype.blueFlagDropTime = 0;
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlag );
return 1; return 1;
} }
@ -229,11 +244,13 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
{ {
case ITEM_BLUEFLAG: case ITEM_BLUEFLAG:
trap_Cmd_TextMessage ( -1, va("%s has dropped the Blue Flag!", clientname ) ); trap_Cmd_TextMessage ( -1, va("%s has dropped the Blue Flag!", clientname ) );
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlagDropped );
gametype.blueFlagDropTime = time; gametype.blueFlagDropTime = time;
break; break;
case ITEM_REDFLAG: case ITEM_REDFLAG:
trap_Cmd_TextMessage ( -1, va("%s has dropped the Red Flag!", clientname ) ); trap_Cmd_TextMessage ( -1, va("%s has dropped the Red Flag!", clientname ) );
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlagDropped );
gametype.redFlagDropTime = time; gametype.redFlagDropTime = time;
break; break;
} }
@ -252,6 +269,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_TextMessage ( -1, va("%s has taken the Blue Flag!", clientname ) ); trap_Cmd_TextMessage ( -1, va("%s has taken the Blue Flag!", clientname ) );
trap_Cmd_StartGlobalSound ( gametype.flagTakenSound ); trap_Cmd_StartGlobalSound ( gametype.flagTakenSound );
trap_Cmd_RadioMessage ( arg1, "got_it" ); trap_Cmd_RadioMessage ( arg1, "got_it" );
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlagCarried );
gametype.blueFlagDropTime = 0; gametype.blueFlagDropTime = 0;
return 1; return 1;
@ -266,6 +284,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_TextMessage ( -1, va("%s has taken the Red Flag!", clientname ) ); trap_Cmd_TextMessage ( -1, va("%s has taken the Red Flag!", clientname ) );
trap_Cmd_StartGlobalSound ( gametype.flagTakenSound ); trap_Cmd_StartGlobalSound ( gametype.flagTakenSound );
trap_Cmd_RadioMessage ( arg1, "got_it" ); trap_Cmd_RadioMessage ( arg1, "got_it" );
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlagCarried );
gametype.redFlagDropTime = 0; gametype.redFlagDropTime = 0;
return 1; return 1;
@ -287,6 +306,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_ResetItem ( ITEM_REDFLAG ); trap_Cmd_ResetItem ( ITEM_REDFLAG );
trap_Cmd_StartGlobalSound ( gametype.flagCaptureSound ); trap_Cmd_StartGlobalSound ( gametype.flagCaptureSound );
trap_Cmd_AddTeamScore ( arg2, 1 ); trap_Cmd_AddTeamScore ( arg2, 1 );
trap_Cmd_SetHUDIcon ( 0, gametype.iconRedFlag );
if ( !gt_simpleScoring.integer ) if ( !gt_simpleScoring.integer )
{ {
@ -306,6 +326,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_ResetItem ( ITEM_BLUEFLAG ); trap_Cmd_ResetItem ( ITEM_BLUEFLAG );
trap_Cmd_StartGlobalSound ( gametype.flagCaptureSound ); trap_Cmd_StartGlobalSound ( gametype.flagCaptureSound );
trap_Cmd_AddTeamScore ( arg2, 1 ); trap_Cmd_AddTeamScore ( arg2, 1 );
trap_Cmd_SetHUDIcon ( 1, gametype.iconBlueFlag );
if ( !gt_simpleScoring.integer ) if ( !gt_simpleScoring.integer )
{ {

View file

@ -0,0 +1,30 @@
@set include=
del /q vm
mkdir vm
cd vm
set cc=..\..\..\..\bin\sof2lcc -A -DQ3_VM -DMISSIONPACK -S -Wf-target=bytecode -Wf-g -I..\..\..\gametype -I..\..\gt_dem -I..\..\..\game %1
%cc% ../gt_main.c
@if errorlevel 1 goto quit
%cc% ../../gt_syscalls.c
@if errorlevel 1 goto quit
%cc% ../../../game/bg_lib.c
@if errorlevel 1 goto quit
%cc% ../../../game/q_shared.c
@if errorlevel 1 goto quit
%cc% ../../../game/q_math.c
@if errorlevel 1 goto quit
..\..\..\..\bin\sof2asm -f ../gt_dem
@if errorlevel 1 goto quit
mkdir "..\..\..\..\base\vm"
copy *.map "..\..\..\..\base\vm"
copy *.qvm "..\..\..\..\base\vm"
:quit
cd ..

View file

@ -0,0 +1,134 @@
# Microsoft Developer Studio Project File - Name="gt_dem" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=gt_dem - Win32 Debug SoF2
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "gt_dem.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "gt_dem.mak" CFG="gt_dem - Win32 Debug SoF2"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "gt_dem - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "gt_dem - Win32 Debug SoF2" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SoF2/code/gametype/gt_dem", ZRDAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "gt_dem - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "gt_dem_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "gt_dem_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "gt_dem - Win32 Debug SoF2"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug SoF2"
# PROP BASE Intermediate_Dir "Debug SoF2"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\Debug"
# PROP Intermediate_Dir "..\..\Debug\gt_dem"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "gt_dem_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_SOF2" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x40000000" /dll /map /debug /machine:I386 /out:"..\..\Debug/gt_demx86.dll"
!ENDIF
# Begin Target
# Name "gt_dem - Win32 Debug"
# Name "gt_dem - Win32 Debug SoF2"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\game\bg_lib.c
# End Source File
# Begin Source File
SOURCE=.\gt_main.c
# End Source File
# Begin Source File
SOURCE=..\gt_syscalls.c
# End Source File
# Begin Source File
SOURCE=..\..\game\q_math.c
# End Source File
# Begin Source File
SOURCE=..\..\game\q_shared.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\gt_local.h
# End Source File
# Begin Source File
SOURCE=..\gt_public.h
# End Source File
# Begin Source File
SOURCE=..\sof2_gametype.def
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View file

@ -0,0 +1,7 @@
-o "gt_dem"
gt_main
bg_lib
q_math
q_shared
..\..\gt_syscalls

View file

@ -0,0 +1,37 @@
// Copyright (C) 2001-2002 Raven Software.
//
// gt_local.h -- local definitions for gametype module
#include "../../game/q_shared.h"
#include "../gt_public.h"
#include "../gt_syscalls.h"
typedef struct gametypeLocals_s
{
int time;
int bombBeepTime;
int bombPlantTime;
vec3_t bombPlantOrigin;
char bombPlantTarget[MAX_QPATH];
qboolean firstFrame;
int bombExplodeEffect;
int bombBeepSound;
int bombTakenSound;
int bombExplodedSound;
int bombPlantedSound;
int iconBombPlanted[7];
int bombGiveClient;
int bombPlantClient;
qboolean roundOver;
} gametypeLocals_t;
extern gametypeLocals_t gametype;

View file

@ -0,0 +1,440 @@
// Copyright (C) 2001-2002 Raven Software.
//
#include "gt_local.h"
#define TRIGGER_DEMOSITE_1 200
#define TRIGGER_DEMOSITE_2 201
#define ITEM_BOMB 300
#define ITEM_PLANTED_BOMB 301
void GT_Init ( void );
void GT_RunFrame ( int time );
int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int arg4 );
gametypeLocals_t gametype;
typedef struct
{
vmCvar_t *vmCvar;
char *cvarName;
char *defaultString;
int cvarFlags;
float mMinValue, mMaxValue;
int modificationCount; // for tracking changes
qboolean trackChange; // track this variable, and announce if changed
qboolean teamShader; // track and if changed, update shader state
} cvarTable_t;
vmCvar_t gt_bombFuseTime;
vmCvar_t gt_bombDefuseTime;
vmCvar_t gt_bombPlantTime;
vmCvar_t gt_simpleScoring;
static cvarTable_t gametypeCvarTable[] =
{
// don't override the cheat state set by the system
{ &gt_bombFuseTime, "gt_bombFuseTime", "30", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
{ &gt_bombDefuseTime, "gt_bombDefuseTime", "3", CVAR_ARCHIVE|CVAR_LATCH, 0.0f, 0.0f, 0, qfalse },
{ &gt_bombPlantTime, "gt_bombPlantTime", "3", CVAR_ARCHIVE|CVAR_LATCH, 0.0f, 0.0f, 0, qfalse },
{ &gt_simpleScoring, "gt_simpleScoring", "0", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },
};
static int gametypeCvarTableSize = sizeof( gametypeCvarTable ) / sizeof( gametypeCvarTable[0] );
/*
================
vmMain
This is the only way control passes into the module.
This must be the very first function compiled into the .q3vm file
================
*/
int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 )
{
switch ( command )
{
case GAMETYPE_INIT:
GT_Init ( );
return 0;
case GAMETYPE_START:
gametype.firstFrame = qtrue;
gametype.bombPlantTime = 0;
gametype.bombBeepTime = 0;
gametype.roundOver = qfalse;
trap_Cmd_SetHUDIcon ( 0, 0 );
return 0;
case GAMETYPE_RUN_FRAME:
GT_RunFrame ( arg0 );
return 0;
case GAMETYPE_EVENT:
return GT_Event ( arg0, arg1, arg2, arg3, arg4, arg5, arg6 );
}
return -1;
}
/*
=================
GT_RegisterCvars
=================
*/
void GT_RegisterCvars( void )
{
int i;
cvarTable_t *cv;
for ( i = 0, cv = gametypeCvarTable ; i < gametypeCvarTableSize ; i++, cv++ )
{
trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags, cv->mMinValue, cv->mMaxValue );
if ( cv->vmCvar )
{
cv->modificationCount = cv->vmCvar->modificationCount;
}
}
}
/*
=================
GT_UpdateCvars
=================
*/
void GT_UpdateCvars( void )
{
int i;
cvarTable_t *cv;
for ( i = 0, cv = gametypeCvarTable ; i < gametypeCvarTableSize ; i++, cv++ )
{
if ( cv->vmCvar )
{
trap_Cvar_Update( cv->vmCvar );
if ( cv->modificationCount != cv->vmCvar->modificationCount )
{
cv->modificationCount = cv->vmCvar->modificationCount;
}
}
}
}
/*
================
GT_Init
initializes the gametype by spawning the gametype items and
preparing them
================
*/
void GT_Init ( void )
{
gtTriggerDef_t triggerDef;
gtItemDef_t itemDef;
memset ( &gametype, 0, sizeof(gametype) );
// Register all cvars for this gametype
GT_RegisterCvars ( );
gametype.bombTakenSound = trap_Cmd_RegisterSound ( "sound/ctf_flag.mp3" );
gametype.bombExplodedSound = trap_Cmd_RegisterSound ( "sound/ctf_win.mp3" );
gametype.bombPlantedSound = trap_Cmd_RegisterSound ( "sound/ctf_base.mp3" );
gametype.bombExplodeEffect = trap_Cmd_RegisterEffect ( "explosions/mushroom_explosion.efx" );
gametype.bombBeepSound = trap_Cmd_RegisterSound ( "sound/misc/c4/beep" );
// Register the triggers
memset ( &triggerDef, 0, sizeof(triggerDef) );
triggerDef.size = sizeof(triggerDef);
triggerDef.use = qtrue;
triggerDef.useTime = gt_bombPlantTime.integer * 1000;
triggerDef.useIcon = trap_Cmd_RegisterIcon ( "gfx/menus/hud/tnt" );
triggerDef.useSound = trap_Cmd_RegisterSound ( "sound/misc/c4/c4_loop" );
trap_Cmd_RegisterTrigger ( TRIGGER_DEMOSITE_1, "demolition_site_1", &triggerDef );
trap_Cmd_RegisterTrigger ( TRIGGER_DEMOSITE_2, "demolition_site_2", &triggerDef );
memset ( &itemDef, 0, sizeof(itemDef) );
itemDef.size = sizeof(itemDef);
trap_Cmd_RegisterItem ( ITEM_BOMB, "c4", &itemDef );
itemDef.use = qtrue;
itemDef.useTime = gt_bombDefuseTime.integer * 1000;
itemDef.useSound = triggerDef.useSound;
itemDef.useIcon = trap_Cmd_RegisterIcon ( "gfx/menus/hud/wire_cutters" );
trap_Cmd_RegisterItem ( ITEM_PLANTED_BOMB, "armed_c4", &itemDef );
gametype.iconBombPlanted[0] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted" );
gametype.iconBombPlanted[1] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted1" );
gametype.iconBombPlanted[2] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted2" );
gametype.iconBombPlanted[3] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted3" );
gametype.iconBombPlanted[4] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted4" );
gametype.iconBombPlanted[5] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted5" );
gametype.iconBombPlanted[6] = trap_Cmd_RegisterIcon ( "gfx/menus/hud/dem_planted6" );
}
/*
================
GT_RunFrame
Runs all thinking code for gametype
================
*/
void GT_RunFrame ( int time )
{
gametype.time = time;
if ( gametype.firstFrame )
{
int clients[MAX_CLIENTS];
int count;
count = trap_Cmd_GetClientList ( TEAM_BLUE, clients, 64 );
if ( count )
{
gametype.bombGiveClient = gametype.bombGiveClient % count;
trap_Cmd_GiveClientItem ( clients[gametype.bombGiveClient], ITEM_BOMB );
gametype.firstFrame = qfalse;
// Next time use the next client in the list
gametype.bombGiveClient = (gametype.bombGiveClient + 1 ) % count;
}
}
if ( gametype.bombPlantTime )
{
static const int slowTime = 1000;
static const int fastTime = 100;
if ( !gametype.bombBeepTime || gametype.time > gametype.bombBeepTime )
{
float addTime;
addTime = (float)(gametype.bombPlantTime - gametype.time) / (float)(gt_bombFuseTime.integer * 1000);
addTime = fastTime + (addTime * (float)(slowTime - fastTime) );
gametype.bombBeepTime = gametype.time + (int)addTime;
trap_Cmd_StartSound ( gametype.bombBeepSound, gametype.bombPlantOrigin );
addTime = (float)(gametype.bombPlantTime - gametype.time) / (float)(gt_bombFuseTime.integer * 1000);
addTime = 6.0f - 6.0f * addTime ;
trap_Cmd_SetHUDIcon ( 0, gametype.iconBombPlanted[ Com_Clamp ( 0, 6, (int)addTime ) ] );
}
}
if ( gametype.bombPlantTime && gametype.time > gametype.bombPlantTime )
{
static vec3_t up = {0,0,1};
int clients[MAX_CLIENTS];
int count;
trap_Cmd_PlayEffect ( gametype.bombExplodeEffect, gametype.bombPlantOrigin, up );
trap_Cmd_UseTargets ( gametype.bombPlantTarget );
trap_Cmd_ResetItem ( ITEM_PLANTED_BOMB );
if ( !gametype.roundOver )
{
trap_Cmd_AddTeamScore ( TEAM_BLUE, 1 );
trap_Cmd_TextMessage ( -1, "Blue team has destroyed the target!" );
trap_Cmd_StartGlobalSound ( gametype.bombExplodedSound );
trap_Cmd_Restart ( 5 );
}
// Give the guy who planted it some props
if ( !gt_simpleScoring.integer )
{
trap_Cmd_AddClientScore ( gametype.bombPlantClient, 10 );
}
gametype.bombPlantTime = 0;
// Get the bomb client # so we can give the bomb to the same guy again
count = trap_Cmd_GetClientList ( TEAM_BLUE, clients, 64 );
if ( count )
{
for ( count--; count >= 0; count-- )
{
if ( clients[count] == gametype.bombPlantClient )
{
gametype.bombGiveClient = count;
break;
}
}
}
gametype.roundOver = qtrue;
}
GT_UpdateCvars ( );
}
/*
================
GT_Event
Handles all events sent to the gametype
================
*/
int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int arg4 )
{
switch ( cmd )
{
case GTEV_ITEM_DEFEND:
if ( !gt_simpleScoring.integer )
{
trap_Cmd_AddClientScore ( arg1, 5 );
}
return 0;
case GTEV_ITEM_STUCK:
break;
case GTEV_ITEM_DROPPED:
{
char clientname[MAX_QPATH];
trap_Cmd_GetClientName ( arg1, clientname, MAX_QPATH );
trap_Cmd_TextMessage ( -1, va("%s has dropped the bomb!", clientname ) );
break;
}
case GTEV_ITEM_TOUCHED:
if ( arg0 == ITEM_BOMB && arg2 == TEAM_BLUE )
{
char clientname[MAX_QPATH];
trap_Cmd_GetClientName ( arg1, clientname, MAX_QPATH );
trap_Cmd_TextMessage ( -1, va("%s has taken the bomb!", clientname ) );
trap_Cmd_StartGlobalSound ( gametype.bombTakenSound );
trap_Cmd_RadioMessage ( arg1, "got_it" );
return 1;
}
return 0;
case GTEV_ITEM_CANBEUSED:
if ( arg0 == ITEM_PLANTED_BOMB && arg2 == TEAM_RED )
{
return 1;
}
return 0;
case GTEV_TRIGGER_TOUCHED:
return 0;
case GTEV_TRIGGER_CANBEUSED:
if ( trap_Cmd_DoesClientHaveItem ( arg1, ITEM_BOMB ) )
{
return 1;
}
return 0;
case GTEV_TIME_EXPIRED:
trap_Cmd_TextMessage ( -1, "Red team has defended the bomb site!" );
trap_Cmd_AddTeamScore ( TEAM_RED, 1 );
trap_Cmd_Restart ( 5 );
break;
case GTEV_TEAM_ELIMINATED:
switch ( arg0 )
{
case TEAM_RED:
trap_Cmd_TextMessage ( -1, "Red team eliminated!" );
trap_Cmd_AddTeamScore ( TEAM_BLUE, 1 );
trap_Cmd_Restart ( 5 );
gametype.roundOver = qtrue;
break;
case TEAM_BLUE:
// If the bomb is planted the defending team MUST defuse it.
if ( !gametype.bombPlantTime )
{
trap_Cmd_TextMessage ( -1, "Blue team eliminated!" );
trap_Cmd_AddTeamScore ( TEAM_RED, 1 );
trap_Cmd_Restart ( 5 );
gametype.roundOver = qtrue;
}
break;
}
break;
case GTEV_ITEM_USED:
{
char name[128];
trap_Cmd_ResetItem ( ITEM_PLANTED_BOMB );
gametype.bombPlantTime = 0;
gametype.bombBeepTime = 0;
trap_Cmd_AddTeamScore ( TEAM_RED, 1 );
trap_Cmd_GetClientName ( arg1, name, 128 );
trap_Cmd_TextMessage ( -1, va("%s has defused the bomb!", name ) );
trap_Cmd_StartGlobalSound ( gametype.bombExplodedSound );
trap_Cmd_Restart ( 5 );
gametype.roundOver = qtrue;
// Give the guy who defused it some props
if ( !gt_simpleScoring.integer )
{
trap_Cmd_AddClientScore ( arg1, 10 );
}
return 1;
}
case GTEV_TRIGGER_USED:
{
char name[128];
gametype.bombPlantTime = time + gt_bombFuseTime.integer * 1000;
gametype.bombPlantClient = arg1;
trap_Cmd_GetClientOrigin ( arg1, gametype.bombPlantOrigin );
trap_Cmd_TakeClientItem ( arg1, ITEM_BOMB );
trap_Cmd_SpawnItem ( ITEM_PLANTED_BOMB, gametype.bombPlantOrigin, vec3_origin );
trap_Cmd_GetClientName ( arg1, name, 128 );
trap_Cmd_TextMessage ( -1, va("%s has planted the bomb!", name ) );
trap_Cmd_GetTriggerTarget ( arg0, gametype.bombPlantTarget, sizeof(gametype.bombPlantTarget) );
trap_Cmd_SetHUDIcon ( 0, gametype.iconBombPlanted[0] );
trap_Cmd_StartGlobalSound ( gametype.bombPlantedSound );
return 0;
}
}
return 0;
}
#ifndef GAMETYPE_HARD_LINKED
// this is only here so the functions in q_shared.c and bg_*.c can link (FIXME)
void QDECL Com_Error( int level, const char *msg, ... )
{
va_list argptr;
char text[1024];
va_start (argptr, msg);
vsprintf (text, msg, argptr);
va_end (argptr);
trap_Error( text );
}
void QDECL Com_Printf( const char *msg, ... )
{
va_list argptr;
char text[1024];
va_start (argptr, msg);
vsprintf (text, msg, argptr);
va_end (argptr);
trap_Print( text );
}
#endif

View file

@ -127,9 +127,9 @@ void GT_Init ( void )
GT_RegisterCvars ( ); GT_RegisterCvars ( );
// Register the global sounds // Register the global sounds
gametype.caseTakenSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_flag.mp3" ); gametype.caseTakenSound = trap_Cmd_RegisterSound ( "sound/ctf_flag.mp3" );
gametype.caseCaptureSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_win.mp3" ); gametype.caseCaptureSound = trap_Cmd_RegisterSound ( "sound/ctf_win.mp3" );
gametype.caseReturnSound = trap_Cmd_RegisterGlobalSound ( "sound/ctf_return.mp3" ); gametype.caseReturnSound = trap_Cmd_RegisterSound ( "sound/ctf_return.mp3" );
// Register the items // Register the items
memset ( &itemDef, 0, sizeof(itemDef) ); memset ( &itemDef, 0, sizeof(itemDef) );
@ -239,6 +239,7 @@ int GT_Event ( int cmd, int time, int arg0, int arg1, int arg2, int arg3, int ar
trap_Cmd_GetClientName ( arg1, clientname, MAX_QPATH ); trap_Cmd_GetClientName ( arg1, clientname, MAX_QPATH );
trap_Cmd_TextMessage ( -1, va("%s has escaped with the briefcase!", clientname ) ); trap_Cmd_TextMessage ( -1, va("%s has escaped with the briefcase!", clientname ) );
trap_Cmd_StartGlobalSound ( gametype.caseCaptureSound ); trap_Cmd_StartGlobalSound ( gametype.caseCaptureSound );
trap_Cmd_TakeClientItem ( arg1, ITEM_BRIEFCASE );
trap_Cmd_AddTeamScore ( arg2, 1 ); trap_Cmd_AddTeamScore ( arg2, 1 );
if ( !gt_simpleScoring.integer ) if ( !gt_simpleScoring.integer )

View file

@ -41,7 +41,7 @@ typedef enum
GT_RESETITEM, // void ( int itemid ); GT_RESETITEM, // void ( int itemid );
GT_GETCLIENTNAME, // void ( int clientid, const char* buffer, int buffersize ); GT_GETCLIENTNAME, // void ( int clientid, const char* buffer, int buffersize );
GT_REGISTERGLOBALSOUND, // int ( const char* filename ); GT_REGISTERSOUND, // int ( const char* filename );
GT_STARTGLOBALSOUND, // void ( int soundid ); GT_STARTGLOBALSOUND, // void ( int soundid );
GT_REGISTERITEM, // bool ( int itemid, const char* name, gtItemDef_t* def ); GT_REGISTERITEM, // bool ( int itemid, const char* name, gtItemDef_t* def );
@ -59,6 +59,23 @@ typedef enum
GT_REGISTEREFFECT, // int ( const char* name ); GT_REGISTEREFFECT, // int ( const char* name );
GT_PLAYEFFECT, // void ( int effect, vec3_t origin, vec3_t angles ); GT_PLAYEFFECT, // void ( int effect, vec3_t origin, vec3_t angles );
GT_REGISTERICON, // int ( const char* icon );
GT_USETARGETS, // void ( const char* targetname );
GT_GETCLIENTORIGIN, // void ( int clientid, vec3_t origin );
GT_GIVECLIENTITEM, // void ( int clientid, int itemid );
GT_TAKECLIENTITEM, // void ( int clientid, int itemid );
GT_SPAWNITEM, // void ( int itemid, vec3_t origin, vec3_t angles );
GT_STARTSOUND, // void ( int soundid, vec3_t origin );
GT_GETTRIGGERTARGET, // void ( int triggerid, char* buffer, int buffersize );
GT_GETCLIENTLIST, // int ( team_t team, int* clients, int clientcount );
GT_SETHUDICON, // void ( int index, int icon );
} gametypeImport_t; } gametypeImport_t;
@ -78,7 +95,7 @@ typedef enum
GTCMD_RESETITEM, // void ( const char* itemName ); GTCMD_RESETITEM, // void ( const char* itemName );
GTCMD_GETCLIENTNAME, // void ( int clientid, char* buffer, int buffersize ); GTCMD_GETCLIENTNAME, // void ( int clientid, char* buffer, int buffersize );
GTCMD_REGISTERGLOBALSOUND, // int ( const char* soundFile ); GTCMD_REGISTERSOUND, // int ( const char* soundFile );
GTCMD_STARTGLOBALSOUND, // void ( int soundid ); GTCMD_STARTGLOBALSOUND, // void ( int soundid );
GTCMD_REGISTERITEM, // int ( const char* name, gtItemDef_t* def ); GTCMD_REGISTERITEM, // int ( const char* name, gtItemDef_t* def );
@ -96,6 +113,24 @@ typedef enum
GTCMD_REGISTEREFFECT, // int ( const char* name ); GTCMD_REGISTEREFFECT, // int ( const char* name );
GTCMD_PLAYEFFECT, // void ( int effect, vec3_t origin, vec3_t angles ); GTCMD_PLAYEFFECT, // void ( int effect, vec3_t origin, vec3_t angles );
GTCMD_REGISTERICON, // int ( const char* icon );
GTCMD_USETARGETS, // void ( const char* targetname );
GTCMD_GETCLIENTORIGIN, // void ( int clientid, vec3_t origin );
GTCMD_GIVECLIENTITEM, // void ( int clientid, int itemid );
GTCMD_TAKECLIENTITEM, // void ( int clientid, int itemid );
GTCMD_SPAWNITEM, // void ( int itemid, vec3_t origin, vec3_t angles );
GTCMD_STARTSOUND, // void ( int soundid, vec3_t origin );
GTCMD_GETTRIGGERTARGET, // void ( int triggerid, char* bufferr, int buffersize );
GTCMD_GETCLIENTLIST, // int ( team_t team, int* clients, int clientcount );
GTCMD_SETHUDICON, // void ( int index, int icon );
} gametypeCommand_t; } gametypeCommand_t;
@ -116,6 +151,13 @@ typedef enum
GTEV_CLIENT_DEATH, // void ( int clientID, int clientTeam, int killerID, int killerTeam ); GTEV_CLIENT_DEATH, // void ( int clientID, int clientTeam, int killerID, int killerTeam );
GTEV_TRIGGER_USED, // int ( int trigID, int clientID, int clientTeam );
GTEV_TRIGGER_CANBEUSED, // int ( int trigID, int clientID, int clientTeam );
GTEV_ITEM_CANBEUSED, // int ( int itemID, int clientID, int clientTeam );
GTEV_ITEM_USED, // int ( int itemID, int clientID, int clientTeam );
GTEV_MAX GTEV_MAX
} gametypeEvent_t; } gametypeEvent_t;
@ -123,15 +165,21 @@ typedef enum
typedef struct gtItemDef_s typedef struct gtItemDef_s
{ {
int size; // size of structure
qboolean use; // whether or not the item needs to be used qboolean use; // whether or not the item needs to be used
int useTime; // If the item needs to be used, this is the time it takes to use it int useTime; // If the item needs to be used, this is the time it takes to use it
int useIcon; // Icon to display on screen if the item requires using
int useSound; // Sound to loop when using this item
} gtItemDef_t; } gtItemDef_t;
typedef struct gtTriggerDef_s typedef struct gtTriggerDef_s
{ {
int size; // size of structure
qboolean use; // Whether or not the trigger needs to be used qboolean use; // Whether or not the trigger needs to be used
int useTime; // If the trigger needs to be used, this is the time it takes to use it int useTime; // If the trigger needs to be used, this is the time it takes to use it
int useIcon; // Icon to display on screen if the trigger requires using
int useSound; // Sound to loop when using this trigger
} gtTriggerDef_t; } gtTriggerDef_t;

View file

@ -11,10 +11,13 @@ equ trap_Cvar_VariableStringBuffer -8 ; GT_CVAR_VARIABLE_STRING_BUFFER
equ trap_Cmd_Restart -129 ; GT_RESTART equ trap_Cmd_Restart -129 ; GT_RESTART
equ trap_Cmd_TextMessage -117 ; GT_TEXTMESSAGE equ trap_Cmd_TextMessage -117 ; GT_TEXTMESSAGE
equ trap_Cmd_RadioMessage -123 ; GT_RADIOMESSAGE equ trap_Cmd_RadioMessage -123 ; GT_RADIOMESSAGE
equ trap_Cmd_RegisterGlobalSound -120 ; GT_REGISTERGLOBALSOUND equ trap_Cmd_RegisterSound -120 ; GT_REGISTERSOUND
equ trap_Cmd_StartGlobalSound -121 ; GT_STARTGLOBALSOUND equ trap_Cmd_StartGlobalSound -121 ; GT_STARTGLOBALSOUND
equ trap_Cmd_StartSound -138 ; GT_STARTSOUND
equ trap_Cmd_RegisterEffect -130 ; GT_REGISTEREFFECT equ trap_Cmd_RegisterEffect -130 ; GT_REGISTEREFFECT
equ trap_Cmd_PlayEffect -131 ; GT_PLAYEFFECT equ trap_Cmd_PlayEffect -131 ; GT_PLAYEFFECT
equ trap_Cmd_RegisterIcon -132 ; GT_REGISTERICON
equ trap_Cmd_SetHUDIcon -141 ; GT_SETHUDICON
equ trap_Cmd_AddTeamScore -127 ; GT_ADDTEAMSCORE equ trap_Cmd_AddTeamScore -127 ; GT_ADDTEAMSCORE
equ trap_Cmd_AddClientScore -128 ; GT_ADDCLIENTSCORE equ trap_Cmd_AddClientScore -128 ; GT_ADDCLIENTSCORE
equ trap_Cmd_RegisterItem -122 ; GT_REGISTERITEM equ trap_Cmd_RegisterItem -122 ; GT_REGISTERITEM
@ -23,6 +26,13 @@ equ trap_Cmd_ResetItem -118 ; GT_RESETITEM
equ trap_Cmd_GetClientName -119 ; GT_GETCLIENTNAME equ trap_Cmd_GetClientName -119 ; GT_GETCLIENTNAME
equ trap_Cmd_GetClientItems -125 ; GT_GETCLIENTITEMS equ trap_Cmd_GetClientItems -125 ; GT_GETCLIENTITEMS
equ trap_Cmd_DoesClientHaveItem -126 ; GT_DOESCLIENTHAVEITEM equ trap_Cmd_DoesClientHaveItem -126 ; GT_DOESCLIENTHAVEITEM
equ trap_Cmd_GetClientOrigin -134 ; GT_GETCLIENTORIGIN
equ trap_Cmd_GiveClientItem -135 ; GT_GIVECLIENTITEM
equ trap_Cmd_GetClientList -140 ; GT_GETCLIENTLIST
equ trap_Cmd_TakeClientItem -136 ; GT_TAKECLIENTITEM
equ trap_Cmd_SpawnItem -137 ; GT_SPAWNITEM
equ trap_Cmd_UseTargets -133 ; GT_USETARGETS
equ trap_Cmd_GetTriggerTarget -139 ; GT_GETTRIGGERTARGET
; hardcoded functions ; hardcoded functions

View file

@ -76,9 +76,9 @@ void trap_Cmd_RadioMessage ( int client, const char* message )
syscall ( GT_RADIOMESSAGE, client, message ); syscall ( GT_RADIOMESSAGE, client, message );
} }
int trap_Cmd_RegisterGlobalSound ( const char* sound ) int trap_Cmd_RegisterSound ( const char* sound )
{ {
return syscall ( GT_REGISTERGLOBALSOUND, sound ); return syscall ( GT_REGISTERSOUND, sound );
} }
void trap_Cmd_StartGlobalSound ( int sound ) void trap_Cmd_StartGlobalSound ( int sound )
@ -86,6 +86,11 @@ void trap_Cmd_StartGlobalSound ( int sound )
syscall ( GT_STARTGLOBALSOUND, sound ); syscall ( GT_STARTGLOBALSOUND, sound );
} }
void trap_Cmd_StartSound ( int sound, vec3_t origin )
{
syscall ( GT_STARTSOUND, sound, origin );
}
int trap_Cmd_RegisterEffect ( const char* effect ) int trap_Cmd_RegisterEffect ( const char* effect )
{ {
return syscall ( GT_REGISTEREFFECT, effect ); return syscall ( GT_REGISTEREFFECT, effect );
@ -96,6 +101,16 @@ void trap_Cmd_PlayEffect ( int effect, vec3_t origin, vec3_t angles )
syscall ( GT_PLAYEFFECT, effect, origin, angles ); syscall ( GT_PLAYEFFECT, effect, origin, angles );
} }
int trap_Cmd_RegisterIcon ( const char* icon )
{
return syscall ( GT_REGISTERICON, icon);
}
void trap_Cmd_SetHUDIcon ( int index, int icon )
{
syscall ( GT_SETHUDICON, index, icon );
}
void trap_Cmd_AddTeamScore ( team_t team, int score ) void trap_Cmd_AddTeamScore ( team_t team, int score )
{ {
syscall ( GT_ADDTEAMSCORE, team, score ); syscall ( GT_ADDTEAMSCORE, team, score );
@ -136,3 +151,37 @@ qboolean trap_Cmd_DoesClientHaveItem ( int clientid, int itemid )
return (qboolean) syscall ( GT_DOESCLIENTHAVEITEM, clientid, itemid ); return (qboolean) syscall ( GT_DOESCLIENTHAVEITEM, clientid, itemid );
} }
void trap_Cmd_GetClientOrigin ( int clientid, vec3_t origin )
{
syscall ( GT_GETCLIENTORIGIN, clientid, origin );
}
void trap_Cmd_GiveClientItem ( int clientid, int itemid )
{
syscall ( GT_GIVECLIENTITEM, clientid, itemid );
}
int trap_Cmd_GetClientList ( team_t team, int* clients, int clientcount )
{
return syscall ( GT_GETCLIENTLIST, team, clients, clientcount );
}
void trap_Cmd_TakeClientItem ( int clientid, int itemid )
{
syscall ( GT_TAKECLIENTITEM, clientid, itemid );
}
void trap_Cmd_SpawnItem ( int clientid, vec3_t origin, vec3_t angles )
{
syscall ( GT_SPAWNITEM, clientid, origin, angles );
}
void trap_Cmd_UseTargets ( const char* targetname )
{
syscall ( GT_USETARGETS, targetname );
}
void trap_Cmd_GetTriggerTarget ( int triggerid, const char* buffer, int buffersize )
{
syscall ( GT_GETTRIGGERTARGET, triggerid, buffer, buffersize );
}

View file

@ -23,21 +23,32 @@ void trap_Cvar_VariableStringBuffer ( const char *var_name, char *buffer, int b
void trap_Cmd_Restart ( int delay ); void trap_Cmd_Restart ( int delay );
void trap_Cmd_TextMessage ( int client, const char* message ); void trap_Cmd_TextMessage ( int client, const char* message );
void trap_Cmd_RadioMessage ( int client, const char* message ); void trap_Cmd_RadioMessage ( int client, const char* message );
int trap_Cmd_RegisterGlobalSound ( const char* sound ); int trap_Cmd_RegisterSound ( const char* sound );
void trap_Cmd_StartGlobalSound ( int sound ); void trap_Cmd_StartGlobalSound ( int sound );
void trap_Cmd_StartSound ( int sound, vec3_t origin );
void trap_Cmd_AddTeamScore ( team_t team, int score ); void trap_Cmd_AddTeamScore ( team_t team, int score );
int trap_Cmd_RegisterEffect ( const char* effect ); int trap_Cmd_RegisterEffect ( const char* effect );
void trap_Cmd_PlayEffect ( int effect, vec3_t origin, vec3_t angles ); void trap_Cmd_PlayEffect ( int effect, vec3_t origin, vec3_t angles );
int trap_Cmd_RegisterIcon ( const char* icon );
void trap_Cmd_SetHUDIcon ( int index, int icon );
void trap_Cmd_UseTargets ( const char* targetname );
// Item commands // Item commands
qboolean trap_Cmd_RegisterItem ( int itemid, const char* name, gtItemDef_t* def ); qboolean trap_Cmd_RegisterItem ( int itemid, const char* name, gtItemDef_t* def );
void trap_Cmd_ResetItem ( int itemid ); void trap_Cmd_ResetItem ( int itemid );
void trap_Cmd_SpawnItem ( int itemid, vec3_t origin, vec3_t angles );
// Trigger commands // Trigger commands
qboolean trap_Cmd_RegisterTrigger ( int trigid, const char* name, gtTriggerDef_t* def ); qboolean trap_Cmd_RegisterTrigger ( int triggerid, const char* name, gtTriggerDef_t* def );
void trap_Cmd_GetTriggerTarget ( int triggerid, const char* buffer, int buffersize );
// Client commands // Client commands
void trap_Cmd_GetClientName ( int clientid, const char* buffer, int buffersize ); void trap_Cmd_GetClientName ( int clientid, const char* buffer, int buffersize );
void trap_Cmd_GetClientItems ( int clientid, int* buffer, int buffersize ); void trap_Cmd_GetClientItems ( int clientid, int* buffer, int buffersize );
qboolean trap_Cmd_DoesClientHaveItem ( int clientid, int itemid ); qboolean trap_Cmd_DoesClientHaveItem ( int clientid, int itemid );
void trap_Cmd_AddClientScore ( int clientid, int score ); void trap_Cmd_AddClientScore ( int clientid, int score );
void trap_Cmd_GetClientOrigin ( int clientid, vec3_t origin );
void trap_Cmd_GiveClientItem ( int clientid, int itemid );
void trap_Cmd_TakeClientItem ( int clientid, int itemid );
int trap_Cmd_GetClientList ( team_t team, int* clients, int clientcount );

View file

@ -83,6 +83,8 @@ extern vmCvar_t ui_joinserver;
extern vmCvar_t ui_allowparental; extern vmCvar_t ui_allowparental;
extern vmCvar_t ui_noNetCheck;
typedef void *TGhoul2; typedef void *TGhoul2;
#define G2SURFACEFLAG_ISBOLT 0x00000001 #define G2SURFACEFLAG_ISBOLT 0x00000001
@ -450,7 +452,7 @@ typedef struct {
#define UI_FONT_THRESHOLD 0.1 #define UI_FONT_THRESHOLD 0.1
#define MAX_DISPLAY_SERVERS 2048 #define MAX_DISPLAY_SERVERS 2048
#define MAX_SERVERSTATUS_LINES 128 #define MAX_SERVERSTATUS_LINES 128
#define MAX_SERVERSTATUS_TEXT 1024 #define MAX_SERVERSTATUS_TEXT 4096
#define MAX_FOUNDPLAYER_SERVERS 16 #define MAX_FOUNDPLAYER_SERVERS 16
#define TEAM_MEMBERS 5 #define TEAM_MEMBERS 5
#define MAPS_PER_TIER 3 #define MAPS_PER_TIER 3

View file

@ -2441,6 +2441,11 @@ Verifies that there is a network connection and if not dumps a com_error
*/ */
qboolean UI_VerifyNetwork ( void ) qboolean UI_VerifyNetwork ( void )
{ {
if ( ui_noNetCheck.integer )
{
return qtrue;
}
if ( !trap_NET_Available ( ) ) if ( !trap_NET_Available ( ) )
{ {
if ( !(int)trap_Cvar_VariableValue ( "com_ignoreverifynetwork" ) ) if ( !(int)trap_Cvar_VariableValue ( "com_ignoreverifynetwork" ) )
@ -3487,7 +3492,7 @@ UI_GetServerStatusInfo
================== ==================
*/ */
static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) { static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) {
char *p, *score, *ping, *name; char *p, *score, *ping, *name, *team;
int i, len; int i, len;
if (!info) { if (!info) {
@ -3555,6 +3560,11 @@ static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t
if (!p) if (!p)
break; break;
*p++ = '\0'; *p++ = '\0';
team = p;
p = strchr(p, ' ');
if (!p)
break;
*p++ = '\0';
name = p; name = p;
Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i); Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i);
info->lines[info->numLines][0] = &info->pings[len]; info->lines[info->numLines][0] = &info->pings[len];
@ -4448,6 +4458,7 @@ void _UI_Init( qboolean inGameLoad )
if ( inGameLoad ) if ( inGameLoad )
{ {
uiInfo.menusFile = "ui/ingame.txt"; uiInfo.menusFile = "ui/ingame.txt";
uiInfo.inGameLoad = qtrue;
} }
else else
{ {
@ -4597,7 +4608,7 @@ qboolean _UI_MouseEvent( int dx, int dy )
void UI_LoadNonIngame() void UI_LoadNonIngame()
{ {
UI_LoadMenus("ui/menus.txt", qfalse); UI_LoadMenus("ui/menus.txt", qtrue );
uiInfo.inGameLoad = qfalse; uiInfo.inGameLoad = qfalse;
} }
@ -4632,12 +4643,14 @@ void UI_SetActiveMenu( uiMenuCommand_t menu )
trap_Key_SetCatcher( KEYCATCH_UI ); trap_Key_SetCatcher( KEYCATCH_UI );
Menus_CloseAll();
if (uiInfo.inGameLoad) if (uiInfo.inGameLoad)
{ {
uiInfo.inGameLoad = qfalse;
UI_LoadNonIngame(); UI_LoadNonIngame();
} }
Menus_CloseAll();
menudef = Menus_ActivateByName("main"); menudef = Menus_ActivateByName("main");
// the ui_joinserver cvar tells us whether or not we should jump // the ui_joinserver cvar tells us whether or not we should jump
@ -4813,24 +4826,24 @@ static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint,
leftWidth = 320; leftWidth = 320;
UI_SetColor(colorWhite); UI_SetColor(colorWhite);
Text_PaintCenter(centerPoint, yStart + 112, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, dlText, 0 ); Text_PaintCenter(centerPoint, yStart, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, dlText, 0 );
Text_PaintCenter(centerPoint, yStart + 192, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, etaText, 0 ); Text_PaintCenter(centerPoint, yStart + 90, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, etaText, 0 );
Text_PaintCenter(centerPoint, yStart + 248, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, xferText, 0 ); Text_PaintCenter(centerPoint, yStart + 50, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, xferText, 0 );
if (downloadSize > 0) { if (downloadSize > 0) {
s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); s = va( "%s (%d%%)", downloadName, (int)((float)downloadCount * (100.0f / (float)downloadSize)) );
} else { } else {
s = downloadName; s = downloadName;
} }
Text_PaintCenter(centerPoint, yStart+136, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, s, 0 ); Text_PaintCenter(centerPoint, yStart+15, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, s, 0 );
UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount ); UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount );
UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize ); UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize );
if (downloadCount < 4096 || !downloadTime) { if (downloadCount < 4096 || !downloadTime) {
Text_PaintCenter(leftWidth, yStart+216, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, "estimating", 0 ); Text_PaintCenter(leftWidth, yStart+105, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, "estimating", 0 );
Text_PaintCenter(leftWidth, yStart+160, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 ); Text_PaintCenter(leftWidth, yStart+30, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 );
} else { } else {
if ((uiInfo.uiDC.realTime - downloadTime) / 1000) { if ((uiInfo.uiDC.realTime - downloadTime) / 1000) {
xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000); xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000);
@ -4847,19 +4860,19 @@ static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint,
UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf,
(n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000);
Text_PaintCenter(leftWidth, yStart+216, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, dlTimeBuf, 0 ); Text_PaintCenter(leftWidth, yStart+105, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, dlTimeBuf, 0 );
Text_PaintCenter(leftWidth, yStart+160, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 ); Text_PaintCenter(leftWidth, yStart+30, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 );
} else { } else {
Text_PaintCenter(leftWidth, yStart+216, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, "estimating", 0 ); Text_PaintCenter(leftWidth, yStart+105, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, "estimating", 0 );
if (downloadSize) { if (downloadSize) {
Text_PaintCenter(leftWidth, yStart+160, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 ); Text_PaintCenter(leftWidth, yStart+30, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0 );
} else { } else {
Text_PaintCenter(leftWidth, yStart+160, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("(%s copied)", dlSizeBuf), 0 ); Text_PaintCenter(leftWidth, yStart+30, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, va("(%s copied)", dlSizeBuf), 0 );
} }
} }
if (xferRate) { if (xferRate) {
Text_PaintCenter(leftWidth, yStart+272, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("%s/Sec", xferRateBuf), 0 ); Text_PaintCenter(leftWidth, yStart+65, uiInfo.uiDC.Assets.defaultFont, scale, colorMdGrey, va("%s/Sec", xferRateBuf), 0 );
} }
} }
} }
@ -4904,6 +4917,28 @@ void UI_DrawConnectScreen( qboolean overlay ) {
// see what information we should display // see what information we should display
trap_GetClientState( &cstate ); trap_GetClientState( &cstate );
if ( cstate.connState == CA_CONNECTED )
{
char downloadName[MAX_INFO_VALUE];
trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) );
if (*downloadName)
{
if (!Q_stricmp(cstate.servername,"localhost"))
{
Text_PaintCenter(centerPoint, 50, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite, va("Loading..."), 0 );
}
else
{
strcpy(text, va("Connecting to %s", cstate.servername));
Text_PaintCenter(centerPoint, 50, uiInfo.uiDC.Assets.defaultFont, scale, colorWhite,text , 0 );
}
UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, 0.43f );
return;
}
}
info[0] = '\0'; info[0] = '\0';
if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) )
{ {
@ -4960,15 +4995,7 @@ void UI_DrawConnectScreen( qboolean overlay ) {
case CA_CHALLENGING: case CA_CHALLENGING:
s = va("Awaiting challenge...%i", cstate.connectPacketCount); s = va("Awaiting challenge...%i", cstate.connectPacketCount);
break; break;
case CA_CONNECTED: { case CA_CONNECTED:
char downloadName[MAX_INFO_VALUE];
trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) );
if (*downloadName) {
UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale );
return;
}
}
s = "Awaiting gamestate"; s = "Awaiting gamestate";
break; break;
case CA_LOADING: case CA_LOADING:
@ -5113,6 +5140,8 @@ vmCvar_t ui_joinserver;
vmCvar_t ui_allowparental; vmCvar_t ui_allowparental;
vmCvar_t ui_noNetCheck;
static cvarTable_t cvarTable[] = static cvarTable_t cvarTable[] =
{ {
{ &ui_botteam, "ui_botteam", "auto", 0 }, { &ui_botteam, "ui_botteam", "auto", 0 },
@ -5198,6 +5227,8 @@ static cvarTable_t cvarTable[] =
{ &ui_joinserver, "ui_joinserver", "0", CVAR_ROM|CVAR_INTERNAL }, { &ui_joinserver, "ui_joinserver", "0", CVAR_ROM|CVAR_INTERNAL },
{ &ui_allowparental, "ui_allowparental", "1", CVAR_ROM | CVAR_INTERNAL | CVAR_PARENTAL }, { &ui_allowparental, "ui_allowparental", "1", CVAR_ROM | CVAR_INTERNAL | CVAR_PARENTAL },
{ &ui_noNetCheck, "ui_noNetCheck", "0", CVAR_ARCHIVE },
}; };
static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]);

View file

@ -2942,6 +2942,7 @@ void Item_StartCapture(itemDef_t *item, int key) {
case ITEM_TYPE_EDITFIELD: case ITEM_TYPE_EDITFIELD:
case ITEM_TYPE_PASSWORDFIELD: case ITEM_TYPE_PASSWORDFIELD:
case ITEM_TYPE_NUMERICFIELD: case ITEM_TYPE_NUMERICFIELD:
break;
case ITEM_TYPE_COMBOBOX: case ITEM_TYPE_COMBOBOX:
case ITEM_TYPE_LISTBOX: case ITEM_TYPE_LISTBOX:
@ -4055,6 +4056,8 @@ static bind_t g_bindings[] =
{"+goggles", K_ENTER, -1, -1, -1}, {"+goggles", K_ENTER, -1, -1, -1},
{"vote yes", K_F1, -1, -1, -1}, {"vote yes", K_F1, -1, -1, -1},
{"vote no", K_F2, -1, -1, -1}, {"vote no", K_F2, -1, -1, -1},
{"+use", 'x', -1, -1, -1},
{"dropitem", -1, -1, -1, -1},
}; };

Binary file not shown.

Binary file not shown.

BIN
docs/Nav Point System.doc Normal file

Binary file not shown.

BIN
docs/RMG tutorial.doc Normal file

Binary file not shown.

Binary file not shown.

BIN
docs/SoF2_ConfusEd.doc Normal file

Binary file not shown.

BIN
docs/SoF2_Model_Formats.doc Normal file

Binary file not shown.

Binary file not shown.

BIN
docs/SoF2_Scripting.doc Normal file

Binary file not shown.

BIN
docs/SoF2_StripEd.doc Normal file

Binary file not shown.

Binary file not shown.

BIN
docs/Using_EffectsEd.doc Normal file

Binary file not shown.

36
readme.txt Normal file
View file

@ -0,0 +1,36 @@
base
Full example map and scripts for kam6
bin
behaved.exe
behaved.bhc (required to script for SoF2)
ibize.exe (script compiler)
radiant.exe
sof2.qe4 (project file for SoF2)
sklview.exe (get listing of animations for scripting)
sof2map.exe
sof2data.exe
striped.exe
docs
Docs for:
Vertigons (surface sprites)
Weather
Nav points
RMG
Animation
ConfusEd
Menus
Scripting
StripEd
EffectsEd (exe was in MP SDK)
gamecode
Only two files included as they are needed for scripting and single player entities.
resources
Max files for a male figure and the inview hands
SDK V0.02 07/03/2002
-----------------------

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