as released 2007-06-15

This commit is contained in:
archive 2007-06-15 00:00:00 +00:00
commit 70db9d566e
749 changed files with 616436 additions and 0 deletions

BIN
Animation Examples/animations.zip Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,111 @@
//------------------------------------------------
// SDK Example Content
// Slimy Lobber
//
// Compare the entries in this def file to those of the monster_slimy_transfer
// (def/ai/monster_slimy_transfer.def) as an example of how to implement new
// monsters and monster attacks using only existing AI code.
//
// aweldon Nov 05
//------------------------------------------------
model model_monster_slimy_lobber
{
inherit model_monster_slimy_transfer // Use Slimy Transfer mesh and anims as base.
// Lobbing anim -----------------------------------------------------------------------------------------
anim lob models/monsters/slimy_transfer/attack01.md5anim // Use existing melee anim
{
frame 1,13,27,36,57 sound snd_flesh // Use pre-existing sounds
frame 19 ai_attack melee r_wrist // Throw at appropriate frame
frame 19 fx fx_lob r_wrist
}
}
entityDef damage_lobber_grenade
{
// These values are copied from the monster_gunner .def file and seem to work ok.
"inherit" "damage_monster_base"
"knockback" "0"
"damage" "60"
"push" "10000"
"tv_scale" "0.7"
"tv_time" "4200"
}
entityDef damage_lobber_grenade_splash
{
// These values are copied from the monster_gunner .def file and seem to work ok.
"inherit" "damage_monster_base"
"knockback" "0"
"damage" "80"
"radius" "200"
"push" "10000"
"tv_scale" "0.7"
"tv_time" "4200"
}
entityDef projectile_lobber_bit
{
"inherit" "projectile_gunner_grenade" // inherit defaults from the Gunner grenade
"fuse" "3" //shorten the fuse
"detonate_on_actor" "1" // Explode when hitting directly
"model" "models/gibs/head_pork.lwo" // New 'grenade' model (brraaaaaaainnnnns...)
"fx_fly" "effects/impact/impact_flesh.fx" // When flying, play the impact effect. Admittedly not the best effect for this purpose.
"fx_detonate" "effects/monsters/gib.fx" // Use the splatty gib effect for 'explosions'
"fx_impact" "effects/monsters/gib.fx" // Use the splatty gib effect for 'explosions'
"def_splash_damage" "damage_lobber_grenade_splash" // Use damage def specified above
"def_damage" "damage_lobber_grenade" // Use damage def specified above
"speed" "500" // Adjust speed
"angular_velocity" "0 -900 200" // Give a nudge up and towards center.
"bounce" "15" // Make with the bouncing
"contact_friction" "1" // Reduced friction for better bounce behavior
"delay_splash" "0" // Splash damage effects are instantaneous
"snd_ricochet" "failedtransfer_flesh" // Fleshy sound on bounce
}
// New EntityDef
entityDef monster_slimy_lobber
{
"inherit" "monster_slimy_transfer" // Inherit from the Slimy Transfer
// --------------------------------- Actions ------------------------------------
"action_meleeAttack" "1" // Leave this enabled, we'll replace it with our lobbing attack
"action_meleeAttack_anim" "lob" // 'New' anim on melee attack
"action_meleeAttack_minrange" "80" // Minimum distance (in units) for attack.
"action_meleeAttack_maxrange" "512" // Maximum distance (in units) for attack.
"action_meleeAttack_blendFrames" "6" // Blend frames on attack
"action_meleeAttack_rate" ".5" // Rate of attack
"action_vomitAttack" "1" // Keep the vomit attack enabled
"action_vomitAttack_minrange" "0" // Minimum distance (in units) for attack.
"action_vomitAttack_maxrange" "128" // Maximum distance (in units) for attack.
// --------------------------------- Body ------------------------------------
"model" "model_monster_slimy_lobber" // Use our new ModelDef from above
// --------------------------------- Combat ----------------------------------
"health" "75" // Beef these guys up a bit
"painThreshold" "40" // Can take more damage before playing pain anims
"def_attack_melee" "projectile_lobber_bit" // Change melee attack to our new projectile
"fx_lob" "effects/impact/impact_flesh.fx" // Effect to play when lobbing (added on frame commands above)
}

View file

@ -0,0 +1,84 @@
//------------------------------------------------
// SDK Example Content
// Rocket Launcher Strogg Marine
//
// Compare the entries in this def file to those of the monster_strogg_marine_sgun
// (monster_strogg_marine.def) as an example of how to implement new monsters
// and monster attacks using only existing AI code.
//
// aweldon Nov 05
//------------------------------------------------
entityDef projectile_strogg_marine_rocket
{
// We'll just steal the standard single player rocket.
"inherit" "projectile_rocket"
// ...but that does a little too much damage!
"def_damage" "damage_strogg_marine_rocket"
"def_splash_damage" "damage_strogg_marine_rocket_splash"
}
entityDef damage_strogg_marine_rocket
{
// Inherit the standard single player rocket damage
"inherit" "damage_rocketDirect"
// Lower damage from 150 to something more reasonable.
"damage" "65"
}
entityDef damage_strogg_marine_rocket_splash
{
// Inherit the standard single player rocket splash damage
// Lower damage from 150 to something more reasonable.
"damage" "45"
// This might also get a little messy...
"gib" "1"
}
entityDef monster_strogg_marine_rocket
{
"inherit" "monster_strogg_marine_sgun" // Use the shotgun guy as a base
"editor_usage" "Rocket Strogg Marine" // What will display in the editor
"editor_ignore" "0" // Show the entity in the right click menu
"model" "monster_strogg_marine_sgun" // Use the mesh and anims from the shotgun guy
"skin" "skins/monsters/strogg_marine/smv_shotgun" // Leave the skin as the shotgun guy
// --------------------------------- Defs ----------------------------------
"minShots" "1" // Will fire at least once.
"maxShots" "3" // ...and up to 3 times in sequence.
// These refer only to the number of times the fire animation will play, and not how many physical shots are fired
// That can be modified by including multiple shots on frame commands or by upping the count per attack.
"actionTimer_rangedAttack_rate" ".5" // Was .25. Time between attacks
"action_rangedAttack" "1"
"action_rangedAttack_anim" "shotgun_range_attack" // Anim to play when attacking
"action_rangedAttack_minRange" "128" // Minimum attack range in units. Was 0 on shotgun.
"action_rangedAttack_maxRange" "640" // Maximum attack range in units. Was 400 on shotgun.
"action_rangedAttack_failrate" "0" // Attack will never fail.
"action_rollAttack_rate" "2" // Was .25. Time between attacks.
"action_strafe" "0" // Disable Strafing
"def_attack_base" "projectile_strogg_marine_rocket" // Use our new projectile for base attacks.
"attack_base_count" "1" // One projectile
"attack_base_spread" "0" // no spread
"attack_base_hitscan" "0" // Does not hit instantly
"attack_base_accuracy" "1" // increased accuracy
"def_attack_jointDir" "projectile_strogg_marine_rocket" // Use our new projectile for joint attacks.
"attack_jointDir_locktojoint" "1" // Lock to joint direction
"attack_jointDir_count" "1" // One projectile
"attack_jointDir_spread" "0" // no spread
"attack_jointDir_hitscan" "0" // does not hit instantly
"attack_jointDir_accuracy" "0" // no change
// --------------------------------- Effects ---------------------------------
"fx_blaster_muzzleflash" "effects\weapons\rocket\muzzleflash_world.fx" // Rocket launcher muzzle flash
"snd_weapon_fire" "weapon_rocket_fire" // Rocket launcher sound shader
}

BIN
Font Examples/marine_ansi.zip Executable file

Binary file not shown.

BIN
Font Examples/marine_symbol.zip Executable file

Binary file not shown.

BIN
Font Examples/q4font.zip Executable file

Binary file not shown.

55
License.txt Normal file
View file

@ -0,0 +1,55 @@
QUAKE 4 (TM) SOFTWARE DEVELOPMENT KIT
LIMITED USE LICENSE AGREEMENT
This QUAKE 4 (TM) Software Development Kit Limited Use License Agreement (this "Agreement") is a legal agreement among you, the end-user, and Id Software, Inc. ("Id Software"). BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THIS SOFTWARE DEVELOPMENT KIT (THE "SOFTWARE") FOR THE GAME PROGRAM ENTITLED QUAKE 4 (TM), BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU ACKNOWLEDGE AND UNDERSTAND THAT IN ORDER TO OPERATE THE SOFTWARE, YOU MUST HAVE THE FULL VERSION OF THE ID SOFTWARE GAME ENTITLED QUAKE 4 (TM) INSTALLED ON YOUR COMPUTER.
1. Grant of License. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software only in executable or object code form. The term "Software" includes all elements of the Software, including, without limitation, data files and screen displays. You are not receiving any ownership or proprietary right, title, or interest in or to the Software or the copyrights, trademarks, or other rights related thereto. For purposes of the first sentence of this Section, "use" means loading the Software into RAM and/or onto computer hard drive, as well as installation of the Software on a hard disk or other storage device, and means the uses permitted in Sections 2 and 5 hereinbelow. You agree that the Software will not be downloaded, shipped, transferred, exported or re-exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the Software in any other manner in violation of any applicable law. The Software shall not be downloaded or otherwise exported or re-exported into (or to a national or resident of) any country to which the United States has embargoed goods, or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. In exercising your limited rights hereunder, you shall comply, at all times, with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement, including, without limitation, all rights to Id Software's trademarks.
2. Permitted New Creations. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software to create for the software game QUAKE 4 (TM) your own modifications (the "New Creations") that shall operate only with QUAKE 4 (TM) (but not any demo, test, or other version of QUAKE 4 (TM)). You may include within the New Creations certain textures and other images (the "Software Images") from the Software. You shall not create any New Creations that infringe against any third-party right or that are libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. You agree that the New Creations will not be downloaded, shipped, transferred, exported, or re-exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the New Creations in any other manner in violation of any applicable law. The New Creations shall not be downloaded or otherwise exported or re-exported into (or to a national or resident of) any country to which the United States has embargoed goods or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. You shall not rent, sell, lease, lend, offer on a pay-per-play basis, or otherwise commercially exploit or commercially distribute the New Creations. You are permitted to distribute, without any cost or charge, the New Creations only to other end-users so long as such distribution is not infringing against any third-party right and otherwise is not illegal or unlawful. As noted below, in the event you commit any breach of this Agreement, your license and this Agreement automatically shall terminate, without notice.
3. Prohibitions with Regard to the Software. You, whether directly or indirectly, shall not do any of the following acts:
a. rent the Software;
b. sell the Software;
c. lease or lend the Software;
d. offer the Software on a pay-per-play basis;
e. distribute the Software (except as permitted under Section 5 hereinbelow);
f. in any other manner and through any medium whatsoever commercially exploit the Software or use the Software for any commercial purpose;
g. disassemble, reverse engineer, decompile, modify (except as permitted under Section 2 hereinabove) or alter the Software;
h. translate the Software;
i. reproduce or copy the Software (except as permitted under Section 5 hereinbelow);
j. publicly display the Software;
k. prepare or develop derivative works based upon the Software;
l. remove or alter any notices or other markings or legends, such as trademark or copyright notices, affixed on or within the Software; or
m. remove, alter, modify, disable, or reduce any of the anti-piracy measures contained in the Software or in QUAKE 4 (TM), including, without limitation, measures relating to multiplayer play.
4. Prohibition against Cheat Programs. Any attempt by you, either directly or indirectly, to circumvent or bypass any element of the Software to gain any advantage in multiplayer play of the Software is a material breach of this Agreement. It is a material breach of this Agreement for you, whether directly or indirectly, to create, develop, copy, reproduce, distribute, or otherwise make any use of any software program or any modification to the Software ("Cheat Program") itself that enables or allows the user thereof to obtain an advantage or otherwise exploit another Software player or user when playing the Software against other players or users on a local area network, any other network, or on the Internet. Hacking into the executable of the Software, modification of the Software, or any other use of the Software in connection with the creation, development, or use of any such unauthorized Cheat Program is a material breach of this Agreement. Cheat Programs include, but are not limited to, programs that allow Software players or users to see through walls or other level geometry; programs that allow Software players or users to change their rate of speed outside the allowable limits of the Software; programs that crash either and/or other Software players, users, PC clients, or network servers; programs that automatically target other Software players or users (commonly referred to as "aimbots") that automatically simulate Software player or user input for the purpose of gaining an advantage over other Software players or users; or any other program or modification that functions in a similar capacity or allows any prohibited conduct.
In the event you breach this Section or otherwise breach this Agreement, your license and this Agreement automatically shall terminate, without notice, and you shall have no right to play the Software against other players or make any other use of the Software.
5. Permitted Distribution and Copying. So long as this Agreement accompanies each copy you make of the Software, and so long as you comply fully at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to copy the Software and to distribute such copies of the Software free of charge for non-commercial purposes that shall include the free-of-charge distribution of copies of the Software as mounted on the covers of magazines; provided, however, you shall not copy or distribute the Software in any infringing manner or in any manner that violates any law or third-party right, and you shall not distribute the Software together with any material that infringes against any third-party right or that is libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. Subject to the terms and conditions of this Agreement, you also may: (i) download one (1) copy of the Software or copy the Software from the CD ROM on which you received your copy of the Software onto your computer RAM; (ii) copy the Software from your computer RAM onto your computer hard drive; and (iii) make one (1) "backup" or archival copy of the Software on one (1) hard disk. In exercising your limited rights hereunder, you shall comply at all times with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement. You shall not distribute the Software commercially unless you first enter into a separate contract with Id Software, on terms and conditions determined in Id Software's sole discretion, and only upon your receipt of a written agreement executed by an authorized officer of Id Software.
6. Intellectual Property Rights. The Software and all copyrights, trademarks, and all other conceivable intellectual property rights related to the Software are owned by Id Software and are protected by United States copyright laws, international treaty provisions, and all applicable law, such as the Lanham Act. You must treat the Software like any other copyrighted material, as required by 17 U.S.C. § 101 et seq. and other applicable law. You agree to use your best efforts to see that any user of the Software licensed hereunder or the New Creations complies with this Agreement. You agree that you are receiving a copy of the Software by limited license only and not by sale and that the "first sale" doctrine of 17 U.S.C. § 109 does not apply to your receipt or use of the Software. This Section shall survive the cancellation or termination of this Agreement.
7. NO ID SOFTWARE WARRANTIES. ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTY OF NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE SOFTWARE IMAGES, AND OTHERWISE. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ID SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD NOT BE RELIED UPON. This Section shall survive the cancellation or termination of this Agreement.
8. Governing Law, Venue, Indemnity, and Liability Limitation. This Agreement shall be construed in accordance with and governed by the applicable laws of the State of Texas (but excluding conflicts of laws principles) and applicable United States federal law. Except as set forth below, exclusive venue for all litigation regarding this Agreement shall be in Dallas County, Texas, and you agree to submit to the jurisdiction of the federal and state courts in Dallas County, Texas, for any such litigation. You hereby agree to indemnify, defend and hold harmless Id Software and Id Software's officers, employees, directors, agents, licensees (excluding you), sub-licensees (excluding you), successors, and assigns from and against all losses, lawsuits, damages, causes of action, and claims relating to and/or arising from the New Creations or the distribution or other use of the New Creations or relating to and/or arising from your breach of this Agreement. You agree that your unauthorized use of the Software Images or the Software, or any part thereof, immediately and irreparably may damage Id Software such that Id Software could not be adequately compensated solely by a monetary award, and in such event, at Id Software's option, that Id Software shall be entitled to an injunctive order, in addition to all other available remedies, including a monetary award, to prohibit such unauthorized use without the necessity of Id Software posting bond or other security. IN ANY CASE, ID SOFTWARE AND ID SOFTWARE'S OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB-LICENSEES (EXCLUDING YOU), SUCCESSORS, AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR PUNITIVE DAMAGES, OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE OR ITS RESPECTIVE AGENT(S) HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you. This Section shall survive the cancellation or termination of this Agreement.
9. United States Government Restricted Rights. To the extent applicable, the United States Government shall have only those rights to use the Software as expressly stated and expressly limited and restricted in this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204, inclusive.
10. General Provisions. Neither this Agreement nor any part or portion hereof shall be assigned or sublicensed by you. Id Software may assign its rights under this Agreement in its sole discretion. Should any provision of this Agreement be held to be void, invalid, unenforceable, or illegal by a court of competent jurisdiction, the validity and enforceability of the other provisions shall not be affected thereby. If any provision is determined to be unenforceable by a court of competent jurisdiction, you agree to a modification of such provision to provide for enforcement of the provision's intent, to the extent permitted by applicable law. Failure of Id Software to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH, OR YOUR BREACH OF ANY TERM OR PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT AUTOMATICALLY SHALL TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU THAT ARE AVAILABLE UNDER APPLICABLE LAW AND/OR THIS AGREEMENT. Immediately upon termination of this Agreement, any and all rights you are granted hereunder shall terminate, you shall have no right to use the Software or the New Creations, in any manner, you immediately shall destroy all copies of the Software and the New Creations in your possession, custody, or control, and all rights granted hereunder shall revert, without notice, to and be vested in Id Software.
YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS AGREEMENT, AND YOU UNDERSTAND THAT, BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN, SEPARATE AGREEMENTS, IF ANY, BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO RELATING TO THE SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT.

Binary file not shown.

2
README Normal file
View file

@ -0,0 +1,2 @@
For documentation and help, please see:
http://www.iddevnet.com/quake4/

Binary file not shown.

Binary file not shown.

BIN
q4icon.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

2
readme.txt Executable file
View file

@ -0,0 +1,2 @@
For information on using the example files included with the Quake 4 (TM) SDK, please go to http://www.iddevnet.com/quake4/

View file

@ -0,0 +1,27 @@
#ifndef __MAYA_MAIN_H__
#define __MAYA_MAIN_H__
/*
==============================================================
Maya Import
==============================================================
*/
// RAVEN BEGIN
// rhummer: unify allocation strategy to try to eliminate some of our crashes
#ifdef RV_UNIFIED_ALLOCATOR
typedef bool ( *exporterDLLEntry_t )( int version, idCommon *common, idSys *sys, void *(*allocator)(size_t size), void (*deallocator)(void *), size_t (*msize)(void *) );
#else
typedef bool ( *exporterDLLEntry_t )( int version, idCommon *common, idSys *sys );
#endif
// RAVEN END
// RAVEN BEGIN
// bdube: default src and dest ospath's
typedef const char *( *exporterInterface_t )( const char *src_ospath, const char* dst_ospath, const char *commandline );
// RAVEN END
typedef void ( *exporterShutdown_t )( void );
#endif /* !__MAYA_MAIN_H__ */

799
source/SConstruct Normal file
View file

@ -0,0 +1,799 @@
# -*- mode: python -*-
# Quake4 build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string
import SCons
sys.path.append( 'sys/scons' )
import scons_utils
conf_filename='site.conf'
# choose configuration variables which should be saved between runs
# ( we handle all those as strings )
serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'IDNET_HOST', 'GL_HARDLINK', 'DEDICATED',
'DEBUG_MEMORY', 'LIBC_MALLOC', 'ID_NOLANADDRESS', 'ID_MCHECK',
'TARGET_CORE', 'TARGET_CORE_SMP', 'TARGET_GAME', 'TARGET_SPGAME', 'TARGET_MPGAME', 'TARGET_MONO', 'TARGET_MONO_IS_SP', 'TARGET_DEMO', 'NOCURL',
'BUILD_ROOT', 'Q4TEST', 'TARGET_GAMEPAK', 'OSX_BUILDSTYLE', 'SILENT', 'GCC_X86_ASM' ]
# global build mode ------------------------------
g_sdk = not os.path.exists( 'sys/scons/SConscript.core' )
# ------------------------------------------------
# help -------------------------------------------
help_string = """
Usage: scons [OPTIONS] [TARGET] [CONFIG]
[OPTIONS] and [TARGET] are covered in command line options, use scons -H
[CONFIG]: KEY="VALUE" [...]
a number of configuration options saved between runs in the """ + conf_filename + """ file
erase """ + conf_filename + """ to start with default settings again
CC (default gcc)
CXX (default g++)
Specify C and C++ compilers (defaults gcc and g++)
ex: CC="gcc-4.1"
You can use ccache and distcc, for instance:
CC="ccache distcc gcc" CXX="ccache distcc g++"
JOBS (default 1)
Parallel build
BUILD (default debug)
Use debug-all/debug/release to select build settings
ex: BUILD="release"
debug-all: no optimisations, debugging symbols
debug: -O -g
release: all optimisations, including CPU target etc.
test: release with debug symbols and all optimizations except omitted frame pointers
BUILD_ROOT (default 'build')
change the build root directory
NOCONF (default 0, not saved)
ignore site configuration and use defaults + command line only
SILENT ( default 0, saved )
hide the compiler output, unless error
GCC_X86_ASM ( defaul 0, saved )
compile in gcc x86 asm optimizations
"""
if ( not g_sdk ):
help_string += """
DEDICATED (default 0)
Control regular / dedicated type of build:
0 - client
1 - dedicated server
2 - both
TARGET_CORE (default 1)
Build the core
TARGET_CORE_SMP (default 0)
Build an SMP-enabled core
TARGET_GAME (default 1)
Build the singleplayer and multiplayer game code
TARGET_SPGAME (default 0)
Build the singleplayer game code
TARGET_MPGAME (default 0)
Build the multiplayer game code
TARGET_MONO (default 0)
Build a monolithic binary
TARGET_MONO_IS_SP (default 0)
Build the monolithic binary as singleplayer instead of multiplayer
TARGET_DEMO (default 0)
Build demo client ( both a core and game, no mono )
NOTE: if you *only* want the demo client, set TARGET_CORE and TARGET_GAME to 0
IDNET_HOST (default to source hardcoded)
Override builtin IDNET_HOST with your own settings
GL_HARDLINK (default 0)
Instead of dynamically loading the OpenGL libraries, use implicit dependencies
NOTE: no GL logging capability and no r_glDriver with GL_HARDLINK 1
DEBUG_MEMORY (default 0)
Enables memory logging to file
LIBC_MALLOC (default 1)
Toggle idHeap memory / libc malloc usage
When libc malloc is on, memory size statistics are wrong ( no _msize )
ID_NOLANADDRESS (default 0)
Don't recognize any IP as LAN address. This is useful when debugging network
code where LAN / not LAN influences application behaviour
ID_MCHECK (default 2)
Perform heap consistency checking
0: on in Debug / off in Release
1 forces on, 2 forces off
note that idlib has it's own block allocator/checking
this should not be considered a replacement, but an additional tool
note: this is the same as MALLOC_CHECK_, but different from mtrace
SETUP_TAGGED (default 0, not saved)
build tagged binaries distribution implies release, excludes other setups
SETUP_DEDICATED (default 0, not saved)
build dedicated server setup. implies release
SETUP_DEMO (default 0, not saved)
build demo setup. implies release
SETUP_FULL (default 0, not saved)
build full setup. implies release
SETUP_INCREMENTAL (default 0, not saved)
builds the incremental setup
TARGET_GAMEPAK (default 0, not saved)
build a game pak pk4
if no setup is scheduled, from whatever game is being compiled ( current configuration )
if setups are scheduled, controls gamepak building during setup ( might wanna use a reference one for pure-compatible updates )
SDK (default 0, not saved)
build an SDK release
NOCURL (default 0)
set to 1 to disable usage of libcurl and http/ftp downloads feature
FIX_INCLUDE (default 0, not saved)
fix include paths while compiling
wraps around the compiler call to catch and fix include path errors
note that since this process modifies files on the fly, it's not a good idea to use it with several jobs
FIX_SUPER (default 0, not saved)
fix usage of __super msvc-ism
wraps around gcc to do a search and fix pass
Q4TEST (default 0)
q4test build
MP-only gamecode, enables binary tagging
ASSETS (optional, not saved)
point to the setup assets directory
OSX_BUILDSTYLE (default 0)
Styles 1 & 2 will override CC and CXX only if they are left to the defaults
0 - Uses the system gcc/include/libs
1 - Uses GCC 3.3 + 10.3.9 SDK
2 - Uses GCC 4.0 + 10.4u SDK
"""
Help( help_string )
# end help ---------------------------------------
# sanity -----------------------------------------
EnsureSConsVersion( 0, 96 )
# end sanity -------------------------------------
# system detection -------------------------------
# OS and CPU
OS = commands.getoutput( 'uname -s' )
if ( OS == 'Linux' ):
cpu = commands.getoutput( 'uname -m' )
if ( cpu == 'i686' ):
cpu = 'x86'
else:
cpu = 'cpu'
elif ( OS == 'Darwin' ):
cpu = commands.getoutput( 'uname -m' )
if ( cpu == 'Power Macintosh' ):
cpu = 'ppc'
else:
cpu = 'cpu'
# end system detection ---------------------------
# default settings -------------------------------
CC = 'gcc-4.1'
CXX = 'g++-4.1'
JOBS = '1'
BUILD = 'debug'
DEDICATED = '0'
TARGET_CORE = '1'
TARGET_GAME = '1'
TARGET_SPGAME = '0'
TARGET_MPGAME = '0'
TARGET_GAMEPAK = '0'
TARGET_MONO = '0'
TARGET_MONO_IS_SP = '0'
TARGET_DEMO = '0'
IDNET_HOST = ''
GL_HARDLINK = '0'
if ( OS == 'Darwin' ):
GL_HARDLINK = '1'
DEBUG_MEMORY = '0'
LIBC_MALLOC = '1'
ID_NOLANADDRESS = '0'
ID_MCHECK = '2'
BUILD_ROOT = 'build'
SETUP_TAGGED = '0'
SETUP_DEDICATED = '0'
SETUP_DEMO = '0'
SETUP_FULL = '0'
SETUP_INCREMENTAL = '0'
SETUP = '0' # no cmdline control, will be set to 1 if any form of setup is requested
SDK = '0'
NOCONF = '0'
NOCURL = '0'
FIX_INCLUDES = '0'
FIX_SUPER = '0'
Q4TEST = '0'
ASSETS = ''
OSX_BUILDSTYLE = '0'
SILENT = '0'
TARGET_CORE_SMP = '0'
GCC_X86_ASM = '0'
# end default settings ---------------------------
# site settings ----------------------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
site_dict = {}
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
site_dict = p.load()
print 'Loading build configuration from ' + conf_filename + ':'
for k, v in site_dict.items():
exec_cmd = k + '=\'' + v + '\''
print ' ' + exec_cmd
exec(exec_cmd)
else:
print 'Site settings ignored'
# end site settings ------------------------------
# command line settings --------------------------
for k in ARGUMENTS.keys():
exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
print 'Command line: ' + exec_cmd
exec( exec_cmd )
# end command line settings ----------------------
# save site configuration ----------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
for k in serialized:
exec_cmd = 'site_dict[\'' + k + '\'] = ' + k
exec(exec_cmd)
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(site_dict)
site_file.close()
# end save site configuration ------------------
# configuration rules --------------------------
if ( SETUP_TAGGED != '0' or SETUP_DEDICATED != '0' or SETUP_DEMO != '0' or SETUP_FULL != '0' or SETUP_INCREMENTAL != '0' ):
DEDICATED = '2'
BUILD = 'release'
SETUP = '1'
TARGET_GAME = '1'
TARGET_CORE = '1'
TARGET_CORE_SMP = '1'
TARGET_GAMEPAK = '0'
if ( TARGET_GAMEPAK == '1' ):
TARGET_GAME = '1'
if ( SETUP != '0' ):
if ( SETUP_TAGGED != '0' ):
SETUP_DEDICATED = '0'
SETUP_DEMO = '0'
SETUP_FULL = '0'
Q4TEST = '1'
else:
Q4TEST = '0'
if ( g_sdk ):
TARGET_CORE = '0'
TARGET_CORE_SMP = '0'
TARGET_MONO = '0'
TARGET_DEMO = '0'
if ( SDK != '0' ):
DEDICATED = '0'
TARGET_CORE = '0'
TARGET_CORE_SMP = '0'
TARGET_GAME = '0'
TARGET_MPGAME = '0'
TARGET_SPGAME = '0'
TARGET_MONO = '0'
TARGET_DEMO = '0'
if ( TARGET_GAME == '1' ):
TARGET_MPGAME = '1'
TARGET_SPGAME = '1'
if ( BUILD == 'test' ):
print 'WARNING: compiling a release build in test configuration'
# end configuration rules ----------------------
# general configuration, target selection --------
g_build = BUILD_ROOT + '/' + BUILD
SConsignFile( 'scons.signatures' )
if ( GL_HARDLINK != '0' ):
g_build += '-hardlink'
if ( DEBUG_MEMORY != '0' ):
g_build += '-debugmem'
if ( LIBC_MALLOC != '1' ):
g_build += '-nolibcmalloc'
if ( Q4TEST != '0' ):
g_build += '-q4test'
SetOption('num_jobs', JOBS)
LINK = CXX
# common flags
# BASE + CORE + OPT for engine
# BASE + GAME + OPT for game
# _noopt versions of the environements are built without the OPT
BASECPPFLAGS = [ ]
CORECPPPATH = [ ]
CORELIBPATH = [ ]
CORECPPFLAGS = [ ]
GAMECPPFLAGS = [ ]
BASELINKFLAGS = [ ]
CORELINKFLAGS = [ ]
# for release build, further optimisations that may not work on all files
OPTCPPFLAGS = [ ]
BASECPPFLAGS.append( '-pipe' )
# warn all
BASECPPFLAGS.append( '-Wall' )
# don't wrap gcc messages
BASECPPFLAGS.append( '-fmessage-length=0' )
if ( OS == 'Linux' ):
# gcc 4.x option only - only export what we mean to from the game SO
BASECPPFLAGS.append( '-fvisibility=hidden' )
# get the 64 bits machine on the distcc array to produce 32 bit binaries :)
BASECPPFLAGS.append( '-m32' )
BASELINKFLAGS.append( '-m32' )
if ( g_sdk or SDK != '0' ):
BASECPPFLAGS.append( '-DQ4SDK' )
if ( Q4TEST == '1' ):
# _MPBETA implie ID_TAGGED_BUILD but also disables some single player functionality
#BASECPPFLAGS.append( '-D_MPBETA' )
BASECPPFLAGS.append( '-DID_TAGGED_BUILD' )
if ( OS == 'Darwin' ):
# a few more common defines
BASECPPFLAGS += [ '-Wno-long-double', '-arch', 'ppc', '-fasm-blocks', '-fpascal-strings', '-faltivec', '-mcpu=G5', '-mtune=G5' ]
BASECPPFLAGS += [ '-DMACOS_X' ]
BASECPPFLAGS += [ '-Wno-unknown-pragmas' ]
BASECPPFLAGS += [ '-DMAC_OS_X_VERSION_MIN_REQUIRED=1030' ]
# Override CC & CXX only if they contain the default values. Allows for distcc invocations
if ( OSX_BUILDSTYLE == '1' ):
if ( CC == 'gcc' ):
CC = [ '/usr/bin/gcc-3.3' ]
if ( CXX == 'g++' ):
CXX = [ '/usr/bin/g++-3.3' ]
BASECPPFLAGS += [ '-isystem', '/Developer/SDKs/MacOSX10.3.9.sdk/usr/include/gcc/darwin/3.3' ]
BASECPPFLAGS += [ '-I/Developer/SDKs/MacOSX10.3.9.sdk/usr/include/gcc/darwin/3.3/c++' ]
BASECPPFLAGS += [ '-I/Developer/SDKs/MacOSX10.3.9.sdk/usr/include/gcc/darwin/3.3/c++/ppc-darwin' ]
BASECPPFLAGS += [ '-isystem', '/Developer/SDKs/MacOSX10.3.9.sdk/usr/include' ]
BASELINKFLAGS += [ '-Wl,-syslibroot,/Developer/SDKs/MacOSX10.3.9.sdk' ]
CORELIBPATH += [ '/Developer/SDKs/MacOSX10.3.9.sdk/usr/lib' ]
os.environ['NEXT_ROOT'] = '/Developer/SDKs/MacOSX10.3.9.sdk'
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
elif ( OSX_BUILDSTYLE == '2' ):
if ( CC == 'gcc' ):
CC = [ '/usr/bin/gcc-4.0' ]
if ( CXX == 'g++' ):
CXX = [ '/usr/bin/g++-4.0' ]
BASECPPFLAGS += [ '-isystem', '/Developer/SDKs/MacOSX10.4u.sdk/usr/include/gcc/darwin/4.0' ]
BASECPPFLAGS += [ '-mone-byte-bool' ]
BASECPPFLAGS += [ '-fvisibility-inlines-hidden' ]
BASECPPFLAGS += [ '-fpermissive' ]
BASECPPFLAGS += [ '-I/Developer/SDKs/MacOSX10.4u.sdk/usr/include/gcc/darwin/4.0/c++' ]
BASECPPFLAGS += [ '-I/Developer/SDKs/MacOSX10.4u.sdk/usr/include/gcc/darwin/4.0/c++/ppc-darwin' ]
BASECPPFLAGS += [ '-isystem', '/Developer/SDKs/MacOSX10.4u.sdk/usr/include' ]
BASELINKFLAGS += [ '-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk' ]
CORELIBPATH += [ '/Developer/SDKs/MacOSX10.4u.sdk/usr/lib' ]
os.environ['NEXT_ROOT'] = '/Developer/SDKs/MacOSX10.4u.sdk'
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
if ( BUILD == 'debug-all' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-D_DEBUG' )
if ( ID_MCHECK == '0' ):
ID_MCHECK = '1'
elif ( BUILD == 'debug' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-O1' )
BASECPPFLAGS.append( '-D_DEBUG' )
if ( ID_MCHECK == '0' ):
ID_MCHECK = '1'
elif ( BUILD == 'test' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-D_FINAL' )
BASECPPFLAGS.append( '-D_TEST' )
if ( OS == 'Linux' ):
# Don't omit frame pointers in the test build
OPTCPPFLAGS = [ '-O3', '-march=pentium3', '-Winline', '-ffast-math', '-fno-unsafe-math-optimizations' ]
if ( ID_MCHECK == '0' ):
ID_MCHECK = '2'
elif ( OS == 'Darwin' ):
OPTCPPFLAGS = [ '-O3', '-falign-functions=16', '-falign-loops=16', '-finline' ]
elif ( BUILD == 'release' ):
BASECPPFLAGS.append( '-D_FINAL' )
if ( OS == 'Linux' ):
# -fomit-frame-pointer: "-O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging."
# on x86 have to set it explicitely
# -finline-functions: implicit at -O3
# -fschedule-insns2: implicit at -O2
# no-unsafe-math-optimizations: that should be on by default really. hit some wonko bugs in physics code because of that
OPTCPPFLAGS = [ '-O3', '-march=pentium3', '-Winline', '-ffast-math', '-fno-unsafe-math-optimizations', '-fomit-frame-pointer' ]
if ( ID_MCHECK == '0' ):
ID_MCHECK = '2'
elif ( OS == 'Darwin' ):
OPTCPPFLAGS = [ '-O3', '-falign-functions=16', '-falign-loops=16', '-finline' ]
else:
print 'Unknown build configuration ' + BUILD
sys.exit(0)
if ( GL_HARDLINK != '0' ):
CORECPPFLAGS.append( '-DID_GL_HARDLINK' )
if ( DEBUG_MEMORY != '0' ):
BASECPPFLAGS += [ '-DID_DEBUG_MEMORY', '-DID_REDIRECT_NEWDELETE' ]
if ( LIBC_MALLOC != '1' ):
BASECPPFLAGS.append( '-DUSE_LIBC_MALLOC=0' )
if ( len( IDNET_HOST ) ):
CORECPPFLAGS.append( '-DIDNET_HOST=\\"%s\\"' % IDNET_HOST )
if ( ID_NOLANADDRESS != '0' ):
CORECPPFLAGS.append( '-DID_NOLANADDRESS' )
if ( ID_MCHECK == '1' ):
BASECPPFLAGS.append( '-DID_MCHECK' )
# create the build environements
if ( FIX_INCLUDES == '1' ):
CC = './sys/scons/fixincludes.py \'' + CC + '\''
CXX = './sys/scons/fixincludes.py \'' + CXX + '\''
if ( FIX_SUPER == '1' ):
CC = './sys/scons/fixsuper.py \'' + CC + '\''
CXX = './sys/scons/fixsuper.py \'' + CXX + '\''
g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH, OS = OS )
scons_utils.SetupUtils( g_base_env )
g_base_env.Append( CXXFLAGS = [ '-Wno-invalid-offsetof' ] )
g_env = g_base_env.Copy()
g_env['CPPFLAGS'] += OPTCPPFLAGS
g_env['CPPFLAGS'] += CORECPPFLAGS
g_env['LINKFLAGS'] += CORELINKFLAGS
if ( BUILD != 'release' and BUILD != 'test' ):
g_env_noopt = g_env.Copy()
else:
g_env_noopt = g_base_env.Copy()
g_env_noopt['CPPFLAGS'] += CORECPPFLAGS
# g_env_noopt.Append( CPPFLAGS = '-O1' )
g_env_noopt['LINKFLAGS'] += CORELINKFLAGS
g_game_env = g_base_env.Copy()
g_game_env['CPPFLAGS'] += OPTCPPFLAGS
g_game_env['CPPFLAGS'] += GAMECPPFLAGS
# maintain this dangerous optimization off at all times
g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
g_env_noopt.Append( CPPFLAGS = '-fno-strict-aliasing' )
g_game_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
if ( int(JOBS) > 1 ):
print 'Using buffered process output'
silent = False
if ( SILENT == '1' ):
silent = True
scons_utils.SetupBufferedOutput( g_env, silent )
scons_utils.SetupBufferedOutput( g_game_env, silent )
# mark the globals
local_dedicated = 0
# 0 for monolithic build
local_gamedll = 1
# carry around rather than using .a, avoids binutils bugs
idlib_objects = []
game_objects = []
local_demo = 0
# curl usage. there is a global toggle flag
local_curl = 0
curl_lib = []
# if idlib should produce PIC objects ( depending on core or game inclusion )
local_idlibpic = 0
eventdefs = None
# compile for SMP ( affects idlib and core )
local_smp = 0
idsdl_info = []
local_mpgame = 0
GLOBALS = 'g_env g_env_noopt g_game_env OS ID_MCHECK idlib_objects game_objects local_dedicated local_gamedll local_demo local_idlibpic curl_lib local_curl local_smp idsdl_info local_mpgame eventdefs GL_HARDLINK NOCURL Q4TEST OSX_BUILDSTYLE TARGET_CORE_SMP BUILD GCC_X86_ASM'
# end general configuration ----------------------
# targets ----------------------------------------
Export( 'GLOBALS ' + GLOBALS )
quake4 = None
q4ded = None
game = None
mpgame = None
q4_mon = None
Default( None )
# build curl if needed
if ( NOCURL == '0' and ( TARGET_CORE == '1' or TARGET_MONO == '1' or TARGET_CORE_SMP == '1' ) ):
# 1: debug, 2: release
if ( BUILD == 'release' or BUILD == 'test' ):
local_curl = 2
else:
local_curl = 1
Export( 'GLOBALS ' + GLOBALS )
curl_lib = SConscript( 'sys/scons/SConscript.curl' )
# build our custom SDL library if needed
if ( TARGET_CORE_SMP == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/sdl', '.', duplicate = 0 )
idsdl_info = SConscript( 'sys/scons/SConscript.idsdl' )
if ( TARGET_CORE_SMP == '1' ):
local_gamedll = 1
local_demo = 0
local_idlibpic = 0
local_dedicated = 0
local_smp = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/core-smp/glimp', '.', duplicate = 1 )
SConscript( g_build + '/core-smp/glimp/sys/scons/SConscript.gl' )
BuildDir( g_build + '/core-smp', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/core-smp/sys/scons/SConscript.idlib' )
Export( 'GLOBALS ' + GLOBALS ) # update idlib_objects
quake4smp = SConscript( g_build + '/core-smp/sys/scons/SConscript.core' )
if ( BUILD != 'test' ):
quake4smp = InstallAs( '#quake4smp.%s' % cpu, quake4smp )
if ( OS == 'Linux' ):
Default( quake4smp )
if ( TARGET_CORE == '1' ):
local_gamedll = 1
local_demo = 0
local_idlibpic = 0
local_smp = 0
if ( DEDICATED == '0' or DEDICATED == '2' ):
local_dedicated = 0
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/core/glimp', '.', duplicate = 1 )
SConscript( g_build + '/core/glimp/sys/scons/SConscript.gl' )
BuildDir( g_build + '/core', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/core/sys/scons/SConscript.idlib' )
Export( 'GLOBALS ' + GLOBALS ) # update idlib_objects
quake4 = SConscript( g_build + '/core/sys/scons/SConscript.core' )
if ( BUILD != 'test' ):
quake4 = InstallAs( '#quake4.%s' % cpu, quake4 )
if ( OS == 'Linux' ):
Default( quake4 )
if ( DEDICATED == '1' or DEDICATED == '2' ):
local_dedicated = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/dedicated/glimp', '.', duplicate = 1 )
SConscript( g_build + '/dedicated/glimp/sys/scons/SConscript.gl' )
BuildDir( g_build + '/dedicated', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/dedicated/sys/scons/SConscript.idlib' )
Export( 'GLOBALS ' + GLOBALS )
q4ded = SConscript( g_build + '/dedicated/sys/scons/SConscript.core' )
if ( BUILD != 'test' ):
q4ded = InstallAs( '#q4ded.%s' % cpu, q4ded )
if ( OS == 'Linux' ):
Default( q4ded )
if ( TARGET_SPGAME == '1' ):
local_gamedll = 1
local_demo = 0
local_dedicated = 0
local_idlibpic = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/game', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/game/sys/scons/SConscript.idlib' )
local_mpgame = 0
Export( 'GLOBALS ' + GLOBALS )
game = SConscript( g_build + '/game/sys/scons/SConscript.game' )
if ( BUILD != 'test' ):
if ( OS == 'Darwin' ):
game = InstallAs( '#spgame.so' , game )
else:
game = InstallAs( '#spgame%s.so' % cpu, game )
Default( game )
if ( TARGET_MPGAME == '1' ):
local_gamedll = 1
local_demo = 0
local_dedicated = 0
local_idlibpic = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/mpgame', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/mpgame/sys/scons/SConscript.idlib' )
local_mpgame = 1
Export( 'GLOBALS ' + GLOBALS )
mpgame = SConscript( g_build + '/mpgame/sys/scons/SConscript.game' )
if ( BUILD != 'test' ):
if ( OS == 'Darwin' ):
mpgame = InstallAs( '#mpgame.so' , mpgame )
else:
mpgame = InstallAs( '#mpgame%s.so' % cpu, mpgame )
Default( mpgame )
if ( TARGET_MONO == '1' ):
# the game in a single piece
local_gamedll = 0
local_dedicated = 0
local_demo = 0
local_idlibpic = 0
if ( TARGET_MONO_IS_SP == '1' ):
local_mpgame = 0
else:
local_mpgame = 1
if ( DEDICATED == '0' or DEDICATED == '2' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/mono/glimp', '.', duplicate = 1 )
SConscript( g_build + '/mono/glimp/sys/scons/SConscript.gl' )
BuildDir( g_build + '/mono', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/mono/sys/scons/SConscript.idlib' )
game_objects = SConscript( g_build + '/mono/sys/scons/SConscript.game' )
Export( 'GLOBALS ' + GLOBALS )
q4_mono = SConscript( g_build + '/mono/sys/scons/SConscript.core' )
if ( BUILD != 'test' ):
q4_mono = InstallAs( '#q4mono.%s' % cpu, q4_mono )
if ( OS == 'Linux' ):
Default( q4_mono )
if ( DEDICATED == '1' or DEDICATED == '2' ):
local_dedicated = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/monoded/glimp', '.', duplicate = 1 )
SConscript( g_build + '/monoded/glimp/sys/scons/SConscript.gl' )
BuildDir( g_build + '/monoded', '.', duplicate = 0 )
idlib_objects = SConscript( g_build + '/monoded/sys/scons/SConscript.idlib' )
game_objects = SConscript( g_build + '/monoded/sys/scons/SConscript.game' )
Export( 'GLOBALS ' + GLOBALS )
q4_monoded = SConscript( g_build + '/monoded/sys/scons/SConscript.core' )
if ( BUILD != 'test' ):
q4_monoded = InstallAs( '#q4monoded.%s' % cpu, q4_monoded )
if ( OS == 'Linux' ):
Default( q4_monoded )
if ( OS == 'Darwin' ):
src = []
if ( TARGET_CORE == '1' ):
if ( DEDICATED == '0' or DEDICATED == '2' ):
src.append( quake4 )
if ( DEDICATED == '1' or DEDICATED == '2' ):
src.append( q4ded )
if ( TARGET_MONO == '1' ):
if ( DEDICATED == '0' or DEDICATED == '2' ):
src.append( q4_mono )
if ( DEDICATED == '1' or DEDICATED == '2' ):
src.append( q4_monoded )
if ( len( src ) ):
q4mac = Command( 'q4mac', src, Action( g_env.BuildBundle ) )
Default( q4mac )
if ( SETUP == '1' ):
brandelf = Program( 'brandelf', 'sys/linux/setup/brandelf.c' )
setup_source = [ brandelf, quake4, q4ded, game, quake4smp ]
do_gamepak = ( TARGET_GAMEPAK != '0' )
setups = []
if ( SETUP_TAGGED == '1' ):
g_env_tagged = g_env.Copy()
g_env_tagged.Prepare( do_gamepak, ASSETS )
setup_tagged = Command( 'setup_tagged', setup_source, Action( g_env_tagged.BuildSetup ) )
Default( setup_tagged )
setups.append( setup_tagged )
if ( SETUP_DEMO == '1' ):
g_env_demo = g_env.Copy()
g_env_demo.Prepare( do_gamepak, ASSETS )
setup_demo = Command( 'setup_demo', setup_source, Action( g_env_demo.BuildSetup ) )
Default( setup_demo )
setups.append( setup_demo )
if ( SETUP_DEDICATED == '1' ):
g_env_ded = g_env.Copy()
g_env_ded.Prepare( do_gamepak, ASSETS )
setup_ded = Command( 'setup_ded', setup_source, Action( g_env_ded.BuildSetup ) )
Default( setup_ded )
setups.append( setup_ded )
if ( SETUP_FULL == '1' ):
g_env_full = g_env.Copy()
g_env_full.Prepare( do_gamepak, ASSETS )
setup_full = Command( 'setup_full', setup_source, Action( g_env_full.BuildSetup ) )
Default( setup_full )
setups.append( setup_full )
if ( SETUP_INCREMENTAL == '1' ):
g_env_incr = g_env.Copy()
g_env_incr.Prepare( do_gamepak, ASSETS )
setup_incr = Command( 'setup_incremental', setup_source, Action( g_env_incr.BuildSetup ) )
Default( setup_incr )
setups.append( setup_incr )
# setup dependencies so they are built sequentially
i = 1
while ( i < len( setups ) ):
Depends( setups[ i ], setups[ i - 1 ] )
i += 1
else:
if ( TARGET_GAMEPAK == '1' ):
spgame_pak = Command( 'spgamepak', game, Action( g_env.BuildGamePak ) )
Default( spgame_pak )
mpgame_pak = Command( 'mpgamepak', mpgame, Action( g_env.BuildGamePak ) )
Default( mpgame_pak )
if ( SDK != '0' ):
setup_sdk = Command( 'sdk', [ ], Action( g_env.BuildSDK ) )
Default( setup_sdk )
# end targets ------------------------------------

471
source/aas/AASFile.h Normal file
View file

@ -0,0 +1,471 @@
#ifndef __AASFILE_H__
#define __AASFILE_H__
/*
===============================================================================
AAS File
===============================================================================
*/
#define AAS_FILEID "DewmAAS"
#define AAS_FILEVERSION "1.08"
// travel flags
#define TFL_INVALID BIT(0) // not valid
#define TFL_WALK BIT(1) // walking
#define TFL_CROUCH BIT(2) // crouching
#define TFL_WALKOFFLEDGE BIT(3) // walking of a ledge
#define TFL_BARRIERJUMP BIT(4) // jumping onto a barrier
#define TFL_JUMP BIT(5) // jumping
#define TFL_LADDER BIT(6) // climbing a ladder
#define TFL_SWIM BIT(7) // swimming
#define TFL_WATERJUMP BIT(8) // jump out of the water
#define TFL_TELEPORT BIT(9) // teleportation
#define TFL_ELEVATOR BIT(10) // travel by elevator
#define TFL_FLY BIT(11) // fly
#define TFL_SPECIAL BIT(12) // special
#define TFL_WATER BIT(21) // travel through water
#define TFL_AIR BIT(22) // travel through air
// face flags
#define FACE_SOLID BIT(0) // solid at the other side
#define FACE_LADDER BIT(1) // ladder surface
#define FACE_FLOOR BIT(2) // standing on floor when on this face
#define FACE_LIQUID BIT(3) // face seperating two areas with liquid
#define FACE_LIQUIDSURFACE BIT(4) // face seperating liquid and air
// area flags
#define AREA_FLOOR BIT(0) // AI can stand on the floor in this area
#define AREA_GAP BIT(1) // area has a gap
#define AREA_LEDGE BIT(2) // if entered the AI bbox partly floats above a ledge
#define AREA_LADDER BIT(3) // area contains one or more ladder faces
#define AREA_LIQUID BIT(4) // area contains a liquid
#define AREA_CROUCH BIT(5) // AI cannot walk but can only crouch in this area
#define AREA_REACHABLE_WALK BIT(6) // area is reachable by walking or swimming
#define AREA_REACHABLE_FLY BIT(7) // area is reachable by flying
// area contents flags
#define AREACONTENTS_SOLID BIT(0) // solid, not a valid area
#define AREACONTENTS_WATER BIT(1) // area contains water
#define AREACONTENTS_CLUSTERPORTAL BIT(2) // area is a cluster portal
#define AREACONTENTS_OBSTACLE BIT(3) // area contains (part of) a dynamic obstacle
#define AREACONTENTS_TELEPORTER BIT(4) // area contains (part of) a teleporter trigger
// bits for different bboxes
#define AREACONTENTS_BBOX_BIT 24
// RAVEN BEGIN
// cdr: AASTactical
// feature bits
#define FEATURE_COVER BIT(0) // provides cover
#define FEATURE_LOOK_LEFT BIT(1) // attack by leaning left
#define FEATURE_LOOK_RIGHT BIT(2) // attack by leaning right
#define FEATURE_LOOK_OVER BIT(3) // attack by leaning over the cover
#define FEATURE_CORNER_LEFT BIT(4) // is a left corner
#define FEATURE_CORNER_RIGHT BIT(5) // is a right corner
#define FEATURE_PINCH BIT(6) // is a tight area connecting two larger areas
#define FEATURE_VANTAGE BIT(7) // provides a good view of the sampled area as a whole
// forward reference of sensor object
struct rvAASTacticalSensor;
struct rvMarker;
// RAVEN END
#define MAX_REACH_PER_AREA 256
#define MAX_AAS_TREE_DEPTH 128
#define MAX_AAS_BOUNDING_BOXES 4
typedef enum {
RE_WALK,
RE_WALKOFFLEDGE,
RE_FLY,
RE_SWIM,
RE_WATERJUMP,
RE_BARRIERJUMP,
RE_SPECIAL
};
// reachability to another area
class idReachability {
public:
int travelType; // type of travel required to get to the area
short toAreaNum; // number of the reachable area
short fromAreaNum; // number of area the reachability starts
idVec3 start; // start point of inter area movement
idVec3 end; // end point of inter area movement
int edgeNum; // edge crossed by this reachability
unsigned short travelTime; // travel time of the inter area movement
byte number; // reachability number within the fromAreaNum (must be < 256)
byte disableCount; // number of times this reachability has been disabled
idReachability * next; // next reachability in list
idReachability * rev_next; // next reachability in reversed list
unsigned short * areaTravelTimes; // travel times within the fromAreaNum from reachabilities that lead towards this area
};
class idReachability_Walk : public idReachability {
};
class idReachability_BarrierJump : public idReachability {
};
class idReachability_WaterJump : public idReachability {
};
class idReachability_WalkOffLedge : public idReachability {
};
class idReachability_Swim : public idReachability {
};
class idReachability_Fly : public idReachability {
};
class idReachability_Special : public idReachability {
friend class idAASFileLocal;
private:
idDict dict;
};
// index
typedef int aasIndex_t;
// vertex
typedef idVec3 aasVertex_t;
// edge
typedef struct aasEdge_s {
int vertexNum[2]; // numbers of the vertexes of this edge
} aasEdge_t;
// area boundary face
typedef struct aasFace_s {
unsigned short planeNum; // number of the plane this face is on
unsigned short flags; // face flags
int numEdges; // number of edges in the boundary of the face
int firstEdge; // first edge in the edge index
short areas[2]; // area at the front and back of this face
} aasFace_t;
// area with a boundary of faces
typedef struct aasArea_s {
int numFaces; // number of faces used for the boundary of the area
int firstFace; // first face in the face index used for the boundary of the area
idBounds bounds; // bounds of the area
idVec3 center; // center of the area an AI can move towards
float ceiling; // top of the area
unsigned short flags; // several area flags
unsigned short contents; // contents of the area
short cluster; // cluster the area belongs to, if negative it's a portal
short clusterAreaNum; // number of the area in the cluster
int travelFlags; // travel flags for traveling through this area
idReachability * reach; // reachabilities that start from this area
idReachability * rev_reach; // reachabilities that lead to this area
// RAVEN BEGIN
// cdr: AASTactical
unsigned short numFeatures; // number of features in this area
unsigned short firstFeature; // first feature in the feature index within this area
// cdr: Obstacle Avoidance
rvMarker* firstMarker; // first obstacle avoidance threat in this area (0 if none)
// RAVEN END
} aasArea_t;
// nodes of the bsp tree
typedef struct aasNode_s {
unsigned short planeNum; // number of the plane that splits the subspace at this node
int children[2]; // child nodes, zero is solid, negative is -(area number)
} aasNode_t;
// cluster portal
typedef struct aasPortal_s {
short areaNum; // number of the area that is the actual portal
short clusters[2]; // number of cluster at the front and back of the portal
short clusterAreaNum[2]; // number of this portal area in the front and back cluster
unsigned short maxAreaTravelTime; // maximum travel time through the portal area
} aasPortal_t;
// cluster
typedef struct aasCluster_s {
int numAreas; // number of areas in the cluster
int numReachableAreas; // number of areas with reachabilities
int numPortals; // number of cluster portals
int firstPortal; // first cluster portal in the index
} aasCluster_t;
// RAVEN BEGIN
// cdr: AASTactical
typedef struct aasFeature_s {
short x; // 2 Bytes
short y; // 2 Bytes
short z; // 2 Bytes
unsigned short flags; // 2 Bytes
unsigned char normalx; // 1 Byte
unsigned char normaly; // 1 Byte
unsigned char height; // 1 Byte
unsigned char weight; // 1 Byte
idVec3& Normal();
idVec3& Origin();
void DrawDebugInfo( int index=-1 );
int GetLookPos( idVec3& lookPos, const idVec3& aimAtOrigin, const float leanDistance=16.0f );
} aasFeature_t; //--------------------------------
// 12 Bytes
// RAVEN END
// trace through the world
typedef struct aasTrace_s {
// parameters
int flags; // areas with these flags block the trace
int travelFlags; // areas with these travel flags block the trace
int maxAreas; // size of the 'areas' array
int getOutOfSolid; // trace out of solid if the trace starts in solid
// output
float fraction; // fraction of trace completed
idVec3 endpos; // end position of trace
int planeNum; // plane hit
int lastAreaNum; // number of last area the trace went through
int blockingAreaNum; // area that could not be entered
int numAreas; // number of areas the trace went through
int * areas; // array to store areas the trace went through
idVec3 * points; // points where the trace entered each new area
aasTrace_s( void ) { areas = NULL; points = NULL; getOutOfSolid = false; flags = travelFlags = maxAreas = 0; }
} aasTrace_t;
// settings
class idAASSettings {
public:
// collision settings
int numBoundingBoxes;
idBounds boundingBoxes[MAX_AAS_BOUNDING_BOXES];
bool usePatches;
bool writeBrushMap;
bool playerFlood;
bool noOptimize;
bool allowSwimReachabilities;
bool allowFlyReachabilities;
// RAVEN BEGIN
// bkreimeier
bool generateAllFaces;
// cdr: AASTactical
bool generateTacticalFeatures;
// scork: AASOnly numbers
int iAASOnly; // 0, else 32,48,96,250 or -1 for all
// RAVEN END
idStr fileExtension;
// physics settings
idVec3 gravity;
idVec3 gravityDir;
idVec3 invGravityDir;
float gravityValue;
float maxStepHeight;
float maxBarrierHeight;
float maxWaterJumpHeight;
float maxFallHeight;
float minFloorCos;
// fixed travel times
int tt_barrierJump;
int tt_startCrouching;
int tt_waterJump;
int tt_startWalkOffLedge;
// RAVEN BEGIN
// rjohnson: added more debug drawing
idVec4 debugColor;
bool debugDraw;
// RAVEN END
public:
idAASSettings( void );
bool FromFile( const idStr &fileName );
// RAVEN BEGIN
// jsinger: changed to be Lexer instead of idLexer so that we have the ability to read binary files
bool FromParser( Lexer &src );
// RAVEN END
bool FromDict( const char *name, const idDict *dict );
bool WriteToFile( idFile *fp ) const;
bool ValidForBounds( const idBounds &bounds ) const;
bool ValidEntity( const char *classname, bool* needFlyReachabilities=NULL ) const;
// RAVEN BEGIN
float Radius( float scale=1.0f ) const;
// RAVEN END
private:
// RAVEN BEGIN
// jsinger: changed to be Lexer instead of idLexer so that we have the ability to read binary files
bool ParseBool( Lexer &src, bool &b );
bool ParseInt( Lexer &src, int &i );
bool ParseFloat( Lexer &src, float &f );
bool ParseVector( Lexer &src, idVec3 &vec );
bool ParseBBoxes( Lexer &src );
// RAVEN END
};
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
the cluster number set to the negative portal number
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
- portal zero is a dummy
- cluster zero is a dummy
*/
typedef struct sizeEstimate_s {
int numEdgeIndexes;
int numFaceIndexes;
int numAreas;
int numNodes;
} sizeEstimate_t;
class idAASFile {
public:
virtual ~idAASFile( void ) {}
// RAVEN BEGIN
// jscott: made pure virtual
virtual class idAASFile * CreateNew( void ) = 0;
virtual class idAASSettings * CreateAASSettings( void ) = 0;
virtual class idReachability * CreateReachability( int type ) = 0;
// RAVEN BEGIN
// jsinger: changed to be Lexer instead of idLexer so that we have the ability to read binary files
virtual bool FromParser( class idAASSettings *edit, Lexer &src ) = 0;
// RAVEN END
virtual const char * GetName( void ) const = 0;
virtual unsigned int GetCRC( void ) const = 0;
virtual void SetSizes( sizeEstimate_t size ) = 0;
virtual int GetNumPlanes( void ) const = 0;
virtual idPlane & GetPlane( int index ) = 0;
virtual int FindPlane( const idPlane &plane, const float normalEps, const float distEps ) = 0;
virtual int GetNumVertices( void ) const = 0;
virtual aasVertex_t & GetVertex( int index ) = 0;
virtual int AppendVertex( aasVertex_t &vert ) = 0;
virtual int GetNumEdges( void ) const = 0;
virtual aasEdge_t & GetEdge( int index ) = 0;
virtual int AppendEdge( aasEdge_t &edge ) = 0;
virtual int GetNumEdgeIndexes( void ) const = 0;
virtual aasIndex_t & GetEdgeIndex( int index ) = 0;
virtual int AppendEdgeIndex( aasIndex_t &edgeIdx ) = 0;
virtual int GetNumFaces( void ) const = 0;
virtual aasFace_t & GetFace( int index ) = 0;
virtual int AppendFace( aasFace_t &face ) = 0;
virtual int GetNumFaceIndexes( void ) const = 0;
virtual aasIndex_t & GetFaceIndex( int index ) = 0;
virtual int AppendFaceIndex( aasIndex_t &faceIdx ) = 0;
virtual int GetNumAreas( void ) const = 0;
virtual aasArea_t & GetArea( int index ) = 0;
virtual int AppendArea( aasArea_t &area ) = 0;
virtual int GetNumNodes( void ) const = 0;
virtual aasNode_t & GetNode( int index ) = 0;
virtual int AppendNode( aasNode_t &node ) = 0;
virtual void SetNumNodes( int num ) = 0;
virtual int GetNumPortals( void ) const = 0;
virtual aasPortal_t & GetPortal( int index ) = 0;
virtual int AppendPortal( aasPortal_t &portal ) = 0;
virtual int GetNumPortalIndexes( void ) const = 0;
virtual aasIndex_t & GetPortalIndex( int index ) = 0;
virtual int AppendPortalIndex( aasIndex_t &portalIdx, int clusterNum ) = 0;
virtual int GetNumClusters( void ) const = 0;
virtual aasCluster_t & GetCluster( int index ) = 0;
virtual int AppendCluster( aasCluster_t &cluster ) = 0;
// RAVEN BEGIN
// cdr: AASTactical
virtual void ClearTactical( void ) = 0;
virtual int GetNumFeatureIndexes( void ) const = 0;
virtual aasIndex_t & GetFeatureIndex( int index ) = 0;
virtual int AppendFeatureIndex( aasIndex_t &featureIdx ) = 0;
virtual int GetNumFeatures( void ) const = 0;
virtual aasFeature_t & GetFeature( int index ) = 0;
virtual int AppendFeature( aasFeature_t &cluster ) = 0;
// RAVEN END
virtual idAASSettings & GetSettings( void ) = 0;
virtual void SetSettings( const idAASSettings &in ) = 0;
virtual void SetPortalMaxTravelTime( int index, int time ) = 0;
virtual void SetAreaTravelFlag( int index, int flag ) = 0;
virtual void RemoveAreaTravelFlag( int index, int flag ) = 0;
// RAVEN END
virtual idVec3 EdgeCenter( int edgeNum ) const = 0;
virtual idVec3 FaceCenter( int faceNum ) const = 0;
virtual idVec3 AreaCenter( int areaNum ) const = 0;
virtual idBounds EdgeBounds( int edgeNum ) const = 0;
virtual idBounds FaceBounds( int faceNum ) const = 0;
virtual idBounds AreaBounds( int areaNum ) const = 0;
virtual int PointAreaNum( const idVec3 &origin ) const = 0;
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const = 0;
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const = 0;
virtual void PushPointIntoAreaNum( int areaNum, idVec3 &point ) const = 0;
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;
virtual void PrintInfo( void ) const = 0;
// RAVEN BEGIN
// jscott: added
virtual size_t GetMemorySize( void ) = 0;
virtual void Init( void ) = 0;
virtual bool Load( const idStr &fileName, unsigned int mapFileCRC ) = 0;
virtual bool Write( const idStr &fileName, unsigned int mapFileCRC ) = 0;
virtual void Clear( void ) = 0;
virtual void FinishAreas( void ) = 0;
virtual void ReportRoutingEfficiency( void ) const = 0;
virtual void LinkReversedReachability( void ) = 0;
virtual void DeleteReachabilities( void ) = 0;
virtual void DeleteClusters( void ) = 0;
virtual void Optimize( void ) = 0;
virtual bool IsDummyFile( unsigned int mapFileCRC ) = 0;
// RAVEN END
virtual const idDict & GetReachabilitySpecialDict( idReachability *reach ) const = 0;
virtual void SetReachabilitySpecialDictKeyValue( idReachability *reach, const char *key, const char *value ) = 0;
};
// RAVEN BEGIN
extern idAASFile *AASFile;
// RAVEN END
#endif /* !__AASFILE_H__ */

View file

@ -0,0 +1,23 @@
#ifndef __AASFILEMANAGER_H__
#define __AASFILEMANAGER_H__
/*
===============================================================================
AAS File Manager
===============================================================================
*/
class idAASFileManager {
public:
virtual ~idAASFileManager( void ) {}
virtual idAASFile * LoadAAS( const char *fileName, unsigned int mapFileCRC ) = 0;
virtual void FreeAAS( idAASFile *file ) = 0;
};
extern idAASFileManager * AASFileManager;
#endif /* !__AASFILEMANAGER_H__ */

103
source/bse/BSEInterface.h Normal file
View file

@ -0,0 +1,103 @@
#ifndef _BSE_INTERFACE_H_INC_
#define _BSE_INTERFACE_H_INC_
#define BSE_EFFECT_EXTENSION "fx"
enum
{
VIEWEFFECT_DOUBLEVISION = 0,
VIEWEFFECT_SHAKE,
VIEWEFFECT_TUNNEL
};
typedef enum {
EC_IGNORE = 0,
EC_IMPACT,
EC_IMPACT_PARTICLES,
EC_MAX,
} effectCategory_t;
extern idCVar bse_enabled;
extern idCVar bse_render;
extern idCVar bse_debug;
extern idCVar bse_showBounds;
extern idCVar bse_physics;
extern idCVar bse_debris;
extern idCVar bse_scale;
extern idCVar bse_singleEffect;
extern idCVar bse_maxParticles;
// Interface to the effects system
class rvBSEManager
{
public:
virtual ~rvBSEManager( void ) {}
virtual bool Init( void ) = 0;
virtual bool Shutdown( void ) = 0;
virtual bool PlayEffect( class rvRenderEffectLocal *def, float time ) = 0;
virtual bool ServiceEffect( class rvRenderEffectLocal *def, float time ) = 0;
virtual void StopEffect( rvRenderEffectLocal *def ) = 0;
virtual void FreeEffect( rvRenderEffectLocal *def ) = 0;
virtual float EffectDuration( const rvRenderEffectLocal *def ) = 0;
virtual bool CheckDefForSound( const renderEffect_t *def ) = 0;
virtual void BeginLevelLoad( void ) = 0;
virtual void EndLevelLoad( void ) = 0;
virtual void StartFrame( void ) = 0;
virtual void EndFrame( void ) = 0;
virtual bool Filtered( const char *name, effectCategory_t category ) = 0;
virtual void UpdateRateTimes( void ) = 0;
virtual bool CanPlayRateLimited( effectCategory_t category ) = 0;
};
extern rvBSEManager *bse;
class rvDeclEffectEdit
{
public:
virtual ~rvDeclEffectEdit() {}
virtual void Finish( class rvDeclEffect *edit ) = 0;
virtual class rvSegmentTemplate *GetSegmentTemplate( class rvDeclEffect *edit, const char *name ) = 0;
virtual class rvSegmentTemplate *GetSegmentTemplate( class rvDeclEffect *edit, int i ) = 0;
virtual void CopyData( class rvDeclEffect *edit, class rvDeclEffect *copy ) = 0;
virtual int AddSegment( class rvDeclEffect *edit, class rvSegmentTemplate *add ) = 0;
virtual void DeleteSegment( class rvDeclEffect *edit, int index ) = 0;
virtual void SwapSegments( class rvSegmentTemplate *seg1, class rvSegmentTemplate *seg2 ) = 0;
virtual void CreateEditorOriginal( class rvDeclEffect *edit ) = 0;
virtual void DeleteEditorOriginal( class rvDeclEffect *edit ) = 0;
virtual bool CompareToEditorOriginal( class rvDeclEffect *edit ) = 0;
virtual void RevertToEditorOriginal( class rvDeclEffect *edit ) = 0;
virtual void Init( class rvSegmentTemplate *edit, class rvDeclEffect *effect ) = 0;
virtual bool Parse( class rvSegmentTemplate *edit, class rvDeclEffect *effect, int type, class idLexer *lexer ) = 0;
virtual void Finish( class rvSegmentTemplate *edit, class rvDeclEffect *effect ) = 0;
virtual bool Compare( class rvSegmentTemplate *edit, const class rvSegmentTemplate *other ) const = 0;
virtual void SetName( class rvSegmentTemplate *edit, const char *name ) = 0;
virtual void Finish( class rvParticleTemplate *edit ) = 0;
virtual bool Compare( class rvParticleTemplate *edit, const class rvParticleTemplate *other ) const = 0;
virtual void Init( class rvParticleTemplate *edit ) = 0;
virtual void FixupParms( class rvParticleTemplate *edit, class rvParticleParms *parms ) = 0;
virtual void SetMaterialName( class rvParticleTemplate *edit, const char *name ) = 0;
virtual void SetModelName( class rvParticleTemplate *edit, const char *name ) = 0;
virtual void SetEntityDefName( class rvParticleTemplate *edit, const char *name ) = 0;
virtual void SetTrailTypeName( class rvParticleTemplate *edit, const char *name ) = 0;
virtual void SetTrailMaterialName( class rvParticleTemplate *edit, const char *name ) = 0;
virtual bool Compare( class rvParticleParms *edit, const class rvParticleParms *other ) const = 0;
virtual void CalcRate( class rvEnvParms *edit, float *rate, float duration, int count ) = 0;
virtual void Evaluate3( class rvEnvParms *edit, float time, const float *start, const float *rate, const float *end, float *dest ) = 0;
};
extern rvDeclEffectEdit *declEffectEdit;
#endif // _BSE_INTERFACE_H_INC_

150
source/cm/CollisionModel.h Normal file
View file

@ -0,0 +1,150 @@
#ifndef __COLLISIONMODELMANAGER_H__
#define __COLLISIONMODELMANAGER_H__
/*
===============================================================================
Trace model vs. polygonal model collision detection.
Short translations are the least expensive. Retrieving contact points is
about as cheap as a short translation. Position tests are more expensive
and rotations are most expensive.
There is no position test at the start of a translation or rotation. In other
words if a translation with start != end or a rotation with angle != 0 starts
in solid, this goes unnoticed and the collision result is undefined.
A translation with start == end or a rotation with angle == 0 performs
a position test and fills in the trace_t structure accordingly.
===============================================================================
*/
// contact type
enum contactType_t {
CONTACT_NONE, // no contact
CONTACT_EDGE, // trace model edge hits model edge
CONTACT_MODELVERTEX, // model vertex hits trace model polygon
CONTACT_TRMVERTEX // trace model vertex hits model polygon
};
// contact info
struct contactInfo_t {
contactType_t type; // contact type
idVec3 point; // point of contact
idVec3 normal; // contact plane normal
float dist; // contact plane distance
float separation; // contact feature separation at initial position
int contents; // contents at other side of surface
const idMaterial * material; // surface material
int modelFeature; // contact feature on model
int trmFeature; // contact feature on trace model
int entityNum; // entity the contact surface is a part of
int id; // id of clip model the contact surface is part of
// RAVEN BEGIN
// jscott: for material type code
const rvDeclMatType *materialType; // material type of texture (possibly indirected though a hit map)
// RAVEN END
};
// trace result
struct trace_t {
float fraction; // fraction of movement completed, 1.0 = didn't hit anything
idVec3 endpos; // final position of trace model
idMat3 endAxis; // final axis of trace model
contactInfo_t c; // contact information, only valid if fraction < 1.0
};
#define WORLD_MODEL_NAME "worldMap" // name of world model
#define CM_CLIP_EPSILON 0.25f // always stay this distance away from any model
#define CM_BOX_EPSILON 1.0f // should always be larger than clip epsilon
#define CM_MAX_TRACE_DIST 4096.0f // maximum distance a trace model may be traced, point traces are unlimited
// collision model
class idCollisionModel {
public:
virtual ~idCollisionModel() { }
// Returns the name of the model.
virtual const char * GetName( void ) const = 0;
// Gets the bounds of the model.
virtual bool GetBounds( idBounds &bounds ) const = 0;
// Gets all contents flags of brushes and polygons of the model ored together.
virtual bool GetContents( int &contents ) const = 0;
// Gets a vertex of the model.
virtual bool GetVertex( int vertexNum, idVec3 &vertex ) const = 0;
// Gets an edge of the model.
virtual bool GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const = 0;
// Gets a polygon of the model.
virtual bool GetPolygon( int polygonNum, idFixedWinding &winding ) const = 0;
};
// collision model manager
class idCollisionModelManager {
public:
virtual ~idCollisionModelManager( void ) {}
virtual void Init( void ) = 0;
virtual void Shutdown( void ) = 0;
// Loads collision models from a map file.
virtual void LoadMap( const idMapFile *mapFile, bool forceReload ) = 0;
// Frees all the collision models for the given map.
virtual void FreeMap( const char *mapName ) = 0;
// Loads a collision model.
virtual idCollisionModel * LoadModel( const char *mapName, const char *modelName ) = 0;
// RAVEN BEGIN
// mwhitlock: conversion from idRenderModel to MD5R fixes (to keep redundant collision surfaces out of the MD5R files).
virtual idCollisionModel * ExtractCollisionModel( idRenderModel *renderModel, const char *modelName ) = 0;
// RAVEN END
// Precaches a collision model.
virtual void PreCacheModel( const char *mapName, const char *modelName ) = 0;
// Free the given model.
virtual void FreeModel( idCollisionModel *model ) = 0;
// Purge all unused models.
virtual void PurgeModels( void ) = 0;
// Sets up a trace model for collision with other trace models.
virtual idCollisionModel * ModelFromTrm( const char *mapName, const char *modelName, const idTraceModel &trm, const idMaterial *material ) = 0;
// Creates a trace model from a collision model, returns true if succesfull.
virtual bool TrmFromModel( const char *mapName, const char *modelName, idTraceModel &trm ) = 0;
// Creates a trace model for each primitive of the collision model, returns the number of trace models.
virtual int CompoundTrmFromModel( const char *mapName, const char *modelName, idTraceModel *trms, int maxTrms ) = 0;
// Translates a trace model and reports the first collision if any.
virtual void Translation( trace_t *results, const idVec3 &start, const idVec3 &end,
const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
// Rotates a trace model and reports the first collision if any.
virtual void Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation,
const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
// Returns the contents touched by the trace model or 0 if the trace model is in free space.
virtual int Contents( const idVec3 &start,
const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
// Stores all contact points of the trace model with the model, returns the number of contacts.
virtual int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
const idTraceModel *trm, const idMat3 &trmAxis, int contentMask,
idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0;
// Tests collision detection.
virtual void DebugOutput( const idVec3 &viewOrigin, const idMat3 &viewAxis ) = 0;
// Draws a model.
virtual void DrawModel( idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis,
const idVec3 &viewOrigin, const idMat3 &viewAxis, const float radius ) = 0;
// Lists all loaded models.
virtual void ListModels( void ) = 0;
// Prints model information, use -1 for accumulated model info.
virtual void ModelInfo( int num ) = 0;
virtual void PrintMemInfo( MemInfo *mi ) = 0;
virtual bool IsLoaded( void ) = 0;
// Writes a collision model file for the given map entity.
virtual bool WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ) = 0;
};
extern idCollisionModelManager *collisionModelManager;
#endif /* !__COLLISIONMODELMANAGER_H__ */

View file

@ -0,0 +1,74 @@
/*
===============================================================================
Preprocessor settings for compiling different versions.
===============================================================================
*/
// useful for network debugging, turns off 'LAN' checks, all IPs are classified 'internet'
#ifndef ID_NOLANADDRESS
#define ID_NOLANADDRESS 0
#endif
// let .dds be loaded from FS without altering pure state. only for developement.
#ifndef ID_PURE_ALLOWDDS
#define ID_PURE_ALLOWDDS 0
#endif
// build an exe with no CVAR_CHEAT controls
#ifndef ID_ALLOW_CHEATS
#define ID_ALLOW_CHEATS 0
#endif
#ifndef ID_ENABLE_CURL
#if !defined( _XENON )
#define ID_ENABLE_CURL 1
#else
#define ID_ENABLE_CURL 0
#endif
#endif
// fake a pure client. useful to connect an all-debug client to a server
#ifndef ID_FAKE_PURE
#define ID_FAKE_PURE 0
#endif
// don't do backtraces in release builds.
// atm, we have no useful way to reconstruct the trace, so let's leave it off
#define ID_BT_STUB
#ifndef ID_BT_STUB
#if defined( __linux__ )
#if defined( _DEBUG )
#define ID_BT_STUB
#endif
#else
#define ID_BT_STUB
#endif
#endif
#ifndef ID_ENFORCE_KEY
# if !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD )
# define ID_ENFORCE_KEY 1
# else
// twhitaker: just leave it undefined
// TTimo: that breaks the ability to control it from command line settings with !win32 builds, but I can live with it
//# define ID_ENFORCE_KEY 0
# endif
#endif
// verify checksums in clientinfo traffic
// NOTE: this makes the network protocol incompatible
#ifndef ID_CLIENTINFO_TAGS
#define ID_CLIENTINFO_TAGS 0
#endif
// if this is defined, the executable positively won't work with any paks other
// than the demo pak, even if productid is present.
//#define ID_DEMO_BUILD
#if !defined( _WIN32 )
// DOA? didn't see the pbuffer code used at all through the code
#define TMP_PBUFFSTUB
#endif

View file

@ -0,0 +1,3 @@
// that one is no longer updated with the Q4 source in SVN
// but is used in some of the single player mishmush so I don't want to touch it
const int BUILD_NUMBER = 1283;

View file

@ -0,0 +1,415 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __CVARSYSTEM_H__
#define __CVARSYSTEM_H__
/*
===============================================================================
Console Variables (CVars) are used to hold scalar or string variables
that can be changed or displayed at the console as well as accessed
directly in code.
CVars are mostly used to hold settings that can be changed from the
console or saved to and loaded from configuration files. CVars are also
occasionally used to communicate information between different modules
of the program.
CVars are restricted from having the same names as console commands to
keep the console interface from being ambiguous.
CVars can be accessed from the console in three ways:
cvarName prints the current value
cvarName X sets the value to X if the variable exists
set cvarName X as above, but creates the CVar if not present
CVars may be declared in the global namespace, in classes and in functions.
However declarations in classes and functions should always be static to
save space and time. Making CVars static does not change their
functionality due to their global nature.
CVars should be contructed only through one of the constructors with name,
value, flags and description. The name, value and description parameters
to the constructor have to be static strings, do not use va() or the like
functions returning a string.
CVars may be declared multiple times using the same name string. However,
they will all reference the same value and changing the value of one CVar
changes the value of all CVars with the same name.
CVars should always be declared with the correct type flag: CVAR_BOOL,
CVAR_INTEGER or CVAR_FLOAT. If no such flag is specified the CVar
defaults to type string. If the CVAR_BOOL flag is used there is no need
to specify an argument auto-completion function because the CVar gets
one assigned automatically.
CVars are automatically range checked based on their type and any min/max
or valid string set specified in the constructor.
CVars are always considered cheats except when CVAR_NOCHEAT, CVAR_INIT,
CVAR_ROM, CVAR_ARCHIVE, CVAR_USERINFO, CVAR_SERVERINFO, CVAR_NETWORKSYNC
is set.
===============================================================================
*/
typedef enum {
CVAR_ALL = -1, // all flags
CVAR_BOOL = BIT(0), // variable is a boolean
CVAR_INTEGER = BIT(1), // variable is an integer
CVAR_FLOAT = BIT(2), // variable is a float
CVAR_SYSTEM = BIT(3), // system variable
CVAR_RENDERER = BIT(4), // renderer variable
CVAR_SOUND = BIT(5), // sound variable
CVAR_GUI = BIT(6), // gui variable
CVAR_GAME = BIT(7), // game variable
CVAR_TOOL = BIT(8), // tool variable
CVAR_USERINFO = BIT(9), // sent to servers, available to menu
CVAR_SERVERINFO = BIT(10), // sent from servers, available to menu
CVAR_NETWORKSYNC = BIT(11), // cvar is synced from the server to clients
CVAR_STATIC = BIT(12), // statically declared, not user created
CVAR_CHEAT = BIT(13), // variable is considered a cheat
CVAR_NOCHEAT = BIT(14), // variable is not considered a cheat
CVAR_INIT = BIT(15), // can only be set from the command-line
CVAR_ROM = BIT(16), // display only, cannot be set by user at all
CVAR_ARCHIVE = BIT(17), // set to cause it to be saved to a config file
CVAR_MODIFIED = BIT(18), // set when the variable is modified
CVAR_INFO = BIT(19), // sent as part of the MOTD packet
CVAR_NORESET = BIT(20), // don't reset the contents on cvar system restart
CVAR_CASE_SENSITIVE = BIT(21), // a change in case of the string contents sets the modified flag
CVAR_SPECIAL_CONCAT = BIT(22), // special concatination of the incoming string to the cvar system, will remove space between ^ and the code that is produced by tokenzier
CVAR_STRIPTRAILING = BIT(23), // always strip trailing / on that cvar
CVAR_REPEATERINFO = BIT(24), // sent from repeaters, available to menu
} cvarFlags_t;
/*
===============================================================================
idCVar
===============================================================================
*/
class idCVar {
public:
// Never use the default constructor.
idCVar( void ) { assert( typeid( this ) != typeid( idCVar ) ); }
// Always use one of the following constructors.
idCVar( const char *name, const char *value, int flags, const char *description,
argCompletion_t valueCompletion = NULL );
idCVar( const char *name, const char *value, int flags, const char *description,
float valueMin, float valueMax, argCompletion_t valueCompletion = NULL );
idCVar( const char *name, const char *value, int flags, const char *description,
const char **valueStrings, argCompletion_t valueCompletion = NULL );
virtual ~idCVar( void ) {}
const char * GetName( void ) const { return internalVar->name; }
int GetFlags( void ) const { return internalVar->flags; }
const char * GetDescription( void ) const { return internalVar->description; }
float GetMinValue( void ) const { return internalVar->valueMin; }
float GetMaxValue( void ) const { return internalVar->valueMax; }
const char ** GetValueStrings( void ) const { return valueStrings; }
argCompletion_t GetValueCompletion( void ) const { return valueCompletion; }
bool IsModified( void ) const { return ( internalVar->flags & CVAR_MODIFIED ) != 0; }
void SetModified( void ) { internalVar->flags |= CVAR_MODIFIED; }
void ClearModified( void ) { internalVar->flags &= ~CVAR_MODIFIED; }
const char * GetString( void ) const { return internalVar->value; }
bool GetBool( void ) const { return ( internalVar->integerValue != 0 ); }
int GetInteger( void ) const { return internalVar->integerValue; }
float GetFloat( void ) const { return internalVar->floatValue; }
void SetString( const char *value ) { internalVar->InternalSetString( value ); }
void SetBool( const bool value ) { internalVar->InternalSetBool( value ); }
void SetInteger( const int value ) { internalVar->InternalSetInteger( value ); }
void SetFloat( const float value ) { internalVar->InternalSetFloat( value ); }
void SetInternalVar( idCVar *cvar ) { internalVar = cvar; }
void SetFlag( const cvarFlags_t flag ) { internalVar->flags |= flag; }
void RemoveFlag( const cvarFlags_t flag ) { internalVar->flags &= ~flag; }
static void RegisterStaticVars( void );
protected:
const char * name; // name
const char * value; // value
const char * description; // description
int flags; // CVAR_? flags
float valueMin; // minimum value
float valueMax; // maximum value
const char ** valueStrings; // valid value strings
argCompletion_t valueCompletion; // value auto-completion function
int integerValue; // atoi( string )
float floatValue; // atof( value )
idCVar * internalVar; // internal cvar
idCVar * next; // next statically declared cvar
private:
void Init( const char *name, const char *value, int flags, const char *description,
float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion );
virtual void InternalSetString( const char *newValue ) {}
virtual void InternalSetBool( const bool newValue ) {}
virtual void InternalSetInteger( const int newValue ) {}
virtual void InternalSetFloat( const float newValue ) {}
static idCVar * staticVars;
};
ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description,
argCompletion_t valueCompletion ) {
if ( !valueCompletion && ( flags & CVAR_BOOL ) ) {
valueCompletion = idCmdSystem::ArgCompletion_Boolean;
}
Init( name, value, flags, description, 1, -1, NULL, valueCompletion );
}
ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description,
float valueMin, float valueMax, argCompletion_t valueCompletion ) {
Init( name, value, flags, description, valueMin, valueMax, NULL, valueCompletion );
}
ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description,
const char **valueStrings, argCompletion_t valueCompletion ) {
Init( name, value, flags, description, 1, -1, valueStrings, valueCompletion );
}
// RAVEN BEGIN
// rjohnson: new help system for cvar ui
/*
===============================================================================
idCVarHelp
===============================================================================
*/
typedef enum {
CVARHELP_ALL = -1, // all categories
CVARHELP_GAME = BIT(0), // game menu
CVARHELP_RENDERER = BIT(1), // renderer menu
CVARHELP_PHYSICS = BIT(2), // physics menu
CVARHELP_SOUND = BIT(3), // sound menu
CVARHELP_AI = BIT(4), // AI menu
} cvarHelpCategory_t;
class idCVarHelp {
public:
// Never use the default constructor.
idCVarHelp( void ) { assert( typeid(this) != typeid(idCVarHelp) ); }
// Always use one of the following constructors.
idCVarHelp( const char *cvarName, const char *friendlyName, const char *choices, const char *values, cvarHelpCategory_t category );
idCVarHelp( const idCVarHelp &copy );
const char * GetCVarName( void ) const { return cvarName; }
const char * GetFriendlyName( void ) const { return friendlyName; }
const char * GetChoices( void ) const { return choices; }
const char * GetValues( void ) const { return values; }
const cvarHelpCategory_t GetCategory( void ) const { return category; }
const idCVarHelp * GetNext( void ) const { return next; }
void SetNext( const idCVarHelp *value ) { next = value; }
static void RegisterStatics( void );
private:
const char * cvarName; // the cvar this help belongs to
const char * friendlyName; // a textual name for the cvar impaired
const char * choices; // a textual list of choices for the cvar impaired
const char * values; // the list of values that goes with the choices
cvarHelpCategory_t category; // the category(s) this cvar should appear under
const idCVarHelp * next; // next statically declared cvar helper
static idCVarHelp * staticCVarHelps;
static idCVarHelp * staticCVarHelpsTail;
};
ID_INLINE idCVarHelp::idCVarHelp( const idCVarHelp &copy ) {
cvarName = copy.cvarName;
friendlyName = copy.friendlyName;
choices = copy.choices;
values = copy.values;
category = copy.category;
next = NULL;
}
// RAVEN END
/*
===============================================================================
idCVarSystem
===============================================================================
*/
class idCVarSystem {
public:
virtual ~idCVarSystem( void ) {}
virtual void Init( void ) = 0;
virtual void Shutdown( void ) = 0;
virtual bool IsInitialized( void ) const = 0;
// Registers a CVar.
virtual void Register( idCVar *cvar ) = 0;
// RAVEN BEGIN
// rjohnson: new help system for cvar ui
// Registers a CVarHelp.
virtual void Register( const idCVarHelp *cvarHelp ) = 0;
virtual idCVarHelp * GetHelps( cvarHelpCategory_t category ) = 0;
// RAVEN END
// Finds the CVar with the given name.
// Returns NULL if there is no CVar with the given name.
virtual idCVar * Find( const char *name ) = 0;
// Sets the value of a CVar by name.
virtual void SetCVarString( const char *name, const char *value, int flags = 0 ) = 0;
virtual void SetCVarBool( const char *name, const bool value, int flags = 0 ) = 0;
virtual void SetCVarInteger( const char *name, const int value, int flags = 0 ) = 0;
virtual void SetCVarFloat( const char *name, const float value, int flags = 0 ) = 0;
// Gets the value of a CVar by name.
virtual const char * GetCVarString( const char *name ) const = 0;
virtual bool GetCVarBool( const char *name ) const = 0;
virtual int GetCVarInteger( const char *name ) const = 0;
virtual float GetCVarFloat( const char *name ) const = 0;
// Called by the command system when argv(0) doesn't match a known command.
// Returns true if argv(0) is a variable reference and prints or changes the CVar.
virtual bool Command( const idCmdArgs &args ) = 0;
// Command and argument completion using callback for each valid string.
virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0;
virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0;
// Sets/gets/clears modified flags that tell what kind of CVars have changed.
virtual void SetModifiedFlags( int flags ) = 0;
virtual int GetModifiedFlags( void ) const = 0;
virtual void ClearModifiedFlags( int flags ) = 0;
// Resets variables with one of the given flags set.
virtual void ResetFlaggedVariables( int flags ) = 0;
// Removes auto-completion from the flagged variables.
virtual void RemoveFlaggedAutoCompletion( int flags ) = 0;
// Writes variables with one of the given flags set to the given file.
virtual void WriteFlaggedVariables( int flags, const char *setCmd, idFile *f ) const = 0;
// RAVEN BEGIN
// nrausch: memory cvar support
virtual unsigned int WriteFlaggedVariables( int flags, const char *setCmd, byte *buf, unsigned int bufSize ) const = 0;
virtual void ApplyFlaggedVariables( byte *buf, unsigned int bufSize ) = 0;
virtual idStr WriteFlaggedVariables( int flags ) const = 0;
// RAVEN END
// Moves CVars to and from dictionaries.
virtual const idDict * MoveCVarsToDict( int flags ) const = 0;
virtual void SetCVarsFromDict( const idDict &dict ) = 0;
};
extern idCVarSystem * cvarSystem;
/*
===============================================================================
CVar Registration
Each DLL using CVars has to declare a private copy of the static variable
idCVar::staticVars like this: idCVar * idCVar::staticVars = NULL;
Furthermore idCVar::RegisterStaticVars() has to be called after the
cvarSystem pointer is set when the DLL is first initialized.
===============================================================================
*/
ID_INLINE void idCVar::Init( const char *name, const char *value, int flags, const char *description,
float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion ) {
this->name = name;
this->value = value;
this->flags = flags;
this->description = description;
this->flags = flags | CVAR_STATIC;
this->valueMin = valueMin;
this->valueMax = valueMax;
this->valueStrings = valueStrings;
this->valueCompletion = valueCompletion;
this->integerValue = 0;
this->floatValue = 0.0f;
this->internalVar = this;
if ( staticVars != (idCVar *)0xFFFFFFFF ) {
this->next = staticVars;
staticVars = this;
} else {
cvarSystem->Register( this );
}
}
ID_INLINE void idCVar::RegisterStaticVars( void ) {
// RAVEN BEGIN
// jnewquist: Tag scope and callees to track allocations using "new".
MEM_SCOPED_TAG(tag,MA_CVAR);
// RAVEN END
if ( staticVars != (idCVar *)0xFFFFFFFF ) {
for ( idCVar *cvar = staticVars; cvar; cvar = cvar->next ) {
cvarSystem->Register( cvar );
}
staticVars = (idCVar *)0xFFFFFFFF;
}
}
// RAVEN BEGIN
// rjohnson: new help system for cvar ui
ID_INLINE idCVarHelp::idCVarHelp( const char *cvarName, const char *friendlyName, const char *choices, const char *values, cvarHelpCategory_t category ) {
// RAVEN BEGIN
// jnewquist: Tag scope and callees to track allocations using "new".
MEM_SCOPED_TAG(tag,MA_CVAR);
// RAVEN END
this->cvarName = cvarName;
this->friendlyName = friendlyName;
this->choices = choices;
this->values = values;
this->category = category;
this->next = NULL;
if ( staticCVarHelps != (idCVarHelp *)0xFFFFFFFF ) {
if ( !staticCVarHelpsTail ) {
staticCVarHelps = this;
} else {
staticCVarHelpsTail->next = this;
}
staticCVarHelpsTail = this;
staticCVarHelpsTail->next = NULL;
} else {
cvarSystem->Register( this );
}
}
ID_INLINE void idCVarHelp::RegisterStatics( void ) {
// RAVEN BEGIN
// jnewquist: Tag scope and callees to track allocations using "new".
MEM_SCOPED_TAG(tag,MA_CVAR);
// RAVEN END
if ( staticCVarHelps != (idCVarHelp *)0xFFFFFFFF ) {
for ( const idCVarHelp *cvarHelp = staticCVarHelps; cvarHelp; cvarHelp = cvarHelp->next ) {
cvarSystem->Register( cvarHelp );
}
staticCVarHelps = (idCVarHelp *)0xFFFFFFFF;
}
}
// RAVEN END
#endif /* !__CVARSYSTEM_H__ */

View file

@ -0,0 +1,216 @@
#ifndef __CMDSYSTEM_H__
#define __CMDSYSTEM_H__
/*
===============================================================================
Console command execution and command text buffering.
Any number of commands can be added in a frame from several different
sources. Most commands come from either key bindings or console line input,
but entire text files can be execed.
Command execution takes a null terminated string, breaks it into tokens,
then searches for a command or variable that matches the first token.
===============================================================================
*/
// command flags
typedef enum {
CMD_FL_ALL = -1,
CMD_FL_CHEAT = BIT(0), // command is considered a cheat
CMD_FL_SYSTEM = BIT(1), // system command
CMD_FL_RENDERER = BIT(2), // renderer command
CMD_FL_SOUND = BIT(3), // sound command
CMD_FL_GAME = BIT(4), // game command
CMD_FL_TOOL = BIT(5) // tool command
} cmdFlags_t;
// parameters for command buffer stuffing
typedef enum {
CMD_EXEC_NOW, // don't return until completed
CMD_EXEC_INSERT, // insert at current position, but don't run yet
CMD_EXEC_APPEND // add to end of the command buffer (normal case)
} cmdExecution_t;
// command function
typedef void (*cmdFunction_t)( const idCmdArgs &args );
// argument completion function
typedef void (*argCompletion_t)( const idCmdArgs &args, void(*callback)( const char *s ) );
class idCmdSystem {
public:
virtual ~idCmdSystem( void ) {}
virtual void Init( void ) = 0;
virtual void Shutdown( void ) = 0;
// Registers a command and the function to call for it.
virtual void AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion = NULL ) = 0;
// Removes a command.
virtual void RemoveCommand( const char *cmdName ) = 0;
// Remove all commands with one of the flags set.
virtual void RemoveFlaggedCommands( int flags ) = 0;
// Command and argument completion using callback for each valid string.
virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0;
virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0;
// Adds command text to the command buffer, does not add a final \n
virtual void BufferCommandText( cmdExecution_t exec, const char *text ) = 0;
// Pulls off \n \r or ; terminated lines of text from the command buffer and
// executes the commands. Stops when the buffer is empty.
// Normally called once per frame, but may be explicitly invoked.
virtual void ExecuteCommandBuffer( void ) = 0;
// Base for path/file auto-completion.
virtual void ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) = 0;
virtual void ArgCompletion_Models( const idCmdArgs &args, void(*callback)( const char *s ), bool strogg, bool marine ) = 0;
// Base for decl name auto-completion.
virtual void ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ) = 0;
// Adds to the command buffer in tokenized form ( CMD_EXEC_NOW or CMD_EXEC_APPEND only )
virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ) = 0;
// Restore these cvars when the next reloadEngine is done
virtual void SetupCVarsForReloadEngine( const idDict &dict ) = 0;
// Setup a reloadEngine to happen on next command run, and give a command to execute after reload
virtual void SetupReloadEngine( const idCmdArgs &args ) = 0;
virtual bool PostReloadEngine( void ) = 0;
// There is a cache of the last completion operation that may need to be cleared sometimes
virtual void ClearCompletion( void ) = 0;
// Default argument completion functions.
static void ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) );
template<int min,int max>
static void ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) );
template<const char **strings>
static void ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) );
template<int type>
static void ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) );
// RAVEN BEGIN
// mekberg: added
static void ArgCompletion_GuiName( const idCmdArgs &args, void(*callback)( const char *s ) );
// RAVEN END
static void ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_ForceModel( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_ForceModelStrogg( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_ForceModelMarine( const idCmdArgs &args, void(*callback)( const char *s ) );
// RAVEN BEGIN
// nrausch: standalone video support
static void ArgCompletion_StandaloneVideoName( const idCmdArgs &args, void(*callback)( const char *s ) );
// rjohnson: netdemo completion
static void ArgCompletion_NetDemoName( const idCmdArgs &args, void(*callback)( const char *s ) );
// RAVEN END
static void ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) );
static void ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) );
};
extern idCmdSystem * cmdSystem;
ID_INLINE void idCmdSystem::ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) ) {
callback( va( "%s 0", args.Argv( 0 ) ) );
callback( va( "%s 1", args.Argv( 0 ) ) );
}
template<int min,int max> ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) ) {
for ( int i = min; i <= max; i++ ) {
callback( va( "%s %d", args.Argv( 0 ), i ) );
}
}
template<const char **strings> ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) ) {
for ( int i = 0; strings[i]; i++ ) {
callback( va( "%s %s", args.Argv( 0 ), strings[i] ) );
}
}
template<int type> ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_DeclName( args, callback, type );
}
ID_INLINE void idCmdSystem::ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, "", NULL );
}
// RAVEN BEGIN
// mekberg: added
ID_INLINE void idCmdSystem::ArgCompletion_GuiName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "guis/", false, ".gui", NULL );
}
// RAVEN END
ID_INLINE void idCmdSystem::ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "maps/", true, ".map", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "sound/", false, ".wav", ".ogg", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", false, ".tga", ".dds", ".jpg", ".pcx", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "video/", false, ".roq", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_ForceModel( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_Models( args, callback, true, true );
}
ID_INLINE void idCmdSystem::ArgCompletion_ForceModelStrogg( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_Models( args, callback, true, false );
}
ID_INLINE void idCmdSystem::ArgCompletion_ForceModelMarine( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_Models( args, callback, false, true );
}
// RAVEN BEGIN
// nrausch: standalone video support
ID_INLINE void idCmdSystem::ArgCompletion_StandaloneVideoName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "video/", false, ".wmv", NULL );
}
// rjohnson: netdemo completion
extern char netDemoExtension[16];
ID_INLINE void idCmdSystem::ArgCompletion_NetDemoName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "demos/", true, netDemoExtension, NULL );
}
// RAVEN END
ID_INLINE void idCmdSystem::ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, ".cfg", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "SaveGames/", true, ".save", NULL );
}
ID_INLINE void idCmdSystem::ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
cmdSystem->ArgCompletion_FolderExtension( args, callback, "demos/", true, ".demo", NULL );
}
#endif /* !__CMDSYSTEM_H__ */

351
source/framework/Common.h Normal file
View file

@ -0,0 +1,351 @@
#ifndef __COMMON_H__
#define __COMMON_H__
/*
==============================================================
Common
==============================================================
*/
// RAVEN BEGIN
// mekberg: added more save types
typedef enum {
ST_REGULAR,
ST_QUICK,
ST_AUTO,
ST_CHECKPOINT,
} saveType_t;
// RAVEN END
typedef enum {
EDITOR_NONE = 0,
EDITOR_RADIANT = BIT(1),
EDITOR_GUI = BIT(2),
EDITOR_DEBUGGER = BIT(3),
EDITOR_SCRIPT = BIT(4),
EDITOR_LIGHT = BIT(5),
EDITOR_SOUND = BIT(6),
EDITOR_DECL = BIT(7),
EDITOR_AF = BIT(8),
EDITOR_PDA = BIT(9),
EDITOR_FX = BIT(10),
EDITOR_REVERB = BIT(11),
EDITOR_PLAYBACKS = BIT(12),
EDITOR_MODVIEW = BIT(13),
EDITOR_LOGVIEW = BIT(14),
EDITOR_ENTVIEW = BIT(15),
EDITOR_MATERIAL = BIT(16),
// Just flags to prevent caching of unneeded assets
EDITOR_AAS = BIT(17),
EDITOR_RENDERBUMP = BIT(18),
EDITOR_SPAWN_GUI = BIT(19),
// Specifies that a decl validation run is happening
EDITOR_DECL_VALIDATING = BIT(20),
EDITOR_ALL = -1
};
// RAVEN END
#define MAX_OUTPUT_HISTORY 16
#define STRTABLE_ID "#str_"
#define STRTABLE_ID_LENGTH 5
extern idCVar com_version;
extern idCVar com_skipRenderer;
extern idCVar com_asyncSound;
extern idCVar com_machineSpec;
extern idCVar com_purgeAll;
extern idCVar com_developer;
extern idCVar com_allowConsole;
extern idCVar com_speeds;
extern idCVar com_showFPS;
extern idCVar com_showMemoryUsage;
extern idCVar com_showAsyncStats;
extern idCVar com_showSoundDecoders;
extern idCVar com_makingBuild;
extern idCVar com_skipUltraQuality;
extern idCVar com_updateLoadSize;
extern idCVar com_videoRam;
// RAVEN BEGIN
// ksergent: added bundler
extern idCVar com_Bundler;
#ifndef _XENON
// nrausch: generate rdf's for xenon load screens
extern idCVar com_MakeLoadScreens;
#endif
// rjohnson: added quick load
extern idCVar com_QuickLoad;
// rjohnson: added limits stuff
extern idCVar com_Limits;
// jsinger: added build for binary lexer
extern idCVar com_BinaryWrite;
extern idCVar com_BinaryRead;
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
extern idCVar com_BinaryDeclRead;
#endif
// jsinger: added to support loading of all decls from a single file
#ifdef RV_SINGLE_DECL_FILE
extern idCVar com_SingleDeclFile;
extern idCVar com_WriteSingleDeclFIle;
#endif
// jshepard: warning suppresion
extern idCVar com_uniqueWarnings;
// amccarthy: show Mem_Alloc tag statistics
extern idCVar com_showMemAllocTags;
#if defined(_XENON)
// mwhitlock: changes for Xenon to enable us to use texture resources from .xpr bundles.
extern idCVar com_showXenTexCacheStats;
extern idCVar com_showXenHardwareTimers;
// ksergent: show thread usage.
extern idCVar com_showXenThreadUsage;
#endif // _XENON
extern idCVar sys_lang;
// RAVEN END
extern int time_gameFrame; // game logic time
extern int time_gameDraw; // game present time
extern int time_frontend; // renderer frontend time
extern int time_backend; // renderer backend time
// RAVEN BEGIN
extern int time_waiting; // game logic time
// RAVEN END
extern int com_frameTime; // time for the current frame in milliseconds
extern volatile int com_ticNumber; // 60 hz tics, incremented by async function
// RAVEN BEGIN
// bdube: added timing dict
extern bool com_debugHudActive; // The debug hud is active in the game
// RAVEN END
#ifdef _WINDOWS
const char DMAP_MSGID[] = "DMAPOutput";
const char DMAP_DONE[] = "DMAPDone";
#endif
// RAVEN BEGIN
// bdube: forward declarations
class idInterpreter;
class idProgram;
// converted to a class so the idStr gets constructed
class MemInfo {
public:
MemInfo( void );
idStr filebase;
int total;
int assetTotals;
// asset totals
int imageAssetsTotal;
int modelAssetsTotal;
int soundAssetsTotal;
// RAVEN BEGIN
int collAssetsTotal;
int animsAssetsTotal;
int aasAssetsTotal;
int imageAssetsCount;
int modelAssetsCount;
int soundAssetsCount;
int collAssetsCount;
int animsAssetsCount;
int aasAssetsCount;
};
// RAVEN END
class idCommon {
public:
virtual ~idCommon( void ) {}
// Initialize everything.
// if the OS allows, pass argc/argv directly (without executable name)
// otherwise pass the command line in a single string (without executable name)
virtual void Init( int argc, const char **argv, const char *cmdline ) = 0;
// Shuts down everything.
virtual void Shutdown( void ) = 0;
// Shuts down everything.
virtual void Quit( void ) = 0;
// Returns true if common initialization is complete.
virtual bool IsInitialized( void ) const = 0;
// Called repeatedly as the foreground thread for rendering and game logic.
virtual void Frame( void ) = 0;
// Called repeatedly by blocking function calls with GUI interactivity.
virtual void GUIFrame( bool execCmd, bool network ) = 0;
// Called 60 times a second from a background thread for sound mixing,
// and input generation. Not called until idCommon::Init() has completed.
virtual void Async( void ) = 0;
// Checks for and removes command line "+set var arg" constructs.
// If match is NULL, all set commands will be executed, otherwise
// only a set with the exact name. Only used during startup.
// set once to clear the cvar from +set for early init code
virtual void StartupVariable( const char *match, bool once ) = 0;
// RAVEN BEGIN
virtual int GetUserCmdHz( void ) const = 0;
virtual int GetUserCmdMSec( void ) const = 0;
// Returns com_frameTime - which is 0 if a command is added to the command line
virtual int GetFrameTime( void ) const = 0;
// returns if the game is processing the last frame when it processes multiple frames
virtual bool IsRenderableGameFrame( void ) const = 0;
virtual void SetRenderableGameFrame( bool in ) = 0;
// returns the last message from common->Error
virtual const char *GetErrorMessage( void ) const = 0;
// Initializes a tool with the given dictionary.
virtual void InitTool( const int tool, const idDict *dict ) = 0;
// Returns true if an editor has focus
virtual bool IsToolActive( void ) const = 0;
// Returns an interface to source control
virtual class rvISourceControl *GetSourceControl( void ) = 0;
// RAVEN END
// RAVEN BEGIN
// dluetscher: added the following method to initialize each of the memory heaps
#ifdef _RV_MEM_SYS_SUPPORT
virtual void InitHeaps( void ) = 0; // initializes each of the memory heaps for use
virtual void ShutdownHeaps( void ) = 0; // shuts down each of the memory heaps from further use
#endif
// RAVEN END
// Activates or deactivates a tool.
virtual void ActivateTool( bool active ) = 0;
// Writes the user's configuration to a file
virtual void WriteConfigToFile( const char *filename ) = 0;
// Writes cvars with the given flags to a file.
virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) = 0;
// RAVEN BEGIN
// bdube: new exports
// Modview thinks in the middle of a game frame
virtual void ModViewThink ( void ) = 0;
// rjohnson: added option for guis to always think
virtual void RunAlwaysThinkGUIs ( int time ) = 0;
// Debbugger hook to check if a breakpoint has been hit
virtual void DebuggerCheckBreakpoint ( idInterpreter* interpreter, idProgram* program, int instructionPointer ) = 0;
// scork: need to test if validating to catch some model errors that would stop the validation and convert to warnings...
virtual bool DoingDeclValidation( void ) = 0;
// scork: guess
virtual void SetCrashReportAutoSendString( const char *psString ) = 0;
virtual void LoadToolsDLL( void ) = 0;
virtual void UnloadToolsDLL( void ) = 0;
// RAVEN END
// Begins redirection of console output to the given buffer.
virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ), bool rcon = false ) = 0;
// Stops redirection of console output.
virtual void EndRedirect( void ) = 0;
// Update the screen with every message printed.
virtual void SetRefreshOnPrint( bool set ) = 0;
// Prints message to the console, which may cause a screen update if com_refreshOnPrint is set.
virtual void Printf( const char *fmt, ... )id_attribute((format(printf,2,3))) = 0;
// Same as Printf, with a more usable API - Printf pipes to this.
virtual void VPrintf( const char *fmt, va_list arg ) = 0;
// Prints message that only shows up if the "developer" cvar is set,
// and NEVER forces a screen update, which could cause reentrancy problems.
virtual void DPrintf( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// Prints WARNING %s message and adds the warning message to a queue for printing later on.
virtual void Warning( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// Prints WARNING %s message in yellow that only shows up if the "developer" cvar is set.
virtual void DWarning( const char *fmt, ...) id_attribute((format(printf,2,3))) = 0;
// Prints all queued warnings.
virtual void PrintWarnings( void ) = 0;
// Removes all queued warnings.
virtual void ClearWarnings( const char *reason ) = 0;
// Issues a C++ throw. Normal errors just abort to the game loop,
// which is appropriate for media or dynamic logic errors.
virtual void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// Fatal errors quit all the way to a system dialog box, which is appropriate for
// static internal errors or cases where the system may be corrupted.
virtual void FatalError( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// RAVEN BEGIN
// Brings up notepad with the warnings generated while running the game
virtual void DumpWarnings( void ) = 0;
// Returns the localised string of the token, of the token if it does not begin with #str_
virtual const char * GetLocalizedString( const char *token, int langIndex = -1 ) = 0;
// Returns the localised string at position 'index'
virtual const idLangKeyValue * GetLocalizedString( int index, int langIndex = -1 ) = 0;
// Returns the number of languages the game found
virtual int GetNumLanguages( void ) const = 0;
// Returns the number of strings in the English langdict
virtual int GetNumLocalizedStrings( void ) const = 0;
// Returns the name of the language
virtual const char * GetLanguage( int index ) const = 0;
// Returns whether the language has VO
virtual bool LanguageHasVO( int index ) const = 0;
// Returns key bound to the command
virtual const char * KeysFromBinding( const char *bind ) = 0;
// Returns the binding bound to the key
virtual const char * BindingFromKey( const char *key ) = 0;
// Directly sample a button.
virtual int ButtonState( int key ) = 0;
// Directly sample a keystate.
virtual int KeyState( int key ) = 0;
// mekberg: added
virtual int GetRModeForMachineSpec( int machineSpec ) const = 0;
virtual void SetDesiredMachineSpec( int machineSpec ) = 0;
// RAVEN END
// returns true if we are currently executing an rcon operation
virtual bool IsRCon( void ) const = 0;
};
extern idCommon * common;
#endif /* !__COMMON_H__ */

142
source/framework/DeclPDA.h Normal file
View file

@ -0,0 +1,142 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLPDA_H__
#define __DECLPDA_H__
/*
===============================================================================
idDeclPDA
===============================================================================
*/
class idDeclEmail : public idDecl {
public:
idDeclEmail() {}
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void ) const;
virtual void List( void ) const;
const char * GetFrom() const { return from; }
const char * GetBody() const { return text; }
const char * GetSubject() const { return subject; }
const char * GetDate() const { return date; }
const char * GetTo() const { return to; }
const char * GetImage() const { return image; }
private:
idStr text;
idStr subject;
idStr date;
idStr to;
idStr from;
idStr image;
};
class idDeclVideo : public idDecl {
public:
idDeclVideo() {};
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void ) const;
virtual void List( void ) const;
const char * GetRoq() const { return video; }
const char * GetWave() const { return audio; }
const char * GetVideoName() const { return videoName; }
const char * GetInfo() const { return info; }
const char * GetPreview() const { return preview; }
private:
idStr preview;
idStr video;
idStr videoName;
idStr info;
idStr audio;
};
class idDeclAudio : public idDecl {
public:
idDeclAudio() {};
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void ) const;
virtual void List( void ) const;
const char * GetAudioName() const { return audioName; }
const char * GetWave() const { return audio; }
const char * GetInfo() const { return info; }
const char * GetPreview() const { return preview; }
private:
idStr audio;
idStr audioName;
idStr info;
idStr preview;
};
class idDeclPDA : public idDecl {
public:
idDeclPDA() { originalEmails = originalVideos = 0; };
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void ) const;
virtual void List( void ) const;
virtual void AddVideo( const char *name, bool unique = true ) const;
virtual void AddAudio( const char *name, bool unique = true ) const;
virtual void AddEmail( const char *name, bool unique = true ) const;
virtual void RemoveAddedEmailsAndVideos() const;
virtual const int GetNumVideos() const;
virtual const int GetNumAudios() const;
virtual const int GetNumEmails() const;
virtual const idDeclVideo *GetVideoByIndex( int index ) const;
virtual const idDeclAudio *GetAudioByIndex( int index ) const;
virtual const idDeclEmail *GetEmailByIndex( int index ) const;
virtual void SetSecurity( const char *sec ) const;
const char * GetPdaName() const { return pdaName; }
const char * GetSecurity() const {return security; }
const char * GetFullName() const { return fullName; }
const char * GetIcon() const { return icon; }
const char * GetPost() const { return post; }
const char * GetID() const { return id; }
const char * GetTitle() const { return title; }
private:
mutable idStrList videos;
mutable idStrList audios;
mutable idStrList emails;
idStr pdaName;
idStr fullName;
idStr icon;
idStr id;
idStr post;
idStr title;
mutable idStr security;
mutable int originalEmails;
mutable int originalVideos;
};
#endif /* !__DECLPDA_H__ */

View file

@ -0,0 +1,41 @@
//----------------------------------------------------------------
// DeclPlayerModel.h
//
// Copyright 2002-2006 Raven Software
//----------------------------------------------------------------
#ifndef __DECLPLAYERMODEL_H__
#define __DECLPLAYERMODEL_H__
/*
===============================================================================
rvDeclPlayerModel
===============================================================================
*/
class rvDeclPlayerModel : public idDecl {
public:
rvDeclPlayerModel();
idStr model;
idStr head;
idVec3 headOffset;
idStr uiHead;
idStr team;
idStr skin;
idStr description;
idDict sounds;
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition() const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void );
virtual bool RebuildTextSource( void ) { return( false ); }
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
};
#endif

366
source/framework/File.h Normal file
View file

@ -0,0 +1,366 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __FILE_H__
#define __FILE_H__
/*
==============================================================
File Streams.
==============================================================
*/
// mode parm for Seek
typedef enum {
FS_SEEK_CUR,
FS_SEEK_END,
FS_SEEK_SET
} fsOrigin_t;
class idFileSystemLocal;
// RAVEN BEGIN
// jscott: made idFile a pure virtual interface
class idFile {
public:
virtual ~idFile( void ) {}
// Get the name of the file.
virtual const char * GetName( void ) = 0;
// Get the full file path.
virtual const char * GetFullPath( void ) = 0;
// Read data from the file to the buffer.
virtual int Read( void *buffer, int len ) = 0;
// Write data from the buffer to the file.
virtual int Write( const void *buffer, int len ) = 0;
// Returns the length of the file.
virtual int Length( void ) = 0;
// Return a time value for reload operations.
virtual unsigned int Timestamp( void ) = 0;
// Returns offset in file.
virtual int Tell( void ) = 0;
// Forces flush on files being writting to.
virtual void ForceFlush( void ) = 0;
// Causes any buffered data to be written to the file.
virtual void Flush( void ) = 0;
// Seek on a file.
virtual int Seek( long offset, fsOrigin_t origin ) = 0;
// Go back to the beginning of the file.
virtual void Rewind( void ) = 0;
// Like fprintf.
virtual int Printf( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// Like fprintf but with argument pointer
virtual int VPrintf( const char *fmt, va_list arg ) = 0;
// Write a string with high precision floating point numbers to the file.
virtual int WriteFloatString( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
// Endian portable alternatives to Read(...)
virtual int ReadInt( int &value ) = 0;
virtual int ReadUnsignedInt( unsigned int &value ) = 0;
virtual int ReadShort( short &value ) = 0;
virtual int ReadUnsignedShort( unsigned short &value ) = 0;
virtual int ReadChar( char &value ) = 0;
virtual int ReadUnsignedChar( unsigned char &value ) = 0;
virtual int ReadFloat( float &value ) = 0;
virtual int ReadBool( bool &value ) = 0;
virtual int ReadString( idStr &string ) = 0;
virtual int ReadVec2( idVec2 &vec ) = 0;
virtual int ReadVec3( idVec3 &vec ) = 0;
virtual int ReadVec4( idVec4 &vec ) = 0;
virtual int ReadVec5( idVec5 &vec ) = 0;
virtual int ReadVec6( idVec6 &vec ) = 0;
virtual int ReadMat3( idMat3 &mat ) = 0;
virtual int ReadBounds( idBounds &bounds ) = 0;
// Endian portable alternatives to Write(...)
virtual int WriteInt( const int value ) = 0;
virtual int WriteUnsignedInt( const unsigned int value ) = 0;
virtual int WriteShort( const short value ) = 0;
virtual int WriteUnsignedShort( unsigned short value ) = 0;
virtual int WriteChar( const char value ) = 0;
virtual int WriteUnsignedChar( const unsigned char value ) = 0;
virtual int WriteFloat( const float value ) = 0;
virtual int WriteBool( const bool value ) = 0;
virtual int WriteString( const char *string ) = 0;
virtual int WriteVec2( const idVec2 &vec ) = 0;
virtual int WriteVec3( const idVec3 &vec ) = 0;
virtual int WriteVec4( const idVec4 &vec ) = 0;
virtual int WriteVec5( const idVec5 &vec ) = 0;
virtual int WriteVec6( const idVec6 &vec ) = 0;
virtual int WriteMat3( const idMat3 &mat ) = 0;
virtual int WriteBounds( const idBounds &bounds ) = 0;
// dluetscher: added method to write a structure array that is made up of numerics (floats, ints) from the given storage
virtual void WriteNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage, const char *prepend ) = 0;
// jscott: for savegame and demo file syncing
virtual void WriteSyncId( void ) = 0;
virtual void ReadSyncId( const char *detail = "unspecified", const char *classname = NULL ) = 0;
};
class idFile_Common : public idFile
{
public:
virtual ~idFile_Common( void ) {}
// Get the name of the file.
virtual const char * GetName( void ) { return( "" ); }
// Get the full file path.
virtual const char * GetFullPath( void ) { return( "" ); }
// Read data from the file to the buffer.
virtual int Read( void *buffer, int len );
// Write data from the buffer to the file.
virtual int Write( const void *buffer, int len );
// Returns the length of the file.
virtual int Length( void ) { return( 0 ); }
// Return a time value for reload operations.
virtual unsigned int Timestamp( void ) { return( 0 ); }
// Returns offset in file.
virtual int Tell( void ) { return( 0 ); }
// Forces flush on files being writting to.
virtual void ForceFlush( void ) {}
// Causes any buffered data to be written to the file.
virtual void Flush( void ) {}
// Seek on a file.
virtual int Seek( long offset, fsOrigin_t origin ) { return( -1 ); }
// Go back to the beginning of the file.
virtual void Rewind( void );
// Like fprintf.
virtual int Printf( const char *fmt, ... ) id_attribute((format(printf,2,3)));
// Like fprintf but with argument pointer
virtual int VPrintf( const char *fmt, va_list arg );
// Write a string with high precision floating point numbers to the file.
virtual int WriteFloatString( const char *fmt, ... ) id_attribute((format(printf,2,3)));
// Endian portable alternatives to Read(...)
virtual int ReadInt( int &value );
virtual int ReadUnsignedInt( unsigned int &value );
virtual int ReadShort( short &value );
virtual int ReadUnsignedShort( unsigned short &value );
virtual int ReadChar( char &value );
virtual int ReadUnsignedChar( unsigned char &value );
virtual int ReadFloat( float &value );
virtual int ReadBool( bool &value );
virtual int ReadString( idStr &string );
virtual int ReadVec2( idVec2 &vec );
virtual int ReadVec3( idVec3 &vec );
virtual int ReadVec4( idVec4 &vec );
virtual int ReadVec5( idVec5 &vec );
virtual int ReadVec6( idVec6 &vec );
virtual int ReadMat3( idMat3 &mat );
virtual int ReadBounds( idBounds &bounds );
// Endian portable alternatives to Write(...)
virtual int WriteInt( const int value );
virtual int WriteUnsignedInt( const unsigned int value );
virtual int WriteShort( const short value );
virtual int WriteUnsignedShort( unsigned short value );
virtual int WriteChar( const char value );
virtual int WriteUnsignedChar( const unsigned char value );
virtual int WriteFloat( const float value );
virtual int WriteBool( const bool value );
virtual int WriteString( const char *string );
virtual int WriteVec2( const idVec2 &vec );
virtual int WriteVec3( const idVec3 &vec );
virtual int WriteVec4( const idVec4 &vec );
virtual int WriteVec5( const idVec5 &vec );
virtual int WriteVec6( const idVec6 &vec );
virtual int WriteMat3( const idMat3 &mat );
virtual int WriteBounds( const idBounds &bounds );
// dluetscher: added method to write a structure array that is made up of numerics (floats, ints) from the given storage
virtual void WriteNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage, const char *prepend );
// jscott: for savegame and demo file syncing
virtual void WriteSyncId( void );
virtual void ReadSyncId( const char *detail = "unspecific", const char *classname = NULL );
};
class idFile_Memory : public idFile_Common {
// RAVEN END
friend class idFileSystemLocal;
public:
idFile_Memory( void ); // file for writing without name
idFile_Memory( const char *name ); // file for writing
idFile_Memory( const char *name, char *data, int length ); // file for writing
idFile_Memory( const char *name, const char *data, int length ); // file for reading
virtual ~idFile_Memory( void );
virtual const char * GetName( void ) { return name.c_str(); }
virtual const char * GetFullPath( void ) { return name.c_str(); }
virtual int Read( void *buffer, int len );
virtual int Write( const void *buffer, int len );
virtual int Length( void );
virtual unsigned int Timestamp( void );
virtual int Tell( void );
virtual void ForceFlush( void );
virtual void Flush( void );
virtual int Seek( long offset, fsOrigin_t origin );
virtual void Rewind( void );
// changes memory file to read only
virtual void MakeReadOnly( void );
// clear the file
virtual void Clear( bool freeMemory = true );
// set data for reading
void SetData( const char *data, int length );
// returns const pointer to the memory buffer
const char * GetDataPtr( void ) const { return filePtr; }
// set the file granularity
void SetGranularity( int g ) { assert( g > 0 ); granularity = g; }
private:
idStr name; // name of the file
int mode; // open mode
int maxSize; // maximum size of file
int fileSize; // size of the file
int allocated; // allocated size
int granularity; // file granularity
char * filePtr; // buffer holding the file data
char * curPtr; // current read/write pointer
};
// RAVEN BEGIN
class idFile_BitMsg : public idFile_Common {
// RAVEN END
friend class idFileSystemLocal;
public:
idFile_BitMsg( idBitMsg &msg );
idFile_BitMsg( const idBitMsg &msg );
virtual ~idFile_BitMsg( void );
virtual const char * GetName( void ) { return name.c_str(); }
virtual const char * GetFullPath( void ) { return name.c_str(); }
virtual int Read( void *buffer, int len );
virtual int Write( const void *buffer, int len );
virtual int Length( void );
virtual unsigned int Timestamp( void );
virtual int Tell( void );
virtual void ForceFlush( void );
virtual void Flush( void );
virtual int Seek( long offset, fsOrigin_t origin );
private:
idStr name; // name of the file
int mode; // open mode
idBitMsg * msg;
};
// RAVEN BEGIN
class idFile_Permanent : public idFile_Common {
// RAVEN END
friend class idFileSystemLocal;
public:
idFile_Permanent( void );
virtual ~idFile_Permanent( void );
virtual const char * GetName( void ) { return name.c_str(); }
virtual const char * GetFullPath( void ) { return fullPath.c_str(); }
virtual int Read( void *buffer, int len );
virtual int Write( const void *buffer, int len );
virtual int Length( void );
virtual unsigned int Timestamp( void );
virtual int Tell( void );
virtual void ForceFlush( void );
virtual void Flush( void );
virtual int Seek( long offset, fsOrigin_t origin );
// returns file pointer
FILE * GetFilePtr( void ) { return o; }
private:
idStr name; // relative path of the file - relative path
idStr fullPath; // full file path - OS path
int mode; // open mode
int fileSize; // size of the file
FILE * o; // file handle
bool handleSync; // true if written data is immediately flushed
};
class idFile_ASCII : public idFile_Permanent
{
int inside;
public:
idFile_ASCII( void );
virtual int Read( void *buffer, int len );
// Write data from the buffer to the file.
virtual int Write( const void *buffer, int len );
// Endian portable alternatives to Read(...)
virtual int ReadInt( int &value );
virtual int ReadUnsignedInt( unsigned int &value );
virtual int ReadShort( short &value );
virtual int ReadUnsignedShort( unsigned short &value );
virtual int ReadChar( char &value );
virtual int ReadUnsignedChar( unsigned char &value );
virtual int ReadFloat( float &value );
virtual int ReadBool( bool &value );
virtual int ReadString( idStr &string );
virtual int ReadVec2( idVec2 &vec );
virtual int ReadVec3( idVec3 &vec );
virtual int ReadVec4( idVec4 &vec );
virtual int ReadVec5( idVec5 &vec );
virtual int ReadVec6( idVec6 &vec );
virtual int ReadMat3( idMat3 &mat );
// Endian portable alternatives to Write(...)
virtual int WriteInt( const int value );
virtual int WriteUnsignedInt( const unsigned int value );
virtual int WriteShort( const short value );
virtual int WriteUnsignedShort( unsigned short value );
virtual int WriteChar( const char value );
virtual int WriteUnsignedChar( const unsigned char value );
virtual int WriteFloat( const float value );
virtual int WriteBool( const bool value );
virtual int WriteString( const char *string );
virtual int WriteVec2( const idVec2 &vec );
virtual int WriteVec3( const idVec3 &vec );
virtual int WriteVec4( const idVec4 &vec );
virtual int WriteVec5( const idVec5 &vec );
virtual int WriteVec6( const idVec6 &vec );
virtual int WriteMat3( const idMat3 &mat );
// dluetscher: added method to write a structure array that is made up of numerics (floats, ints) from the given storage
virtual void WriteNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage, const char *prepend );
// jscott: for savegame and demo file syncing
virtual void WriteSyncId( void );
virtual void ReadSyncId( const char *detail = "unspecific", const char *classname = NULL );
};
// RAVEN BEGIN
class idFile_InZip : public idFile_Common {
// RAVEN END
friend class idFileSystemLocal;
public:
idFile_InZip( void );
virtual ~idFile_InZip( void );
virtual const char * GetName( void ) { return name.c_str(); }
virtual const char * GetFullPath( void ) { return fullPath.c_str(); }
virtual int Read( void *buffer, int len );
virtual int Write( const void *buffer, int len );
virtual int Length( void );
virtual unsigned int Timestamp( void );
virtual int Tell( void );
virtual void ForceFlush( void );
virtual void Flush( void );
virtual int Seek( long offset, fsOrigin_t origin );
private:
idStr name; // name of the file in the pak
idStr fullPath; // full file path including pak file name
int zipFilePos; // zip file info position in pak
int fileSize; // size of the file
void * z; // unzip info
};
#endif /* !__FILE_H__ */

View file

@ -0,0 +1,418 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __FILESYSTEM_H__
#define __FILESYSTEM_H__
/*
===============================================================================
File System
No stdio calls should be used by any part of the game, because of all sorts
of directory and separator char issues. Throughout the game a forward slash
should be used as a separator. The file system takes care of the conversion
to an OS specific separator. The file system treats all file and directory
names as case insensitive.
The following cvars store paths used by the file system:
"fs_basepath" path to local install, read-only
"fs_savepath" path to config, save game, etc. files, read & write
"fs_cdpath" path to cd, read-only
"fs_devpath" path to files created during development, read & write
The base path for file saving can be set to "fs_savepath" or "fs_devpath".
===============================================================================
*/
static const unsigned FILE_NOT_FOUND_TIMESTAMP = 0xFFFFFFFF;
static const int MAX_PURE_PAKS = 128;
// master server can keep server updated with a list of allowed paks per OS
static const int MAX_GAMEPAK_PER_OS = 10;
static const int MAX_OSPATH = 256;
// modes for OpenFileByMode. used as bit mask internally
typedef enum {
FS_READ = 0,
FS_WRITE = 1,
FS_APPEND = 2
} fsMode_t;
typedef enum {
PURE_OK, // we are good to connect as-is
PURE_RESTART, // restart required
PURE_MISSING, // pak files missing on the client
PURE_NODLL, // no DLL could be extracted
// PURE_DIFFERENT, // differing checksums
} fsPureReply_t;
typedef enum {
DLTYPE_URL,
DLTYPE_FILE
} dlType_t;
typedef enum {
DL_WAIT, // waiting in the list for beginning of the download
DL_INPROGRESS, // in progress
DL_DONE, // download completed, success
DL_ABORTING, // this one can be set during a download, it will force the next progress callback to abort - then will go to DL_FAILED
DL_FAILED
} dlStatus_t;
typedef enum {
FILE_EXEC,
FILE_OPEN
} dlMime_t;
typedef enum {
FIND_NO,
FIND_YES,
FIND_ADDON
} findFile_t;
typedef struct urlDownload_s {
idStr url;
idStr urlAuth;
idStr referer;
char dlerror[ MAX_STRING_CHARS ];
int dltotal;
int dlnow;
int dlstatus;
dlStatus_t status;
} urlDownload_t;
typedef struct fileDownload_s {
int position;
int length;
void * buffer;
} fileDownload_t;
typedef struct proxyDownload_s {
idStr proxyUrl;
idStr proxyAuth;
} proxyDownload_t;
// RAVEN BEGIN
// mwhitlock: changes for Xenon to enable us to use texture resources from .xpr
// bundles.
#if defined(_XENON)
#include "Xtl.h"
#endif
// RAVEN END
// RAVEN BEGIN
// mwhitlock: changes for Xenon to enable us to use texture resources from .xpr
// bundles.
#if defined(_XENON)
// Define this to enable background streaming via Xenon's native file I/O
// routines (unbuffered reads).
#define _XENON_USE_NATIVE_FILEIO
typedef struct backgroundDownload_s
{
static const int MAX_SEGMENTS = 2;
struct backgroundDownload_s *next; // Set by the fileSystem.
dlType_t opcode;
idFile * f;
int numSegments;
fileDownload_t file[MAX_SEGMENTS];
urlDownload_t url;
volatile bool completed;
double ticksToLoad; // Used for performance profiling.
public:
void Clear(void)
{
numSegments=0;
completed=false;
f=0;
}
void AddSegment(int position, int length, void* buffer)
{
assert(position>0);
assert(length>0);
assert(buffer!=0);
assert(numSegments<MAX_SEGMENTS);
if(numSegments<MAX_SEGMENTS)
{
file[numSegments].position=position;
file[numSegments].length=length;
file[numSegments].buffer=buffer;
numSegments++;
}
#if defined(_DEBUG)
// Sanity: segements should not overlap.
for(int s=0;s<numSegments-1;s++)
{
assert(file[s].position+file[s].length-1 < file[s+1].position);
}
#endif
}
int DownloadSize(void) const
{
int size=0;
for(int s=0;s<numSegments;s++)
{
size+=file[s].length;
}
return size;
}
} backgroundDownload_t;
#else
typedef struct backgroundDownload_s {
struct backgroundDownload_s *next; // set by the fileSystem
dlType_t opcode;
idFile * f;
fileDownload_t file;
int numSegments;
urlDownload_t url;
proxyDownload_t proxy;
volatile bool completed;
} backgroundDownload_t;
#endif
// RAVEN END
// file list for directory listings
class idFileList {
friend class idFileSystemLocal;
public:
const char * GetBasePath( void ) const { return basePath; }
int GetNumFiles( void ) const { return list.Num(); }
const char * GetFile( int index ) const { return list[index]; }
const idStrList & GetList( void ) const { return list; }
private:
idStr basePath;
idStrList list;
};
// mod list
class idModList {
friend class idFileSystemLocal;
public:
int GetNumMods( void ) const { return mods.Num(); }
const char * GetMod( int index ) const { return mods[index]; }
const char * GetDescription( int index ) const { return descriptions[index]; }
private:
idStrList mods;
idStrList descriptions;
};
class idFileSystem {
public:
virtual ~idFileSystem() {}
// Initializes the file system.
virtual void Init( void ) = 0;
// Restarts the file system.
virtual void Restart( void ) = 0;
// Shutdown the file system.
virtual void Shutdown( bool reloading ) = 0;
// Returns true if the file system is initialized.
virtual bool IsInitialized( void ) const = 0;
// Returns true if we are doing an fs_copyfiles.
virtual bool PerformingCopyFiles( void ) const = 0;
// Returns a list of mods found along with descriptions
// 'mods' contains the directory names to be passed to fs_game
// 'descriptions' contains a free form string to be used in the UI
virtual idModList * ListMods( void ) = 0;
// Frees the given mod list
virtual void FreeModList( idModList *modList ) = 0;
// Lists files with the given extension in the given directory.
// Directory should not have either a leading or trailing '/'
// The returned files will not include any directories or '/' unless fullRelativePath is set.
// The extension must include a leading dot and may not contain wildcards.
// If extension is "/", only subdirectories will be returned.
virtual idFileList * ListFiles( const char *relativePath, const char *extension, bool sort = false, bool fullRelativePath = false, const char* gamedir = NULL ) = 0;
// Lists files in the given directory and all subdirectories with the given extension.
// Directory should not have either a leading or trailing '/'
// The returned files include a full relative path.
// The extension must include a leading dot and may not contain wildcards.
virtual idFileList * ListFilesTree( const char *relativePath, const char *extension, bool sort = false, const char* gamedir = NULL ) = 0;
// Frees the given file list.
virtual void FreeFileList( idFileList *fileList ) = 0;
// Converts a relative path to a full OS path.
virtual const char * OSPathToRelativePath( const char *OSPath ) = 0;
// Converts a full OS path to a relative path.
virtual const char * RelativePathToOSPath( const char *relativePath, const char *basePath = "fs_devpath" ) = 0;
// Builds a full OS path from the given components.
virtual const char * BuildOSPath( const char *base, const char *game, const char *relativePath ) = 0;
// Creates the given OS path for as far as it doesn't exist already.
virtual void CreateOSPath( const char *OSPath ) = 0;
// Returns true if a file is in a pak file.
virtual bool FileIsInPAK( const char *relativePath ) = 0;
// Returns a space separated string containing the checksums of all referenced pak files.
// will call SetPureServerChecksums internally to restrict itself
virtual void UpdatePureServerChecksums( void ) = 0;
// setup the mapping of OS -> game pak checksum
virtual bool UpdateGamePakChecksums( void ) = 0;
// 0-terminated list of pak checksums
// if pureChecksums[ 0 ] == 0, all data sources will be allowed
// otherwise, only pak files that match one of the checksums will be checked for files
// with the sole exception of .cfg files.
// the function tries to configure pure mode from the paks already referenced and this new list
// it returns wether the switch was successfull, and sets the missing checksums
// use fs_debug 1 to verbose
virtual fsPureReply_t SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum[ MAX_GAMEPAK_PER_OS ], int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum, int *restartGamePakChecksu ) = 0;
// fills a 0-terminated list of pak checksums for a client
// if OS is -1, give the current game pak checksum. if >= 0, lookup the game pak table (server only)
// indexes > 0 may be provided on servers when the master is giving additional game paks to let in
virtual void GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int gamePakChecksum[ MAX_GAMEPAK_PER_OS ] ) = 0;
// before doing a restart, force the pure list and the search order
// if the given checksum list can't be completely processed and set, will error out
virtual void SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ) = 0;
// equivalent to calling SetPureServerChecksums with an empty list
virtual void ClearPureChecksums( void ) = 0;
// get a mask of supported OSes. if not pure, returns -1
virtual unsigned int GetOSMask( void ) = 0;
// Reads a complete file.
// Returns the length of the file, or -1 on failure.
// A null buffer will just return the file length without loading.
// A null timestamp will be ignored.
// As a quick check for existance. -1 length == not present.
// A 0 byte will always be appended at the end, so string ops are safe.
// The buffer should be considered read-only, because it may be cached for other uses.
virtual int ReadFile( const char *relativePath, void **buffer, unsigned *timestamp = NULL ) = 0;
// Frees the memory allocated by ReadFile.
virtual void FreeFile( void *buffer ) = 0;
// Writes a complete file, will create any needed subdirectories.
// Returns the length of the file, or -1 on failure.
virtual int WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath = "fs_savepath" ) = 0;
// Removes the given file.
// RAVEN BEGIN
// rjohnson: can specify the path cvar
virtual void RemoveFile( const char *relativePath, const char *basePath = "fs_savepath" ) = 0;
// bdube: added method
// Removes the given file and returns the filesystem status of the removal
virtual int RemoveExplicitFile ( const char *OSPath ) = 0;
// mekberg: is file loading allowed?
virtual void SetIsFileLoadingAllowed(bool mode) = 0;
// dluetscher: returns file loading status
virtual bool GetIsFileLoadingAllowed() const = 0;
// amccarthy: set the current asset log name.
virtual void SetAssetLogName(const char *logName) = 0;
// amccarthy: write out a list of all files loaded.
virtual void WriteAssetLog() = 0;
// jnewquist: clear list of all files loaded.
virtual void ClearAssetLog() = 0;
// jnewquist: Accessor for asset log name (with filter)
virtual const char* GetAssetLogName() = 0;
// jscott: new functions for tools
virtual idFile * GetNewFileMemory( void ) = 0;
virtual idFile * GetNewFilePermanent( void ) = 0;
// RAVEN END
// Opens a file for reading.
virtual idFile * OpenFileRead( const char *relativePath, bool allowCopyFiles = true, const char* gamedir = NULL ) = 0;
// Opens a file for writing, will create any needed subdirectories.
virtual idFile * OpenFileWrite( const char *relativePath, const char *basePath = "fs_savepath", bool ASCII = false ) = 0;
// Opens a file for writing at the end.
virtual idFile * OpenFileAppend( const char *filename, bool sync = false, const char *basePath = "fs_basepath" ) = 0;
// Opens a file for reading, writing, or appending depending on the value of mode.
virtual idFile * OpenFileByMode( const char *relativePath, fsMode_t mode ) = 0;
// Opens a file for reading from a full OS path.
virtual idFile * OpenExplicitFileRead( const char *OSPath ) = 0;
// Opens a file for writing to a full OS path.
virtual idFile * OpenExplicitFileWrite( const char *OSPath ) = 0;
// Closes a file.
virtual void CloseFile( idFile *f ) = 0;
// Returns immediately, performing the read from a background thread.
virtual void BackgroundDownload( backgroundDownload_t *bgl ) = 0;
// resets the bytes read counter
virtual void ResetReadCount( void ) = 0;
// retrieves the current read count
virtual int GetReadCount( void ) = 0;
// adds to the read count
virtual void AddToReadCount( int c ) = 0;
// look for a dynamic module
virtual void FindDLL( const char *basename, char dllPath[ MAX_OSPATH ], bool updateChecksum ) = 0;
// case sensitive filesystems use an internal directory cache
// the cache is cleared when calling OpenFileWrite and RemoveFile
// in some cases you may need to use this directly
virtual void ClearDirCache( void ) = 0;
// lookup a relative path, return the size or 0 if not found
virtual int RelativeDownloadPathForChecksum( int checksum, char path[ MAX_STRING_CHARS ] ) = 0;
// verify the file can be downloaded, lookup a relative path, return the size or 0 if not found
virtual int ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isGamePak ) = 0;
// verify the file can be downloaded, lookup an absolute (OS) path, return the size or 0 if not found
virtual int ValidateDownloadPakForRelativePath( const char *relativePath, char path[ MAX_STRING_CHARS ], bool &isGamePakReturn ) = 0;
virtual idFile * MakeTemporaryFile( void ) = 0;
// make downloaded pak files known so pure negociation works next time
virtual int AddZipFile( const char *path ) = 0;
// RAVEN BEGIN
// nrausch: explicit pak add/removal
#ifdef _XENON
virtual bool AddDownloadedPak( const char *path ) = 0;
virtual void RemoveDownloadedPak( const char *path ) = 0;
virtual bool AddExplicitPak( const char *path ) = 0;
virtual void RemoveExplicitPak( const char *path ) = 0;
virtual bool IsPakLoaded( const char *path ) = 0;
#endif
// RAVEN END
// look for a file in the loaded paks or the addon paks
// if the file is found in addons, FS's internal structures are ready for a reloadEngine
virtual findFile_t FindFile( const char *path ) = 0;
// get map/addon decls and take into account addon paks that are not on the search list
// the decl 'name' is in the "path" entry of the dict
virtual int GetNumMaps() = 0;
virtual int GetMapDeclIndex( const char *mapName ) = 0;
virtual const idDict * GetMapDecl( int i ) = 0;
virtual const idDict * GetMapDecl( const char *mapName ) = 0;
virtual void FindMapScreenshot( const char *path, char *buf, int len ) = 0;
// RAVEN BEGIN
// rjohnson: added new functions
// Converts a full OS path to an import path.
virtual bool OSpathToImportPath( const char *osPath, idStr &iPath, bool stripTemp = false ) = 0;
// Opens a file for reading from the fs_importpath directory
virtual idFile * OpenImportFileRead( const char *filename ) = 0;
// Copy a file
virtual void CopyOSFile( const char *fromOSPath, const char *toOSPath ) = 0;
virtual void CopyOSFile( idFile *src, const char *toOSPath ) = 0;
// RAVEN END
// demo functions - only for use by the core ( and not DLL boundary / memory safe anyway )
// ReadDemoHeader: returns -1 if a reloadEngine is requested before trying again, 0 if we failed with no backup, and 1 if we can continue
// if demo_enforceFS is 0, will always ret 1
virtual void WriteDemoHeader( idFile *file ) = 0;
virtual int ReadDemoHeader( idFile *file ) = 0;
// new in 1.3
// indicates if the filesystem is currently running with pak files restrictions or addons
virtual bool IsRunningWithRestrictions( void ) = 0;
// new in 1.4
virtual void ReadCodePakLists( const idBitMsg &msg ) = 0;
virtual bool HaveCodePakLists( void ) const = 0;
// pick best language - used by the core to pick a good default language based on present zpaks
virtual void SelectDefaultLanguage( void ) = 0;
virtual void ClearAddonList( void ) = 0;
};
extern idFileSystem * fileSystem;
#endif /* !__FILESYSTEM_H__ */

View file

@ -0,0 +1,233 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __USERCMDGEN_H__
#define __USERCMDGEN_H__
/*
===============================================================================
Samples a set of user commands from player input.
===============================================================================
*/
const int USERCMD_HZ_SP = 60; // 60 frames per second
const int USERCMD_MSEC_SP = 1000 / USERCMD_HZ_SP;
//const int USERCMD_HZ_MP = 30; // 30 frames per second
//const int USERCMD_MSEC_MP = 1000 / USERCMD_HZ_MP;
//const int USERCMD_HZ_MP = 60; // 60 frames per second
//const int USERCMD_MSEC_MP = 1000 / USERCMD_HZ_MP;
// usercmd_t->button bits
const int BUTTON_ATTACK = BIT(0);
const int BUTTON_RUN = BIT(1);
const int BUTTON_ZOOM = BIT(2);
const int BUTTON_SCORES = BIT(3);
const int BUTTON_MLOOK = BIT(4);
// RAVEN BEGIN
// ddynerman: stats
const int BUTTON_INGAMESTATS = BIT(5);
// jscott: for voicechat
const int BUTTON_VOICECHAT = BIT(6);
// ddynerman: tourney display
const int BUTTON_TOURNEY = BIT(7);
// twhitaker: strafe
const int BUTTON_STRAFE = BIT(8);
// RAVEN END
// usercmd_t->impulse commands
const int IMPULSE_0 = 0; // weap 0
const int IMPULSE_1 = 1; // weap 1
const int IMPULSE_2 = 2; // weap 2
const int IMPULSE_3 = 3; // weap 3
const int IMPULSE_4 = 4; // weap 4
const int IMPULSE_5 = 5; // weap 5
const int IMPULSE_6 = 6; // weap 6
const int IMPULSE_7 = 7; // weap 7
const int IMPULSE_8 = 8; // weap 8
const int IMPULSE_9 = 9; // weap 9
const int IMPULSE_10 = 10; // weap 10
const int IMPULSE_11 = 11; // weap 11
const int IMPULSE_12 = 12; // weap 12
const int IMPULSE_13 = 13; // weap reload
const int IMPULSE_14 = 14; // weap next
const int IMPULSE_15 = 15; // weap prev
const int IMPULSE_16 = 16; // <unused>
const int IMPULSE_17 = 17; // ready to play ( toggles ui_ready )
const int IMPULSE_18 = 18; // center view
const int IMPULSE_19 = 19; // show PDA/INV/MAP
const int IMPULSE_20 = 20; // toggle team ( toggles ui_team )
const int IMPULSE_21 = 21; // tourney toggle waiting room/spec
const int IMPULSE_22 = 22; // spectate
const int IMPULSE_23 = 23; // <unused>
const int IMPULSE_24 = 24; // <unused>
const int IMPULSE_25 = 25; // <unused>
const int IMPULSE_26 = 26; // <unused>
const int IMPULSE_27 = 27; // <unused>
const int IMPULSE_28 = 28; // vote yes
const int IMPULSE_29 = 29; // vote no
const int IMPULSE_40 = 40; // repeast last radio chatter
// RAVEN BEGIN
// bdube: added flashlight
const int IMPULSE_50 = 50; // activate flashlight
const int IMPULSE_51 = 51; // switch to last weapon
// ddynerman: mp stats
const int IMPULSE_52 = 52; // mp statistics
// RAVEN END
// RAVEN BEGIN
// asalmon: impulses for weapons combos for xbox
#ifdef _XBOX
const int IMPULSE_70 = 70; //Weapon switch up
const int IMPULSE_71 = 71; //Weapon switch down
const int IMPULSE_72 = 72; //Weapon switch right
const int IMPULSE_73 = 73; //Weapon Switch left
#endif
//RAVEN END
// RITUAL BEGIN
// squirrel: Mode-agnostic buymenus
const int IMPULSE_100 = 100; // Buy weapon_shotgun
const int IMPULSE_101 = 101; // Buy weapon_machinegun
const int IMPULSE_102 = 102; // Buy weapon_hyperblaster
const int IMPULSE_103 = 103; // Buy weapon_grenadelauncher
const int IMPULSE_104 = 104; // Buy weapon_nailgun
const int IMPULSE_105 = 105; // Buy weapon_rocketlauncher
const int IMPULSE_106 = 106; // Buy weapon_railgun
const int IMPULSE_107 = 107; // Buy weapon_lightninggun
const int IMPULSE_108 = 108; // UNUSED
const int IMPULSE_109 = 109; // Buy weapon_napalmgun
const int IMPULSE_110 = 110; // Buy weapon_dmg
const int IMPULSE_111 = 111; // UNUSED
const int IMPULSE_112 = 112; // UNUSED
const int IMPULSE_113 = 113; // UNUSED
const int IMPULSE_114 = 114; // UNUSED
const int IMPULSE_115 = 115; // UNUSED
const int IMPULSE_116 = 116; // UNUSED
const int IMPULSE_117 = 117; // UNUSED
const int IMPULSE_118 = 118; // Buy item_armor_small
const int IMPULSE_119 = 119; // Buy item_armor_large
const int IMPULSE_120 = 120; // Buy ammorefill
const int IMPULSE_121 = 121; // UNUSED
const int IMPULSE_122 = 122; // UNUSED
const int IMPULSE_123 = 123; // Buy team powerup: ammo_regen
const int IMPULSE_124 = 124; // Buy team powerup: health_regen
const int IMPULSE_125 = 125; // Buy team powerup: damage_boost
const int IMPULSE_126 = 126; // UNUSED
const int IMPULSE_127 = 127; // UNUSED
// RITUAL END
const int KEY_MOVESPEED = 127;
// usercmd_t->flags
const int UCF_IMPULSE_SEQUENCE = 0x0001; // toggled every time an impulse command is sent
class usercmd_t {
public:
int gameFrame; // frame number
int gameTime; // game time
int realTime; // real game time
int duplicateCount; // duplication count for networking
// RAVEN BEGIN
// ddynerman: expand buttons to 2 bytes
short buttons; // buttons
// RAVEN END
signed char forwardmove; // forward/backward movement
signed char rightmove; // left/right movement
signed char upmove; // up/down movement
short angles[3]; // view angles
short mx; // mouse delta x
short my; // mouse delta y
signed char impulse; // impulse command
byte flags; // additional flags
int sequence; // just for debugging
public:
void ByteSwap(); // on big endian systems, byte swap the shorts and ints
bool operator==( const usercmd_t &rhs ) const;
};
typedef enum {
INHIBIT_SESSION = 0,
INHIBIT_ASYNC
} inhibit_t;
const int MAX_BUFFERED_USERCMD = 64;
class idUsercmdGen {
public:
virtual ~idUsercmdGen( void ) {}
// Sets up all the cvars and console commands.
virtual void Init( void ) = 0;
// Prepares for a new map.
virtual void InitForNewMap( void ) = 0;
// Shut down.
virtual void Shutdown( void ) = 0;
// Clears all key states and face straight.
virtual void Clear( void ) = 0;
// Clears view angles.
virtual void ClearAngles( void ) = 0;
// When the console is down or the menu is up, only emit default usercmd, so the player isn't moving around.
// Each subsystem (session and game) may want an inhibit will OR the requests.
virtual void InhibitUsercmd( inhibit_t subsystem, bool inhibit ) = 0;
// Returns a buffered command for the given game tic.
virtual usercmd_t TicCmd( int ticNumber ) = 0;
// Called async at regular intervals.
virtual void UsercmdInterrupt( void ) = 0;
// Set a value that can safely be referenced by UsercmdInterrupt() for each key binding.
virtual int CommandStringUsercmdData( const char *cmdString ) = 0;
// Returns the number of user commands.
virtual int GetNumUserCommands( void ) = 0;
// Returns the name of a user command via index.
virtual const char *GetUserCommandName( int index ) = 0;
// Continuously modified, never reset. For full screen guis.
virtual void MouseState( int *x, int *y, int *button, bool *down ) = 0;
// Directly sample a button.
virtual int ButtonState( int key ) = 0;
// Directly sample a keystate.
virtual int KeyState( int key ) = 0;
// Directly sample a usercmd.
virtual usercmd_t GetUsercmd( void ) = 0;
//RAVEN BEGIN
//asalmon: slow down the joystick movement for aim assist on xenon
virtual void SetSlowJoystick(int slow) = 0;
// nrausch: Stuff an arbitrary impulse in, which will override any other impulse this cycle
virtual void StuffImpulse( int impulse ) = 0;
virtual void StuffKey( const char *keyName, bool down ) = 0;
#ifdef _XENON
virtual void GetInputs( int &y, int &p, int &r, int &f ) = 0;
#endif
//RAVEN END
};
extern idUsercmdGen *usercmdGen;
#endif /* !__USERCMDGEN_H__ */

View file

@ -0,0 +1,133 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __NETWORKSYSTEM_H__
#define __NETWORKSYSTEM_H__
/*
===============================================================================
Network System.
===============================================================================
*/
typedef struct {
idStr nickname;
idStr clan;
short ping;
int rate;
} scannedClient_t;
typedef struct {
netadr_t adr;
idDict serverInfo;
int ping;
int clients;
int OSMask;
//RAVEN BEGIN
// shouchard: added favorite flag
bool favorite; // true if this has been marked by a user as a favorite
bool dedicated;
// shouchard: added performance filtered flag
bool performanceFiltered; // true if the client machine is too wimpy to have good performance
//RAVEN END
} scannedServer_t;
typedef enum {
SC_NONE = -1,
SC_FAVORITE,
SC_LOCKED,
SC_DEDICATED,
SC_PB,
SC_NAME,
SC_PING,
SC_REPEATER,
SC_PLAYERS,
SC_GAMETYPE,
SC_MAP,
SC_ALL,
NUM_SC
} sortColumn_t;
typedef struct {
sortColumn_t column;
idList<int>::cmp_t* compareFn;
idList<int>::filter_t* filterFn;
const char* description;
} sortInfo_t;
class idNetworkSystem {
public:
virtual ~idNetworkSystem( void ) {}
virtual void Shutdown( void );
virtual void ServerSendReliableMessage( int clientNum, const idBitMsg &msg, bool inhibitRepeater = false );
virtual void RepeaterSendReliableMessage( int clientNum, const idBitMsg &msg, bool inhibitHeader = false, int including = -1 );
virtual void RepeaterSendReliableMessageExcluding( int excluding, const idBitMsg &msg, bool inhibitHeader = false, int clientNum = -1 ); // NOTE: Message is sent to all viewers if clientNum is -1; excluding is used for playback.
virtual void ServerSendReliableMessageExcluding( int clientNum, const idBitMsg &msg, bool inhibitRepeater = false );
virtual int ServerGetClientPing( int clientNum );
virtual int ServerGetClientTimeSinceLastPacket( int clientNum );
virtual int ServerGetClientTimeSinceLastInput( int clientNum );
virtual int ServerGetClientOutgoingRate( int clientNum );
virtual int ServerGetClientIncomingRate( int clientNum );
virtual float ServerGetClientIncomingPacketLoss( int clientNum );
virtual int ServerGetClientNum( int clientId );
virtual int ServerGetServerTime( void );
// returns the new clientNum or -1 if there weren't any free.
virtual int ServerConnectBot( void );
virtual int RepeaterGetClientNum( int clientId );
virtual void ClientSendReliableMessage( const idBitMsg &msg );
virtual int ClientGetPrediction( void );
virtual int ClientGetTimeSinceLastPacket( void );
virtual int ClientGetOutgoingRate( void );
virtual int ClientGetIncomingRate( void );
virtual float ClientGetIncomingPacketLoss( void );
// RAVEN BEGIN
// ddynerman: added some utility functions
// uses a static buffer, copy it before calling in game again
virtual const char* GetServerAddress( void );
virtual const char* GetClientAddress( int clientNum );
virtual void AddFriend( int clientNum );
virtual void RemoveFriend( int clientNum );
// for MP games
virtual void SetLoadingText( const char* loadingText );
virtual void AddLoadingIcon( const char* icon );
virtual const char* GetClientGUID( int clientNum );
// RAVEN END
virtual void GetTrafficStats( int &bytesSent, int &packetsSent, int &bytesReceived, int &packetsReceived ) const;
// server browser
virtual int GetNumScannedServers( void );
virtual const scannedServer_t* GetScannedServerInfo( int serverNum );
virtual const scannedClient_t* GetScannedServerClientInfo( int serverNum, int clientNum );
virtual void AddSortFunction( const sortInfo_t &sortInfo );
virtual bool RemoveSortFunction( const sortInfo_t &sortInfo );
virtual void UseSortFunction( const sortInfo_t &sortInfo, bool use = true );
virtual bool SortFunctionIsActive( const sortInfo_t &sortInfo );
// returns true if enabled
virtual bool HTTPEnable( bool enable );
virtual void ClientSetServerInfo( const idDict &serverSI );
virtual void RepeaterSetInfo( const idDict &info );
virtual const char* GetViewerGUID( int clientNum );
private:
scannedServer_t scannedServer;
scannedClient_t scannedClient;
};
extern idNetworkSystem * networkSystem;
#endif /* !__NETWORKSYSTEM_H__ */

272
source/framework/declAF.h Normal file
View file

@ -0,0 +1,272 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLAF_H__
#define __DECLAF_H__
/*
===============================================================================
Articulated Figure
===============================================================================
*/
class idDeclAF;
typedef enum {
DECLAF_CONSTRAINT_INVALID,
DECLAF_CONSTRAINT_FIXED,
DECLAF_CONSTRAINT_BALLANDSOCKETJOINT,
DECLAF_CONSTRAINT_UNIVERSALJOINT,
DECLAF_CONSTRAINT_HINGE,
DECLAF_CONSTRAINT_SLIDER,
DECLAF_CONSTRAINT_SPRING
} declAFConstraintType_t;
typedef enum {
DECLAF_JOINTMOD_AXIS,
DECLAF_JOINTMOD_ORIGIN,
DECLAF_JOINTMOD_BOTH
} declAFJointMod_t;
typedef bool (*getJointTransform_t)( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis );
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idAFVector : public Serializable<'AFV '> {
public:
// Serialization methods
void Write(SerialOutputStream &stream) const;
void AddReferences() const;
idAFVector(SerialInputStream &stream);
#else
class idAFVector {
public:
#endif
enum idAFVectorType_t {
// RAVEN END
VEC_COORDS = 0,
VEC_JOINT,
VEC_BONECENTER,
VEC_BONEDIR
} type;
idStr joint1;
idStr joint2;
public:
idAFVector( void );
bool Parse( idLexer &src );
bool Finish( const char *fileName, const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const;
bool Write( idFile *f ) const;
const char * ToString( idStr &str, const int precision = 8 );
const idVec3 & ToVec3( void ) const { return vec; }
idVec3 & ToVec3( void ) { return vec; }
private:
mutable idVec3 vec;
bool negate;
};
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclAF_Body : public Serializable<'DAFB'> {
public:
// Serializable Methods
void Write( SerialOutputStream &stream ) const;
idDeclAF_Body( SerialInputStream &stream );
void AddReferences() const;
#else
class idDeclAF_Body {
#endif
public:
idDeclAF_Body();
// RAVEN END
idStr name;
idStr jointName;
declAFJointMod_t jointMod;
int modelType;
idAFVector v1, v2;
int numSides;
float width;
float density;
idAFVector origin;
idAngles angles;
int contents;
int clipMask;
bool selfCollision;
idMat3 inertiaScale;
float linearFriction;
float angularFriction;
float contactFriction;
idStr containedJoints;
idAFVector frictionDirection;
idAFVector contactMotorDirection;
public:
void SetDefault( const idDeclAF *file );
};
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclAF_Constraint : public Serializable<'DAFC'> {
public:
// Serializable Methods
void Write( SerialOutputStream &stream ) const;
idDeclAF_Constraint( SerialInputStream &stream );
void AddReferences() const;
#else
class idDeclAF_Constraint {
public:
#endif
idDeclAF_Constraint();
// RAVEN END
idStr name;
idStr body1;
idStr body2;
declAFConstraintType_t type;
float friction;
float stretch;
float compress;
float damping;
float restLength;
float minLength;
float maxLength;
idAFVector anchor;
idAFVector anchor2;
idAFVector shaft[2];
idAFVector axis;
// RAVEN BEGIN
// jsinger: added declAFLimitType_t to support serialization/deserialization of binary decls
enum declAFLimitType_t {
LIMIT_NONE = -1,
LIMIT_CONE,
LIMIT_PYRAMID
} limit;
// RAVEN END
idAFVector limitAxis;
float limitAngles[3];
public:
void SetDefault( const idDeclAF *file );
};
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclAF : public idDecl, public Serializable<'DAF '> {
public:
idDeclAF( SerialInputStream &stream );
void Write( SerialOutputStream &stream ) const;
void AddReferences() const;
#else
class idDeclAF : public idDecl {
#endif
// RAVEN END
friend class idAFFileManager;
public:
idDeclAF( void );
virtual ~idDeclAF( void );
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
// RAVEN BEGIN
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
virtual void Finish( const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const;
bool Save( void );
void NewBody( const char *name );
void RenameBody( const char *oldName, const char *newName );
void DeleteBody( const char *name );
void NewConstraint( const char *name );
void RenameConstraint( const char *oldName, const char *newName );
void DeleteConstraint( const char *name );
static int ContentsFromString( const char *str );
static const char * ContentsToString( const int contents, idStr &str );
static declAFJointMod_t JointModFromString( const char *str );
static const char * JointModToString( declAFJointMod_t jointMod );
public:
bool modified;
idStr model;
idStr skin;
float defaultLinearFriction;
float defaultAngularFriction;
float defaultContactFriction;
float defaultConstraintFriction;
float totalMass;
idVec2 suspendVelocity;
idVec2 suspendAcceleration;
float noMoveTime;
float noMoveTranslation;
float noMoveRotation;
float minMoveTime;
float maxMoveTime;
int contents;
int clipMask;
bool selfCollision;
// RAVEN BEGIN
// rjohnson: fast AF eval to skip some things that are not needed for specific circumstances
bool fastEval;
// RAVEN END
idList<idDeclAF_Body *> bodies;
idList<idDeclAF_Constraint *> constraints;
private:
bool ParseContents( idLexer &src, int &c ) const;
bool ParseBody( idLexer &src );
bool ParseFixed( idLexer &src );
bool ParseBallAndSocketJoint( idLexer &src );
bool ParseUniversalJoint( idLexer &src );
bool ParseHinge( idLexer &src );
bool ParseSlider( idLexer &src );
bool ParseSpring( idLexer &src );
bool ParseSettings( idLexer &src );
bool WriteBody( idFile *f, const idDeclAF_Body &body ) const;
bool WriteFixed( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteBallAndSocketJoint( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteUniversalJoint( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteHinge( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteSlider( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteSpring( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteConstraint( idFile *f, const idDeclAF_Constraint &c ) const;
bool WriteSettings( idFile *f ) const;
bool RebuildTextSource( void );
};
// RAVEN BEGIN
class rvDeclAFEdit
{
public:
virtual ~rvDeclAFEdit() { }
virtual bool Save( idDeclAF *edit ) = 0;
virtual void NewBody( idDeclAF *edit, char const *name ) = 0;
virtual void RenameBody( idDeclAF *edit, char const *oldName, char const *newName ) = 0;
virtual void DeleteBody( idDeclAF *edit, char const *name ) = 0;
virtual void NewConstraint( idDeclAF *edit, char const *name ) = 0;
virtual void RenameConstraint( idDeclAF *edit, char const *oldName, char const *newName ) = 0;
virtual void DeleteConstraint( idDeclAF *edit, char const *name ) = 0;
};
extern rvDeclAFEdit *declAFEdit;
// RAVEN END
#endif /* !__DECLAF_H__ */

View file

@ -0,0 +1,46 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLENTITYDEF_H__
#define __DECLENTITYDEF_H__
/*
===============================================================================
idDeclEntityDef
===============================================================================
*/
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclEntityDef : public idDecl, public Serializable<'DED '> {
public:
virtual void AddReferences() const;
virtual void Write(SerialOutputStream &stream) const;
idDeclEntityDef(SerialInputStream &stream);
#else
class idDeclEntityDef : public idDecl {
#endif
// RAVEN END
public:
idDeclEntityDef();
idDict dict;
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition() const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual void Print( void );
// RAVEN BEGIN
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
};
#endif /* !__DECLENTITYDEF_H__ */

View file

@ -0,0 +1,74 @@
#ifndef __DECLLIPSYNC_H__
#define __DECLLIPSYNC_H__
// A way of cross referencing strings and sound shaders
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class rvDeclLipSync : public idDecl, public Serializable<'RDLS'>
{
public:
virtual void Write( SerialOutputStream &stream ) const;
virtual void AddReferences() const;
rvDeclLipSync( SerialInputStream &stream );
#else
class rvDeclLipSync : public idDecl
{
#endif
// RAVEN END
public:
rvDeclLipSync( void ) {}
~rvDeclLipSync( void ) {}
void SetDescription( const char *desc ) { mDescription = desc; }
const idStr &GetDescription( void ) const { return( mDescription ); }
void SetHMM( idStr &hmm ) { mHMM = hmm; }
const idStr &GetHMM( void ) const { return( mHMM ); }
void SetTranscribeText( const char *text ) { mTranscribeText = text; }
const char *GetTranscribeText( int langIndex = -1 ) const { return( common->GetLocalizedString( mTranscribeText, langIndex ) ); }
const char *GetRawTranscribeText( void ) const { return( mTranscribeText.c_str() ); }
void SetLipSyncData( const char *lsd, const char *lang );
const char *GetLipSyncData( int langIdx = -1 ) const;
virtual const char *DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual bool RebuildTextSource( void );
virtual size_t Size( void ) const;
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
private:
idStr mDescription;
idStr mTranscribeText;
idStr mHMM;
idDict mLipSyncData;
};
ID_INLINE const char *rvDeclLipSync::GetLipSyncData( int langIdx ) const
{
if( common->LanguageHasVO( langIdx ) )
{
return( mLipSyncData.GetString( common->GetLanguage( langIdx ) ) );
}
return( mLipSyncData.GetString( "english" ) );
}
class rvDeclLipSyncEdit
{
public:
virtual ~rvDeclLipSyncEdit() { }
virtual void SetLipSyncDescription( rvDeclLipSync *edit, const char *desc ) = 0;
virtual void SetLipSyncTranscribeText( rvDeclLipSync *edit, const char *text ) = 0;
virtual void SetLipSyncData( rvDeclLipSync *edit, const char *lsd, const char *lang ) = 0;
};
extern rvDeclLipSyncEdit *declLipSyncEdit;
#endif // __DECLLIPSYNC_H__

View file

@ -0,0 +1,458 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLMANAGER_H__
#define __DECLMANAGER_H__
/*
===============================================================================
Declaration Manager
All "small text" data types, like materials, sound shaders, fx files,
entity defs, etc. are managed uniformly, allowing reloading, purging,
listing, printing, etc. All "large text" data types that never have more
than one declaration in a given file, like maps, models, AAS files, etc.
are not handled here.
A decl will never, ever go away once it is created. The manager is
garranteed to always return the same decl pointer for a decl type/name
combination. The index of a decl in the per type list also stays the
same throughout the lifetime of the engine. Although the pointer to
a decl always stays the same, one should never maintain pointers to
data inside decls. The data stored in a decl is not garranteed to stay
the same for more than one engine frame.
The decl indexes of explicitely defined decls are garrenteed to be
consistent based on the parsed decl files. However, the indexes of
implicit decls may be different based on the order in which levels
are loaded.
The decl namespaces are separate for each type. Comments for decls go
above the text definition to keep them associated with the proper decl.
During decl parsing, errors should never be issued, only warnings
followed by a call to MakeDefault().
===============================================================================
*/
typedef enum {
DECL_TABLE = 0,
DECL_MATERIAL,
DECL_SKIN,
DECL_SOUND,
DECL_ENTITYDEF,
DECL_MODELDEF,
// RAVEN BEGIN
// jscott: added new decls
DECL_MATERIALTYPE,
DECL_LIPSYNC,
DECL_PLAYBACK,
DECL_EFFECT,
// rjohnson: camera is now contained in a def for frame commands
DECL_CAMERADEF,
// jscott: don't use these
// DECL_FX,
// DECL_PARTICLE,
// RAVEN END
DECL_AF,
DECL_PDA,
DECL_VIDEO,
DECL_AUDIO,
DECL_EMAIL,
DECL_MODELEXPORT,
DECL_MAPDEF,
// new decl types can be added here
DECL_PLAYER_MODEL,
DECL_MAX_TYPES = 32
} declType_t;
typedef enum {
DS_UNPARSED,
DS_DEFAULTED, // set if a parse failed due to an error, or the lack of any source
DS_PARSED
} declState_t;
const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated
LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings
LEXFL_ALLOWPATHNAMES | // allow path seperators in names
LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals
LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated
LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring
class idDeclBase {
public:
virtual ~idDeclBase() {};
virtual const char * GetName( void ) const = 0;
virtual declType_t GetType( void ) const = 0;
virtual declState_t GetState( void ) const = 0;
virtual bool IsImplicit( void ) const = 0;
virtual bool IsValid( void ) const = 0;
virtual void Invalidate( void ) = 0;
virtual void Reload( void ) = 0;
virtual void EnsureNotPurged( void ) = 0;
virtual int Index( void ) const = 0;
virtual int GetLineNum( void ) const = 0;
virtual const char * GetFileName( void ) const = 0;
virtual void GetText( char *text ) const = 0;
virtual int GetTextLength( void ) const = 0;
// RAVEN BEGIN
virtual int GetCompressedLength( void ) const = 0;
// RAVEN END
virtual void SetText( const char *text ) = 0;
virtual bool ReplaceSourceFileText( void ) = 0;
virtual bool SourceFileChanged( void ) const = 0;
virtual void MakeDefault( void ) = 0;
virtual bool EverReferenced( void ) const = 0;
// RAVEN BEGIN
virtual void SetReferencedThisLevel( void ) = 0;
// RAVEN END
virtual bool SetDefaultText( void ) = 0;
virtual const char * DefaultDefinition( void ) const = 0;
virtual bool Parse( const char *text, const int textLength, bool noCaching ) = 0;
virtual void FreeData( void ) = 0;
virtual size_t Size( void ) const = 0;
virtual void List( void ) const = 0;
virtual void Print( void ) const = 0;
// RAVEN BEGIN
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: Validation call for detailed error-reporting
virtual bool Validate( const char *psText, int iLength, idStr &strReportTo ) const = 0;
// RAVEN END
};
// RAVEN BEGIN
// jscott: for guides
#define MAX_GUIDE_PARMS 20
#define MAX_GUIDE_SHADER_SIZE 20480
class rvDeclGuide
{
private:
idStr mName;
idStr mParms[MAX_GUIDE_PARMS];
idStr mDefinition;
int mNumParms;
public:
rvDeclGuide( idStr &name );
~rvDeclGuide( void );
const char *GetName( void ) const { return( mName.c_str() ); }
int GetNumParms( void ) const { return( mNumParms ); }
const char *GetParm( int index ) const { assert( index < mNumParms ); return( mParms[index].c_str() ); }
void SetParm( int index, const char *value );
void RemoveOuterBracing( void );
void Parse( idLexer *src );
bool Evaluate( idLexer *src, idStr &definition );
};
// RAVEN END
class idDecl {
public:
// The constructor should initialize variables such that
// an immediate call to FreeData() does no harm.
idDecl( void ) { base = NULL; }
virtual ~idDecl( void ) {};
// Returns the name of the decl.
const char * GetName( void ) const { return base->GetName(); }
// Returns the decl type.
declType_t GetType( void ) const { return base->GetType(); }
// Returns the decl state which is usefull for finding out if a decl defaulted.
declState_t GetState( void ) const { return base->GetState(); }
// Returns true if the decl was defaulted or the text was created with a call to SetDefaultText.
bool IsImplicit( void ) const { return base->IsImplicit(); }
// The only way non-manager code can have an invalid decl is if the *ByIndex()
// call was used with forceParse = false to walk the lists to look at names
// without touching the media.
bool IsValid( void ) const { return base->IsValid(); }
// Sets state back to unparsed.
// Used by decl editors to undo any changes to the decl.
void Invalidate( void ) { base->Invalidate(); }
// if a pointer might possible be stale from a previous level,
// call this to have it re-parsed
void EnsureNotPurged( void ) { base->EnsureNotPurged(); }
// Returns the index in the per-type list.
int Index( void ) const { return base->Index(); }
// Returns the line number the decl starts.
int GetLineNum( void ) const { return base->GetLineNum(); }
// Returns the name of the file in which the decl is defined.
const char * GetFileName( void ) const { return base->GetFileName(); }
// Returns the decl text.
void GetText( char *text ) const { base->GetText( text ); }
// Returns the length of the decl text.
int GetTextLength( void ) const { return base->GetTextLength(); }
// Returns the compressed length of the decl text.
int GetCompressedLength( void ) const { return( base->GetCompressedLength() ); }
// Sets new decl text.
void SetText( const char *text ) { base->SetText( text ); }
// Saves out new text for the decl.
// Used by decl editors to replace the decl text in the source file.
bool ReplaceSourceFileText( void ) { return base->ReplaceSourceFileText(); }
// Returns true if the source file changed since it was loaded and parsed.
bool SourceFileChanged( void ) const { return base->SourceFileChanged(); }
// Frees data and makes the decl a default.
void MakeDefault( void ) { base->MakeDefault(); }
// Returns true if the decl was ever referenced.
bool EverReferenced( void ) const { return base->EverReferenced(); }
public:
// Sets textSource to a default text if necessary.
// This may be overridden to provide a default definition based on the
// decl name. For instance materials may default to an implicit definition
// using a texture with the same name as the decl.
virtual bool SetDefaultText( void ) { return base->SetDefaultText(); }
// Each declaration type must have a default string that it is guaranteed
// to parse acceptably. When a decl is not explicitly found, is purged, or
// has an error while parsing, MakeDefault() will do a FreeData(), then a
// Parse() with DefaultDefinition(). The defaultDefintion should start with
// an open brace and end with a close brace.
virtual const char * DefaultDefinition( void ) const { return base->DefaultDefinition(); }
// The manager will have already parsed past the type, name and opening brace.
// All necessary media will be touched before return.
// The manager will have called FreeData() before issuing a Parse().
// The subclass can call MakeDefault() internally at any point if
// there are parse errors.
virtual bool Parse( const char *text, const int textLength, bool noCaching ) { return base->Parse( text, textLength, noCaching ); }
// Frees any pointers held by the subclass. This may be called before
// any Parse(), so the constructor must have set sane values. The decl will be
// invalid after issuing this call, but it will always be immediately followed
// by a Parse()
virtual void FreeData( void ) { base->FreeData(); }
// Returns the size of the decl in memory.
virtual size_t Size( void ) const { return base->Size(); }
// If this isn't overridden, it will just print the decl name.
// The manager will have printed 7 characters on the line already,
// containing the reference state and index number.
virtual void List( void ) const { base->List(); }
// The print function will already have dumped the text source
// and common data, subclasses can override this to dump more
// explicit data.
virtual void Print( void ) const { base->Print(); }
// RAVEN BEGIN
// Rebuilds the text source of the decl for saving
virtual bool RebuildTextSource( void ) { return( base->RebuildTextSource() ); }
// Marks this decl as referenced this level
virtual void SetReferencedThisLevel( void ) { base->SetReferencedThisLevel(); }
// scork: for detailed error reporting
virtual bool Validate( const char *psText, int iLength, idStr &strReportTo ) const { return base->Validate( psText, iLength, strReportTo ); }
// RAVEN END
public:
idDeclBase * base;
};
template< class type >
ID_INLINE idDecl *idDeclAllocator( void ) {
return new type;
}
// RAVEN BEGIN
// jsinger: added to allow support for serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
template< class type >
ID_INLINE SerializableBase *idDeclStreamAllocator( SerialInputStream &stream ) {
type *ptr = new type(stream);
return dynamic_cast<SerializableBase *>(ptr);
}
#endif
class idMaterial;
class idDeclTable;
class idDeclSkin;
class idSoundShader;
// RAVEN BEGIN
// jscott: new decl types
class rvDeclMatType;
class rvDeclLipSync;
class rvDeclPlayback;
class rvDeclEffect;
class rvDeclPlayerModel;
// RAVEN END
class idDeclManager {
public:
virtual ~idDeclManager( void ) {}
virtual void SetInsideLoad( bool var ) = 0;
virtual bool GetInsideLoad( void ) = 0;
virtual void Init( void ) = 0;
virtual void Shutdown( void ) = 0;
virtual void Reload( bool force ) = 0;
virtual void BeginLevelLoad() = 0;
virtual void EndLevelLoad() = 0;
// Registers a new decl type.
// RAVEN BEGIN
// jsinger: Added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ), SerializableBase *(*streamAllocator)( SerialInputStream &stream ) ) = 0;
#else
virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) = 0;
#endif
// jsinger: Added to support loading all decls from a single file
#ifdef RV_SINGLE_DECL_FILE
virtual void StartLoadingDecls() = 0;
virtual void FinishLoadingDecls() = 0;
virtual void LoadDeclsFromFile() = 0;
virtual void WriteDeclFile() = 0;
virtual void FlushDecls() = 0;
#endif
// RAVEN END
// RAVEN BEGIN
// jscott: for timing
// Registers a new folder with decl files.
virtual void RegisterDeclFolderWrapper( const char *folder, const char *extension, declType_t defaultType, bool unique = false, bool norecurse = false ) = 0;
// RAVEN END
// Returns a checksum for all loaded decl text.
virtual int GetChecksum( void ) const = 0;
// Returns the number of decl types.
virtual int GetNumDeclTypes( void ) const = 0;
// Returns the type name for a decl type.
virtual const char * GetDeclNameFromType( declType_t type ) const = 0;
// Returns the decl type for a type name.
virtual declType_t GetDeclTypeFromName( const char *typeName ) const = 0;
// If makeDefault is true, a default decl of appropriate type will be created
// if an explicit one isn't found. If makeDefault is false, NULL will be returned
// if the decl wasn't explcitly defined.
virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true, bool noCaching = false ) = 0;
virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ) = 0;
virtual void ReloadFile( const char* filename, bool force ) = 0;
// Returns the number of decls of the given type.
virtual int GetNumDecls( declType_t type ) = 0;
// The complete lists of decls can be walked to populate editor browsers.
// If forceParse is set false, you can get the decl to check name / filename / etc.
// without causing it to parse the source and load media.
virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ) = 0;
// List and print decls.
virtual void ListType( const idCmdArgs &args, declType_t type ) = 0;
virtual void PrintType( const idCmdArgs &args, declType_t type ) = 0;
// Creates a new default decl of the given type with the given name in
// the given file used by editors to create a new decls.
virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ) = 0;
// BSM - Added for the material editors rename capabilities
virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ) = 0;
// When media files are loaded, a reference line can be printed at a
// proper indentation if decl_show is set
virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
virtual void WritePrecacheCommands( idFile *f ) = 0;
// RAVEN BEGIN
// jscott: precache any guide (template) files
virtual void ParseGuides( void ) = 0;
virtual void ShutdownGuides( void ) = 0;
virtual bool EvaluateGuide( idStr &name, idLexer *src, idStr &definition ) = 0;
virtual bool EvaluateInlineGuide( idStr &name, idStr &definition ) = 0;
// RAVEN END
// Convenience functions for specific types.
virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ) = 0;
virtual const idDeclTable * FindTable( const char *name, bool makeDefault = true ) = 0;
virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ) = 0;
virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ) = 0;
// RAVEN BEGIN
// jscott: for new Raven decls
virtual const rvDeclMatType * FindMaterialType( const char *name, bool makeDefault = true ) = 0;
virtual const rvDeclLipSync * FindLipSync( const char *name, bool makeDefault = true ) = 0;
virtual const rvDeclPlayback * FindPlayback( const char *name, bool makeDefault = true ) = 0;
virtual const rvDeclEffect * FindEffect( const char *name, bool makeDefault = true ) = 0;
// RAVEN END
virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ) = 0;
virtual const idDeclTable * TableByIndex( int index, bool forceParse = true ) = 0;
virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ) = 0;
virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ) = 0;
// RAVEN BEGIN
// jscott: for new Raven decls
virtual const rvDeclMatType * MaterialTypeByIndex( int index, bool forceParse = true ) = 0;
virtual const rvDeclLipSync * LipSyncByIndex( int index, bool forceParse = true ) = 0;
virtual const rvDeclPlayback * PlaybackByIndex( int index, bool forceParse = true ) = 0;
virtual const rvDeclEffect * EffectByIndex( int index, bool forceParse = true ) = 0;
virtual void StartPlaybackRecord( rvDeclPlayback *playback ) = 0;
virtual bool SetPlaybackData( rvDeclPlayback *playback, int now, int control, class rvDeclPlaybackData *pbd ) = 0;
virtual bool GetPlaybackData( const rvDeclPlayback *playback, int control, int now, int last, class rvDeclPlaybackData *pbd ) = 0;
virtual bool FinishPlayback( rvDeclPlayback *playback ) = 0;
virtual idStr GetNewName( declType_t type, const char *base ) = 0;
virtual const char * GetDeclTypeName( declType_t type ) = 0;
virtual size_t ListDeclSummary( const idCmdArgs &args ) = 0;
virtual void RemoveDeclFile( const char *file ) = 0;
// scork: Validation call for detailed error-reporting
virtual bool Validate( declType_t type, int iIndex, idStr &strReportTo ) = 0;
virtual idDecl * AllocateDecl( declType_t type ) = 0;
#if defined(_XENON)
// mwhitlock: Xenon texture streaming
virtual void SetLightMaterialList(idList<idMaterial*>* materialList) = 0;
virtual void SetEntityMaterialList(idList<idMaterial*>* materialList) = 0;
virtual void PurgeType( declType_t type ) = 0;
#endif
// RAVEN END
};
extern idDeclManager * declManager;
template< declType_t type >
ID_INLINE void idListDecls_f( const idCmdArgs &args ) {
declManager->ListType( args, type );
}
template< declType_t type >
ID_INLINE void idPrintDecls_f( const idCmdArgs &args ) {
declManager->PrintType( args, type );
}
#endif /* !__DECLMANAGER_H__ */

View file

@ -0,0 +1,53 @@
#ifndef __DECLMATTYPE_H__
#define __DECLMATTYPE_H__
// Defines a material type - such as concrete, metal, glass etc
#ifdef RV_BINARYDECLS
class rvDeclMatType : public idDecl, public Serializable<'RDMT'>
{
public:
// jsinger: allow exporting of this decl type in a preparsed form
virtual void Write( SerialOutputStream &stream ) const;
virtual void AddReferences() const;
rvDeclMatType( SerialInputStream &stream );
#else
class rvDeclMatType : public idDecl
{
public:
#endif
rvDeclMatType( void ) { *( ulong *)mTint = 0; }
~rvDeclMatType( void ) {}
void SetDescription( idStr &desc ) { mDescription = desc; }
const idStr &GetDescription( void ) const { return( mDescription ); }
void SetTint( byte tint[4] ) { *( ulong *)mTint = *( ulong *)tint; }
int GetTint( void ) const { return( *( int *)mTint ); }
float GetRed( void ) const { return( mTint[0] / 255.0f ); }
float GetGreen( void ) const { return( mTint[1] / 255.0f ); }
float GetBlue( void ) const { return( mTint[2] / 255.0f ); }
virtual const char *DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual size_t Size( void ) const;
// RAVEN BEGIN
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
private:
idStr mDescription;
byte mTint[4];
};
byte *MT_GetMaterialTypeArray( idStr image, int &width, int &height );
#endif // __DECLMATTYPE_H__

View file

@ -0,0 +1,185 @@
#ifndef __DECLPLAYBACK_H__
#define __DECLPLAYBACK_H__
// WARNING: These must stay mirrored in both Q4Monster.state
#define PBFL_GET_POSITION BIT( 0 ) // Stored in playback file
#define PBFL_GET_ANGLES BIT( 1 )
#define PBFL_GET_BUTTONS BIT( 2 )
#define PBFL_GET_VELOCITY BIT( 4 ) // Derived from data
#define PBFL_GET_ACCELERATION BIT( 5 )
#define PBFL_GET_ANGLES_FROM_VEL BIT( 6 )
#define PBFL_AT_DEST BIT( 7 )
#define PBFL_RELATIVE_POSITION BIT( 8 )
#define PBFL_ED_MODIFIED BIT( 29 )
#define PBFL_ED_NEW BIT( 30 )
#define PBFL_ED_CHECKEDIN BIT( 31 )
#define PBFL_ED_MASK ( PBFL_ED_MODIFIED | PBFL_ED_NEW | PBFL_ED_CHECKEDIN )
#define PBCB_NONE 0
#define PBCB_BUTTON_DOWN 1
#define PBCB_BUTTON_UP 2
#define PBCB_IMPULSE 3
typedef void ( *pbCallback_t )( int type, float time, const void *data );
class rvDeclPlaybackData
{
public:
void Init( void ) { entity = NULL; Callback = NULL; position.Zero(); velocity.Zero(); acceleration.Zero(); angles.Zero(); changed = 0; button = 0; impulse = 0; }
void SetPosition( const idVec3 &pos ) { position = pos; }
void SetVelocity( const idVec3 &vel ) { velocity = vel; }
void SetAcceleration( const idVec3 &accel ) { acceleration = accel; }
void SetAngles( const idAngles &ang ) { angles = ang; }
void SetChanged( const byte chg ) { changed = chg; }
void SetButtons( const byte btn ) { button = btn; }
void SetImpulse( const byte imp ) { impulse = imp; }
const idVec3 &GetPosition( void ) const { return( position ); }
const idVec3 &GetVelocity( void ) const { return( velocity ); }
const idVec3 &GetAcceleration( void ) const { return( acceleration ); }
const idAngles &GetAngles( void ) const { return( angles ); }
byte GetChanged( void ) const { return( changed ); }
byte GetButtons( void ) const { return( button ); }
byte GetImpulse( void ) const { return( impulse ); }
class idEntity *GetEntity( void ) const { return( entity ); }
void SetCallback( class idEntity *ent, pbCallback_t cb ) { entity = ent; Callback = cb; }
void CallCallback( int type, float time ) { if( Callback ) { Callback( type, time, this ); } }
private:
class idEntity *entity;
pbCallback_t Callback;
idVec3 position;
idVec3 velocity;
idVec3 acceleration;
idAngles angles;
byte changed;
byte button;
byte impulse;
};
class rvButtonState
{
public:
void Init( float t, byte b = 0, byte i = 0 ) { time = t; state = b; impulse = i; }
float time;
byte state;
byte impulse;
};
#ifdef RV_BINARYDECLS
class rvDeclPlayback : public idDecl, public Serializable<'RDP '>
{
public:
// jsinger: allow exporting of this decl type in a preparsed form
virtual void Write( SerialOutputStream &stream ) const;
virtual void AddReferences() const;
rvDeclPlayback( SerialInputStream &stream );
#else
class rvDeclPlayback : public idDecl
{
#endif
public:
rvDeclPlayback( void );
~rvDeclPlayback( void );
void SetFlag( bool on, int flag ) { on ? flags |= flag : flags &= ~flag; }
bool GetHasPositions( void ) const { return( !!( flags & PBFL_GET_POSITION ) ); }
bool GetHasAngles( void ) const { return( !!( flags & PBFL_GET_ANGLES ) ); }
bool GetHasButtons( void ) const { return( !!( flags & PBFL_GET_BUTTONS ) ); }
bool GetEditorModified( void ) const { return( !!( flags & PBFL_ED_MODIFIED ) ); }
bool GetEditorNew( void ) const { return( !!( flags & PBFL_ED_NEW ) ); }
bool GetEditorCheckedIn( void ) const { return( !!( flags & PBFL_ED_CHECKEDIN ) ); }
void SetHasPositions( bool pos ) { SetFlag( pos, PBFL_GET_POSITION ); }
void SetHasAngles( bool ang ) { SetFlag( ang, PBFL_GET_ANGLES ); }
void SetHasButtons( bool btn ) { SetFlag( btn, PBFL_GET_BUTTONS ); }
void SetEditorModified( bool em ) { SetFlag( em, PBFL_ED_MODIFIED ); }
void SetEditorNew( bool en ) { SetFlag( en, PBFL_ED_NEW ); }
void SetEditorCheckedIn( bool eci ) { SetFlag( eci, PBFL_ED_CHECKEDIN ); }
int GetFlags( void ) const { return( flags ); }
void SetFlags( int in ) { flags = in; }
float GetFrameRate( void ) const { return( frameRate ); }
void SetFrameRate( float in ) { frameRate = in; }
idVec3 GetOrigin( void ) const { return( origin ); }
void SetOrigin( idVec3 &in ) { origin = in; }
float GetDuration( void ) const { return( duration ); }
void SetDuration( float dur ) { duration = dur; }
idBounds GetBounds( void ) const { return( bounds ); }
void ParseSample( idLexer *src, idVec3 &pos, idAngles &ang );
void WriteData( idFile_Memory &f );
void WriteButtons( idFile_Memory &f );
void WriteSequence( idFile_Memory &f );
bool ParseData( idLexer *src );
void ParseButton( idLexer *src, byte &button, rvButtonState &state );
bool ParseSequence( idLexer *src );
bool ParseButtons( idLexer *src );
void Copy( rvDeclPlayback *pb );
void SetOrigin( void );
void Start( void );
bool Finish( float desiredDuration = -1.0f );
bool SetCurrentData( float localTime, int control, rvDeclPlaybackData *pbd );
bool GetCurrentOffset( float localTime, idVec3 &pos ) const;
bool GetCurrentAngles( float localTime, idAngles &ang ) const;
bool GetCurrentData( int control, float localTime, float lastTime, rvDeclPlaybackData *pbd ) const;
virtual const char *DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
virtual bool RebuildTextSource( void );
virtual size_t Size( void ) const;
// RAVEN BEGIN
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
idCurve_UniformCubicBSpline<idVec3> &GetPoints( void ) { return( points ); }
idCurve_UniformCubicBSpline<idAngles> &GetAngles( void ) { return( angles ); }
idList<rvButtonState> &GetButtons( void ) { return( buttons ); }
private:
int flags;
float frameRate;
float duration;
idVec3 origin;
idBounds bounds;
idCurve_UniformCubicBSpline<idVec3> points;
idCurve_UniformCubicBSpline<idAngles> angles;
idList<rvButtonState> buttons;
};
class rvDeclPlaybackEdit
{
public:
virtual ~rvDeclPlaybackEdit() {}
virtual bool Finish( rvDeclPlayback *edit, float desiredDuration ) = 0;
virtual void SetOrigin( rvDeclPlayback *edit ) = 0;
virtual void SetOrigin( rvDeclPlayback *edit, idVec3 &origin ) = 0;
virtual void Copy( rvDeclPlayback *edit, rvDeclPlayback *copy ) = 0;
};
extern rvDeclPlaybackEdit *declPlaybackEdit;
#endif // __DECLPLAYBACK_H__

View file

@ -0,0 +1,74 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLSKIN_H__
#define __DECLSKIN_H__
/*
===============================================================================
idDeclSkin
===============================================================================
*/
typedef struct {
const idMaterial * from; // 0 == any unmatched shader
const idMaterial * to;
} skinMapping_t;
// RAVEN BEGIN
// jsinger: allow support for serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclSkin : public idDecl, public Serializable<'DSKN'> {
public:
// jsinger: allow exporting of this decl type in a preparsed form
virtual void Write( SerialOutputStream &stream) const;
virtual void AddReferences() const;
idDeclSkin(SerialInputStream &stream);
#else
class idDeclSkin : public idDecl {
#endif
public:
idDeclSkin();
virtual size_t Size( void ) const;
virtual bool SetDefaultText( void );
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
// RAVEN BEGIN
// mwhitlock: Xenon texture streaming
#if defined(_XENON)
void StreamAllSkinTargets(bool inBackground);
void GetSkinTargetsList(idList<const idMaterial*>& outList) const;
#endif
// RAVEN END
const idMaterial * RemapShaderBySkin( const idMaterial *shader ) const;
// model associations are just for the preview dialog in the editor
// RAVEN BEGIN
// jscott: inlined for access from tools dll
const int GetNumModelAssociations() const { return( associatedModels.Num() ); }
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: validation member for more detailed error-checks
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
const char * GetAssociatedModel( int index ) const;
private:
idList<skinMapping_t> mappings;
idStrList associatedModels;
};
// RAVEN BEGIN
// jscott: inlined for access from tools dll
ID_INLINE const char *idDeclSkin::GetAssociatedModel( int index ) const {
if ( index >= 0 && index < associatedModels.Num() ) {
return associatedModels[ index ];
}
return "";
}
// RAVEN END
#endif /* !__DECLSKIN_H__ */

View file

@ -0,0 +1,58 @@
// Copyright (C) 2004 Id Software, Inc.
//
#ifndef __DECLTABLE_H__
#define __DECLTABLE_H__
/*
===============================================================================
tables are used to map a floating point input value to a floating point
output value, with optional wrap / clamp and interpolation
===============================================================================
*/
// RAVEN BEGIN
// jsinger: allow support for serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclTable : public idDecl, public Serializable<'DTAB'> {
public:
// jsinger: allow exporting of this decl type in a preparsed form
virtual void Write( SerialOutputStream &stream) const;
virtual void AddReferences() const;
idDeclTable( SerialInputStream &stream);
#else
class idDeclTable : public idDecl {
#endif
public:
idDeclTable();
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
// RAVEN BEGIN
// jscott: for BSE
float GetMaxValue( void ) const { return( maxValue ); }
float GetMinValue( void ) const { return( minValue ); }
// bdube: made virtual so it can be accessed in game
virtual float TableLookup( float index ) const;
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
private:
bool clamp;
bool snap;
// RAVEN BEGIN
// jscott: for BSE
float minValue;
float maxValue;
// RAVEN END
idList<float> values;
};
#endif /* !__DECLTABLE_H__ */

128
source/framework/licensee.h Normal file
View file

@ -0,0 +1,128 @@
/*
===============================================================================
Definitions for information that is related to a licensee's game name and location.
===============================================================================
*/
// RAVEN BEGIN
// rjohnson: this is the name of the game we are making
#define GAME_NAME "Quake4" // appears on window titles and errors
#define GAME_ICON "q4icon.bmp"
// jnewquist: build type
#if defined(_DEBUG)
#define GAME_BUILD_TYPE "Debug"
#elif defined(_MPBETA)
#define GAME_BUILD_TYPE "MPBeta"
#elif defined(_FINAL)
#define GAME_BUILD_TYPE ""
#elif defined(_RELEASE)
#define GAME_BUILD_TYPE ""
#endif
// paths
#define CD_BASEDIR "Quake4"
#define BASE_GAMEDIR "q4base"
#define BASE_MPGAMEDIR "q4mp"
#define DEMO_GAMEDIR "demo"
// filenames
#define CD_EXE "Quake4.exe"
#ifdef _XENON
#define CONFIG_FILE "save:/Quake4Config.cfg"
#else
#define CONFIG_FILE "Quake4Config.cfg"
#endif
// base folder where the source code lives
#define SOURCE_CODE_BASE_FOLDER "code"
#define DEVELOPER_DOMAIN "ravensoft.com"
// RAVEN END
// RAVEN BEGIN
// rjohnson: changed the host to our temp address
// default idnet host address
#ifndef IDNET_HOST
#define IDNET_HOST "q4master.idsoftware.com"
#endif
// RAVEN END
// default idnet master port
#ifndef IDNET_MASTER_PORT
#define IDNET_MASTER_PORT "27650"
#endif
#ifndef MOTD_HOST
#define MOTD_HOST "q4m-test.ravensoft.com"
#endif
#ifndef MOTD_PORT
#define MOTD_PORT "27700"
#endif
// default network server port
#ifndef PORT_SERVER
//RAVEN BEGIN
#define PORT_SERVER 28004
//RAVEN END
#endif
// Q4TV default network repeater port
#ifndef PORT_REPEATER
#define PORT_REPEATER 28104
#endif
#ifndef PORT_HTTP
#define PORT_HTTP 28004
#endif
// broadcast scan this many ports after PORT_SERVER so a single machine can run multiple servers
#define NUM_SERVER_PORTS 4
// see ASYNC_PROTOCOL_VERSION
// use a different major for each game
// RAVEN BEGIN
// ddynerman: rev ASYNC_PROTOCOL_MAJOR to 2 for Quake 4
#define ASYNC_PROTOCOL_MAJOR 2
// RAVEN END
// Savegame Version
// Update when you can no longer maintain compatibility with previous savegames.
// For testing, we're using the build number to ensure no one ever tries to load a stale savegame
#define SAVEGAME_VERSION VERSION_BUILD_NUMBER
// editor info
#define EDITOR_WINDOWTEXT "QuakeEdit"
// win32 info
#define WIN32_CONSOLE_CLASS "Quake 4 WinConsole"
#define WIN32_SPLASH_CLASS "Quake 4 Splash"
#define WIN32_WINDOW_CLASS_NAME "Quake4"
#define WIN32_FAKE_WINDOW_CLASS_NAME "QUAKE4_WGL_FAKE"
#ifdef __linux__
#define DEFAULT_BASE_PATH "/usr/local/games/quake4"
#elif defined( MACOS_X )
#define DEFAULT_BASE_PATH "/Applications/Quake4"
#endif
// CD Key file info
#define CDKEY_FILE "quake4key"
#define CDKEY_TEXT "\n// Do not give this file to ANYONE.\n" \
"// id Software, Raven Software or Activision will NOT ask you to send this file to them.\n"
// FIXME: Update to Doom
// Product ID. Stored in "productid.txt".
// This file is copyright 1999 Id Software, and may not be duplicated except during a licensed installation of the full commercial version of Quake 3:Arena
#undef PRODUCT_ID
#define PRODUCT_ID 220, 129, 255, 108, 244, 163, 171, 55, 133, 65, 199, 36, 140, 222, 53, 99, 65, 171, 175, 232, 236, 193, 210, 250, 169, 104, 231, 231, 21, 201, 170, 208, 135, 175, 130, 136, 85, 215, 71, 23, 96, 32, 96, 83, 44, 240, 219, 138, 184, 215, 73, 27, 196, 247, 55, 139, 148, 68, 78, 203, 213, 238, 139, 23, 45, 205, 118, 186, 236, 230, 231, 107, 212, 1, 10, 98, 30, 20, 116, 180, 216, 248, 166, 35, 45, 22, 215, 229, 35, 116, 250, 167, 117, 3, 57, 55, 201, 229, 218, 222, 128, 12, 141, 149, 32, 110, 168, 215, 184, 53, 31, 147, 62, 12, 138, 67, 132, 54, 125, 6, 221, 148, 140, 4, 21, 44, 198, 3, 126, 12, 100, 236, 61, 42, 44, 251, 15, 135, 14, 134, 89, 92, 177, 246, 152, 106, 124, 78, 118, 80, 28, 42
#undef PRODUCT_ID_LENGTH
#define PRODUCT_ID_LENGTH 152
#define CONFIG_SPEC "config.spec"

1115
source/game.vcproj Normal file

File diff suppressed because it is too large Load diff

1336
source/game/AF.cpp Normal file

File diff suppressed because it is too large Load diff

97
source/game/AF.h Normal file
View file

@ -0,0 +1,97 @@
#ifndef __GAME_AF_H__
#define __GAME_AF_H__
/*
===============================================================================
Articulated figure controller.
===============================================================================
*/
typedef struct jointConversion_s {
int bodyId; // id of the body
jointHandle_t jointHandle; // handle of joint this body modifies
AFJointModType_t jointMod; // modify joint axis, origin or both
idVec3 jointBodyOrigin; // origin of body relative to joint
idMat3 jointBodyAxis; // axis of body relative to joint
} jointConversion_t;
typedef struct afTouch_s {
idEntity * touchedEnt;
idClipModel * touchedClipModel;
idAFBody * touchedByBody;
} afTouch_t;
class idAF {
public:
idAF( void );
~idAF( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetAnimator( idAnimator *a ) { animator = a; }
// RAVEN BEGIN
// ddynerman: purge constraints/joints before loading a new one
bool Load( idEntity *ent, const char *fileName, bool purgeAF = false );
// RAVEN END
bool IsLoaded( void ) const { return isLoaded && self != NULL; }
const char * GetName( void ) const { return name.c_str(); }
void SetupPose( idEntity *ent, int time );
void ChangePose( idEntity *ent, int time );
int EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const;
void Start( void );
void StartFromCurrentPose( int inheritVelocityTime );
void Stop( void );
void Rest( void );
bool IsActive( void ) const { return isActive; }
void SetConstraintPosition( const char *name, const idVec3 &pos );
idPhysics_AF * GetPhysics( void ) { return &physicsObj; }
const idPhysics_AF * GetPhysics( void ) const { return &physicsObj; }
idBounds GetBounds( void ) const;
bool UpdateAnimation( void );
void GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const;
void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
int BodyForClipModelId( int id ) const;
void SaveState( idDict &args ) const;
void LoadState( const idDict &args );
void AddBindConstraints( void );
void RemoveBindConstraints( void );
idPhysics_AF physicsObj; // articulated figure physics
bool TestSolid( void ) const;
protected:
idStr name; // name of the loaded .af file
idEntity * self; // entity using the animated model
idAnimator * animator; // animator on entity
int modifiedAnim; // anim to modify
idVec3 baseOrigin; // offset of base body relative to skeletal model origin
idMat3 baseAxis; // axis of base body relative to skeletal model origin
idList<jointConversion_t>jointMods; // list with transforms from skeletal model joints to articulated figure bodies
idList<int> jointBody; // table to find the nearest articulated figure body for a joint of the skeletal model
int poseTime; // last time the articulated figure was transformed to reflect the current animation pose
int restStartTime; // time the articulated figure came to rest
bool isLoaded; // true when the articulated figure is properly loaded
bool isActive; // true if the articulated figure physics is active
bool hasBindConstraints; // true if the bind constraints have been added
protected:
void SetBase( idAFBody *body, const idJointMat *joints );
void AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod );
bool LoadBody( const idDeclAF_Body *fb, const idJointMat *joints );
bool LoadConstraint( const idDeclAF_Constraint *fc );
};
#endif /* !__GAME_AF_H__ */

3203
source/game/AFEntity.cpp Normal file

File diff suppressed because it is too large Load diff

508
source/game/AFEntity.h Normal file
View file

@ -0,0 +1,508 @@
#ifndef __GAME_AFENTITY_H__
#define __GAME_AFENTITY_H__
/*
===============================================================================
idMultiModelAF
Entity using multiple separate visual models animated with a single
articulated figure. Only used for debugging!
===============================================================================
*/
const int GIB_DELAY = 200; // only gib this often to keep performace hits when blowing up several mobs
class idMultiModelAF : public idEntity {
public:
CLASS_PROTOTYPE( idMultiModelAF );
void Spawn( void );
~idMultiModelAF( void );
virtual void Think( void );
virtual void Present( void );
protected:
idPhysics_AF physicsObj;
void SetModelForId( int id, const idStr &modelName );
private:
idList<idRenderModel *> modelHandles;
idList<int> modelDefHandles;
};
/*
===============================================================================
idChain
Chain hanging down from the ceiling. Only used for debugging!
===============================================================================
*/
class idChain : public idMultiModelAF {
public:
CLASS_PROTOTYPE( idChain );
void Spawn( void );
protected:
void BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld = true );
};
/*
===============================================================================
idAFAttachment
===============================================================================
*/
typedef struct {
jointModTransform_t mod;
jointHandle_t from;
jointHandle_t to;
} copyJoints_t;
class idAFAttachment : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idAFAttachment );
idAFAttachment( void );
virtual ~idAFAttachment( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetBody ( idAnimatedEntity* body, const char *headModel, jointHandle_t damageJoint );
void SetDamageJoint ( jointHandle_t damageJoint );
void ClearBody ( void );
idEntity * GetBody ( void ) const;
virtual void Think ( void );
virtual void Hide ( void );
virtual void Show ( void );
// RAVEN BEGIN
// bdube: added channel
virtual bool UpdateAnimationControllers ( void );
void PlayIdleAnim( int channel, int blendTime );
// Returns the entity that should take damage for this entity
virtual idEntity* GetDamageEntity ( void );
// for getting th speaker position
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// jshepard: animations for heads
void Event_PlayAnim ( int channel, const char *animname );
// jdischler: animations for heads
void Event_PlayCycle ( int channel, const char *animname );
void Event_ClearAnims ( void );
// RAVEN END
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse, bool splash = false );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual bool CanPlayImpactEffect ( idEntity* attacker, idEntity* target );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
void SetCombatModel( void );
idClipModel * GetCombatModel( void ) const;
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
// Lipsync
int StartLipSyncing( const char *speechDecl );
void HandleLipSync( void );
void EndLipSyncing( void );
bool IsLipSyncing( void ) const;
void InitCopyJoints ( void );
void CopyJointsFromBody ( void );
bool GetNoPlayerImpactFX( void );
protected:
idEntityPtr<idAnimatedEntity> body;
idClipModel * combatModel; // render model for hit detection of head
int idleAnim;
jointHandle_t damageJoint;
jointHandle_t soundJoint;
int lipSyncAnim; // Anim that contains the visemes
class rvLipSyncData* lipSyncData; // The current instance of lip syncing data
idList<copyJoints_t> copyJoints; // copied from the body animation to the head model
bool noPlayerImpactFX;
};
// RAVEN BEGIN
// bdube: inlines
ID_INLINE bool idAFAttachment::IsLipSyncing( void ) const {
return !!lipSyncData;
}
ID_INLINE void idAFAttachment::SetDamageJoint ( jointHandle_t _damageJoint ) {
damageJoint = _damageJoint;
}
// RAVEN END
/*
===============================================================================
idAFEntity_Base
===============================================================================
*/
class idAFEntity_Base : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idAFEntity_Base );
idAFEntity_Base( void );
virtual ~idAFEntity_Base( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse, bool splash = false );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual bool CanPlayImpactEffect ( idEntity* attacker, idEntity* target );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool UpdateAnimationControllers( void );
virtual void FreeModelDef( void );
virtual bool LoadAF( const char* keyname = NULL );
bool IsActiveAF( void ) const { return af.IsActive(); }
const char * GetAFName( void ) const { return af.GetName(); }
idPhysics_AF * GetAFPhysics( void ) { return af.GetPhysics(); }
void SetCombatModel( void );
idClipModel * GetCombatModel( void ) const;
// contents of combatModel can be set to 0 or re-enabled (mp)
void SetCombatContents( bool enable );
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
int BodyForClipModelId( int id ) const;
void SaveState( idDict &args ) const;
void LoadState( const idDict &args );
void AddBindConstraints( void );
void RemoveBindConstraints( void );
virtual void ShowEditingDialog( void );
static void DropAFs( idEntity *ent, const char *type, idList<idEntity *> *list );
bool GetNoPlayerImpactFX( void );
protected:
idAF af; // articulated figure
idClipModel * combatModel; // render model for hit detection
int combatModelContents;
idVec3 spawnOrigin; // spawn origin
idMat3 spawnAxis; // rotation axis used when spawned
int nextSoundTime; // next time this can make a sound
bool noPlayerImpactFX;
void Event_SetConstraintPosition( const char *name, const idVec3 &pos );
};
/*
===============================================================================
idAFEntity_Gibbable
===============================================================================
*/
extern const idEventDef EV_Gib;
extern const idEventDef EV_Gibbed;
class idAFEntity_Gibbable : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_Gibbable );
idAFEntity_Gibbable( void );
~idAFEntity_Gibbable( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Present( void );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
protected:
idRenderModel * skeletonModel;
int skeletonModelDefHandle;
bool gibbed;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
void InitSkeletonModel( void );
void Event_Gib( const char *damageDefName );
};
/*
===============================================================================
idAFEntity_Generic
===============================================================================
*/
class idAFEntity_Generic : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAFEntity_Generic );
idAFEntity_Generic( void );
~idAFEntity_Generic( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void KeepRunningPhysics( void ) { keepRunningPhysics = true; }
private:
void Event_Activate( idEntity *activator );
bool keepRunningPhysics;
};
/*
===============================================================================
idAFEntity_WithAttachedHead
===============================================================================
*/
class idAFEntity_WithAttachedHead : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAFEntity_WithAttachedHead );
idAFEntity_WithAttachedHead();
~idAFEntity_WithAttachedHead();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void SetupHead( const char* headDefName = "" );
virtual void Think( void );
virtual void Hide( void );
virtual void Show( void );
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
protected:
virtual void Gib( const idVec3 &dir, const char *damageDefName );
idEntityPtr<idAFAttachment> head; // safe pointer to attached head
private:
void Event_Gib( const char *damageDefName );
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idAFEntity_Vehicle
===============================================================================
*/
class idAFEntity_Vehicle : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_Vehicle );
idAFEntity_Vehicle( void );
void Spawn( void );
void Use( idPlayer *player );
protected:
idPlayer * player;
jointHandle_t eyesJoint;
jointHandle_t steeringWheelJoint;
float wheelRadius;
float steerAngle;
float steerSpeed;
// const idDeclParticle * dustSmoke;
float GetSteerAngle( void );
};
/*
===============================================================================
idAFEntity_VehicleFourWheels
===============================================================================
*/
class idAFEntity_VehicleFourWheels : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleFourWheels );
idAFEntity_VehicleFourWheels( void );
void Spawn( void );
virtual void Think( void );
protected:
idAFBody * wheels[4];
idAFConstraint_Hinge * steering[2];
jointHandle_t wheelJoints[4];
float wheelAngles[4];
};
/*
===============================================================================
idAFEntity_VehicleSixWheels
===============================================================================
*/
class idAFEntity_VehicleSixWheels : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleSixWheels );
idAFEntity_VehicleSixWheels( void );
void Spawn( void );
virtual void Think( void );
private:
idAFBody * wheels[6];
idAFConstraint_Hinge * steering[4];
jointHandle_t wheelJoints[6];
float wheelAngles[6];
};
/*
===============================================================================
idAFEntity_SteamPipe
===============================================================================
*/
class idAFEntity_SteamPipe : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_SteamPipe );
idAFEntity_SteamPipe( void );
~idAFEntity_SteamPipe( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
int steamBody;
float steamForce;
float steamUpForce;
idForce_Constant force;
renderEntity_t steamRenderEntity;
qhandle_t steamModelDefHandle;
void InitSteamRenderEntity( void );
};
/*
===============================================================================
idAFEntity_ClawFourFingers
===============================================================================
*/
class idAFEntity_ClawFourFingers : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_ClawFourFingers );
idAFEntity_ClawFourFingers( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idAFConstraint_Hinge * fingers[4];
void Event_SetFingerAngle( float angle );
void Event_StopFingers( void );
};
// RAVEN BEGIN
// bdube: AFAttractor
/*
===============================================================================
idAFAttractor
===============================================================================
*/
class rvAFAttractor : public idEntity {
public:
CLASS_PROTOTYPE( rvAFAttractor );
rvAFAttractor( void ) { }
private:
};
// RAVEN END
#endif /* !__GAME_AFENTITY_H__ */

3855
source/game/Actor.cpp Normal file

File diff suppressed because it is too large Load diff

426
source/game/Actor.h Normal file
View file

@ -0,0 +1,426 @@
// RAVEN BEGIN
// bdube: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 09/30/2004
#ifndef __GAME_ACTOR_H__
#define __GAME_ACTOR_H__
/*
===============================================================================
idActor
===============================================================================
*/
extern const idEventDef AI_EnableEyeFocus;
extern const idEventDef AI_DisableEyeFocus;
extern const idEventDef EV_Footstep;
extern const idEventDef EV_FootstepLeft;
extern const idEventDef EV_FootstepRight;
extern const idEventDef EV_EnableWalkIK;
extern const idEventDef EV_DisableWalkIK;
extern const idEventDef EV_EnableLegIK;
extern const idEventDef EV_DisableLegIK;
extern const idEventDef AI_SetAnimPrefix;
extern const idEventDef AI_PlayAnim;
extern const idEventDef AI_PlayCycle;
extern const idEventDef AI_AnimDone;
extern const idEventDef AI_SetBlendFrames;
extern const idEventDef AI_GetBlendFrames;
extern const idEventDef AI_ScriptedMove;
extern const idEventDef AI_ScriptedDone;
extern const idEventDef AI_ScriptedStop;
// RAVEN BEGIN
// bdube: added flashlight
extern const idEventDef AI_Flashlight;
extern const idEventDef AI_EnterVehicle;
extern const idEventDef AI_ExitVehicle;
// nmckenzie:
extern const idEventDef AI_OverrideAnim;
extern const idEventDef AI_IdleAnim;
extern const idEventDef AI_SetState;
// jshepard: adjust animation speed
extern const idEventDef AI_SetAnimRate;
//MCG: damage over time
extern const idEventDef EV_DamageOverTime;
extern const idEventDef EV_DamageOverTimeEffect;
//MCG: script-callable joint crawl effect
extern const idEventDef EV_JointCrawlEffect;
// abahr:
extern const idEventDef AI_LookAt;
extern const idEventDef AI_FaceEnemy;
extern const idEventDef AI_FaceEntity;
extern const idEventDef AI_JumpDown;
extern const idEventDef AI_SetLeader;
// RAVEN END
class idAnimState {
public:
bool idleAnim;
int animBlendFrames;
int lastAnimBlendFrames; // allows override anims to blend based on the last transition time
public:
idAnimState();
~idAnimState();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Init( idEntity *owner, idAnimator *_animator, int animchannel );
void Shutdown( void );
void SetState ( const char *name, int blendFrames, int flags = 0 );
void PostState ( const char* name, int blendFrames = 0, int delay = 0, int flags = 0 );
void StopAnim( int frames );
void PlayAnim( int anim );
void CycleAnim( int anim );
void BecomeIdle( void );
bool UpdateState( void );
bool Disabled( void ) const;
void Enable( int blendFrames );
void Disable( void );
bool AnimDone( int blendFrames ) const;
bool IsIdle( void ) const;
animFlags_t GetAnimFlags( void ) const;
rvStateThread& GetStateThread ( void );
idAnimator * GetAnimator( void ) const {return animator;};
private:
// RAVEN BEGIN
// bdube: converted self to entity ptr so any entity can use it
idEntity * self;
// RAVEN END
idAnimator * animator;
int channel;
bool disabled;
rvStateThread stateThread;
};
ID_INLINE rvStateThread& idAnimState::GetStateThread ( void ) {
return stateThread;
}
class idAttachInfo {
public:
idEntityPtr<idEntity> ent;
int channel;
};
class idActor : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idActor );
int team;
idLinkList<idActor> teamNode;
int rank; // monsters don't fight back if the attacker's rank is higher
idMat3 viewAxis; // view axis of the actor
idLinkList<idActor> enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him
idLinkList<idActor> enemyList; // list of characters that have targeted the player as their enemy
public:
idActor( void );
virtual ~idActor( void );
void Spawn( void );
virtual void Restart( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Hide( void );
virtual void Show( void );
virtual int GetDefaultSurfaceType( void ) const;
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual bool LoadAF( const char* keyname = NULL, bool purgeAF = false );
void SetupBody( void );
virtual void CheckBlink( void );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// script state management
void ShutdownThreads ( void );
void UpdateState ( void );
virtual void OnStateThreadClear ( const char *statename, int flags = 0 );
void SetState ( const char *statename, int flags = 0 );
void PostState ( const char* statename, int delay = 0, int flags = 0 );
void InterruptState ( const char* statename, int delay = 0, int flags = 0 );
// vision testing
void SetEyeHeight( float height );
void SetChestHeight ( float height );
float EyeHeight( void ) const;
virtual idVec3 GetEyePosition( void ) const;
virtual idVec3 GetChestPosition ( void ) const;
idEntity* GetGroundEntity ( void ) const;
virtual idEntity* GetGroundElevator( idEntity* testElevator=NULL ) const;
void Present( void );
virtual void GetViewPos ( idVec3 &origin, idMat3 &axis ) const;
void SetFOV ( float fov, float fovClose );
bool CheckFOV ( const idVec3 &pos, float ang = -1.0f ) const;
virtual bool HasFOV ( idEntity *ent );
virtual bool CanSee ( const idEntity *ent, bool useFOV ) const;
virtual bool CanSeeFrom ( const idVec3& from, const idEntity *ent, bool useFOV ) const;
virtual bool CanSeeFrom ( const idVec3& from, const idVec3& toPos, bool useFOV ) const;
// damage
void SetupDamageGroups( void );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
// RAVEN BEGIN
// nmckenzie: a final hook in the middle of the damage function
virtual void AdjustHealthByDamage ( int inDamage ){health -= inDamage;}
// RAVEN END
virtual int GetDamageForLocation( int damage, int location );
const char * GetDamageGroup( int location );
void ClearPain( void );
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
// model/combat model/ragdoll
void SetCombatModel( void );
idClipModel * GetCombatModel( void ) const;
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
bool StartRagdoll( void );
void StopRagdoll( void );
virtual bool UpdateAnimationControllers( void );
// delta view angles to allow movers to rotate the view of the actor
const idAngles & GetDeltaViewAngles( void ) const;
void SetDeltaViewAngles( const idAngles &delta );
bool HasEnemies( void ) const;
idActor * ClosestEnemyToPoint( const idVec3 &pos, float maxRange=0.0f, bool returnFirst=false, bool checkPVS=false );
idActor * EnemyWithMostHealth();
virtual bool OnLadder ( void ) const;
virtual void OnStateChange ( int channel );
virtual void OnFriendlyFire ( idActor* attacker );
virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const;
void Attach( idEntity *ent );
idEntity* FindAttachment( const char* attachmentName );
void HideAttachment( const char* attachmentName );
void ShowAttachment( const char* attachmentName );
idEntity* GetHead() { return head; }
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
virtual renderView_t * GetRenderView();
// Animation
int PlayAnim ( int channel, const char *name, int blendFrames );
bool PlayCycle ( int channel, const char *name, int blendFrames );
void IdleAnim ( int channel, const char *name, int blendFrames );
void OverrideAnim ( int channel );
bool HasAnim ( int channel, const char *name, bool forcePrefix = false );
int GetAnim ( int channel, const char *name, bool forcePrefix = false );
bool AnimDone ( int channel, int blendFrames );
// animation state control
void UpdateAnimState ( void );
void SetAnimState ( int channel, const char *name, int blendFrames = 0, int flags = 0 );
void PostAnimState ( int channel, const char *name, int blendFrames = 0, int delay = 0, int flags = 0 );
void StopAnimState ( int channel );
bool InAnimState ( int channel, const char *name );
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
// RAVEN BEGIN
// bdube: added for vehicle
bool IsInVehicle ( void ) const;
rvVehicleController& GetVehicleController ( void );
virtual void GuidedProjectileIncoming( idGuidedProjectile * projectile );
bool DebugFilter (const idCVar& test) const;
// RAVEN END
virtual bool IsCrouching ( void ) const {return false;};
virtual bool SkipImpulse( idEntity* ent, int id );
int lightningNextTime;
int lightningEffects;
protected:
friend class idAnimState;
float fovDot; // cos( fovDegrees )
float fovCloseDot; // cos( fovDegreesClose )
float fovCloseRange; // range within to use fovCloseDot
idVec3 eyeOffset; // offset of eye relative to physics origin
idVec3 chestOffset; // offset of chest relative to physics origin
idVec3 modelOffset; // offset of visual model relative to the physics origin
idAngles deltaViewAngles; // delta angles relative to view input angles
int pain_debounce_time; // next time the actor can show pain
int pain_delay; // time between playing pain sound
idStrList damageGroups; // body damage groups
idList<float> damageScale; // damage scale per damage gruop
bool inDamageEvent; // hacky-ass bool to prevent us from starting a new EV_DamageOverTime in our ::Damage
bool use_combat_bbox; // whether to use the bounding box for combat collision
// joint handles
jointHandle_t leftEyeJoint;
jointHandle_t rightEyeJoint;
jointHandle_t soundJoint;
jointHandle_t eyeOffsetJoint;
jointHandle_t chestOffsetJoint;
jointHandle_t neckJoint;
jointHandle_t headJoint;
idIK_Walk walkIK;
idStr animPrefix;
idStr painType;
idStr painAnim;
// blinking
int blink_anim;
int blink_time;
int blink_min;
int blink_max;
idAnimState headAnim;
idAnimState torsoAnim;
idAnimState legsAnim;
rvStateThread stateThread;
idEntityPtr<idAFAttachment> head; // safe pointer to attached head
bool disablePain;
bool allowEyeFocus;
bool finalBoss;
int painTime;
idList<idAttachInfo> attachments;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
void CheckDeathObjectives( void );
// RAVEN BEGIN
// bdube: vehicles
virtual bool EnterVehicle ( idEntity* vehicle );
virtual bool ExitVehicle ( bool force = false );
// RAVEN END
// removes attachments with "remove" set for when character dies
void RemoveAttachments( void );
// RAVEN BEGIN
// bdube: vehicles
rvVehicleController vehicleController;
// bdube: flashlights
renderLight_t flashlight;
int flashlightHandle;
jointHandle_t flashlightJoint;
idVec3 flashlightOffset;
// bdube: death force
int deathPushTime;
idVec3 deathPushForce;
jointHandle_t deathPushJoint;
void FlashlightUpdate ( bool forceOn = false );
void InitDeathPush ( const idVec3& dir, int location, const idDict* damageDict, float pushScale = 1.0f );
void DeathPush ( void );
// Add some dynamic externals for debugging
virtual void GetDebugInfo ( debugInfoProc_t proc, void* userData );
// RAVEN END
protected:
virtual void FootStep ( void );
virtual void SetupHead( const char* headDefName = "", idVec3 headOffset = idVec3(0, 0, 0) );
private:
void SyncAnimChannels( int channel, int syncToChannel, int blendFrames );
void FinishSetup( void );
void Event_EnableEyeFocus( void );
void Event_DisableEyeFocus( void );
void Event_EnableBlink( void );
void Event_DisableBlink( void );
void Event_Footstep( void );
void Event_EnableWalkIK( void );
void Event_DisableWalkIK( void );
void Event_EnableLegIK( int num );
void Event_DisableLegIK( int num );
void Event_SetAnimPrefix( const char *name );
void Event_LookAtEntity( idEntity *ent, float duration );
void Event_PreventPain( float duration );
void Event_DisablePain( void );
void Event_EnablePain( void );
void Event_StopAnim( int channel, int frames );
void Event_PlayAnim( int channel, const char *name );
void Event_PlayCycle( int channel, const char *name );
void Event_IdleAnim( int channel, const char *name );
void Event_SetSyncedAnimWeight( int channel, int anim, float weight );
void Event_OverrideAnim( int channel );
void Event_EnableAnim( int channel, int blendFrames );
void Event_SetBlendFrames( int channel, int blendFrames );
void Event_GetBlendFrames( int channel );
void Event_HasEnemies( void );
void Event_NextEnemy( idEntity *ent );
void Event_ClosestEnemyToPoint( const idVec3 &pos );
void Event_StopSound( int channel, int netsync );
void Event_GetHead( void );
void Event_Teleport ( idVec3 &newPos, idVec3 &newAngles );
void Event_Flashlight ( bool enable );
void Event_EnterVehicle ( idEntity* vehicle );
void Event_ExitVehicle ( bool force );
void Event_PreExitVehicle( bool force );
void Event_SetAnimRate ( float multiplier );
void Event_DamageOverTime ( int endTime, int interval, idEntity *inflictor, idEntity *attacker, idVec3 &dir, const char *damageDefName, const float damageScale, int location );
virtual void Event_DamageOverTimeEffect ( int endTime, int interval, const char *damageDefName );
void Event_JointCrawlEffect ( const char *effectKeyName, float crawlSecs );
CLASS_STATES_PROTOTYPE ( idActor );
protected:
// Wait states
stateResult_t State_Wait_LegsAnim ( const stateParms_t& parms );
stateResult_t State_Wait_TorsoAnim ( const stateParms_t& parms );
stateResult_t State_Wait_Frame ( const stateParms_t& parms );
void DisableAnimState ( int channel );
void EnableAnimState ( int channel );
idAnimState& GetAnimState ( int channel );
};
ID_INLINE bool idActor::IsInVehicle( void ) const {
return vehicleController.IsDriving();
}
ID_INLINE rvVehicleController& idActor::GetVehicleController( void ) {
return vehicleController;
}
#endif /* !__GAME_ACTOR_H__ */
// RAVEN END

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,103 @@
#ifndef __GAME_BRITTLEFRACTURE_H__
#define __GAME_BRITTLEFRACTURE_H__
/*
===============================================================================
B-rep Brittle Fracture - Static entity using the boundary representation
of the render model which can fracture.
===============================================================================
*/
typedef struct shard_s {
idClipModel * clipModel;
idFixedWinding winding;
idList<idFixedWinding *> decals;
idList<bool> edgeHasNeighbour;
idList<struct shard_s *> neighbours;
idPhysics_RigidBody physicsObj;
int droppedTime;
bool atEdge;
int islandNum;
} shard_t;
class idBrittleFracture : public idEntity {
public:
CLASS_PROTOTYPE( idBrittleFracture );
idBrittleFracture( void );
virtual ~idBrittleFracture( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Present( void );
virtual void Think( void );
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse, bool splash = false );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName );
bool IsBroken( void ) const;
enum {
EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS,
EVENT_SHATTER,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
// setttings
const idMaterial * material;
const idMaterial * decalMaterial;
float decalSize;
float maxShardArea;
float maxShatterRadius;
float minShatterRadius;
float linearVelocityScale;
float angularVelocityScale;
float shardMass;
float density;
float friction;
float bouncyness;
idStr fxFracture;
// state
idPhysics_StaticMulti physicsObj;
idList<shard_t *> shards;
idBounds bounds;
bool disableFracture;
// for rendering
mutable int lastRenderEntityUpdate;
mutable bool changed;
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
void AddShard( idClipModel *clipModel, idFixedWinding &w );
void RemoveShard( int index );
void DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time );
void Shatter( const idVec3 &point, const idVec3 &impulse, const int time );
void DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time );
void Break( void );
void Fracture_r( idFixedWinding &w );
void CreateFractures( const idRenderModel *renderModel );
void FindNeighbours( void );
void Event_Activate( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
};
#endif /* !__GAME_BRITTLEFRACTURE_H__ */

2208
source/game/Camera.cpp Normal file

File diff suppressed because it is too large Load diff

296
source/game/Camera.h Normal file
View file

@ -0,0 +1,296 @@
#ifndef __GAME_CAMERA_H__
#define __GAME_CAMERA_H__
/*
===============================================================================
Camera providing an alternative view of the level.
===============================================================================
*/
class idCamera : public idEntity {
public:
ABSTRACT_PROTOTYPE( idCamera );
void Spawn( void );
virtual void GetViewParms( renderView_t *view ) = 0;
virtual renderView_t * GetRenderView();
virtual void Stop( void ){} ;
};
/*
===============================================================================
idCameraView
===============================================================================
*/
extern const idEventDef EV_SetFOV;
extern const idEventDef EV_Camera_Start;
extern const idEventDef EV_Camera_Stop;
class idCameraView : public idCamera {
public:
CLASS_PROTOTYPE( idCameraView );
idCameraView();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn( );
virtual void GetViewParms( renderView_t *view );
virtual void Stop( void );
protected:
void Event_Activate( idEntity *activator );
void Event_SetAttachments();
void SetAttachment( idEntity **e, const char *p );
// RAVEN BEGIN
// bdube: changed fov to interpolated value
idInterpolate<float> fov;
// RAVEN END
idEntity *attachedTo;
idEntity *attachedView;
// RAVEN BEGIN
// bdube: added setfov event
void Event_SetFOV ( float fov );
void Event_BlendFOV ( float beginFOV, float endFOV, float blendTime );
void Event_GetFOV ( void );
// RAVEN END
};
/*
===============================================================================
A camera which follows a path defined by an animation.
===============================================================================
*/
// RAVEN BEGIN
// rjohnson: camera is now contained in a def for frame commands
/*
==============================================================================================
rvCameraAnimation
==============================================================================================
*/
class idDeclCameraDef;
typedef struct {
idCQuat q;
idVec3 t;
float fov;
} cameraFrame_t;
class rvCameraAnimation {
private:
idList<int> cameraCuts;
idList<cameraFrame_t> camera;
idList<frameLookup_t> frameLookup;
idList<frameCommand_t> frameCommands;
int frameRate;
idStr name;
idStr realname;
public:
rvCameraAnimation();
rvCameraAnimation( const idDeclCameraDef *cameraDef, const rvCameraAnimation *anim );
~rvCameraAnimation();
void SetAnim( const idDeclCameraDef *cameraDef, const char *sourcename, const char *animname, idStr filename );
const char *Name( void ) const;
const char *FullName( void ) const;
int NumFrames( void ) const;
const cameraFrame_t * GetAnim( int index ) const;
int NumCuts( void ) const;
const int GetCut( int index ) const;
const int GetFrameRate( void ) const;
const char *AddFrameCommand( const class idDeclCameraDef *cameraDef, const idList<int>& frames, idLexer &src, const idDict *def );
void CallFrameCommands( idEntity *ent, int from, int to ) const;
void CallFrameCommandSound ( const frameCommand_t& command, idEntity* ent, const s_channelType channel ) const;
};
ID_INLINE const cameraFrame_t *rvCameraAnimation::GetAnim( int index ) const {
return &camera[ index ];
}
ID_INLINE const int rvCameraAnimation::GetCut( int index ) const {
return cameraCuts[ index ];
}
ID_INLINE const int rvCameraAnimation::GetFrameRate( void ) const {
return frameRate;
}
/*
==============================================================================================
idDeclCameraDef
==============================================================================================
*/
// RAVEN BEGIN
// jsinger: added to support serialization/deserialization of binary decls
#ifdef RV_BINARYDECLS
class idDeclCameraDef : public idDecl, public Serializable<'IDCD'> {
public:
idDeclCameraDef( SerialInputStream &stream );
virtual void Write( SerialOutputStream &stream ) const;
virtual void AddReferences() const;
#else
class idDeclCameraDef : public idDecl {
#endif
// RAVEN END
public:
idDeclCameraDef();
~idDeclCameraDef();
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength, bool noCaching );
virtual void FreeData( void );
// RAVEN BEGIN
// jscott: to prevent a recursive crash
virtual bool RebuildTextSource( void ) { return( false ); }
// scork: for detailed error-reporting
virtual bool Validate( const char *psText, int iTextLength, idStr &strReportTo ) const;
// RAVEN END
void Touch( void ) const;
int NumAnims( void ) const;
const rvCameraAnimation * GetAnim( int index ) const;
int GetSpecificAnim( const char *name ) const;
int GetAnim( const char *name ) const;
bool HasAnim( const char *name ) const;
private:
void CopyDecl( const idDeclCameraDef *decl );
bool ParseAnim( idLexer &src, int numDefaultAnims );
private:
idList<rvCameraAnimation *> anims;
};
ID_INLINE const rvCameraAnimation *idDeclCameraDef::GetAnim( int index ) const {
if ( ( index < 1 ) || ( index > anims.Num() ) ) {
return NULL;
}
return anims[ index - 1 ];
}
/*
==============================================================================================
idCameraAnim
==============================================================================================
*/
class idCameraAnim : public idCamera {
public:
CLASS_PROTOTYPE( idCameraAnim );
idCameraAnim();
~idCameraAnim();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn( void );
virtual void GetViewParms( renderView_t *view );
private:
int threadNum;
idVec3 offset;
int starttime;
int cycle;
const idDeclCameraDef *cameraDef;
int lastFrame;
idEntityPtr<idEntity> activator;
void Start( void );
void Stop( void );
void Think( void );
void LoadAnim( void );
void Event_Start( void );
void Event_Stop( void );
void Event_SetCallback( void );
void Event_Activate( idEntity *activator );
// RAVEN BEGIN
// mekberg: wait support
void Event_IsActive( );
idList<dword> imageTable;
idList<int> imageCmds;
// RAVEN END
};
// RAVEN END
// RAVEN BEGIN
/*
===============================================================================
rvCameraPortalSky
===============================================================================
*/
// jscott: for portal skies
class rvCameraPortalSky : public idCamera {
public:
CLASS_PROTOTYPE( rvCameraPortalSky );
rvCameraPortalSky( void ) {}
~rvCameraPortalSky( void ) {}
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn( void );
virtual void GetViewParms( renderView_t *view );
};
/*
===============================================================================
rvCameraPlayback
===============================================================================
*/
class rvCameraPlayback : public idCamera {
public:
CLASS_PROTOTYPE( rvCameraPlayback );
rvCameraPlayback( void ) {}
~rvCameraPlayback( void ) {}
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn( void );
virtual void GetViewParms( renderView_t *view );
private:
int startTime;
const rvDeclPlayback *playback;
};
// RAVEN END
#endif /* !__GAME_CAMERA_H__ */

463
source/game/Effect.cpp Normal file
View file

@ -0,0 +1,463 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Effect.h"
#include "client/ClientEffect.h"
const idEventDef EV_LookAtTarget( "lookAtTarget", NULL );
const idEventDef EV_Attenuate( "attenuate", "f" );
CLASS_DECLARATION( idEntity, rvEffect )
EVENT( EV_Activate, rvEffect::Event_Activate )
EVENT( EV_LookAtTarget, rvEffect::Event_LookAtTarget )
EVENT( EV_Earthquake, rvEffect::Event_EarthQuake )
EVENT( EV_Camera_Start, rvEffect::Event_Start )
EVENT( EV_Camera_Stop, rvEffect::Event_Stop )
EVENT( EV_Attenuate, rvEffect::Event_Attenuate )
EVENT( EV_IsActive, rvEffect::Event_IsActive )
END_CLASS
/*
================
rvEffect::rvEffect
================
*/
rvEffect::rvEffect ( void ) {
fl.networkSync = true;
loop = false;
lookAtTarget = false;
effect = NULL;
endOrigin.Zero();
}
/*
================
rvEffect::Spawn
================
*/
void rvEffect::Spawn( void ) {
const char* fx;
if ( !spawnArgs.GetString ( "fx", "", &fx ) || !*fx ) {
if ( !( gameLocal.editors & EDITOR_FX ) ) {
gameLocal.Warning ( "no effect file specified on effect entity '%s'", name.c_str() );
PostEventMS ( &EV_Remove, 0 );
return;
}
} else {
effect = ( const idDecl * )declManager->FindEffect( spawnArgs.GetString ( "fx" ) );
if( effect->IsImplicit() ) {
common->Warning( "Unknown effect \'%s\' on entity \'%s\'", spawnArgs.GetString ( "fx" ), GetName() );
}
}
spawnArgs.GetVector ( "endOrigin", "0 0 0", endOrigin );
spawnArgs.GetBool ( "loop", "0", loop );
// If look at target is set the effect will continually update itself to look at its target
spawnArgs.GetBool( "lookAtTarget", "0", lookAtTarget );
renderEntity.shaderParms[SHADERPARM_ALPHA] = spawnArgs.GetFloat ( "_alpha", "1" );
renderEntity.shaderParms[SHADERPARM_BRIGHTNESS] = spawnArgs.GetFloat ( "_brightness", "1" );
if( spawnArgs.GetBool( "start_on", loop ? "1" : "0" ) ) {
ProcessEvent( &EV_Activate, this );
}
#if 0
// If anyone ever gets around to a flood fill from the origin rather than the over generous PushVolumeIntoTree bounds,
// this warning will become useful. Until then, it's a bogus warning.
if( gameRenderWorld->PointInArea( GetPhysics()->GetOrigin() ) < 0 ) {
common->Warning( "Effect \'%s\' out of world", name.c_str() );
}
#endif
}
/*
================
rvEffect::Think
================
*/
void rvEffect::Think( void ) {
if( clientEntities.IsListEmpty ( ) ) {
BecomeInactive( TH_THINK );
// Should the func_fx be removed now?
if( !(gameLocal.editors & EDITOR_FX) && spawnArgs.GetBool( "remove" ) ) {
PostEventMS( &EV_Remove, 0 );
}
return;
}
else if( lookAtTarget ) {
// If activated and looking at its target then update the target information
ProcessEvent( &EV_LookAtTarget );
}
UpdateVisuals();
Present ( );
}
/*
================
rvEffect::Save
================
*/
void rvEffect::Save( idSaveGame *savefile ) const {
savefile->WriteBool( loop );
savefile->WriteBool( lookAtTarget );
savefile->WriteString( effect->GetName() );
savefile->WriteVec3( endOrigin );
clientEffect.Save( savefile );
}
/*
================
rvEffect::Restore
================
*/
void rvEffect::Restore( idRestoreGame *savefile ) {
idStr name;
savefile->ReadBool( loop );
savefile->ReadBool( lookAtTarget );
savefile->ReadString( name );
effect = declManager->FindType( DECL_EFFECT, name );
savefile->ReadVec3( endOrigin );
clientEffect.Restore( savefile );
}
/*
================
rvEffect::Think
================
*/
void rvEffect::Stop( bool destroyParticles ) {
StopEffect ( effect, destroyParticles );
}
/*
================
rvEffect::Play
================
*/
bool rvEffect::Play( void ) {
clientEffect = PlayEffect ( effect, renderEntity.origin, renderEntity.axis, loop, endOrigin );
if ( clientEffect ) {
idVec4 color;
color[0] = renderEntity.shaderParms[SHADERPARM_RED];
color[1] = renderEntity.shaderParms[SHADERPARM_GREEN];
color[2] = renderEntity.shaderParms[SHADERPARM_BLUE];
color[3] = renderEntity.shaderParms[SHADERPARM_ALPHA];
clientEffect->SetColor ( color );
clientEffect->SetBrightness ( renderEntity.shaderParms[ SHADERPARM_BRIGHTNESS ] );
clientEffect->SetAmbient( true );
BecomeActive ( TH_THINK );
return true;
}
return false;
}
/*
================
rvEffect::Attenuate
================
*/
void rvEffect::Attenuate ( float attenuation ) {
rvClientEntity* cent;
for( cent = clientEntities.Next(); cent != NULL; cent = cent->spawnNode.Next() ) {
// RAVEN BEGIN
// jnewquist: Use accessor for static class type
if ( cent->IsType ( rvClientEffect::GetClassType() ) ) {
// RAVEN END
static_cast<rvClientEffect*>(cent)->Attenuate ( attenuation );
}
}
}
/*
================
rvEffect::Restart
================
*/
void rvEffect::Restart( void ) {
Stop( false );
if( loop ) {
Play();
}
}
/*
================
rvEffect::UpdateChangeableSpawnArgs
================
*/
void rvEffect::UpdateChangeableSpawnArgs( const idDict *source ) {
const char* fx;
const idDecl *newEffect;
bool newLoop;
idEntity::UpdateChangeableSpawnArgs(source);
if ( !source ) {
return;
}
if ( source->GetString ( "fx", "", &fx ) && *fx ) {
newEffect = ( const idDecl * )declManager->FindEffect( fx );
} else {
newEffect = NULL;
}
idVec3 color;
source->GetVector( "_color", "1 1 1", color );
renderEntity.shaderParms[ SHADERPARM_RED ] = color[0];
renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[1];
renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[2];
renderEntity.shaderParms[ SHADERPARM_ALPHA ] = source->GetFloat ( "_alpha", "1" );
renderEntity.shaderParms[ SHADERPARM_BRIGHTNESS ] = source->GetFloat ( "_brightness", "1" );
if ( clientEffect ) {
clientEffect->SetColor ( idVec4(color[0],color[1],color[2],renderEntity.shaderParms[ SHADERPARM_ALPHA ]) );
clientEffect->SetBrightness ( renderEntity.shaderParms[ SHADERPARM_BRIGHTNESS ] );
}
source->GetBool ( "loop", "0", newLoop );
spawnArgs.Copy( *source );
// IF the effect handle has changed or the loop status has changed then restart the effect
if ( newEffect != effect || loop != newLoop ) {
Stop ( false );
loop = newLoop;
effect = newEffect;
if ( effect ) {
Play ( );
BecomeActive( TH_THINK );
UpdateVisuals();
} else {
BecomeInactive ( TH_THINK );
UpdateVisuals();
}
}
}
/*
===============
rvEffect::ShowEditingDialog
===============
*/
void rvEffect::ShowEditingDialog( void ) {
common->InitTool( EDITOR_FX, &spawnArgs );
}
/*
=================
rvEffect::WriteToSnapshot
=================
*/
void rvEffect::WriteToSnapshot( idBitMsgDelta &msg ) const {
GetPhysics()->WriteToSnapshot( msg );
WriteBindToSnapshot( msg );
idGameLocal::WriteDecl( msg, effect );
msg.WriteBits( loop, 1 );
}
/*
=================
rvEffect::ReadFromSnapshot
=================
*/
void rvEffect::ReadFromSnapshot( const idBitMsgDelta &msg ) {
const idDecl *old = effect;
GetPhysics()->ReadFromSnapshot( msg );
ReadBindFromSnapshot( msg );
effect = idGameLocal::ReadDecl( msg, DECL_EFFECT );
loop = ( msg.ReadBits( 1 ) != 0 );
if ( effect && !old ) {
// TODO: need to account for when the effect really started
Play();
}
}
/*
=================
rvEffect::ClientPredictionThink
=================
*/
void rvEffect::ClientPredictionThink( void ) {
if ( gameLocal.isNewFrame ) {
Think ( );
}
RunPhysics();
Present();
}
/*
================
rvEffect::Event_Start
================
*/
void rvEffect::Event_Start ( void ) {
if( !effect || !clientEntities.IsListEmpty ( ) ) {
return;
}
if( !Play() ) {
if ( gameLocal.isMultiplayer && !gameLocal.isClient && !gameLocal.isListenServer ) {
// no effects on dedicated server
} else {
gameLocal.Warning( "Unable to play effect '%s'", effect->GetName() );
}
BecomeInactive ( TH_THINK );
}
ProcessEvent( &EV_LookAtTarget );
}
/*
================
rvEffect::Event_Stop
================
*/
void rvEffect::Event_Stop ( void ) {
if( !effect ) {
return;
}
Stop( false );
}
/*
=================
rvEffect::Event_Activate
=================
*/
void rvEffect::Event_Activate( idEntity *activator ) {
// Stop the effect if its already playing
if( !clientEntities.IsListEmpty ( ) ) {
Event_Stop ( );
} else {
Event_Start ( );
}
ActivateTargets( activator );
}
/*
================
rvEffect::Event_LookAtTarget
Reorients the effect entity towards its target and sets the end origin as well
================
*/
void rvEffect::Event_LookAtTarget ( void ) {
const idKeyValue *kv;
idVec3 dir;
if ( !effect || !clientEffect ) {
return;
}
kv = spawnArgs.MatchPrefix( "target", NULL );
while( kv ) {
idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
if( ent ) {
if( !idStr::Icmp( ent->GetEntityDefName(), "target_null" ) ) {
dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
dir.Normalize();
clientEffect->SetEndOrigin ( ent->GetPhysics()->GetOrigin() );
clientEffect->SetAxis ( dir.ToMat3( ) );
return;
}
}
kv = spawnArgs.MatchPrefix( "target", kv );
}
}
/*
================
rvEffect::Event_EarthQuake
================
*/
void rvEffect::Event_EarthQuake ( float requiresLOS ) {
float quakeChance;
if ( !spawnArgs.GetFloat("quakeChance", "0", quakeChance) ) {
return;
}
if ( rvRandom::flrand(0, 1.0f) > quakeChance ) {
// failed its activation roll
return;
}
if ( requiresLOS ) {
// if the player doesn't have line of sight to this fx, don't do anything
trace_t trace;
idPlayer *player = gameLocal.GetLocalPlayer();
idVec3 viewOrigin;
idMat3 viewAxis;
player->GetViewPos(viewOrigin, viewAxis);
// RAVEN BEGIN
// ddynerman: multiple collision worlds
gameLocal.TracePoint( this, trace, viewOrigin, GetPhysics()->GetOrigin(), MASK_OPAQUE, player );
// RAVEN END
if (trace.fraction < 1.0f)
{
// something blocked LOS
return;
}
}
// activate this effect now
ProcessEvent ( &EV_Activate, gameLocal.entities[ENTITYNUM_WORLD] );
}
/*
================
rvEffect::Event_Attenuate
================
*/
void rvEffect::Event_Attenuate( float attenuation ) {
Attenuate( attenuation );
}
/*
================
rvEffect::Event_Attenuate
================
*/
void rvEffect::Event_IsActive( void ) {
idThread::ReturnFloat( ( !effect || !clientEntities.IsListEmpty() ) ? 0.0f : 1.0f );
}
/*
================
rvEffect::InstanceLeave
================
*/
void rvEffect::InstanceLeave( void ) {
idEntity::InstanceLeave();
Stop( true );
}
/*
================
rvEffect::InstanceJoin
================
*/
void rvEffect::InstanceJoin( void ) {
idEntity::InstanceJoin();
Restart();
}

66
source/game/Effect.h Normal file
View file

@ -0,0 +1,66 @@
//----------------------------------------------------------------
// Effect.h
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#ifndef __GAME_EFFECT_H__
#define __GAME_EFFECT_H__
class rvEffect : public idEntity
{
public:
CLASS_PROTOTYPE( rvEffect );
rvEffect ( void );
const bool GetEndOrigin ( idVec3 &result ) const;
void SetEndOrigin ( const idVec3 &origin );
void Spawn ( void );
void Think ( void );
void Save ( idSaveGame *savefile ) const;
void Restore ( idRestoreGame *savefile );
bool Play ( void );
void Stop ( bool destroyParticles = false );
void Restart ( void );
void Attenuate ( float attenuation );
float GetBrightness ( void ) const;
bool IsLooping ( void ) { return( loop ); }
virtual void UpdateChangeableSpawnArgs ( const idDict *source );
virtual void ShowEditingDialog ( void );
virtual void WriteToSnapshot ( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot ( const idBitMsgDelta &msg );
void ClientPredictionThink ( void );
virtual void InstanceLeave ( void );
virtual void InstanceJoin ( void );
protected:
bool loop;
bool lookAtTarget;
const idDecl *effect;
idVec3 endOrigin;
rvClientEntityPtr<rvClientEffect> clientEffect;
private:
void Event_Activate ( idEntity *activator );
void Event_LookAtTarget ( void );
void Event_EarthQuake ( float requiresLOS );
void Event_Start ( void );
void Event_Stop ( void );
void Event_Attenuate ( float attenuation );
void Event_IsActive ( void );
};
#endif // __GAME_EFFECT_H__

6789
source/game/Entity.cpp Normal file

File diff suppressed because it is too large Load diff

849
source/game/Entity.h Normal file
View file

@ -0,0 +1,849 @@
#ifndef __GAME_ENTITY_H__
#define __GAME_ENTITY_H__
/*
===============================================================================
Game entity base class.
===============================================================================
*/
static const int DELAY_DORMANT_TIME = 3000;
extern const idEventDef EV_PostSpawn;
extern const idEventDef EV_FindTargets;
extern const idEventDef EV_Touch;
extern const idEventDef EV_Use;
extern const idEventDef EV_Activate;
extern const idEventDef EV_ActivateTargets;
extern const idEventDef EV_Hide;
extern const idEventDef EV_Show;
extern const idEventDef EV_GetShaderParm;
extern const idEventDef EV_SetShaderParm;
extern const idEventDef EV_SetOwner;
extern const idEventDef EV_GetAngles;
extern const idEventDef EV_SetAngles;
extern const idEventDef EV_SetLinearVelocity;
extern const idEventDef EV_SetAngularVelocity;
extern const idEventDef EV_SetSkin;
extern const idEventDef EV_StartSoundShader;
extern const idEventDef EV_StopSound;
extern const idEventDef EV_CacheSoundShader;
// RAVEN BEGIN
extern const idEventDef EV_CallFunction;
extern const idEventDef EV_SetGuiParm;
extern const idEventDef EV_SetGuiFloat;
extern const idEventDef EV_ClearSkin;
// bdube: more global events for idEntity
extern const idEventDef EV_GetFloatKey;
extern const idEventDef EV_HideSurface;
extern const idEventDef EV_ShowSurface;
extern const idEventDef EV_GuiEvent;
extern const idEventDef EV_StopAllEffects;
extern const idEventDef EV_PlayEffect;
extern const idEventDef EV_Earthquake;
extern const idEventDef EV_GuiEvent;
extern const idEventDef EV_SetKey;
// jscott:
extern const idEventDef EV_PlaybackCallback;
// jshepard:
extern const idEventDef EV_UnbindTargets;
// twhitaker:
extern const idEventDef EV_ApplyImpulse;
// RAVEN END
class idGuidedProjectile;
// Think flags
enum {
TH_ALL = -1,
TH_THINK = 1, // run think function each frame
TH_PHYSICS = 2, // run physics each frame
TH_ANIMATE = 4, // update animation each frame
TH_UPDATEVISUALS = 8, // update renderEntity
};
//
// Signals
// make sure to change script/doom_defs.script if you add any, or change their order
//
typedef enum {
SIG_TOUCH, // object was touched
SIG_USE, // object was used
SIG_TRIGGER, // object was activated
SIG_REMOVED, // object was removed from the game
SIG_DAMAGE, // object was damaged
SIG_BLOCKED, // object was blocked
SIG_MOVER_POS1, // mover at position 1 (door closed)
SIG_MOVER_POS2, // mover at position 2 (door open)
SIG_MOVER_1TO2, // mover changing from position 1 to 2
SIG_MOVER_2TO1, // mover changing from position 2 to 1
// RAVEN BEGIN
// kfuller: added signals
// WARNING: these entries are mirrored in scripts/defs.script so make sure if they move
// here that they move there as well
SIG_REACHED, // object reached it's rotation/motion destination
// RAVEN END
NUM_SIGNALS
} signalNum_t;
// FIXME: At some point we may want to just limit it to one thread per signal, but
// for now, I'm allowing multiple threads. We should reevaluate this later in the project
#define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16
struct signal_t {
int threadnum;
const function_t *function;
};
class signalList_t {
public:
idList<signal_t> signal[ NUM_SIGNALS ];
};
class idEntity : public idClass {
public:
static const int MAX_PVS_AREAS = 4;
int entityNumber; // index into the entity list
int entityDefNumber; // index into the entity def list
idLinkList<idEntity> spawnNode; // for being linked into spawnedEntities list
idLinkList<idEntity> activeNode; // for being linked into activeEntities list
idLinkList<idEntity> snapshotNode; // for being linked into snapshotEntities list
int snapshotSequence; // last snapshot this entity was in
int snapshotBits; // number of bits this entity occupied in the last snapshot
idStr name; // name of entity
idDict spawnArgs; // key/value pairs used to spawn and initialize entity
idScriptObject scriptObject; // contains all script defined data for this entity
int thinkFlags; // TH_? flags
int dormantStart; // time that the entity was first closed off from player
bool cinematic; // during cinematics, entity will only think if cinematic is set
renderView_t * renderView; // for camera views from this entity
idEntity * cameraTarget; // any remoteRenderMap shaders will use this
idList< idEntityPtr<idEntity> > targets; // when this entity is activated these entities entity are activated
int health; // FIXME: do all objects really need health?
// RAVEN BEGIN
// ddynerman: optional pre-prediction
int predictTime;
// bdube: client entities
idLinkList<rvClientEntity> clientEntities;
// rjohnson: will now draw entity info for long thinkers
int mLastLongThinkTime;
idVec4 mLastLongThinkColor;
// RAVEN END
struct entityFlags_s {
bool notarget :1; // if true never attack or target this entity
bool noknockback :1; // if true no knockback from hits
bool takedamage :1; // if true this entity can be damaged
bool hidden :1; // if true this entity is not visible
bool bindOrientated :1; // if true both the master orientation is used for binding
bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities
bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not
bool selected :1; // if true the entity is selected for editing
bool neverDormant :1; // if true the entity never goes dormant
bool isDormant :1; // if true the entity is dormant
bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected
bool networkSync :1; // if true the entity is synchronized over the network
// RAVEN BEGIN
// bdube: added
bool networkStale :1; // was in the snapshot but isnt anymore
// bgeisler: added block
bool triggerAnim :1;
bool usable :1; // if true the entity is usable by the player
// cdr: Obstacle Avoidance
bool isAIObstacle :1; // if true, this entity will add itself to the obstacles list in each aas area it touches
// RAVEN END
// RAVEN BEGIN
// ddynerman: exclude this entity from instance-purging
// twhitaker: moved variable to be within the bit flags
bool persistAcrossInstances :1;
// twhitaker: exited vehicle already?
bool exitedVehicle :1;
// twhitaker: blinking
bool allowAutoBlink :1;
// jshepard: instant burnout when destroyed
bool quickBurn :1;
// RAVEN END
} fl;
public:
ABSTRACT_PROTOTYPE( idEntity );
idEntity();
~idEntity();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
const char * GetEntityDefName( void ) const;
void SetName( const char *name );
const char * GetName( void ) const;
virtual void UpdateChangeableSpawnArgs( const idDict *source );
// clients generate views based on all the player specific options,
// cameras have custom code, and everything else just uses the axis orientation
virtual renderView_t * GetRenderView();
// thinking
virtual void Think( void );
bool CheckDormant( void ); // dormant == on the active list, but out of PVS
virtual void DormantBegin( void ); // called when entity becomes dormant
virtual void DormantEnd( void ); // called when entity wakes from being dormant
bool IsActive( void ) const;
void BecomeActive( int flags );
void BecomeInactive( int flags );
void UpdatePVSAreas( const idVec3 &pos );
// RAVEN BEGIN
// abahr:
bool IsActive( int flags ) const { return (flags & thinkFlags) > 0; }
const char* GetEntityDefClassName() const { return spawnArgs.GetString("classname"); }
bool IsEntityDefClass( const char* className ) const { return !idStr::Icmp(className, GetEntityDefClassName()); }
virtual void GetPosition( idVec3& origin, idMat3& axis ) const;
// kfuller: added methods
virtual void GetLocalAngles(idAngles &localAng);
// RAVEN END
// visuals
virtual void Present( void );
// instance visuals
virtual void InstanceJoin( void );
virtual void InstanceLeave( void );
// RAVEN BEGIN
// bdube: removed virtual so it could be inlined
renderEntity_t * GetRenderEntity( void );
int GetModelDefHandle( void );
// RAVEN END
virtual void SetModel( const char *modelname );
void SetSkin( const idDeclSkin *skin );
const idDeclSkin * GetSkin( void ) const;
// RAVEN BEGIN
// bdube: surfaces
void HideSurface ( const char* surface );
void ShowSurface ( const char* surface );
void ClearSkin( void );
// RAVEN END
void SetShaderParm( int parmnum, float value );
virtual void SetColor( float red, float green, float blue );
virtual void SetColor( const idVec3 &color );
virtual void GetColor( idVec3 &out ) const;
virtual void SetColor( const idVec4 &color );
virtual void GetColor( idVec4 &out ) const;
virtual void FreeModelDef( void );
virtual void FreeLightDef( void );
virtual void Hide( void );
virtual void Show( void );
bool IsHidden( void ) const;
void UpdateVisuals( void );
void UpdateModel( void );
// RAVEN BEGIN
// abahr: added virtual to UpdateModelTransform
virtual
void UpdateModelTransform( void );
virtual void UpdateRenderEntityCallback();
virtual const idAnimator * GetAnimator( void ) const { return NULL; } // returns animator object used by this entity
// RAVEN END
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
int GetNumPVSAreas( void );
const int * GetPVSAreas( void );
void ClearPVSAreas( void );
bool PhysicsTeamInPVS( pvsHandle_t pvsHandle );
// animation
virtual bool UpdateAnimationControllers( void );
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
virtual idAnimator * GetAnimator( void ); // returns animator object used by this entity
// sound
virtual bool CanPlayChatterSounds( void ) const;
bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds
void SetSoundVolume( float volume );
void UpdateSound( void );
int GetListenerId( void ) const;
// RAVEN BEGIN
int GetSoundEmitter( void ) const;
// RAVEN END
void FreeSoundEmitter( bool immediate );
// RAVEN BEGIN
// bdube: added effect functions
// effects
rvClientEffect* PlayEffect ( const char* effectName, jointHandle_t joint, const idVec3& originOffset, const idMat3& axisOffset, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
rvClientEffect* PlayEffect ( const idDecl *effect, jointHandle_t joint, const idVec3& originOffset, const idMat3& axisOffset, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
rvClientEffect* PlayEffect ( const char* effectName, jointHandle_t joint, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
rvClientEffect* PlayEffect ( const char* effectName, const idVec3& origin, const idMat3& axis, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
rvClientEffect* PlayEffect ( const idDecl *effect, const idVec3& origin, const idMat3& axis, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
void StopEffect ( const char* effectName, bool destroyParticles = false );
void StopEffect ( const idDecl *effect, bool destroyParticles = false );
void StopAllEffects ( bool destroyParticles = false );
void UpdateEffects ( void );
float DistanceTo ( idEntity* ent );
float DistanceTo ( const idVec3& pos ) const;
float DistanceTo2d ( idEntity* ent );
float DistanceTo2d ( const idVec3& pos ) const;
virtual bool CanTakeDamage ( void ) const;
// RAVEN END
// entity binding
virtual void PreBind( void );
virtual void PostBind( void );
virtual void PreUnbind( void );
virtual void PostUnbind( void );
void JoinTeam( idEntity *teammember );
void Bind( idEntity *master, bool orientated );
void BindToJoint( idEntity *master, const char *jointname, bool orientated );
void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated );
void BindToBody( idEntity *master, int bodyId, bool orientated );
void Unbind( void );
bool IsBound( void ) const;
// RAVEN BEGIN
// abahr: added const so it can be called from const functions
bool IsBoundTo( const idEntity *master ) const;
// RAVEN END
idEntity * GetBindMaster( void ) const;
jointHandle_t GetBindJoint( void ) const;
int GetBindBody( void ) const;
idEntity * GetTeamMaster( void ) const;
idEntity * GetNextTeamEntity( void ) const;
// RAVEN BEGIN
// abahr: added virtual
virtual
void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis );
// RAVEN END
idVec3 GetLocalVector( const idVec3 &vec ) const;
idVec3 GetLocalCoordinates( const idVec3 &vec ) const;
idVec3 GetWorldVector( const idVec3 &vec ) const;
idVec3 GetWorldCoordinates( const idVec3 &vec ) const;
virtual bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const;
void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const;
// physics
// set a new physics object to be used by this entity
void SetPhysics( idPhysics *phys );
// get the physics object used by this entity
idPhysics * GetPhysics( void ) const;
// restore physics pointer for save games
void RestorePhysics( idPhysics *phys );
// run the physics for this entity
bool RunPhysics( void );
// set the origin of the physics object (relative to bindMaster if not NULL)
void SetOrigin( const idVec3 &org );
// set the axis of the physics object (relative to bindMaster if not NULL)
void SetAxis( const idMat3 &axis );
// use angles to set the axis of the physics object (relative to bindMaster if not NULL)
void SetAngles( const idAngles &ang );
// get the floor position underneath the physics object
bool GetFloorPos( float max_dist, idVec3 &floorpos ) const;
// retrieves the transformation going from the physics origin/axis to the visual origin/axis
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
// retrieves the transformation going from the physics origin/axis to the sound origin/axis
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// called from the physics object when colliding, should return true if the physics simulation should stop
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity, bool &hitTeleporter ) { hitTeleporter = false; return Collide(collision, velocity); }
// retrieves impact information, 'ent' is the entity retrieving the info
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
// apply an impulse to the physics object, 'ent' is the entity applying the impulse
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse, bool splash = false );
// add a force to the physics object, 'ent' is the entity adding the force
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
// activate the physics object, 'ent' is the entity activating this entity
virtual void ActivatePhysics( idEntity *ent );
// returns true if the physics object is at rest
virtual bool IsAtRest( void ) const;
// returns the time the physics object came to rest
virtual int GetRestStartTime( void ) const;
// add a contact entity
virtual void AddContactEntity( idEntity *ent );
// remove a touching entity
virtual void RemoveContactEntity( idEntity *ent );
// RAVEN BEGIN
// kfuller: added blocked methods
virtual void LastBlockedBy(int blockedEntNum) {}
virtual int GetLastBlocker(void) { return -1; }
// rjohnson: moved entity info out of idGameLocal into its own function
virtual void DrawDebugEntityInfo( idBounds *viewBounds = 0, idBounds *viewTextBounds = 0, idVec4 *overrideColor = 0 );
// nmckenzie: Adding ability for non-Actors to be enemies for AI characters. Rename this function at some point, most likely.
virtual idVec3 GetEyePosition( void ) const { return GetPhysics()->GetOrigin(); }
// abahr:
virtual bool SkipImpulse( idEntity *ent, int id );
virtual void ApplyImpulse( idEntity* ent, int id, const idVec3& point, const idVec3& dir, const idDict* damageDef );
// RAVEN END
// damage
// RAVEN BEGIN
// twhitaker: // Sets the damage enitty
void SetDamageEntity ( idEntity * forward ) { forwardDamageEnt = forward; }
// bdube: added ignore entity
// Returns the entity that should take damage for this entity
virtual idEntity* GetDamageEntity ( void );
// returns true if this entity can be damaged from the given origin
virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint, idEntity* ignoreEnt = NULL ) const;
// RAVEN END
// applies damage to this entity
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
// adds a damage effect like overlays, blood, sparks, debris etc.
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
virtual bool CanPlayImpactEffect ( idEntity* attacker, idEntity* target );
// callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller.
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
// notifies this entity that it is in pain
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// notifies this entity that is has been killed
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// scripting
virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
virtual idThread * ConstructScriptObject( void );
virtual void DeconstructScriptObject( void );
void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function );
void ClearSignal( idThread *thread, signalNum_t signalnum );
void ClearSignalThread( signalNum_t signalnum, idThread *thread );
bool HasSignal( signalNum_t signalnum ) const;
void Signal( signalNum_t signalnum );
void SignalEvent( idThread *thread, signalNum_t signalnum );
// gui
void TriggerGuis( void );
bool HandleGuiCommands( idEntity *entityGui, const char *cmds );
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
// targets
// RAVEN BEGIN
// abahr: made virtual
virtual
void FindTargets( void );
virtual
void RemoveNullTargets( void );
virtual
void ActivateTargets( idEntity *activator ) const;
// jshepard: unbind targets
void UnbindTargets( idEntity *activator ) const;
// RAVEN END
// RAVEN BEGIN
// twhitaker: Add to the list of targets (usually from script)
int AppendTarget( idEntity *appendMe );
void RemoveTarget( idEntity *removeMe );
void RemoveTargets( bool destroyContents );
// RAVEN END
// misc
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
bool TouchTriggers( const idTypeInfo* ownerType = NULL ) const;
idCurve_Spline<idVec3> *GetSpline( void ) const;
virtual void ShowEditingDialog( void );
enum {
EVENT_STARTSOUNDSHADER,
EVENT_STOPSOUNDSHADER,
// RAVEN BEGIN
// bdube: new events
EVENT_PLAYEFFECT,
EVENT_PLAYEFFECT_JOINT,
EVENT_STOPEFFECT,
// RAVEN END
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
// RAVEN BEGIN
// the entity was not in the snapshot sent by server. means it either went out of PVS, or was deleted server side
// return true if the entity wishes to be deleted locally
// depending on the entity, understanding stale as just another state, or a removal is best
// ( by default, idEntity keeps the entity around after a little cleanup )
virtual bool ClientStale( void );
virtual void ClientUnstale( void );
// RAVEN END
void WriteBindToSnapshot( idBitMsgDelta &msg ) const;
void ReadBindFromSnapshot( const idBitMsgDelta &msg );
void WriteColorToSnapshot( idBitMsgDelta &msg ) const;
void ReadColorFromSnapshot( const idBitMsgDelta &msg );
void WriteGUIToSnapshot( idBitMsgDelta &msg ) const;
void ReadGUIFromSnapshot( const idBitMsgDelta &msg );
void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
void ServerSendInstanceEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
// RAVEN BEGIN
// bdube: debugging
virtual void GetDebugInfo( debugInfoProc_t proc, void* userData );
// mwhitlock: memory profiling
virtual size_t Size( void ) const;
// ddynerman: multiple arenas (for MP)
virtual void SetInstance( int newInstance );
virtual int GetInstance( void ) const;
// ddynerman: multiple clip world support
virtual int GetClipWorld( void ) const;
virtual void SetClipWorld( int newCW );
// scork: accessors so sound editor can indicate current-highlit ent
virtual int GetRefSoundShaderFlags( void ) const;
virtual void SetRefSoundShaderFlags( int iFlags );
// twhitaker: guided projectiles
virtual void GuidedProjectileIncoming( idGuidedProjectile * projectile ) { }
// RAVEN END
protected:
renderEntity_t renderEntity; // used to present a model to the renderer
int modelDefHandle; // handle to static renderer model
refSound_t refSound; // used to present sound to the audio engine
idEntityPtr< idEntity > forwardDamageEnt; // damage applied to the invoking object will be forwarded to this entity
idEntityPtr< idEntity > bindMaster; // entity bound to if unequal NULL
jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT
private:
idPhysics_Static defaultPhysicsObj; // default physics object
idPhysics * physics; // physics used for this entity
int bindBody; // body bound to if unequal -1
idEntity * teamMaster; // master of the physics team
idEntity * teamChain; // next entity in physics team
int numPVSAreas; // number of renderer areas the entity covers
int PVSAreas[MAX_PVS_AREAS]; // numbers of the renderer areas the entity covers
signalList_t * signals;
int mpGUIState; // local cache to avoid systematic SetStateInt
// RAVEN BEGIN
// abahr: changed to protected for access in children classes
protected:
// ddynerman: multiple game instances
int instance;
// ddynerman: multiple collision worlds
int clipWorld;
// RAVEN END
// RAVEN BEGIN
// bdube: made virtual
virtual bool DoDormantTests( void ); // dormant == on the active list, but out of PVS
// RAVEN END
// physics
// initialize the default physics
void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis );
// update visual position from the physics
void UpdateFromPhysics( bool moveBack );
// entity binding
bool InitBind( idEntity *master ); // initialize an entity binding
void FinishBind( void ); // finish an entity binding
void RemoveBinds( void ); // deletes any entities bound to this object
void QuitTeam( void ); // leave the current team
void UpdatePVSAreas( void );
// RAVEN BEGIN
// bdube: client entities
void RemoveClientEntities ( void ); // deletes any client entities bound to this object
// RAVEN END
// events
void Event_GetName( void );
void Event_SetName( const char *name );
void Event_FindTargets( void );
void Event_ActivateTargets( idEntity *activator );
void Event_NumTargets( void );
void Event_GetTarget( float index );
void Event_RandomTarget( const char *ignore );
void Event_Bind( idEntity *master );
void Event_BindPosition( idEntity *master );
void Event_BindToJoint( idEntity *master, const char *jointname, float orientated );
void Event_Unbind( void );
void Event_RemoveBinds( void );
void Event_SpawnBind( void );
void Event_SetOwner( idEntity *owner );
void Event_SetModel( const char *modelname );
void Event_SetSkin( const char *skinname );
void Event_GetShaderParm( int parmnum );
void Event_SetShaderParm( int parmnum, float value );
void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 );
void Event_SetColor( float red, float green, float blue );
void Event_GetColor( void );
void Event_IsHidden( void );
void Event_Hide( void );
void Event_Show( void );
void Event_CacheSoundShader( const char *soundName );
void Event_StartSoundShader( const char *soundName, int channel );
void Event_StopSound( int channel, int netSync );
void Event_StartSound( const char *soundName, int channel, int netSync );
void Event_FadeSound( int channel, float to, float over );
void Event_GetWorldOrigin( void );
void Event_SetWorldOrigin( idVec3 const &org );
void Event_GetOrigin( void );
void Event_SetOrigin( const idVec3 &org );
void Event_GetAngles( void );
void Event_SetAngles( const idAngles &ang );
void Event_SetLinearVelocity( const idVec3 &velocity );
void Event_GetLinearVelocity( void );
void Event_SetAngularVelocity( const idVec3 &velocity );
void Event_GetAngularVelocity( void );
void Event_SetSize( const idVec3 &mins, const idVec3 &maxs );
void Event_GetSize( void );
void Event_GetMins( void );
void Event_GetMaxs( void );
void Event_Touches( idEntity *ent );
void Event_SetGuiParm( const char *key, const char *val );
void Event_SetGuiFloat( const char *key, float f );
void Event_GetNextKey( const char *prefix, const char *lastMatch );
void Event_SetKey( const char *key, const char *value );
void Event_GetKey( const char *key );
void Event_GetIntKey( const char *key );
void Event_GetFloatKey( const char *key );
void Event_GetVectorKey( const char *key );
void Event_GetEntityKey( const char *key );
void Event_RestorePosition( void );
void Event_UpdateCameraTarget( void );
void Event_DistanceTo( idEntity *ent );
void Event_DistanceToPoint( const idVec3 &point );
void Event_StartFx( const char *fx );
void Event_WaitFrame( void );
void Event_Wait( float time );
void Event_HasFunction( const char *name );
void Event_CallFunction( const char *name );
void Event_SetNeverDormant( int enable );
// RAVEN BEGIN
// kfuller: added events
void Event_SetContents ( int contents );
void Event_GetLastBlocker ( idThread *thread );
// begisler: added
void Event_ClearSkin ( void );
// bdube: effect events
void Event_PlayEffect ( const char* effectName, const char* boneName, bool loop );
void Event_StopEffect ( const char* effectName );
void Event_StopAllEffects ( void );
void Event_GetHealth ( void );
// bdube: mesh events
void Event_ShowSurface ( const char* surface );
void Event_HideSurface ( const char* surface );
// bdube: gui events
void Event_GuiEvent ( const char* eventName );
// jscott:
void Event_PlaybackCallback ( int type, int changed, int impulse );
// nmckenzie: get bind master
void Event_GetBindMaster ( void );
void Event_ApplyImpulse ( idEntity *source, const idVec3 &point, const idVec3 &impulse );
// jshepard: unbind all targets
void Event_UnbindTargets ( idEntity *activator);
// abahr:
void Event_RemoveNullTargets ();
void Event_IsA ( const char* entityDefName );
void Event_IsSameTypeAs ( const idEntity* ent );
void Event_MatchPrefix ( const char *prefix, const char* previousKey );
void Event_ClearTargetList ( float destroyContents );
// twhitaker: added - to add targets from script
void Event_AppendTarget ( idEntity *appendMe );
void Event_RemoveTarget ( idEntity *removeMe );
// mekberg: added
void Event_SetHealth ( float newHealth );
// RAVEN END
};
// RAVEN BEGIN
// bdube: added inlines
ID_INLINE rvClientEffect* idEntity::PlayEffect( const char* effectName, const idVec3& origin, const idMat3& axis, bool loop, const idVec3& endOrigin,
bool broadcast, effectCategory_t category, const idVec4& effectTint ) {
return PlayEffect( gameLocal.GetEffect( spawnArgs, effectName ), origin, axis, loop, endOrigin, broadcast, category, effectTint );
}
ID_INLINE rvClientEffect* idEntity::PlayEffect( const char* effectName, jointHandle_t jointHandle, bool loop, const idVec3& endOrigin,
bool broadcast, effectCategory_t category, const idVec4& effectTint ) {
return PlayEffect( gameLocal.GetEffect( spawnArgs, effectName ), jointHandle, vec3_origin, mat3_identity, loop, endOrigin, broadcast, category, effectTint );
}
ID_INLINE rvClientEffect* idEntity::PlayEffect( const char* effectName, jointHandle_t jointHandle, const idVec3& originOffset, const idMat3& axisOffset, bool loop, const idVec3& endOrigin,
bool broadcast, effectCategory_t category, const idVec4& effectTint ) {
return PlayEffect( gameLocal.GetEffect( spawnArgs, effectName ), jointHandle, originOffset, axisOffset, loop, endOrigin, broadcast, category, effectTint );
}
ID_INLINE idPhysics *idEntity::GetPhysics( void ) const {
return physics;
}
ID_INLINE renderEntity_t *idEntity::GetRenderEntity( void ) {
return &renderEntity;
}
ID_INLINE int idEntity::GetModelDefHandle( void ) {
return modelDefHandle;
}
// scork: accessors so sound editor can indicate current-highlit ent
ID_INLINE int idEntity::GetRefSoundShaderFlags( void ) const
{
return refSound.parms.soundShaderFlags;
}
ID_INLINE void idEntity::SetRefSoundShaderFlags( int iFlags )
{
refSound.parms.soundShaderFlags = iFlags;
}
// RAVEN END
/*
===============================================================================
Animated entity base class.
===============================================================================
*/
typedef struct damageEffect_s {
jointHandle_t jointNum;
idVec3 localOrigin;
idVec3 localNormal;
int time;
// RAVEN BEGIN
// jscott: not using
// const idDeclParticle* type;
// RAVEN END
struct damageEffect_s * next;
} damageEffect_t;
class idAnimatedEntity : public idEntity {
public:
CLASS_PROTOTYPE( idAnimatedEntity );
idAnimatedEntity();
~idAnimatedEntity();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void ClientPredictionThink( void );
virtual void Think( void );
void UpdateAnimation( void );
virtual idAnimator * GetAnimator( void );
virtual void SetModel( const char *modelname );
bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const;
virtual int GetDefaultSurfaceType( void ) const;
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
virtual void ProjectHeadOverlay( const idVec3 &point, const idVec3 &dir, float size, const char *decal ) {}
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
// RAVEN BEGIN
// abahr:
virtual const idAnimator * GetAnimator( void ) const { return &animator; }
virtual void UpdateRenderEntityCallback();
// RAVEN BEGIN
enum {
EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
protected:
idAnimator animator;
damageEffect_t * damageEffects;
// RAVEN BEGIN
// jshepard:
void Event_ClearAnims ( void );
// RAVEN END
private:
void Event_GetJointHandle( const char *jointname );
void Event_ClearAllJoints( void );
void Event_ClearJoint( jointHandle_t jointnum );
void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
void Event_GetJointPos( jointHandle_t jointnum );
void Event_GetJointAngle( jointHandle_t jointnum );
// RAVEN BEGIN
// bdube: programmer controlled joint events
void Event_SetJointAngularVelocity ( const char* jointName, float pitch, float yaw, float roll, int blendTime );
void Event_CollapseJoints ( const char* jointnames, const char* collapseTo );
// RAVEN END
};
// RAVEN BEGIN
void UpdateGuiParms( idUserInterface *gui, const idDict *args );
// RAVEN END
ID_INLINE float idEntity::DistanceTo ( idEntity* ent ) {
return DistanceTo ( ent->GetPhysics()->GetOrigin() );
}
ID_INLINE float idEntity::DistanceTo ( const idVec3& pos ) const {
return (pos - GetPhysics()->GetOrigin()).LengthFast ( );
}
ID_INLINE float idEntity::DistanceTo2d ( idEntity* ent ) {
return DistanceTo2d ( ent->GetPhysics()->GetOrigin() );
}
ID_INLINE bool idEntity::CanTakeDamage ( void ) const {
return fl.takedamage;
}
// RAVEN BEGIN
// ddynerman: MP arena stuff
ID_INLINE int idEntity::GetInstance( void ) const {
return instance;
}
// ddynerman: multiple collision worlds
ID_INLINE int idEntity::GetClipWorld( void ) const {
return clipWorld;
}
ID_INLINE void idEntity::SetClipWorld( int newCW ) {
clipWorld = newCW;
if( GetPhysics() ) {
GetPhysics()->UnlinkClip();
GetPhysics()->LinkClip();
}
}
// RAVEN END
#endif /* !__GAME_ENTITY_H__ */

165
source/game/FreeView.cpp Normal file
View file

@ -0,0 +1,165 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
/*
===============
idFreeView::~idFreeView
===============
*/
idFreeView::~idFreeView() {
if ( physics ) {
delete physics;
physics = NULL;
}
}
/*
===============
idFreeView::SetFreeView
===============
*/
void idFreeView::SetFreeView( int clientNum ) {
trace_t trace;
idPlayer *p;
idVec3 start, end;
idClip *clipWorld;
if ( !physics ) {
Setup();
}
p = static_cast<idPlayer*>( gameLocal.entities[ clientNum ] );
if ( !p ) {
PickRandomSpawn();
return;
}
start = p->GetEyePosition();
end = start; end[2] += 20.0f;
clipWorld = gameLocal.GetEntityClipWorld( p );
if ( clipWorld ) {
clipWorld->Translation( trace, start, end, physics->GetClipModel(), mat3_identity, MASK_PLAYERSOLID, NULL, NULL );
physics->SetOrigin( trace.endpos );
} else {
assert( false );
physics->SetOrigin( start );
}
viewAngles = p->viewAngles;
viewAngles[2] = 0.0f;
snapAngle = true;
}
/*
===============
idFreeView::PickRandomSpawn
===============
*/
void idFreeView::PickRandomSpawn( void ) {
if ( !physics ) {
Setup();
}
idPlayerStart *start = gameLocal.RandomSpawn();
physics->SetOrigin( start->GetPhysics()->GetOrigin() + idVec3( 0.0f, 0.0f, pm_normalheight.GetFloat() ) );
viewAngles = start->GetPhysics()->GetAxis().ToAngles();
snapAngle = true;
}
/*
===============
idFreeView::Fly
===============
*/
void idFreeView::Fly( const usercmd_t &ucmd ) {
idAngles src;
assert( physics );
src[0] = SHORT2ANGLE( ucmd.angles[0] );
src[1] = SHORT2ANGLE( ucmd.angles[1] );
src[2] = 0.0f;
if ( snapAngle ) {
viewAngleOffset = viewAngles - src;
snapAngle = false;
}
viewAngles = src + viewAngleOffset;
physics->SetPlayerInput( ucmd, viewAngles );
physics->Evaluate( gameLocal.time - gameLocal.previousTime, gameLocal.time );
}
/*
===============
idFreeView::Draw
===============
*/
void idFreeView::Draw( void ) {
assert( physics );
view.vieworg = physics->PlayerGetOrigin();
view.viewaxis = viewAngles.ToMat3();
view.time = gameLocal.time;
gameLocal.CalcFov( g_fov.GetFloat(), view.fov_x, view.fov_y );
// free flying demo client rendering
gameLocal.mpGame.SetShaderParms( &view );
// FIXME: player hud? draw scoreboard?
soundSystem->PlaceListener( view.vieworg, view.viewaxis, 0, gameLocal.time, "Undefined" );
// from idPlayerView::SingleView
idCamera *portalSky = gameLocal.GetPortalSky();
if ( portalSky ) {
renderView_t portalSkyView = view;
portalSky->GetViewParms( &portalSkyView );
gameRenderWorld->RenderScene( &portalSkyView, RF_DEFER_COMMAND_SUBMIT | RF_PORTAL_SKY );
}
gameRenderWorld->RenderScene( &view, RF_PRIMARY_VIEW );
}
/*
===============
idFreeView::Setup
===============
*/
void idFreeView::Setup( void ) {
idClipModel *clip;
idBounds b;
assert( !physics );
memset( &view, 0, sizeof( view ) );
view.viewID = 0;
view.x = view.y = 0;
view.width = 640;
view.height = 480;
gameLocal.CalcFov( g_fov.GetFloat(), view.fov_x, view.fov_y );
view.cramZNear = false;
b = idBounds( vec3_origin ).Expand( pm_spectatebbox.GetFloat() * 0.5f );
clip = new idClipModel( idTraceModel( b ), declManager->FindMaterial( "textures/flesh_boundingbox" ) );
physics = new idPhysics_Player();
physics->SetSpeed( pm_spectatespeed.GetFloat(), pm_crouchspeed.GetFloat() );
physics->SetClipModelNoLink( clip );
physics->SetClipMask( MASK_PLAYERSOLID );
physics->SetMovementType( PM_SPECTATOR );
}
/*
===============
idFreeView::Shutdown
===============
*/
void idFreeView::Shutdown( void ) {
if ( physics ) {
delete physics;
physics = NULL;
}
}
/*
===============
idFreeView::GetOrigin
===============
*/
const idVec3 &idFreeView::GetOrigin( void ) {
return view.vieworg;
}

42
source/game/FreeView.h Normal file
View file

@ -0,0 +1,42 @@
#ifndef __FREEVIEW_H__
#define __FREEVIEW_H__
class idPhysics_Player;
class idFreeView {
public:
idFreeView() { physics = NULL; snapAngle = false; }
~idFreeView();
// start free flying from this client's current position
void SetFreeView( int clientNum );
// pick a random spawn in the map
void PickRandomSpawn( void );
// update view and position
void Fly( const usercmd_t &ucmd );
void Draw( void );
bool Initialized( void ) const { return physics != NULL; }
void Shutdown( void );
const idVec3 & GetOrigin( void );
private:
void Setup( void );
renderView_t view;
idPhysics_Player *physics;
idAngles viewAngles;
bool snapAngle;
idAngles viewAngleOffset;
};
#endif

2
source/game/Game.def Normal file
View file

@ -0,0 +1,2 @@
EXPORTS
GetGameAPI

718
source/game/Game.h Normal file
View file

@ -0,0 +1,718 @@
#ifndef __GAME_H__
#define __GAME_H__
/*
===============================================================================
Public game interface with methods to run the game.
===============================================================================
*/
// RAVEN BEGIN
// bgeisler: moved into scripts directory
// default scripts
#define SCRIPT_DEFAULTDEFS "scripts/defs.script"
#define SCRIPT_DEFAULT "scripts/main.script"
// RAVEN END
#define SCRIPT_DEFAULTFUNC "doom_main"
struct gameReturn_t {
char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc
int consistencyHash; // used to check for network game divergence
int health;
int heartRate;
int stamina;
int combat;
bool syncNextGameFrame; // used when cinematics are skipped to prevent session from simulating several game frames to
// keep the game time in sync with real time
};
enum allowReply_t {
ALLOW_YES = 0,
ALLOW_BADPASS, // core will prompt for password and connect again
ALLOW_NOTYET, // core will wait with transmitted message
ALLOW_NO // core will abort with transmitted message
};
enum escReply_t {
ESC_IGNORE = 0, // do nothing
ESC_MAIN, // start main menu GUI
ESC_GUI // set an explicit GUI
};
enum demoState_t {
DEMO_NONE,
DEMO_RECORDING,
DEMO_PLAYING
};
enum demoReliableGameMessage_t {
DEMO_RECORD_CLIENTNUM,
DEMO_RECORD_EXCLUDE,
DEMO_RECORD_COUNT
};
//
// these defines work for all startsounds from all entity types
// make sure to change script/doom_defs.script if you add any channels, or change their order
//
typedef enum {
SND_CHANNEL_ANY = SCHANNEL_ANY,
SND_CHANNEL_VOICE = SCHANNEL_ONE,
SND_CHANNEL_VOICE2,
SND_CHANNEL_BODY,
SND_CHANNEL_BODY2,
SND_CHANNEL_BODY3,
SND_CHANNEL_WEAPON,
SND_CHANNEL_ITEM,
SND_CHANNEL_HEART,
SND_CHANNEL_DEMONIC,
SND_CHANNEL_RADIO,
// internal use only. not exposed to script or framecommands.
SND_CHANNEL_AMBIENT,
SND_CHANNEL_DAMAGE
// RAVEN BEGIN
// bdube: added custom to tell us where the end of the predefined list is
,
SND_CHANNEL_POWERUP,
SND_CHANNEL_POWERUP_IDLE,
SND_CHANNEL_MP_ANNOUNCER,
SND_CHANNEL_CUSTOM
// RAVEN END
} gameSoundChannel_t;
// RAVEN BEGIN
// bdube: forward reference
class rvClientEffect;
// RAVEN END
struct ClientStats_t {
bool isLastPredictFrame;
bool isLagged;
bool isNewFrame;
};
typedef struct userOrigin_s {
idVec3 origin;
int followClient;
} userOrigin_t;
class idGame {
public:
virtual ~idGame() {}
// Initialize the game for the first time.
// RAVEN BEGIN
// jsinger: attempt to eliminate cross-DLL allocation issues
#ifdef RV_UNIFIED_ALLOCATOR
virtual void Init( void *(*allocator)( size_t size ), void (*deallocator)( void *ptr ), size_t (*msize)( void *ptr ) ) = 0;
#else
virtual void Init( void ) = 0;
#endif
// Shut down the entire game.
virtual void Shutdown( void ) = 0;
// Set the local client number. Distinguishes listen ( == 0 ) / dedicated ( == -1 )
virtual void SetLocalClient( int clientNum ) = 0;
// Sets the user info for a client.
// The game can modify the user info in the returned dictionary pointer, server will forward back.
virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient ) = 0;
// Retrieve the game's userInfo dict for a client.
virtual const idDict * GetUserInfo( int clientNum ) = 0;
// Sets the user info for a viewer.
// The game can modify the user info in the returned dictionary pointer.
virtual const idDict * RepeaterSetUserInfo( int clientNum, const idDict &userInfo ) = 0;
// Checks to see if a client is active
virtual bool IsClientActive( int clientNum ) = 0;
// The game gets a chance to alter userinfo before they are emitted to server.
virtual void ThrottleUserInfo( void ) = 0;
// Sets the serverinfo at map loads and when it changes.
virtual void SetServerInfo( const idDict &serverInfo ) = 0;
// The session calls this before moving the single player game to a new level.
virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0;
// The session calls this right before a new level is loaded.
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) = 0;
// Loads a map and spawns all the entities.
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, bool isServer, bool isClient, int randseed ) = 0;
// Loads a map from a savegame file.
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idFile *saveGameFile ) = 0;
// Saves the current game state, the session may have written some data to the file already.
// RAVEN BEGIN
// mekberg: added saveTypes
virtual void SaveGame( idFile *saveGameFile, saveType_t saveType = ST_REGULAR ) = 0;
// RAVEN END
// Shut down the current map.
virtual void MapShutdown( void ) = 0;
// Caches media referenced from in key/value pairs in the given dictionary.
virtual void CacheDictionaryMedia( const idDict *dict ) = 0;
// Spawns the player entity to be used by the client.
virtual void SpawnPlayer( int clientNum ) = 0;
// RAVEN BEGIN
// Runs a game frame, may return a session command for level changing, etc
// lastCatchupFrame is always true except if we are running several game frames in a row and this one is not the last one
// subsystems which can tolerate skipping frames will not run during those catchup frames
// several game frames in a row happen when game + renderer time goes above the tick time ( 16ms )
virtual gameReturn_t RunFrame( const usercmd_t *clientCmds, int activeEditors, bool lastCatchupFrame, int serverGameFrame ) = 0;
virtual void MenuFrame( void ) = 0;
// RAVEN END
// Runs a repeater frame
virtual void RepeaterFrame( const userOrigin_t *clientOrigins, bool lastCatchupFrame, int serverGameFrame ) = 0;
// Makes rendering and sound system calls to display for a given clientNum.
virtual bool Draw( int clientNum ) = 0;
// Let the game do it's own UI when ESCAPE is used
virtual escReply_t HandleESC( idUserInterface **gui ) = 0;
// get the games menu if appropriate ( multiplayer )
virtual idUserInterface * StartMenu() = 0;
// When the game is running it's own UI fullscreen, GUI commands are passed through here
// return NULL once the fullscreen UI mode should stop, or "main" to go to main menu
virtual const char * HandleGuiCommands( const char *menuCommand ) = 0;
// main menu commands not caught in the engine are passed here
virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) = 0;
// Early check to deny connect.
virtual allowReply_t ServerAllowClient( int clientId, int numClients, const char *IP, const char *guid, const char *password, const char *privatePassword, char reason[MAX_STRING_CHARS] ) = 0;
// Connects a client.
virtual void ServerClientConnect( int clientNum, const char *guid ) = 0;
// Spawns the player entity to be used by the client.
virtual void ServerClientBegin( int clientNum ) = 0;
// Disconnects a client and removes the player entity from the game.
virtual void ServerClientDisconnect( int clientNum ) = 0;
// Writes initial reliable messages a client needs to recieve when first joining the game.
virtual void ServerWriteInitialReliableMessages( int clientNum ) = 0;
// Early check to deny connect.
virtual allowReply_t RepeaterAllowClient( int clientId, int numClients, const char *IP, const char *guid, bool repeater, const char *password, const char *privatePassword, char reason[MAX_STRING_CHARS] ) = 0;
// Connects a client.
virtual void RepeaterClientConnect( int clientNum ) = 0;
// Spawns the player entity to be used by the client.
virtual void RepeaterClientBegin( int clientNum ) = 0;
// Disconnects a client and removes the player entity from the game.
virtual void RepeaterClientDisconnect( int clientNum ) = 0;
// Writes initial reliable messages a client needs to recieve when first joining the game.
virtual void RepeaterWriteInitialReliableMessages( int clientNum ) = 0;
// Writes a snapshot of the server game state for the given client.
virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, dword *clientInPVS, int numPVSClients, int lastSnapshotFrame ) = 0;
// Patches the network entity states at the server with a snapshot for the given client.
virtual bool ServerApplySnapshot( int clientNum, int sequence ) = 0;
// Processes a reliable message from a client.
virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0;
// Patches the network entity states at the server with a snapshot for the given client.
virtual bool RepeaterApplySnapshot( int clientNum, int sequence ) = 0;
// Processes a reliable message from a client.
virtual void RepeaterProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0;
// Reads a snapshot and updates the client game state.
virtual void ClientReadSnapshot( int clientNum, int snapshotSequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) = 0;
// Patches the network entity states at the client with a snapshot.
virtual bool ClientApplySnapshot( int clientNum, int sequence ) = 0;
// Processes a reliable message from the server.
virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0;
// Runs prediction on entities at the client.
virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame = true, ClientStats_t *cs = NULL ) = 0;
// RAVEN BEGIN
// ddynerman: client game frame
virtual void ClientRun( void ) = 0;
virtual void ClientEndFrame( void ) = 0;
// jshepard: rcon password check
virtual void ProcessRconReturn( bool success ) = 0;
// RAVEN END
virtual bool ValidateServerSettings( const char *map, const char *gameType ) = 0;
// Returns a summary of stats for a given client
virtual void GetClientStats( int clientNum, char *data, const int len ) = 0;
// Switch a player to a particular team
virtual void SwitchTeam( int clientNum, int team ) = 0;
virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) = 0;
// return true to allow download from the built-in http server
virtual bool HTTPRequest( const char *IP, const char *file, bool isGamePak ) = 0;
// RAVEN BEGIN
// jscott: for the effects system
virtual void StartViewEffect( int type, float time, float scale ) = 0;
virtual rvClientEffect* PlayEffect( const idDecl *effect, const idVec3& origin, const idMat3& axis, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, bool predictBit = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one ) = 0;
virtual void GetPlayerView( idVec3 &origin, idMat3 &axis ) = 0;
virtual const idVec3 GetCurrentGravity( const idVec3& origin, const idMat3& axis ) const = 0;
virtual void Translation( trace_t &trace, idVec3 &source, idVec3 &dest, idTraceModel *trm, int clipMask ) = 0;
virtual void SpawnClientMoveable ( const char* name, int lifetime, const idVec3& origin, const idMat3& axis, const idVec3& velocity, const idVec3& angular_velocity ) = 0;
// bdube: debugging stuff
virtual void DebugSetString ( const char* name, const char* value ) = 0;
virtual void DebugSetFloat ( const char* name, float value ) = 0;
virtual void DebugSetInt ( const char* name, int value ) = 0;
virtual const char* DebugGetStatString ( const char* name ) = 0;
virtual int DebugGetStatInt ( const char* name ) = 0;
virtual float DebugGetStatFloat ( const char* name ) = 0;
virtual bool IsDebugHudActive ( void ) const = 0;
// rjohnson: for new note taking mechanism
virtual bool GetPlayerInfo( idVec3 &origin, idMat3 &axis, int PlayerNum = -1, idAngles *deltaViewAngles = NULL, int reqClientNum = -1 ) = 0;
virtual void SetPlayerInfo( idVec3 &origin, idMat3 &axis, int PlayerNum = -1 ) = 0;
virtual bool PlayerChatDisabled( int clientNum ) = 0;
virtual void SetViewComments( const char *text = 0 ) = 0;
// ddynerman: utility functions
virtual void GetPlayerName( int clientNum, char* name ) = 0;
virtual void GetPlayerClan( int clientNum, char* clan ) = 0;
virtual void SetFriend( int clientNum, bool isFriend ) = 0;
virtual const char* GetLongGametypeName( const char* gametype ) = 0;
virtual void ReceiveRemoteConsoleOutput( const char* output ) = 0;
// rjohnson: entity usage stats
virtual void ListEntityStats( const idCmdArgs &args ) = 0;
// shouchard: for ban lists
virtual void RegisterClientGuid( int clientNum, const char *guid ) = 0;
virtual bool IsMultiplayer( void ) = 0;
// mekberg: added
virtual bool InCinematic( void ) = 0;
// mekberg: so banlist can be populated outside of multiplayer game
virtual void PopulateBanList( idUserInterface* hud ) = 0;
virtual void RemoveGuidFromBanList( const char *guid ) = 0;
// mekberg: interface
virtual void AddGuidToBanList( const char *guid ) = 0;
virtual const char* GetGuidByClientNum( int clientNum ) = 0;
// jshepard: updating player post-menu
virtual void UpdatePlayerPostMainMenu( void ) = 0;
virtual void ResetRconGuiStatus( void ) = 0;
// RAVEN END
// RAVEN BEGIN
// mwhitlock: Dynamic memory consolidation
#if defined(_RV_MEM_SYS_SUPPORT)
virtual void FlushBeforelevelLoad( void ) = 0;
#endif
// RAVEN END
// Set the demo state.
virtual void SetDemoState( demoState_t state, bool serverDemo, bool timeDemo ) = 0;
// Set the repeater state; engine will call this with true for isRepeater if this is a repeater, and true for serverIsRepeater if we are connected to a repeater
virtual void SetRepeaterState( bool isRepeater, bool serverIsRepeater ) = 0;
// Writes current network info to a file (used as initial state for demo recording).
virtual void WriteNetworkInfo( idFile* file, int clientNum ) = 0;
// Reads current network info from a file (used as initial state for demo playback).
virtual void ReadNetworkInfo( int gameTime, idFile* file, int clientNum ) = 0;
// Let gamecode decide if it wants to accept demos from older releases of the engine.
virtual bool ValidateDemoProtocol( int minor_ref, int minor ) = 0;
// Write a snapshot for server demo recording.
virtual void ServerWriteServerDemoSnapshot( int sequence, idBitMsg &msg, int lastSnapshotFrame ) = 0;
// Read a snapshot from a server demo stream.
virtual void ClientReadServerDemoSnapshot( int sequence, const int gameFrame, const int gameTime, const idBitMsg &msg ) = 0;
// Write a snapshot for repeater clients.
virtual void RepeaterWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, dword *clientInPVS, int numPVSClients, const userOrigin_t &pvs_origin, int lastSnapshotFrame ) = 0;
// Done writing snapshots for repeater clients.
virtual void RepeaterEndSnapshots( void ) = 0;
// Read a snapshot from a repeater stream.
virtual void ClientReadRepeaterSnapshot( int sequence, const int gameFrame, const int gameTime, const int aheadOfServer, const idBitMsg &msg ) = 0;
// Get the currently followed client in demo playback
virtual int GetDemoFollowClient( void ) = 0;
// Build a bot's userCmd
virtual void GetBotInput( int clientNum, usercmd_t &userCmd ) = 0;
// Return the name of a gui to override the loading screen
virtual const char * GetLoadingGui( const char *mapDeclName ) = 0;
// Set any additional gui variables needed by the loading screen
virtual void SetupLoadingGui( idUserInterface *gui ) = 0;
};
extern idGame * game;
/*
===============================================================================
Public game interface with methods for in-game editing.
===============================================================================
*/
struct refSound_t {
// RAVEN BEGIN
int referenceSoundHandle; // this is the interface to the sound system, created
// with idSoundWorld::AllocSoundEmitter() when needed
// RAVEN END
idVec3 origin;
// RAVEN BEGIN
// jscott: for Miles doppler
idVec3 velocity;
// RAVEN END
int listenerId; // SSF_PRIVATE_SOUND only plays if == listenerId from PlaceListener
// no spatialization will be performed if == listenerID
const idSoundShader * shader; // this really shouldn't be here, it is a holdover from single channel behavior
float diversity; // 0.0 to 1.0 value used to select which
// samples in a multi-sample list from the shader are used
bool waitfortrigger; // don't start it at spawn time
soundShaderParms_t parms; // override volume, flags, etc
};
enum {
TEST_PARTICLE_MODEL = 0,
TEST_PARTICLE_IMPACT,
TEST_PARTICLE_MUZZLE,
TEST_PARTICLE_FLIGHT,
TEST_PARTICLE_SELECTED
};
class idEntity;
class idMD5Anim;
// RAVEN BEGIN
// bdube: more forward declarations
class idProgram;
class idInterpreter;
class idThread;
typedef void (*debugInfoProc_t) ( const char* classname, const char* name, const char* value, void *userdata );
// RAVEN END
// FIXME: this interface needs to be reworked but it properly separates code for the time being
class idGameEdit {
public:
virtual ~idGameEdit( void ) {}
// These are the canonical idDict to parameter parsing routines used by both the game and tools.
virtual bool ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight );
virtual void ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity );
virtual void ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound );
// Animation system calls for non-game based skeletal rendering.
virtual idRenderModel * ANIM_GetModelFromEntityDef( const char *classname );
virtual const idVec3 &ANIM_GetModelOffsetFromEntityDef( const char *classname );
virtual idRenderModel * ANIM_GetModelFromEntityDef( const idDict *args );
virtual idRenderModel * ANIM_GetModelFromName( const char *modelName );
virtual const idMD5Anim * ANIM_GetAnimFromEntityDef( const char *classname, const char *animname );
// RAVEN BEGIN
// bdube: added
// scork: added 'const' qualifiers so other stuff would compile
virtual const idMD5Anim * ANIM_GetAnimFromEntity( const idEntity* ent, int animNum );
virtual float ANIM_GetAnimPlaybackRateFromEntity ( idEntity* ent, int animNum );
virtual const char* ANIM_GetAnimNameFromEntity ( const idEntity* ent, int animNum );
// RAVEN END
virtual int ANIM_GetNumAnimsFromEntityDef( const idDict *args );
virtual const char * ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum );
virtual const idMD5Anim * ANIM_GetAnim( const char *fileName );
virtual int ANIM_GetLength( const idMD5Anim *anim );
virtual int ANIM_GetNumFrames( const idMD5Anim *anim );
// RAVEN BEGIN
// bdube: added
virtual const char * ANIM_GetFilename( const idMD5Anim* anim );
virtual int ANIM_ConvertFrameToTime ( const idMD5Anim* anim, int frame );
virtual int ANIM_ConvertTimeToFrame ( const idMD5Anim* anim, int time );
// RAVEN END
virtual void ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset );
virtual idRenderModel * ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset );
// RAVEN BEGIN
// mekberg: access to animationlib functions for radiant
virtual void FlushUnusedAnims( void );
// RAVEN END
// Articulated Figure calls for AF editor and Radiant.
virtual bool AF_SpawnEntity( const char *fileName );
virtual void AF_UpdateEntities( const char *fileName );
virtual void AF_UndoChanges( void );
virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet );
// Entity selection.
virtual void ClearEntitySelection( void );
virtual int GetSelectedEntities( idEntity *list[], int max );
virtual void AddSelectedEntity( idEntity *ent );
// Selection methods
virtual void TriggerSelected();
// Entity defs and spawning.
virtual const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
virtual void SpawnEntityDef( const idDict &args, idEntity **ent );
virtual idEntity * FindEntity( const char *name ) const;
virtual const char * GetUniqueEntityName( const char *classname ) const;
// Entity methods.
virtual void EntityGetOrigin( idEntity *ent, idVec3 &org ) const;
virtual void EntityGetAxis( idEntity *ent, idMat3 &axis ) const;
virtual void EntitySetOrigin( idEntity *ent, const idVec3 &org );
virtual void EntitySetAxis( idEntity *ent, const idMat3 &axis );
virtual void EntityTranslate( idEntity *ent, const idVec3 &org );
// RAVEN BEGIN
// scork: const-qualified 'ent' so other things would compile
virtual const idDict * EntityGetSpawnArgs( const idEntity *ent ) const;
// RAVEN END
virtual void EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict );
virtual void EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs );
virtual void EntityUpdateVisuals( idEntity *ent );
virtual void EntitySetModel( idEntity *ent, const char *val );
virtual void EntityStopSound( idEntity *ent );
virtual void EntityDelete( idEntity *ent );
virtual void EntitySetColor( idEntity *ent, const idVec3 color );
// RAVEN BEGIN
// bdube: added
virtual const char* EntityGetName ( idEntity* ent ) const;
virtual int EntityToSafeId( idEntity* ent ) const;
virtual idEntity * EntityFromSafeId( int safeID) const;
virtual void EntitySetSkin ( idEntity *ent, const char* temp ) const;
virtual void EntityClearSkin ( idEntity *ent ) const;
virtual void EntityShow ( idEntity* ent ) const;
virtual void EntityHide ( idEntity* ent ) const;
virtual void EntityGetBounds ( idEntity* ent, idBounds &bounds ) const;
virtual int EntityPlayAnim ( idEntity* ent, int animNum, int time, int blendtime );
virtual void EntitySetFrame ( idEntity* ent, int animNum, int frame, int time, int blendtime );
virtual void EntityStopAllEffects ( idEntity* ent );
virtual void EntityGetDelta ( idEntity* ent, int fromTime, int toTime, idVec3& delta );
virtual void EntityRemoveOriginOffset ( idEntity* ent, bool remove );
virtual const char* EntityGetClassname ( idEntity* ent ) const;
virtual bool EntityIsDerivedFrom ( idEntity* ent, const char* classname ) const;
virtual renderEntity_t* EntityGetRenderEntity ( idEntity* ent );
// scork: accessor functions for various utils
virtual idEntity * EntityGetNextTeamEntity( idEntity *pEnt ) const;
virtual void GetPlayerInfo( idVec3 &v3Origin, idMat3 &mat3Axis, int PlayerNum = -1, idAngles *deltaViewAngles = NULL ) const;
virtual void SetPlayerInfo( idVec3 &v3Origin, idMat3 &mat3Axis, int PlayerNum = -1 ) const;
virtual void EntitySetName( idEntity* pEnt, const char *psName );
// RAVEN END
// Player methods.
virtual bool PlayerIsValid() const;
virtual void PlayerGetOrigin( idVec3 &org ) const;
virtual void PlayerGetAxis( idMat3 &axis ) const;
virtual void PlayerGetViewAngles( idAngles &angles ) const;
virtual void PlayerGetEyePosition( idVec3 &org ) const;
// RAVEN BEGIN
// bdube: new game edit stuff
virtual bool PlayerTraceFromEye ( trace_t &results, float length, int contentMask );
// Effect methods
virtual void EffectRefreshTemplate ( const idDecl *effect ) const;
// Light entity methods
virtual void LightSetParms ( idEntity* ent, int maxLevel, int currentLevel, float radius );
// Common editing functions
virtual int GetGameTime ( int *previous = NULL ) const;
virtual void SetGameTime ( int time ) const;
virtual bool TracePoint ( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask ) const;
virtual void CacheDictionaryMedia ( const idDict* dict ) const;
virtual void SetCamera ( idEntity* camera ) const;
// RAVEN BEGIN
// bdube: added
virtual int GetGameEntityRegisterTime ( void ) const;
virtual idEntity* GetFirstSpawnedEntity ( void ) const;
virtual idEntity* GetNextSpawnedEntity ( idEntity* from ) const;
// jscott: added
virtual void DrawPlaybackDebugInfo( void );
virtual void RecordPlayback( const usercmd_t &cmd, idEntity *source );
virtual bool PlayPlayback( void );
virtual void ShutdownPlaybacks( void );
// RAVEN END
// Script methods
virtual int ScriptGetStatementLineNumber ( idProgram* program, int instructionPointer ) const;
virtual const char* ScriptGetStatementFileName ( idProgram* program, int instructionPointer ) const;
virtual int ScriptGetStatementOperator ( idProgram* program, int instructionPointer ) const;
virtual void* ScriptGetCurrentFunction ( idInterpreter* interpreter ) const;
virtual const char* ScriptGetCurrentFunctionName ( idInterpreter* interpreter ) const;
virtual int ScriptGetCallstackDepth ( idInterpreter* interpreter ) const;
virtual void* ScriptGetCallstackFunction ( idInterpreter* interpreter, int depth ) const;
virtual const char* ScriptGetCallstackFunctionName ( idInterpreter* interpreter, int depth ) const;
virtual int ScriptGetCallstackStatement ( idInterpreter* interpreter, int depth ) const;
virtual bool ScriptIsReturnOperator ( int op ) const;
virtual const char* ScriptGetRegisterValue ( idInterpreter* interpreter, const char* varname, int callstackDepth ) const;
virtual idThread* ScriptGetThread ( idInterpreter* interpreter ) const;
// Thread methods
virtual int ThreadGetCount ( void );
virtual idThread* ThreadGetThread ( int index );
virtual const char* ThreadGetName ( idThread* thread );
virtual int ThreadGetNumber ( idThread* thread );
virtual const char* ThreadGetState ( idThread* thread );
// Class externals for entity viewer
virtual void GetClassDebugInfo ( const idEntity* entity, debugInfoProc_t proc, void* userdata );
// In game map editing support.
virtual const idDict * MapGetEntityDict( const char *name ) const;
virtual void MapSave( const char *path = NULL ) const;
// RAVEN BEGIN
// rjohnson: added entity export
virtual bool MapHasExportEntities( void ) const;
// scork: simple func for the sound editor
virtual const char* MapLoaded( void ) const;
// cdr: AASTactical
virtual idAASFile* GetAASFile( int i );
// jscott: added entries for memory tracking
virtual void PrintMemInfo( MemInfo *mi );
virtual size_t ScriptSummary( const idCmdArgs &args ) const;
virtual size_t ClassSummary( const idCmdArgs &args ) const;
virtual size_t EntitySummary( const idCmdArgs &args ) const;
// RAVEN END
virtual void MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const ;
virtual void MapCopyDictToEntity( const char *name, const idDict *dict ) const;
virtual int MapGetUniqueMatchingKeyVals( const char *key, const char *list[], const int max ) const;
virtual void MapAddEntity( const idDict *dict ) const;
virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const;
virtual void MapRemoveEntity( const char *name ) const;
virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const;
};
extern idGameEdit * gameEdit;
// RAVEN BEGIN
// bdube: game logging
/*
===============================================================================
Game Log.
===============================================================================
*/
class rvGameLog {
public:
virtual ~rvGameLog( void ) {}
virtual void Init ( void ) = 0;
virtual void Shutdown ( void ) = 0;
virtual void BeginFrame ( int time ) = 0;
virtual void EndFrame ( void ) = 0;
virtual void Set ( const char* keyword, int value ) = 0;
virtual void Set ( const char* keyword, float value ) = 0;
virtual void Set ( const char* keyword, const char* value ) = 0;
virtual void Set ( const char* keyword, bool value ) = 0;
virtual void Add ( const char* keyword, int value ) = 0;
virtual void Add ( const char* keyword, float value ) = 0;
};
extern rvGameLog * gameLog;
#define GAMELOG_SET(x,y) {if(g_gamelog.GetBool())gameLog->Set ( x, y );}
#define GAMELOG_ADD(x,y) {if(g_gamelog.GetBool())gameLog->Add ( x, y );}
#define GAMELOG_SET_IF(x,y,z) {if(g_gamelog.GetBool()&&(z))gameLog->Set ( x, y );}
#define GAMELOG_ADD_IF(x,y,z) {if(g_gamelog.GetBool()&&(z))gameLog->Add ( x, y );}
// RAVEN END
/*
===============================================================================
Game API.
===============================================================================
*/
// 4: network demos
// 5: fix idNetworkSystem ( memory / DLL boundary related )
// 6: more network demo APIs
// 7: cleanups
// 8: added some demo functions to the FS class
// 9: bump up for 1.1 patch
// 9: Q4 Gold
// 10: Patch 2 changes
// 14: 1.3
// 26: 1.4 beta
// 30: 1.4
// 37: 1.4.2
const int GAME_API_VERSION = 37;
struct gameImport_t {
int version; // API version
idSys * sys; // non-portable system services
idCommon * common; // common
idCmdSystem * cmdSystem; // console command system
idCVarSystem * cvarSystem; // console variable system
idFileSystem * fileSystem; // file system
idNetworkSystem * networkSystem; // network system
idRenderSystem * renderSystem; // render system
idSoundSystem * soundSystem; // sound system
idRenderModelManager * renderModelManager; // render model manager
idUserInterfaceManager * uiManager; // user interface manager
idDeclManager * declManager; // declaration manager
idAASFileManager * AASFileManager; // AAS file manager
idCollisionModelManager * collisionModelManager; // collision model manager
// RAVEN BEGIN
// jscott:
rvBSEManager * bse; // Raven effects system
// RAVEN END
// RAVEN BEGIN
// dluetscher: added the following members to exchange memory system data
#ifdef _RV_MEM_SYS_SUPPORT
rvHeapArena * heapArena; // main heap arena that all other heaps use
rvHeap * systemHeapArray[MAX_SYSTEM_HEAPS]; // array of pointers to rvHeaps that are common to idLib, Game, and executable
#endif
// RAVEN END
};
struct gameExport_t {
int version; // API version
idGame * game; // interface to run the game
idGameEdit * gameEdit; // interface for in-game editing
// RAVEN BEGIN
// bdube: added
rvGameLog * gameLog; // interface for game logging
// RAVEN END
};
extern "C" {
typedef gameExport_t * (*GetGameAPI_t)( gameImport_t *import );
}
#endif /* !__GAME_H__ */

1960
source/game/GameEdit.cpp Normal file

File diff suppressed because it is too large Load diff

96
source/game/GameEdit.h Normal file
View file

@ -0,0 +1,96 @@
#ifndef __GAME_EDIT_H__
#define __GAME_EDIT_H__
/*
===============================================================================
Ingame cursor.
===============================================================================
*/
class idCursor3D : public idEntity {
public:
CLASS_PROTOTYPE( idCursor3D );
idCursor3D( void );
~idCursor3D( void );
void Spawn( void );
void Present( void );
void Think( void );
idForce_Drag drag;
idVec3 draggedPosition;
};
/*
===============================================================================
Allows entities to be dragged through the world with physics.
===============================================================================
*/
class idDragEntity {
public:
idDragEntity( void );
~idDragEntity( void );
void Clear();
void Update( idPlayer *player );
void SetSelected( idEntity *ent );
idEntity * GetSelected( void ) const { return selected.GetEntity(); }
void DeleteSelected( void );
void BindSelected( void );
void UnbindSelected( void );
private:
idEntityPtr<idEntity> dragEnt; // entity being dragged
jointHandle_t joint; // joint being dragged
int id; // id of body being dragged
idVec3 localEntityPoint; // dragged point in entity space
idVec3 localPlayerPoint; // dragged point in player space
idStr bodyName; // name of the body being dragged
idCursor3D * cursor; // cursor entity
idEntityPtr<idEntity> selected; // last dragged entity
void StopDrag( void );
};
/*
===============================================================================
Handles ingame entity editing.
===============================================================================
*/
typedef struct selectedTypeInfo_s {
idTypeInfo *typeInfo;
idStr textKey;
} selectedTypeInfo_t;
class idEditEntities {
public:
idEditEntities( void );
bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip );
void AddSelectedEntity( idEntity *ent );
void RemoveSelectedEntity( idEntity *ent );
void ClearSelectedEntities( void );
void DisplayEntities( void );
bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL );
// RAVEN BEGIN
// bdube: added
idEntity* FindTraceEntity( idVec3 start, idVec3 end, const idEntity *skip );
// RAVEN END
private:
int nextSelectTime;
idList<selectedTypeInfo_t> selectableEntityClasses;
idList<idEntity *> selectedEntities;
};
#endif /* !__GAME_EDIT_H__ */

372
source/game/Game_Debug.cpp Normal file
View file

@ -0,0 +1,372 @@
//----------------------------------------------------------------
// Game_Debug.cpp
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
rvGameDebug gameDebug;
/*
===============================================================================
rvGameDebug
===============================================================================
*/
/*
================
rvGameDebug::rvGameDebug
================
*/
rvGameDebug::rvGameDebug ( void ) {
}
/*
================
rvGameDebug::Init
================
*/
void rvGameDebug::Init ( void ) {
focusEntity = NULL;
overrideEntity = NULL;
currentHud = NULL;
memset ( &hud, 0, sizeof(hud) );
jumpIndex = -1;
jumpPoints.Clear ( );
}
/*
================
rvGameDebug::Shutdown
================
*/
void rvGameDebug::Shutdown ( void ) {
nonGameState.Clear ( );
gameStats.Clear ( );
currentHud = NULL;
focusEntity = NULL;
overrideEntity = NULL;
memset ( &hud, 0, sizeof(hud) );
}
/*
================
rvGameDebug::Think
================
*/
void rvGameDebug::BeginFrame ( void ) {
int hudIndex;
inFrame = true;
hudIndex = g_showDebugHud.GetInteger();
if ( hudIndex <= 0 ) {
focusEntity = NULL;
currentHud = NULL;
return;
}
// Update the current debug hud if the cvar has changed
if ( g_showDebugHud.IsModified() || !currentHud ) {
if ( hudIndex > DBGHUD_MAX ) {
g_showDebugHud.SetInteger( 0 );
focusEntity = NULL;
currentHud = NULL;
return;
}
g_showDebugHud.ClearModified( );
// If the debug hud hasnt been loaded yet then load it now
if ( !hud[hudIndex] ) {
hud[hudIndex] = uiManager->FindGui( va("guis/debug/hud%d.gui",hudIndex), true, true, true );
// If the hud wasnt found auto-generate one
if ( !hud[hudIndex] ) {
hud[hudIndex] = uiManager->Alloc();
}
}
// Cache the debug hud state.
currentHud = hud[hudIndex];
}
currentHud->ClearState ( );
// IF there is an override entity just use that, otherwise find one that
// is in front of the players crosshair
if ( overrideEntity ) {
focusEntity = overrideEntity;
overrideEntity = NULL;
} else {
idPlayer* player;
idVec3 start;
idVec3 end;
trace_t tr;
player = gameLocal.GetLocalPlayer ( );
start = player->GetEyePosition();
end = start + player->viewAngles.ToForward() * 4096.0f;
gameLocal.TracePoint( player, tr, start, end, MASK_SHOT_BOUNDINGBOX, player );
if ( tr.fraction < 1.0 && tr.c.entityNum != ENTITYNUM_WORLD ) {
focusEntity = static_cast<idEntity*>(gameLocal.entities[ tr.c.entityNum ]);
} else {
focusEntity = NULL;
}
}
// Automatically add some basic entity information
if ( focusEntity ) {
SetInt ( "entityNumber", focusEntity->entityNumber );
SetInt ( "entityHealth", focusEntity->health );
SetString ( "entityName", focusEntity->name );
SetString ( "entityClass", focusEntity->GetClassname ( ) );
}
// General map information
SetString ( "mapname", gameLocal.GetMapName ( ) );
SetString ( "version", cvarSystem->GetCVarString ( "si_version" ) );
if ( gameLocal.GetLocalPlayer() ) {
SetString ( "viewpos", gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin().ToString() );
}
}
/*
================
rvGameDebug::EndFrame
================
*/
void rvGameDebug::EndFrame ( void ) {
inFrame = false;
}
/*
================
rvGameDebug::DrawHud
================
*/
void rvGameDebug::DrawHud ( void ) {
if ( !currentHud ) {
return;
}
// The scratch hud displays key value pairs in a list so
// we need to push the keys into the list
if ( IsHudActive ( DBGHUD_SCRATCH ) ) {
int index;
idDict tempState;
tempState.Copy ( currentHud->State() );
currentHud->ClearState ( );
for ( index = 0; index < tempState.GetNumKeyVals(); index ++ ) {
const idKeyValue* kv;
kv = tempState.GetKeyVal ( index );
SetString ( va("scratchKey_item_%d", index ), kv->GetKey() );
SetString ( va("scratchValue_item_%d", index ), kv->GetValue() );
}
}
else {
int index;
for ( index = 0; index < nonGameState.GetNumKeyVals(); index ++ ) {
const idKeyValue* kv;
kv = nonGameState.GetKeyVal ( index );
currentHud->SetStateString ( kv->GetKey(), kv->GetValue() );
}
}
// Activate the hud to ensure lists get updated and redraw it
currentHud->StateChanged ( gameLocal.time );
currentHud->Redraw( gameLocal.time );
}
/*
================
rvGameDebug::AppendList
================
*/
void rvGameDebug::AppendList ( const char* listname, const char* value ) {
if ( !currentHud ) {
return;
}
int count;
char countName[1024];
char itemName[1024];
idStr::snPrintf ( countName, 1023, "%sCount", listname );
count = GetInt ( countName );
idStr::snPrintf ( itemName, 1023, "%s_item_%d", listname, count );
SetString ( va("%s_item_%d", listname, count ), value );
SetInt ( countName, count + 1 );
}
/*
================
rvGameDebug::Set
================
*/
void rvGameDebug::SetInt ( const char* key, int value ) {
if ( inFrame ) {
if ( currentHud ) {
currentHud->SetStateInt( key, value );
}
} else {
nonGameState.SetInt ( key, value );
}
}
void rvGameDebug::SetFloat ( const char* key, float value ) {
if ( inFrame ) {
if ( currentHud ) {
currentHud->SetStateFloat( key, value );
}
} else {
nonGameState.SetFloat ( key, value );
}
}
void rvGameDebug::SetString ( const char* key, const char* value ) {
if ( inFrame ) {
if ( currentHud ) {
currentHud->SetStateString( key, value );
}
} else {
nonGameState.Set ( key, value );
}
}
/*
================
rvGameDebug::Get
================
*/
int rvGameDebug::GetInt ( const char* key ) {
return currentHud ? currentHud->State().GetInt ( key ) : 0;
}
float rvGameDebug::GetFloat ( const char* key ) {
return currentHud ? currentHud->State().GetFloat ( key ) : 0.0f;
}
const char* rvGameDebug::GetString ( const char* key ) {
return currentHud ? currentHud->State().GetString ( key ) : "";
}
/*
================
rvGameDebug::SetStat
================
*/
void rvGameDebug::SetStatInt ( const char* key, int value ) {
gameStats.SetInt ( key, value );
}
void rvGameDebug::SetStatFloat ( const char* key, float value ) {
gameStats.SetFloat ( key, value );
}
void rvGameDebug::SetStatString ( const char* key, const char* value ) {
gameStats.Set ( key, value );
}
/*
================
rvGameDebug::GetStat
================
*/
int rvGameDebug::GetStatInt ( const char* key ) {
return gameStats.GetInt ( key );
}
float rvGameDebug::GetStatFloat ( const char* key ) {
return gameStats.GetFloat ( key );
}
const char* rvGameDebug::GetStatString ( const char* key ) {
return gameStats.GetString ( key );
}
/*
================
rvGameDebug::JumpAdd
================
*/
void rvGameDebug::JumpAdd ( const char* name, const idVec3& origin, const idAngles& angles ) {
debugJumpPoint_t jump;
jump.name = name;
jump.origin = origin;
jump.angles = angles;
jumpPoints.Append ( jump );
}
/*
================
rvGameDebug::JumpTo
================
*/
void rvGameDebug::JumpTo ( const char* name ) {
int index;
for ( index = 0; index < jumpPoints.Num(); index ++ ) {
if ( !jumpPoints[index].name.Icmp ( name ) ) {
JumpTo ( index );
return;
}
}
}
/*
================
rvGameDebug::JumpTo
================
*/
void rvGameDebug::JumpTo ( int jumpIndex ) {
if ( jumpIndex >= jumpPoints.Num() ) {
return;
}
jumpIndex = jumpIndex;
idPlayer* player = gameLocal.GetLocalPlayer();
if( player ) {
player->Teleport( jumpPoints[jumpIndex].origin, jumpPoints[jumpIndex].angles, NULL );
}
}
/*
================
rvGameDebug::JumpNext
================
*/
void rvGameDebug::JumpNext ( void ) {
if ( !jumpPoints.Num() ) {
return;
}
JumpTo ( ( jumpIndex + 1 ) % jumpPoints.Num() );
}
/*
================
rvGameDebug::JumpPrev
================
*/
void rvGameDebug::JumpPrev ( void ) {
if ( !jumpPoints.Num() ) {
return;
}
JumpTo ( ( jumpIndex + jumpPoints.Num() - 1 ) % jumpPoints.Num() );
}

95
source/game/Game_Debug.h Normal file
View file

@ -0,0 +1,95 @@
//----------------------------------------------------------------
// Game_Debug.h
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#ifndef __GAME_DEBUG_H__
#define __GAME_DEBUG_H__
#define DBGHUD_NONE (0)
#define DBGHUD_PLAYER (1<<0)
#define DBGHUD_PHYSICS (1<<1)
#define DBGHUD_AI (1<<2)
#define DBGHUD_VEHICLE (1<<3)
#define DBGHUD_PERFORMANCE (1<<4)
#define DBGHUD_FX (1<<5)
#define DBGHUD_MAPINFO (1<<6)
#define DBGHUD_AI_PERFORM (1<<7)
#define DBGHUD_SCRATCH (1<<31)
#define DBGHUD_ANY (0xFFFFFFFF)
#define DBGHUD_MAX 32
typedef struct debugJumpPoint_s
{
idStr name;
idVec3 origin;
idAngles angles;
} debugJumpPoint_t;
class rvGameDebug {
public:
rvGameDebug( );
void Init ( void );
void Shutdown ( void );
void BeginFrame ( void );
void EndFrame ( void );
void SetFocusEntity ( idEntity* focusEnt );
bool IsHudActive ( int hudMask, const idEntity* focusEnt = NULL );
void DrawHud ( void );
void AppendList ( const char* listname, const char* value );
void SetInt ( const char* key, int value );
void SetFloat ( const char* key, float value );
void SetString ( const char* key, const char* value );
int GetInt ( const char* key );
float GetFloat ( const char* key );
const char* GetString ( const char* key );
void SetStatInt ( const char* key, int value );
void SetStatFloat ( const char* key, float value );
void SetStatString ( const char* key, const char* value );
int GetStatInt ( const char* key );
float GetStatFloat ( const char* key );
const char* GetStatString ( const char* key );
void JumpAdd ( const char* name, const idVec3& origin, const idAngles& angles );
void JumpTo ( const char* name );
void JumpTo ( int jumpIndex );
void JumpNext ( void );
void JumpPrev ( void );
private:
idList<debugJumpPoint_t> jumpPoints;
int jumpIndex;
idEntityPtr<idEntity> focusEntity;
idEntityPtr<idEntity> overrideEntity;
idUserInterface * hud[DBGHUD_MAX+1];
idUserInterface * currentHud;
idDict nonGameState, gameStats;
bool inFrame;
};
ID_INLINE bool rvGameDebug::IsHudActive ( int hudMask, const idEntity* ent ) {
return (g_showDebugHud.GetInteger() && (hudMask & (1 << (g_showDebugHud.GetInteger()-1))) && (!ent || focusEntity == ent ) );
}
ID_INLINE void rvGameDebug::SetFocusEntity ( idEntity* ent ) {
overrideEntity = ent;
}
extern rvGameDebug gameDebug;
#endif /* !__GAME_DEBUG_H__ */

228
source/game/Game_Log.cpp Normal file
View file

@ -0,0 +1,228 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Game_Log.h"
/*
===============================================================================
rvGameLog
===============================================================================
*/
rvGameLogLocal gameLogLocal;
rvGameLog* gameLog = &gameLogLocal;
/*
================
rvGameLogLocal::rvGameLogLocal
================
*/
rvGameLogLocal::rvGameLogLocal ( ) {
initialized = false;
}
/*
================
rvGameLogLocal::Init
================
*/
void rvGameLogLocal::Init ( void ) {
file = NULL;
indexCount = 0;
initialized = true;
index.Clear ( );
frame.Clear ( );
oldframe.Clear ( );
}
/*
================
rvGameLogLocal::Shutdown
================
*/
void rvGameLogLocal::Shutdown ( void ) {
index.Clear ( );
frame.Clear ( );
oldframe.Clear ( );
if ( initialized && file ) {
const char* out;
out = va(":%d %d", gameLocal.time, gameLocal.framenum );
file->Write ( out, strlen ( out ) );
file->Flush ( );
fileSystem->CloseFile ( file );
file = NULL;
}
initialized = false;
}
/*
================
rvGameLogLocal::BeginFrame
================
*/
void rvGameLogLocal::BeginFrame ( int time ) {
// See if logging has been turned on or not
if ( g_gamelog.GetBool ( ) != initialized ) {
if ( initialized ) {
Shutdown ( );
return;
} else {
Init ( );
}
} else if ( !g_gamelog.GetBool ( ) ) {
return;
}
}
/*
================
rvGameLogLocal::EndFrame
================
*/
void rvGameLogLocal::EndFrame ( void ) {
int i;
const char* out;
bool wroteTime;
// Dont do anything if not logging
if ( !g_gamelog.GetBool ( ) ) {
return;
}
// When not in multiplayer, log the players approx origin and viewangles
if ( !gameLocal.isMultiplayer ) {
idPlayer* player;
player = gameLocal.GetLocalPlayer ( );
if ( player ) {
Set ( "player0_origin", va("%d %d %d", (int)player->GetPhysics()->GetOrigin()[0], (int)player->GetPhysics()->GetOrigin()[1], (int)player->GetPhysics()->GetOrigin()[2] ) );
Set ( "player0_angles_yaw", va("%g", (float)player->viewAngles[YAW] ) );
Set ( "player0_angles_pitch", va("%g", (float)player->viewAngles[PITCH] ) );
Set ( "player0_buttons", player->usercmd.buttons );
Set ( "player0_health", player->health );
Set ( "player0_armor", player->inventory.armor );
}
}
if ( !file ) {
idStr mapName;
idStr filename;
mapName = gameLocal.serverInfo.GetString( "si_map" );
mapName.StripFileExtension ( );
filename = "logs/" + mapName + "/" + cvarSystem->GetCVarString("win_username") + "_";
// Find a unique filename
for ( i = 0; fileSystem->ReadFile( filename + va("%06d.log", i ), NULL, NULL ) > 0; i ++ );
// Actually open the file now
file = fileSystem->OpenFileWrite ( filename + va("%06d.log", i ), "fs_cdpath" );
if ( !file ) {
return;
}
timer_fps.Stop( );
timer_fps.Clear ( );
timer_fps.Start ( );
} else {
static int fpsIndex;
static float fpsValue[4];
timer_fps.Stop ( );
fpsValue[(fpsIndex++)%4] = 1000.0f / (timer_fps.Milliseconds ( ) + 1);
if ( fpsIndex >= 4 ) {
GAMELOG_SET ( "fps", Min(60,(int)((int)(fpsValue[0] + fpsValue[1] + fpsValue[2] + fpsValue[3]) / 40.0f) * 10) );
}
timer_fps.Clear ( );
timer_fps.Start ( );
}
// Write out any new indexes that were added this frame
for ( ; indexCount < index.Num(); indexCount ++ ) {
const char* out;
out = va("#%d ", indexCount );
file->Write ( out, strlen ( out ) );
file->Write ( index[indexCount].c_str(), index[indexCount].Length() );
file->Write ( "\r\n", 2 );
}
// Write out any data that was added this frame
wroteTime = false;
for ( i = frame.Num() - 1; i >= 0; i -- ) {
// TODO: filter
if ( oldframe[i] != frame[i] ) {
if ( !wroteTime ) {
out = va(":%d %d", gameLocal.time, gameLocal.framenum );
file->Write ( out, strlen ( out ) );
wroteTime = true;
}
out = va(" %d \"", i );
file->Write ( out, strlen(out) );
file->Write ( frame[i].c_str(), frame[i].Length ( ) );
file->Write ( "\"", 1 );
oldframe[i] = frame[i];
}
}
if ( wroteTime ) {
file->Write ( "\r\n", 2 );
file->Flush ( );
}
// Clear the frame for next time
for ( i = index.Num() - 1; i >= 0; i -- ) {
frame[i] = "";
}
}
/*
================
rvGameLogLocal::Set
================
*/
void rvGameLogLocal::Set ( const char* keyword, const char* value ) {
int i;
i = index.AddUnique ( keyword );
frame.SetNum ( index.Num(), true );
oldframe.SetNum ( index.Num(), true );
frame[i] = value;
}
void rvGameLogLocal::Set ( const char* keyword, int value ) {
Set ( keyword, va("%d", value ) );
}
void rvGameLogLocal::Set ( const char* keyword, float value ) {
Set ( keyword, va("%g", value ) );
}
void rvGameLogLocal::Set ( const char* keyword, bool value ) {
Set ( keyword, va("%d", (int)value ) );
}
/*
================
rvGameLogLocal::Add
================
*/
void rvGameLogLocal::Add ( const char* keyword, int value ) {
int i;
i = index.AddUnique ( keyword );
frame.SetNum ( index.Num(), true );
oldframe.SetNum ( index.Num(), true );
frame[i] = va("%d",atoi(frame[i].c_str()) + value );
}
void rvGameLogLocal::Add ( const char* keyword, float value ) {
int i;
i = index.AddUnique ( keyword );
frame.SetNum ( index.Num(), true );
oldframe.SetNum ( index.Num(), true );
frame[i] = va("%g",atof(frame[i].c_str()) + value );
}

40
source/game/Game_Log.h Normal file
View file

@ -0,0 +1,40 @@
#ifndef __GAME_LOG_H__
#define __GAME_LOG_H__
//============================================================================
class rvGameLogLocal : public rvGameLog {
public:
rvGameLogLocal ( void );
virtual void Init ( void );
virtual void Shutdown ( void );
virtual void BeginFrame ( int time );
virtual void EndFrame ( void );
virtual void Set ( const char* keyword, int value );
virtual void Set ( const char* keyword, float value );
virtual void Set ( const char* keyword, const char* value );
virtual void Set ( const char* keyword, bool value );
virtual void Add ( const char* keyword, int value );
virtual void Add ( const char* keyword, float value );
protected:
int lastTime;
int indexCount;
idStrList index;
idStrList frame;
idStrList oldframe;
idFile* file;
bool initialized;
idTimer timer_fps;
};
extern rvGameLogLocal gameLogLocal;
#endif // __GAME_LOG_H__

8508
source/game/Game_local.cpp Normal file

File diff suppressed because it is too large Load diff

1412
source/game/Game_local.h Normal file

File diff suppressed because it is too large Load diff

3515
source/game/Game_network.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,209 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Healing_Station.h"
CLASS_DECLARATION( idAnimatedEntity, rvHealingStation )
END_CLASS
/*
================
rvHealingStation::Think
================
*/
void rvHealingStation::Think ( void ) {
// TODO: I'm guessing this is bad, but I wanted to get this in so that people could start
// placing it. The entity decided to stop thinking and I didn't have time to debug it.
BecomeActive( TH_ALL );
stateThread.Execute();
UpdateAnimation();
if ( thinkFlags & TH_UPDATEVISUALS ) {
if ( healthDispensed > 0 ) {
CreateFrame( float( healthDispensed ) / maxHealth );
}
Present();
}
}
/*
================
rvHealingStation::Spawn
================
*/
void rvHealingStation::Spawn ( void ) {
entityToHeal = 0;
nextHealTime = 0;
healFrequency = spawnArgs.GetInt( "heal_frequency", "24" );
healAmount = spawnArgs.GetInt( "heal_amount", "1" );
healthDispensed = 0;
soundStartTime = 0;
soundLength = 0;
maxHealth = spawnArgs.GetInt( "max_health", "100" );
dispenseAnim = GetAnimator()->GetAnim( spawnArgs.GetString( "dispense_anim", "dispense" ) );
CreateFrame( 0 );
stateThread.SetOwner( this );
stateThread.SetName( GetName() );
GetAnimator()->CycleAnim( ANIMCHANNEL_ALL, GetAnimator()->GetAnim( spawnArgs.GetString( "anim", "idle" ) ), gameLocal.time, 4 );
}
/*
================
rvHealingStation::Save
================
*/
void rvHealingStation::Save ( idSaveGame *savefile ) const {
stateThread.Save( savefile );
entityToHeal.Save ( savefile );
savefile->WriteInt( nextHealTime );
savefile->WriteInt( healFrequency );
savefile->WriteInt( healAmount );
savefile->WriteInt( healthDispensed );
savefile->WriteInt( maxHealth );
savefile->WriteInt( dispenseAnim );
savefile->WriteInt( soundStartTime );
savefile->WriteInt( soundLength );
}
/*
================
rvHealingStation::Restore
================
*/
void rvHealingStation::Restore ( idRestoreGame *savefile ) {
stateThread.Restore( savefile, this );
entityToHeal.Restore ( savefile );
savefile->ReadInt( nextHealTime );
savefile->ReadInt( healFrequency );
savefile->ReadInt( healAmount );
savefile->ReadInt( healthDispensed );
savefile->ReadInt( maxHealth );
savefile->ReadInt( dispenseAnim );
savefile->ReadInt( soundStartTime );
savefile->ReadInt( soundLength );
}
/*
================
rvHealingStation::BeginHealing
================
*/
void rvHealingStation::BeginHealing ( idEntity *toHeal ) {
entityToHeal = toHeal;
stateThread.SetState( "Healing" );
}
/*
================
rvHealingStation::EndHealing
================
*/
void rvHealingStation::EndHealing ( void ) {
entityToHeal = NULL;
}
/*
================
rvHealingStation::CreateFrame
================
*/
void rvHealingStation::CreateFrame ( float station_health ) {
// Update the GUI
if ( renderEntity.gui[ 0 ] ) {
renderEntity.gui[ 0 ]->SetStateFloat( "station_health", 1.0f - station_health );
renderEntity.gui[ 0 ]->StateChanged( gameLocal.time, true );
}
// Update the Animation
int numFrames = GetAnimator()->GetAnim( dispenseAnim )->NumFrames();
float lerp = numFrames * station_health;
int frame = lerp;
lerp = lerp - frame;
frameBlend_t frameBlend = { 0, frame, frame + 1, 1.0f - lerp, lerp };
GetAnimator()->SetFrame( ANIMCHANNEL_ALL, dispenseAnim, frameBlend );
}
/*
================
rvHealingStation::IsPlaying
================
*/
bool rvHealingStation::IsPlaying ( void ) {
idSoundEmitter* emitter = soundSystem->EmitterForIndex ( SOUNDWORLD_GAME, GetSoundEmitter ( ) );
if( emitter ) {
return ( emitter->CurrentlyPlaying ( ) );
}
return false;
}
/*
===============================================================================
States
===============================================================================
*/
CLASS_STATES_DECLARATION ( rvHealingStation )
STATE ( "Healing", rvHealingStation::State_Healing )
END_CLASS_STATES
/*
================
rvHealingStation::State_Healing
================
*/
stateResult_t rvHealingStation::State_Healing ( const stateParms_t& parms ) {
enum {
STAGE_INIT,
STAGE_WAIT,
STAGE_DISPENSE,
};
if ( entityToHeal.IsValid() ) {
idPlayer* player = static_cast<idPlayer*>( entityToHeal.GetEntity( ) );
const int entityMaxHealth = player->inventory.maxHealth;
if ( healthDispensed < maxHealth && // and we have health to dispense...
entityToHeal->health < entityMaxHealth && // and the entity needs health.
entityToHeal->health > 0 ) // and he's still alive.
{
switch ( parms.stage ) {
case STAGE_INIT:
soundStartTime = gameLocal.time;
StartSound( "snd_start", SND_CHANNEL_ANY, 0, false, &soundLength );
return SRESULT_STAGE ( STAGE_WAIT );
case STAGE_WAIT:
if ( gameLocal.time > soundStartTime + soundLength ) {
soundStartTime = 0;
soundLength = 0;
return SRESULT_STAGE ( STAGE_DISPENSE );
}
return SRESULT_WAIT;
case STAGE_DISPENSE:
if ( gameLocal.time > nextHealTime ) { // If it's time to heal...
int healthGiven = Min( maxHealth - healthDispensed, Min( healAmount, entityMaxHealth - entityToHeal->health ) );
entityToHeal->health += healthGiven;
healthDispensed += healthGiven;
nextHealTime = gameLocal.time + healFrequency;
}
if ( !IsPlaying ( ) ) {
StartSound( "snd_loop", SND_CHANNEL_ANY, 0, false, NULL );
}
return SRESULT_WAIT;
}
}
}
StopSound ( SND_CHANNEL_ANY, 0 );
StartSound ( "snd_stop", SND_CHANNEL_ANY, 0, false, NULL );
return SRESULT_DONE;
}

View file

@ -0,0 +1,45 @@
/*
===============================================================================
rvHealingStation
===============================================================================
*/
class rvHealingStation : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( rvHealingStation );
virtual void Think ( void );
void Spawn ( void );
void Save ( idSaveGame *savefile ) const;
void Restore ( idRestoreGame *savefile );
void BeginHealing ( idEntity *toHeal );
void EndHealing ( void );
protected:
void CreateFrame ( float station_health );
stateResult_t State_Healing ( const stateParms_t& parms );
rvStateThread stateThread;
idEntityPtr<idEntity> entityToHeal;
int nextHealTime;
int healFrequency;
int healAmount;
int healthDispensed;
int maxHealth;
int dispenseAnim;
int soundStartTime;
int soundLength;
private:
bool IsPlaying ( void );
CLASS_STATES_PROTOTYPE ( rvHealingStation );
};

1062
source/game/IK.cpp Normal file

File diff suppressed because it is too large Load diff

155
source/game/IK.h Normal file
View file

@ -0,0 +1,155 @@
#ifndef __GAME_IK_H__
#define __GAME_IK_H__
/*
===============================================================================
IK base class with a simple fast two bone solver.
===============================================================================
*/
#define IK_ANIM "ik_pose"
class idIK {
public:
idIK( void );
virtual ~idIK( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
bool IsInitialized( void ) const;
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
bool SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos );
float GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis );
protected:
bool initialized;
bool ik_activate;
idEntity * self; // entity using the animated model
idAnimator * animator; // animator on entity
int modifiedAnim; // animation modified by the IK
idVec3 modelOffset;
};
/*
===============================================================================
IK controller for a walking character with an arbitrary number of legs.
===============================================================================
*/
class idIK_Walk : public idIK {
public:
idIK_Walk( void );
virtual ~idIK_Walk( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
void EnableAll( void );
void DisableAll( void );
void EnableLeg( int num );
void DisableLeg( int num );
private:
static const int MAX_LEGS = 8;
idClipModel * footModel;
int numLegs;
int enabledLegs;
jointHandle_t footJoints[MAX_LEGS];
jointHandle_t ankleJoints[MAX_LEGS];
jointHandle_t kneeJoints[MAX_LEGS];
jointHandle_t hipJoints[MAX_LEGS];
jointHandle_t dirJoints[MAX_LEGS];
jointHandle_t waistJoint;
idVec3 hipForward[MAX_LEGS];
idVec3 kneeForward[MAX_LEGS];
float upperLegLength[MAX_LEGS];
float lowerLegLength[MAX_LEGS];
idMat3 upperLegToHipJoint[MAX_LEGS];
idMat3 lowerLegToKneeJoint[MAX_LEGS];
float smoothing;
float waistSmoothing;
float footShift;
float waistShift;
float minWaistFloorDist;
float minWaistAnkleDist;
float footUpTrace;
float footDownTrace;
bool tiltWaist;
bool usePivot;
// state
int pivotFoot;
float pivotYaw;
idVec3 pivotPos;
bool oldHeightsValid;
float oldWaistHeight;
float oldAnkleHeights[MAX_LEGS];
idVec3 waistOffset;
};
/*
===============================================================================
IK controller for reaching a position with an arm or leg.
===============================================================================
*/
class idIK_Reach : public idIK {
public:
idIK_Reach( void );
virtual ~idIK_Reach( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
private:
static const int MAX_ARMS = 2;
int numArms;
int enabledArms;
jointHandle_t handJoints[MAX_ARMS];
jointHandle_t elbowJoints[MAX_ARMS];
jointHandle_t shoulderJoints[MAX_ARMS];
jointHandle_t dirJoints[MAX_ARMS];
idVec3 shoulderForward[MAX_ARMS];
idVec3 elbowForward[MAX_ARMS];
float upperArmLength[MAX_ARMS];
float lowerArmLength[MAX_ARMS];
idMat3 upperArmToShoulderJoint[MAX_ARMS];
idMat3 lowerArmToElbowJoint[MAX_ARMS];
};
#endif /* !__GAME_IK_H__ */

96
source/game/Icon.cpp Normal file
View file

@ -0,0 +1,96 @@
//----------------------------------------------------------------
// Icon.cpp
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Icon.h"
/*
===============
rvIcon::rvIcon
===============
*/
rvIcon::rvIcon() {
iconHandle = -1;
}
/*
===============
rvIcon::~rvIcon
===============
*/
rvIcon::~rvIcon() {
FreeIcon();
}
/*
===============
rvIcon::FreeIcon
===============
*/
void rvIcon::FreeIcon( void ) {
if ( iconHandle != - 1 ) {
gameRenderWorld->FreeEntityDef( iconHandle );
iconHandle = -1;
}
}
/*
===============
rvIcon::CreateIcon
===============
*/
qhandle_t rvIcon::CreateIcon( const char *mtr, int suppressViewID ) {
FreeIcon();
memset( &renderEnt, 0, sizeof( renderEnt ) );
renderEnt.origin = vec3_origin;
renderEnt.axis = mat3_identity;
renderEnt.shaderParms[ SHADERPARM_RED ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_ALPHA ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ] = 16.0f;
renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ] = 16.0f;
renderEnt.hModel = renderModelManager->FindModel( "_sprite" );
renderEnt.callback = NULL;
renderEnt.numJoints = 0;
renderEnt.joints = NULL;
renderEnt.customSkin = 0;
renderEnt.noShadow = true;
renderEnt.noSelfShadow = true;
renderEnt.customShader = declManager->FindMaterial( mtr );
renderEnt.referenceShader = 0;
renderEnt.bounds = renderEnt.hModel->Bounds( &renderEnt );
renderEnt.suppressSurfaceInViewID = suppressViewID;
iconHandle = gameRenderWorld->AddEntityDef( &renderEnt );
return iconHandle;
}
/*
===============
rvIcon::UpdateIcon
===============
*/
void rvIcon::UpdateIcon( const idVec3 &origin, const idMat3 &axis ) {
assert( iconHandle >= 0 );
renderEnt.origin = origin;
renderEnt.axis = axis;
gameRenderWorld->UpdateEntityDef( iconHandle, &renderEnt );
}
int rvIcon::GetWidth( void ) const {
return renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ];
}
int rvIcon::GetHeight( void ) const {
return renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ];
}

34
source/game/Icon.h Normal file
View file

@ -0,0 +1,34 @@
//----------------------------------------------------------------
// Icon.h
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#ifndef __ICON_H__
#define __ICON_H__
class rvIcon {
public:
rvIcon();
~rvIcon();
void UpdateIcon( const idVec3 &origin, const idMat3 &axis );
qhandle_t CreateIcon( const char *mtr, int suppressViewID = 0 );
void FreeIcon( void );
qhandle_t GetHandle( void ) const;
int GetHeight( void ) const;
int GetWidth( void ) const;
private:
void Draw( jointHandle_t joint );
void Draw( const idVec3 &origin );
renderEntity_t renderEnt;
qhandle_t iconHandle;
};
ID_INLINE qhandle_t rvIcon::GetHandle( void ) const {
return iconHandle;
}
#endif /* !_ICON_H_ */

205
source/game/IconManager.cpp Normal file
View file

@ -0,0 +1,205 @@
//----------------------------------------------------------------
// IconManager.cpp
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "IconManager.h"
rvIconManager iconManagerLocal;
rvIconManager* iconManager = &iconManagerLocal;
/*
===============================================================================
rvIconManager
===============================================================================
*/
void rvIconManager::AddIcon( int clientNum, const char* iconName ) {
assert( gameLocal.GetLocalPlayer() );
idPlayer* player = gameLocal.GetLocalPlayer();
icons[ clientNum ].Append( rvPair<rvIcon*, int>(new rvIcon(), gameLocal.time + ICON_STAY_TIME) );
icons[ clientNum ][ icons[ clientNum ].Num() - 1 ].First()->CreateIcon( player->spawnArgs.GetString( iconName ), (clientNum == gameLocal.localClientNum ? gameLocal.localClientNum + 1 : 0) );
}
void rvIconManager::UpdateIcons( void ) {
if( gameLocal.GetLocalPlayer() == NULL || !gameLocal.GetLocalPlayer()->GetRenderView() ) {
return;
}
// draw team icons
if( gameLocal.IsTeamGame() ) {
UpdateTeamIcons();
}
// draw chat icons
UpdateChatIcons();
// remove old icons and icons not in our snapshot
// ** if you want to have permanent icons, you'll have to add support
// ** for the icons to re-appear when the player comes back in your snapshot (like team icons and chat icons)
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
for( int j = 0; j < icons[ i ].Num(); j++ ) {
if( gameLocal.time > icons[ i ][ j ].Second() || (gameLocal.entities[ i ] && gameLocal.entities[ i ]->fl.networkStale) ) {
rvIcon* oldIcon = icons[ i ][ j ].First();
oldIcon->FreeIcon();
icons[ i ].RemoveIndex( j-- );
delete oldIcon;
}
}
}
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
// draw extra icons
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
if( gameLocal.localClientNum == i ) {
continue;
}
if( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::GetClassType() ) ) {
idPlayer* player = static_cast<idPlayer*>(gameLocal.entities[ i ]);
if( player->IsHidden() || !icons[ i ].Num() ) {
continue;
}
// distribute the icons appropriately
int maxHeight = 0;
int totalWidth = 0;
for( int j = 0; j < icons[ i ].Num(); j++ ) {
if( icons[ i ][ j ].First()->GetHeight() > maxHeight ) {
maxHeight = icons[ i ][ j ].First()->GetHeight();
}
totalWidth += icons[ i ][ j ].First()->GetWidth();
}
idVec3 centerIconPosition = player->spawnArgs.GetVector( (player->team ? "team_icon_height_strogg" : "team_icon_height_marine") );
if( teamIcons[ player->entityNumber ].GetHandle() >= 0 ) {
centerIconPosition[ 2 ] += teamIcons[ player->entityNumber ].GetHeight();
}
int incrementalWidth = 0;
for( int j = 0; j < icons[ i ].Num(); j++ ) {
idVec3 iconPosition = centerIconPosition;
iconPosition += ( (-totalWidth / 2) + incrementalWidth + (icons[ i ][ j ].First()->GetWidth() / 2) ) * localPlayer->GetRenderView()->viewaxis[ 1 ];
incrementalWidth += icons[ i ][ j ].First()->GetWidth();
icons[ i ][ j ].First()->UpdateIcon( player->GetPhysics()->GetOrigin() + iconPosition, localPlayer->GetRenderView()->viewaxis );
}
}
}
}
void rvIconManager::UpdateTeamIcons( void ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if ( !localPlayer ) {
return;
}
int localTeam = localPlayer->team;
bool spectating = localPlayer->spectating;
if( localPlayer->spectating ) {
idPlayer* spec = (idPlayer*)gameLocal.entities[ localPlayer->spectator ];
if( spec ) {
localTeam = spec->team;
localPlayer = spec;
} else {
localTeam = -1;
}
}
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
if( gameLocal.localClientNum == i ) {
continue;
}
//if entity i is a player, manage his icon.
if( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::GetClassType() ) && !gameLocal.entities[ i ]->fl.networkStale && !spectating ) {
idPlayer* player = static_cast<idPlayer*>(gameLocal.entities[ i ]);
//if the player is alive and not hidden, show his icon.
if( player->team == localTeam && !player->IsHidden() && !player->pfl.dead && gameLocal.mpGame.IsInGame( i ) ) {
if( teamIcons[ i ].GetHandle() < 0 ) {
teamIcons[ i ].CreateIcon( player->spawnArgs.GetString( player->team ? "mtr_team_icon_strogg" : "mtr_team_icon_marine" ), (player == localPlayer ? localPlayer->entityNumber + 1 : 0) );
}
teamIcons[ i ].UpdateIcon( player->GetPhysics()->GetOrigin() + player->spawnArgs.GetVector( (player->team ? "team_icon_height_strogg" : "team_icon_height_marine") ), localPlayer->GetRenderView()->viewaxis );
//else, the player is hidden, dead, or otherwise not needing an icon-- free it.
} else {
if( teamIcons[ i ].GetHandle() >= 0 ) {
teamIcons[ i ].FreeIcon();
}
}
//if entity i is not a player, free icon i from the map.
} else if( teamIcons[ i ].GetHandle() >= 0 ) {
teamIcons[ i ].FreeIcon();
}
}
}
void rvIconManager::UpdateChatIcons( void ) {
int localInst = gameLocal.GetLocalPlayer()->GetInstance();
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
if ( gameLocal.localClientNum == i ) {
continue;
}
if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::GetClassType() ) && !gameLocal.entities[ i ]->fl.networkStale ) {
idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[ i ] );
if ( player->isChatting &&
!player->IsHidden() &&
!( ( idPhysics_Player* )player->GetPhysics() )->IsDead() &&
gameLocal.mpGame.IsInGame( i )
&& (localInst == player->GetInstance())) {
if ( chatIcons[ i ].GetHandle() < 0 ) {
chatIcons[ i ].CreateIcon( player->spawnArgs.GetString( "mtr_icon_chatting" ), ( player == gameLocal.GetLocalPlayer() ? player->entityNumber + 1 : 0) );
}
int maxHeight = 0;
for ( int j = 0; j < icons[ i ].Num(); j++ ) {
if ( icons[ i ][ j ].First()->GetHeight() > maxHeight ) {
maxHeight = icons[ i ][ j ].First()->GetHeight();
}
}
if ( teamIcons[ i ].GetHandle() >= 0 && teamIcons[ i ].GetHeight() > maxHeight ) {
maxHeight = teamIcons[ i ].GetHeight();
}
idVec3 centerIconPosition = player->spawnArgs.GetVector( ( player->team ? "team_icon_height_strogg" : "team_icon_height_marine") );
centerIconPosition[ 2 ] += maxHeight;
chatIcons[ i ].UpdateIcon( player->GetPhysics()->GetOrigin() + centerIconPosition, gameLocal.GetLocalPlayer()->GetRenderView()->viewaxis );
} else if ( chatIcons[ i ].GetHandle() >= 0 ) {
chatIcons[ i ].FreeIcon();
}
} else if ( chatIcons[ i ].GetHandle() >= 0 ) {
chatIcons[ i ].FreeIcon();
}
}
}
/*
===============
rvIconManager::Shutdown
===============
*/
void rvIconManager::Shutdown( void ) {
int i, j;
for ( i = 0; i < MAX_CLIENTS; i++ ) {
for ( j = 0; j < icons[ i ].Num(); j++ ) {
icons[ i ][ j ].First()->FreeIcon();
}
icons[ i ].Clear();
teamIcons[ i ].FreeIcon();
chatIcons[ i ].FreeIcon();
}
}

30
source/game/IconManager.h Normal file
View file

@ -0,0 +1,30 @@
//----------------------------------------------------------------
// IconManager.h
//
// Copyright 2002-2004 Raven Software
//----------------------------------------------------------------
#ifndef __ICONMANAGER_H__
#define __ICONMANAGER_H__
#include "Icon.h"
const int ICON_STAY_TIME = 2000;
class rvIconManager {
public:
void AddIcon( int clientNum, const char* iconName );
void UpdateIcons( void );
void UpdateTeamIcons( void );
void UpdateChatIcons( void );
void Shutdown( void );
private:
idList<rvPair<rvIcon*, int> > icons[ MAX_CLIENTS ];
rvIcon teamIcons[ MAX_CLIENTS ];
rvIcon chatIcons[ MAX_CLIENTS ];
};
extern rvIconManager* iconManager;
#endif

233
source/game/Instance.cpp Normal file
View file

@ -0,0 +1,233 @@
//----------------------------------------------------------------
// Instance.cpp
//
// Copyright 2002-2005 Raven Software
//----------------------------------------------------------------
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Instance.h"
rvInstance::rvInstance( int id, bool deferPopulate ) {
instanceID = id;
spawnInstanceID = id;
gameLocal.AddClipWorld( id );
mapEntityNumbers = NULL;
numMapEntities = 0;
initialSpawnCount = idGameLocal::INITIAL_SPAWN_COUNT;
if ( !deferPopulate ) {
Populate();
}
}
rvInstance::~rvInstance() {
if ( mapEntityNumbers ) {
delete[] mapEntityNumbers;
mapEntityNumbers = NULL;
}
gameLocal.RemoveClipWorld( instanceID );
}
void rvInstance::Populate( int serverChecksum ) {
gameState_t currentState = gameLocal.GameState();
// disable the minSpawnIndex lock out
int latchMinSpawnIndex = gameLocal.minSpawnIndex;
gameLocal.minSpawnIndex = MAX_CLIENTS;
if ( currentState != GAMESTATE_STARTUP ) {
gameLocal.SetGameState( GAMESTATE_RESTART );
}
if ( gameLocal.isServer ) {
// When populating on a server, record the entity numbers
numMapEntities = gameLocal.GetNumMapEntities();
// mwhitlock: Dynamic memory consolidation
RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL);
if ( mapEntityNumbers ) {
delete[] mapEntityNumbers;
}
mapEntityNumbers = new unsigned short[ numMapEntities ];
RV_POP_HEAP();
memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities );
// read the index we should start populating at as transmitted by the server
gameLocal.firstFreeIndex = gameLocal.GetStartingIndexForInstance( instanceID );
//common->Printf( "pos: get starting index for instance %d sets firstFreeIndex to %d\n", instanceID, gameLocal.firstFreeIndex );
// remember the spawnCount ahead of time, so that the client can accurately reconstruct its spawnIds
gameLocal.SpawnMapEntities( spawnInstanceID, NULL, mapEntityNumbers, &initialSpawnCount );
// only build the message in MP
if ( gameLocal.isMultiplayer ) {
BuildInstanceMessage();
// force joins of anyone in our instance so they get potentially new map entitynumbers
for( int i = 0; i < MAX_CLIENTS; i++ ) {
PACIFIER_UPDATE;
idPlayer* player = (idPlayer*)gameLocal.entities[ i ];
if( player && player->GetInstance() == instanceID ) {
networkSystem->ServerSendReliableMessage( player->entityNumber, mapEntityMsg );
}
}
}
} else {
bool proto69 = ( gameLocal.GetCurrentDemoProtocol() == 69 );
// When populating on a client, spawn the map using existing numbers
// check for good state
// OK to spawn w/o specific entity numbers if we're in the startup process. Otherwise,
// we need entity numbers from the server.
// TTimo: only valid for backward 1.2 playback now
assert( !proto69 || ( mapEntityNumbers || ( instanceID == 0 && gameLocal.GameState() == GAMESTATE_STARTUP ) ) );
if ( !proto69 ) {
// have the client produce a log of the entity layout so we can match it with the server's
// this is also going to be used to issue the EV_FindTargets below
if ( mapEntityNumbers ) {
delete []mapEntityNumbers;
}
numMapEntities = gameLocal.GetNumMapEntities();
RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL);
mapEntityNumbers = new unsigned short[ numMapEntities ];
RV_POP_HEAP();
memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities );
}
gameLocal.firstFreeIndex = gameLocal.GetStartingIndexForInstance( instanceID );
gameLocal.SetSpawnCount( initialSpawnCount ); // that was transmitted through the instance msg
if ( proto69 ) {
gameLocal.SpawnMapEntities( spawnInstanceID, mapEntityNumbers, NULL );
} else {
gameLocal.SpawnMapEntities( spawnInstanceID, NULL, mapEntityNumbers );
LittleRevBytes( mapEntityNumbers, sizeof(unsigned short ), numMapEntities ); //DAJ
int checksum = MD5_BlockChecksum( mapEntityNumbers, sizeof( unsigned short ) * numMapEntities );
if ( serverChecksum != 0 && checksum != serverChecksum ) {
common->Error( "client side map populate checksum ( 0x%x ) doesn't match server's ( 0x%x )", checksum, serverChecksum );
}
}
}
for ( int i = 0; i < numMapEntities; i++ ) {
if ( mapEntityNumbers[ i ] < 0 || mapEntityNumbers[ i ] >= MAX_GENTITIES ) {
continue;
}
if ( (i % 100) == 0 ) {
PACIFIER_UPDATE;
}
idEntity* ent = gameLocal.entities[ mapEntityNumbers[ i ] ];
if ( ent ) {
ent->PostEventMS( &EV_FindTargets, 0 );
ent->PostEventMS( &EV_PostSpawn, 0 );
}
}
if ( currentState != GAMESTATE_STARTUP ) {
gameLocal.SetGameState( currentState );
}
// re-enable the min spawn index
assert( latchMinSpawnIndex == MAX_CLIENTS || gameLocal.firstFreeIndex <= latchMinSpawnIndex );
gameLocal.minSpawnIndex = latchMinSpawnIndex;
}
void rvInstance::PopulateFromMessage( const idBitMsg& msg ) {
bool proto69 = ( gameLocal.GetCurrentDemoProtocol() == 69 );
if ( proto69 ) {
numMapEntities = msg.ReadShort();
}
initialSpawnCount = msg.ReadShort();
delete[] mapEntityNumbers;
mapEntityNumbers = NULL;
if ( proto69 ) {
RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL);
mapEntityNumbers = new unsigned short[ numMapEntities ];
RV_POP_HEAP();
memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities );
for ( int i = 0; i < numMapEntities; i++ ) {
mapEntityNumbers[ i ] = msg.ReadShort();
}
Populate();
} else {
int populateIndex = msg.ReadLong();
gameLocal.ClientSetStartingIndex( populateIndex );
//common->Printf( "pos: set firstFreeIndex to %d\n", populateIndex );
int checksum = msg.ReadLong();
Populate( checksum );
}
}
void rvInstance::Restart( void ) {
if ( gameLocal.isMultiplayer ) {
Populate();
} else {
gameLocal.SpawnMapEntities();
}
}
void rvInstance::BuildInstanceMessage( void ) {
// Build the client join instance msg
mapEntityMsg.BeginWriting();
mapEntityMsg.Init( mapEntityMsgBuf, sizeof( byte ) * MAX_GAME_MESSAGE_SIZE );
mapEntityMsg.WriteByte( GAME_RELIABLE_MESSAGE_SET_INSTANCE );
mapEntityMsg.WriteByte( instanceID );
mapEntityMsg.WriteShort( initialSpawnCount );
// we need to send that down for tourney so the index will match
mapEntityMsg.WriteLong( gameLocal.GetStartingIndexForInstance( instanceID ) );
LittleRevBytes( mapEntityNumbers, sizeof(unsigned short ), numMapEntities ); //DAJ
int checksum = MD5_BlockChecksum( mapEntityNumbers, sizeof( unsigned short ) * numMapEntities );
//common->Printf( "pop: server checksum: 0x%x\n", checksum );
mapEntityMsg.WriteLong( checksum );
}
void rvInstance::JoinInstance( idPlayer* player ) {
assert( player && gameLocal.isServer );
// Transmit the instance information to the new client
if( gameLocal.isListenServer && player == gameLocal.GetLocalPlayer() ) {
gameLocal.mpGame.ServerSetInstance( instanceID );
} else {
networkSystem->ServerSendReliableMessage( player->entityNumber, mapEntityMsg );
}
}
void rvInstance::PrintMapNumbers( void ) {
gameLocal.Printf( "Instance: %d\n", instanceID );
gameLocal.Printf( "Num Map Entities: %d\n", numMapEntities );
for( int i = 0; i < numMapEntities; i++ ) {
gameLocal.Printf( "%d\n", mapEntityNumbers[ i ] );
}
}
/*
================
rvInstance::SetSpawnInstanceID
Sets the spawn instance ID for this instance. On the client, only instance 0 is ever
used, but it spawns in map entities for other instances. spawnInstanceID is used to
spawn map entities with the correct instance number on the client.
================
*/
void rvInstance::SetSpawnInstanceID( int newInstance ) {
assert( gameLocal.isClient );
spawnInstanceID = newInstance;
}

47
source/game/Instance.h Normal file
View file

@ -0,0 +1,47 @@
//----------------------------------------------------------------
// Instance.h
//
// Copyright 2002-2005 Raven Software
//----------------------------------------------------------------
#ifndef __INSTANCE_H__
#define __INSTANCE_H__
#include "Game_local.h"
class rvInstance {
public:
rvInstance( int id, bool deferPopulate = false );
~rvInstance();
void Populate( int serverChecksum = 0 );
void PopulateFromMessage( const idBitMsg& msg );
void Restart( void );
void JoinInstance( idPlayer* player );
int GetInstanceID( void );
void SetSpawnInstanceID( int newInstance );
void PrintMapNumbers( void );
int GetNumMapEntities( void ) { return numMapEntities; }
unsigned short GetMapEntityNumber( int i ) { return mapEntityNumbers[ i ]; }
private:
void BuildInstanceMessage( void );
int instanceID;
int spawnInstanceID;
unsigned short* mapEntityNumbers;
int numMapEntities;
int initialSpawnCount;
idBitMsg mapEntityMsg;
byte mapEntityMsgBuf[ MAX_GAME_MESSAGE_SIZE ];
};
ID_INLINE int rvInstance::GetInstanceID( void ) {
return instanceID;
}
#endif

2375
source/game/Item.cpp Normal file

File diff suppressed because it is too large Load diff

362
source/game/Item.h Normal file
View file

@ -0,0 +1,362 @@
// RAVEN BEGIN
// bdube: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 09/30/2004
#ifndef __GAME_ITEM_H__
#define __GAME_ITEM_H__
extern const int ARENA_POWERUP_MASK;
extern const idEventDef EV_ResetFlag;
extern const idEventDef EV_RespawnItem;
extern const idEventDef EV_SetGravity;
/*
===============================================================================
Items the player can pick up or use.
===============================================================================
*/
class idItem : public idEntity {
public:
CLASS_PROTOTYPE( idItem );
idItem();
virtual ~idItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void GetAttributes( idDict &attributes );
virtual bool GiveToPlayer( idPlayer *player );
virtual bool Pickup( idPlayer *player );
virtual void Think( void );
virtual void Present();
virtual void InstanceJoin( void );
virtual void InstanceLeave( void );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
// RAVEN BEGIN
// mekberg: added
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
// RAVEN END
enum {
EVENT_PICKUP = idEntity::EVENT_MAXEVENTS,
EVENT_RESPAWNFX,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
// networking
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual void Hide( void );
virtual void Show( void );
virtual bool ClientStale( void );
virtual void ClientUnstale( void );
int IsVisible() { return srvReady; }
rvClientEntityPtr<rvClientEffect> effectIdle;
bool simpleItem;
bool pickedUp;
const idDeclSkin* pickupSkin;
void Event_DropToFloor ( void );
protected:
void UpdateTrigger( void );
void SendPickupMsg( int clientNum );
idClipModel * trigger;
bool spin;
// only a small subset of idItem need their physics object synced
bool syncPhysics;
bool pulse;
bool canPickUp;
const idDeclSkin* skin;
private:
idVec3 orgOrigin;
rvPhysics_Particle physicsObj;
// for item pulse effect
int itemShellHandle;
const idMaterial * shellMaterial;
// used to update the item pulse effect
mutable bool inView;
mutable int inViewTime;
mutable int lastCycle;
mutable int lastRenderViewTime;
// synced through snapshots to indicate show/hide or pickupSkin state
// -1 on a client means undef, 0 not ready, 1 ready
public: // FIXME: Temp hack while Eric gets back to me about why GameState.cpp is trying to access this directly
int srvReady;
private: // FIXME: Temp hack while Eric gets back to me about why GameState.cpp is trying to access this directly
int clReady;
int itemPVSArea;
bool UpdateRenderEntity ( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
static bool ModelCallback ( renderEntity_s *renderEntity, const renderView_t *renderView );
void Event_Touch ( idEntity *other, trace_t *trace );
void Event_Trigger ( idEntity *activator );
void Event_Respawn ( void );
void Event_RespawnFx ( void );
void Event_Pickup ( int clientNum );
// RAVEN BEGIN
// abahr
void Event_SetGravity();
// RAVEN END
};
/*
===============================================================================
idItemPowerup
===============================================================================
*/
class idItemPowerup : public idItem {
public:
CLASS_PROTOTYPE( idItemPowerup );
idItemPowerup();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual bool GiveToPlayer( idPlayer *player );
virtual void Think( void );
virtual bool Pickup( idPlayer *player );
protected:
int time;
int type;
int droppedTime;
int team;
bool unique;
};
/*
===============================================================================
riDeadZonePowerup
===============================================================================
*/
class riDeadZonePowerup : public idItemPowerup {
public:
CLASS_PROTOTYPE( riDeadZonePowerup );
riDeadZonePowerup();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Pickup( idPlayer *player );
void Spawn();
void Show();
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
int powerup;
protected:
void ResetSpawn( int powerup );
private:
void Event_ResetSpawn( void );
};
/*
===============================================================================
rvItemCTFFlag
===============================================================================
*/
class rvItemCTFFlag : public idItem {
public:
CLASS_PROTOTYPE( rvItemCTFFlag );
rvItemCTFFlag();
void Spawn();
virtual bool GiveToPlayer ( idPlayer* player );
virtual bool Pickup( idPlayer *player );
static void ResetFlag( int type );
virtual void Think( void );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
private:
int team;
int powerup;
bool dropped;
void Event_ResetFlag( void );
void Event_LinkTrigger( void );
};
/*
===============================================================================
idObjective
===============================================================================
*/
class idObjective : public idItem {
public:
CLASS_PROTOTYPE( idObjective );
idObjective();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
idVec3 playerPos;
// RAVEN BEGIN
// mekberg: store triggered time for timed removal.
int triggerTime;
// RAVEN END
void Event_Trigger( idEntity *activator );
void Event_HideObjective( idEntity *e );
void Event_GetPlayerPos();
void Event_CamShot();
};
/*
===============================================================================
idMoveableItem
===============================================================================
*/
class idMoveableItem : public idItem {
public:
CLASS_PROTOTYPE( idMoveableItem );
idMoveableItem();
virtual ~idMoveableItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Think( void );
static void DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list );
static idEntity* DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
idPhysics_RigidBody physicsObj;
void Gib( const idVec3 &dir, const char *damageDefName );
void Event_Gib( const char *damageDefName );
};
/*
===============================================================================
Item removers.
===============================================================================
*/
class idItemRemover : public idEntity {
public:
CLASS_PROTOTYPE( idItemRemover );
void Spawn();
void RemoveItem( idPlayer *player );
private:
void Event_Trigger( idEntity *activator );
};
/*
===============================================================================
idObjectiveComplete
===============================================================================
*/
class idObjectiveComplete : public idItemRemover {
public:
CLASS_PROTOTYPE( idObjectiveComplete );
idObjectiveComplete();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
idVec3 playerPos;
// RAVEN BEGIN
// mekberg: store triggered time for timed removal.
int triggerTime;
// RAVEN END
void Event_Trigger( idEntity *activator );
void Event_HideObjective( idEntity *e );
void Event_GetPlayerPos();
};
/*
===============================================================================
rvObjectiveFailed
===============================================================================
*/
class rvObjectiveFailed : public idItemRemover {
public:
CLASS_PROTOTYPE( rvObjectiveFailed );
rvObjectiveFailed ();
private:
void Event_Trigger( idEntity *activator );
};
#endif /* !__GAME_ITEM_H__ */
// RAVEN END

1486
source/game/Light.cpp Normal file

File diff suppressed because it is too large Load diff

146
source/game/Light.h Normal file
View file

@ -0,0 +1,146 @@
#ifndef __GAME_LIGHT_H__
#define __GAME_LIGHT_H__
/*
===============================================================================
Generic light.
===============================================================================
*/
extern const idEventDef EV_Light_GetLightParm;
extern const idEventDef EV_Light_SetLightParm;
extern const idEventDef EV_Light_SetLightParms;
class idLight : public idEntity {
public:
CLASS_PROTOTYPE( idLight );
idLight();
~idLight();
void Spawn( void );
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
virtual void UpdateChangeableSpawnArgs( const idDict *source );
virtual void Think( void );
virtual void FreeLightDef( void );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
void Present( void );
void SaveState( idDict *args );
virtual void SetColor( float red, float green, float blue );
virtual void SetColor( const idVec4 &color );
virtual void GetColor( idVec3 &out ) const;
virtual void GetColor( idVec4 &out ) const;
const idVec3 & GetBaseColor( void ) const { return baseColor; }
void SetShader( const char *shadername );
void SetLightParm( int parmnum, float value );
void SetLightParms( float parm0, float parm1, float parm2, float parm3 );
void SetRadiusXYZ( float x, float y, float z );
void SetRadius( float radius );
void On( void );
void Off( void );
void Fade( const idVec4 &to, float fadeTime );
void FadeOut( float time );
void FadeIn( float time );
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void BecomeBroken( idEntity *activator );
qhandle_t GetLightDefHandle( void ) const { return lightDefHandle; }
void SetLightParent( idEntity *lparent ) { lightParent = lparent; }
void SetLightLevel( void );
// RAVEN BEGIN
// jshepard: other entities (speakers) need access to the refSound of a light object
void SetRefSound( int rSound ) { refSound.referenceSoundHandle = rSound;}
// ddynerman: sometimes the game needs to know if this light is ambient
bool IsAmbient( void ) { return renderLight.shader->IsAmbientLight(); }
// RAVEN END
virtual void ShowEditingDialog( void );
enum {
EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
renderLight_t renderLight; // light presented to the renderer
idVec3 localLightOrigin; // light origin relative to the physics origin
idMat3 localLightAxis; // light axis relative to physics axis
qhandle_t lightDefHandle; // handle to renderer light def
idStr brokenModel;
int levels;
int currentLevel;
idVec3 baseColor;
bool breakOnTrigger;
int count;
int triggercount;
idEntity * lightParent;
idVec4 fadeFrom;
idVec4 fadeTo;
int fadeStart;
int fadeEnd;
// RAVEN BEGIN
// bdube: light gui
idEntityPtr<idEntity> lightGUI;
// abahr:
float wait;
float random;
// RAVEN END
private:
bool soundWasPlaying;
void PresentLightDefChange( void );
void PresentModelDefChange( void );
// RAVEN BEGIN
// jscott: added events for light level
private:
void Event_SetCurrentLightLevel ( int in );
void Event_SetMaxLightLevel ( int in );
void Event_IsOn( void );
void Event_Break( idEntity *activator, float turnOff );
void Event_DoneBlinking( void );
void Event_DoneBlinkingOff( void );
void Event_EarthQuake( float requiresLOS );
void Event_Timer( void );
// RAVEN END
private:
void Event_SetShader( const char *shadername );
void Event_GetLightParm( int parmnum );
void Event_SetLightParm( int parmnum, float value );
void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 );
void Event_SetRadiusXYZ( float x, float y, float z );
void Event_SetRadius( float radius );
void Event_Hide( void );
void Event_Show( void );
void Event_On( void );
void Event_Off( void );
void Event_ToggleOnOff( idEntity *activator );
void Event_SetSoundHandles( void );
void Event_FadeOut( float time );
void Event_FadeIn( float time );
// RAVEN BEGIN
// bdube: set light gui
void Event_SetLightGUI( const char* gui );
// RAVEN END
};
// RAVEN BEGIN
// bdube: externed events
extern const idEventDef EV_Light_SetCurrentLightLevel;
extern const idEventDef EV_Light_SetMaxLightLevel;
extern const idEventDef EV_Light_SetRadius;
// RAVEN END
#endif /* !__GAME_LIGHT_H__ */

467
source/game/LipSync.cpp Normal file
View file

@ -0,0 +1,467 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
// 1 normal
// 2 scared
// 3 surprised
// 4 panicked
// 5 angry
// 6 suspicious with rt eyelid raised
// 7 suspicious with lft eyelid raised
// 8 curious
// 9 tired
// 10 happy
idCVar fas_debug( "fas_debug", "0", CVAR_INTEGER, "debug info for facial animation system" );
idCVar fas_threshhold0( "fas_threshhold0", "60", CVAR_INTEGER, "intensity required to use frame set 0" );
idCVar fas_threshhold1( "fas_threshhold1", "30", CVAR_INTEGER, "intensity required to use frame set 1" );
idCVar fas_blendBias( "fas_blendBias", "1.5", 0, "multiplier to the per phoneme blend time" );
idCVar fas_intensityBias( "fas_intensityBias", "0", CVAR_INTEGER, "bias applied to the intensity of the phoneme when trying to extract the viseme" );
idCVar fas_timeOffset( "fas_timeOffset", "50", CVAR_INTEGER, "ms offset to the viseme frame" );
idStr phonemeFile;
idHashTable<rvViseme> *visemeTable100;
idHashTable<rvViseme> *visemeTable66;
idHashTable<rvViseme> *visemeTable33;
/*
================
rvViseme::Init
================
*/
void rvViseme::Init( idStr &phon, int f, int bt )
{
phoneme = phon;
frame = f;
blendTime = bt;
}
/*
================
FAS_LoadPhonemes
Load in the the file that cross references phonemes with visemes.
================
*/
bool FAS_LoadPhonemes( const char *visemes )
{
idStr visemeFile;
rvViseme viseme;
idLexer lexer;
idToken token;
idStr phoneme;
int frame, blendTime, intensity;
phonemeFile = visemes;
visemeTable100->Clear();
visemeTable66->Clear();
visemeTable33->Clear();
common->Printf( "Loading viseme file: %s\n", visemes );
visemeFile = "lipsync/";
visemeFile += visemes;
visemeFile += ".viseme";
lexer.SetFlags( DECL_LEXER_FLAGS );
lexer.LoadFile( visemeFile );
if( !lexer.ExpectTokenString( "visemes" ) )
{
return( false );
}
if( !lexer.ExpectTokenString( "{" ) )
{
return( false );
}
while( true )
{
if( !lexer.ReadToken( &token ) )
{
return( false );
}
if( token == "}" )
{
break;
}
phoneme = token;
lexer.ExpectTokenString( "," );
frame = lexer.ParseInt();
lexer.ExpectTokenString( "," );
blendTime = lexer.ParseInt();
lexer.ExpectTokenString( "," );
intensity = lexer.ParseInt();
viseme.Init( phoneme, frame, blendTime );
if( intensity > fas_threshhold0.GetInteger() )
{
visemeTable100->Set( phoneme, viseme );
}
else if( intensity > fas_threshhold1.GetInteger() )
{
visemeTable66->Set( phoneme, viseme );
}
else
{
visemeTable33->Set( phoneme, viseme );
}
}
return( true );
}
/*
================
rvLipSyncData
================
*/
rvLipSyncData::rvLipSyncData( const rvDeclLipSync *ls, int time )
{
const char *lsd = ls->GetLipSyncData();
mLexer.SetFlags( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWNUMBERNAMES );
mLexer.LoadMemory( lsd, idStr::Length( lsd ), ls->GetName() );
mFlags = 0;
mFrame = 0;
mBlendTime = 0;
mEmotion = "idle";
mNextTokenTime = time;
}
void rvLipSyncData::SetFrame( int frame )
{
mLastFrame = mFrame;
mFrame = frame;
mVisemeStartTime = mNextTokenTime;
}
float rvLipSyncData::GetFrontLerp( void )
{
float lerp = 1.0f - idMath::ClampFloat( 0.0f, 1.0f, ( float )( gameLocal.GetTime() + fas_timeOffset.GetInteger() - mVisemeStartTime ) / ( float )mBlendTime );
return( lerp );
}
/*
================
FAS_StartVisemeExtraction
Use a lexer to extract the phoneme data. This is a pretty slow but safe way.
There shouldn't be much in the way of multiple lip syncs going on, and if there are, it should be in a non performance critical cinematic.
================
*/
rvLipSyncData *FAS_StartVisemeExtraction( const rvDeclLipSync *ls, int time )
{
rvLipSyncData *lsd;
lsd = new rvLipSyncData( ls, time );
return( lsd );
}
/*
================
FAS_EndVisemeExtraction
Delete the workspace. FAS could use a void pointer if it wanted
================
*/
void FAS_EndVisemeExtraction( rvLipSyncData *lsd )
{
delete lsd;
}
/*
================
FAS_ExtractViseme
Extract the correct viseme frame from the lexer
================
*/
void FAS_ExtractViseme( rvLipSyncData *lsd, int time )
{
idToken token;
rvViseme *viseme;
idStr phoneme, duration;
int index, intensity;
// Make sure not to return any garbage
lsd->ClearFlags();
// Grab all the visemes, phrases and emotions until we are current
while( lsd->Ready( time ) )
{
if( !lsd->ReadToken( &token ) )
{
lsd->SetFlags( FAS_ENDED );
return;
}
if( token == "<" )
{
// Extract phrase
if( !lsd->ReadToken( &token ) )
{
common->Printf( "Failed to parse phrase from phoneme string\n" );
lsd->SetFlags( FAS_ENDED );
return;
}
lsd->SetLastPhrase( token );
lsd->ExpectTokenString( ">" );
lsd->SetFlags( FAS_NEW_PHRASE );
}
else if( token == "{" )
{
// Extract emotion
if( !lsd->ReadToken( &token ) )
{
common->Printf( "Failed to parse emotion from phoneme string\n" );
lsd->SetFlags( FAS_ENDED );
return;
}
lsd->SetEmotion( token );
lsd->ExpectTokenString( "}" );
lsd->SetFlags( FAS_NEW_EMOTION );
}
else
{
// Extract phoneme data
index = 0;
phoneme = idStr( token[index] );
if( isupper( phoneme[0] ) )
{
index++;
phoneme += token[index];
}
// Extract duration
index++;
duration = idStr( token[index] );
index++;
if( isdigit( token[index] ) )
{
duration += token[index];
index++;
}
// Extract intensity
intensity = ( token[index] - 'a' ) * 4;
intensity += fas_intensityBias.GetInteger();
// Extract the viseme data for the selected viseme
viseme = NULL;
if( intensity > fas_threshhold0.GetInteger() )
{
visemeTable100->Get( phoneme, &viseme );
}
if( intensity > fas_threshhold1.GetInteger() )
{
visemeTable66->Get( phoneme, &viseme );
}
else
{
visemeTable33->Get( phoneme, &viseme );
}
if( !viseme )
{
common->Printf( "FAS: Failed to find phoneme %s intensity %d", phoneme.c_str(), intensity );
lsd->SetFlags( FAS_ENDED );
return;
}
lsd->SetFrame( viseme->GetFrame() );
lsd->SetNextTokenTime( atol( duration ) * 10 );
lsd->SetBlendTime( int( viseme->GetBlendTime() * fas_blendBias.GetFloat() ) );
lsd->SetFlags( FAS_NEW_VISEME );
}
}
}
/*
================
FAS_Reload_f
================
*/
void FAS_Reload_f( const idCmdArgs &args )
{
// mekberg: disable non pre-cached warnings
fileSystem->SetIsFileLoadingAllowed( true );
FAS_LoadPhonemes( phonemeFile.c_str() );
fileSystem->SetIsFileLoadingAllowed( false );
}
/*
================
FAS_Init
================
*/
bool FAS_Init( const char *visemes )
{
// jnewquist: Tag scope and callees to track allocations using "new".
MEM_SCOPED_TAG( tag, MA_ANIM );
cmdSystem->AddCommand( "reloadFAS", FAS_Reload_f, CMD_FL_SYSTEM, "reloads the viseme data" );
return( FAS_LoadPhonemes( visemes ) );
}
/*
================
FAS_Shutdown
================
*/
void FAS_Shutdown( void )
{
phonemeFile.Clear();
if ( visemeTable100 ) {
visemeTable100->Clear();
visemeTable66->Clear();
visemeTable33->Clear();
}
cmdSystem->RemoveCommand( "reloadFAS" );
}
/*
================
idAFAttachment::EndLipSyncing
================
*/
void idAFAttachment::EndLipSyncing( void )
{
frameBlend_t frameBlend = { 0, 0, 0, 1.0f, 0.0f };
animator.SetFrame( ANIMCHANNEL_TORSO, lipSyncAnim, frameBlend );
animator.CycleAnim( ANIMCHANNEL_HEAD, animator.GetAnim( "emotion_idle" ), gameLocal.time, 200 );
animator.CycleAnim( ANIMCHANNEL_EYELIDS, animator.GetAnim( "emotion_idle" ), gameLocal.time, 200 );
FAS_EndVisemeExtraction( lipSyncData );
lipSyncData = NULL;
}
/*
================
idAFAttachment::StartLipSyncing
================
*/
int idAFAttachment::StartLipSyncing( const char *speechDecl )
{
int length;
length = 0;
// Clean up any spurious data
EndLipSyncing();
// Start a new lipsync if there is one
if( speechDecl[0] )
{
const rvDeclLipSync *lipSync;
int emotion;
idStr anim;
lipSync = declManager->FindLipSync( speechDecl );
lipSyncData = FAS_StartVisemeExtraction( lipSync, gameLocal.GetTime() );
// Output debug info
if( lipSync->GetDescription() && fas_debug.GetInteger() )
{
gameLocal.Printf( "Name: %s\n", speechDecl );
gameLocal.Printf( "Sub: %s\n", lipSync->GetDescription().c_str() );
gameLocal.Printf( "Lip: %s\n", lipSync->GetLipSyncData() );
}
// Start the associated sound
refSound.diversity = 0.0f;
renderEntity.referenceSoundHandle = refSound.referenceSoundHandle;
StartSoundShader( declManager->FindSound( lipSync->GetName() ), SND_CHANNEL_VOICE, refSound.parms.soundShaderFlags | SSF_IS_VO, false, &length );
// Start the default emotion
anim = "emotion_";
anim += lipSyncData->GetEmotion();
emotion = animator.GetAnim( anim );
animator.CycleAnim( ANIMCHANNEL_HEAD, emotion, gameLocal.time, 200 );
animator.CycleAnim( ANIMCHANNEL_EYELIDS, emotion, gameLocal.time, 200 );
}
return( length );
}
/*
================
idAFAttachment::HandleLipSync
================
*/
void idAFAttachment::HandleLipSync( void )
{
idStr anim;
int emotion;
if( !lipSyncData )
{
return;
}
FAS_ExtractViseme( lipSyncData, gameLocal.GetTime() + fas_timeOffset.GetInteger() );
if( lipSyncData->HasEnded() )
{
EndLipSyncing();
return;
}
// If frame non zero - blend to it as a new viseme
if( lipSyncData->GetFrame() || lipSyncData->GetLastFrame() )
{
frameBlend_t frameBlend;
frameBlend.cycleCount = 0;
frameBlend.frame1 = idMath::ClampInt( 0, 120, lipSyncData->GetLastFrame() - 1 );
frameBlend.frame2 = idMath::ClampInt( 0, 120, lipSyncData->GetFrame() - 1 );
frameBlend.frontlerp = lipSyncData->GetFrontLerp();
frameBlend.backlerp = 1.0f - frameBlend.frontlerp;
animator.SetFrame( ANIMCHANNEL_TORSO, lipSyncAnim, frameBlend );
if( fas_debug.GetInteger() > 1 )
{
common->Printf( "Blending: %d (%2f) -> %d (%2f)\n", frameBlend.frame1, frameBlend.frontlerp, frameBlend.frame2, frameBlend.backlerp );
}
}
// If an embedded emotion command, play it.
if( lipSyncData->HasNewEmotion() )
{
anim = "emotion_";
anim += lipSyncData->GetEmotion();
emotion = animator.GetAnim( anim );
animator.CycleAnim( ANIMCHANNEL_HEAD, emotion, gameLocal.time, 200 );
animator.CycleAnim( ANIMCHANNEL_EYELIDS, emotion, gameLocal.time, 200 );
if( fas_debug.GetInteger() )
{
common->Printf( "Emotion: %s\n", lipSyncData->GetEmotion().c_str() );
}
}
// If a new phrase, display in debug mode
if( fas_debug.GetInteger() && lipSyncData->HasNewPhrase() )
{
common->Printf( "Phrase: %s(%i)\n", lipSyncData->GetLastPhrase().c_str(), lipSyncData->GetFrame() );
}
}
// end

87
source/game/LipSync.h Normal file
View file

@ -0,0 +1,87 @@
#ifndef _LIPSYNC_H_INC_
#define _LIPSYNC_H_INC_
// Possible TBDs
// Auto head swapping from simple to lip sync head
// Return time of sound from the speak call for the script to wait
// Set emotion directly without encoding it into the string
class rvViseme
{
public:
rvViseme( void ) {}
~rvViseme( void ) { phoneme.Clear(); }
void Init( idStr &phon, int f, int bt );
int GetFrame( void ) const { return( frame ); }
int GetBlendTime( void ) const { return( blendTime ); }
private:
idStr phoneme;
int frame;
int blendTime;
};
#define FAS_NEW_VISEME BIT( 0 )
#define FAS_NEW_PHRASE BIT( 1 )
#define FAS_NEW_EMOTION BIT( 2 )
#define FAS_ENDED BIT( 3 )
class rvLipSyncData
{
public:
rvLipSyncData( const rvDeclLipSync *ls, int time );
~rvLipSyncData( void ) {}
bool Ready( int time ) { return( time >= mNextTokenTime ); }
int ReadToken( idToken *token ) { return( mLexer.ReadToken( token ) ); }
int ExpectTokenString( const char *str ) { return( mLexer.ExpectTokenString( str ) ); }
void SetNextTokenTime( int time ) { mNextTokenTime += time; }
void ClearFlags( void ) { mFlags = 0; }
void SetFlags( int flags ) { mFlags |= flags; }
bool HasNewPhoneme( void ) const { return( !!( mFlags & FAS_NEW_VISEME ) ); }
bool HasNewPhrase( void ) const { return( !!( mFlags & FAS_NEW_PHRASE ) ); }
bool HasNewEmotion( void ) const { return( !!( mFlags & FAS_NEW_EMOTION ) ); }
bool HasEnded( void ) const { return( !!( mFlags & FAS_ENDED ) ); }
void SetFrame( int frame );
int GetFrame( void ) const { return( mFrame ); }
int GetLastFrame( void ) { return( mLastFrame ); }
void SetBlendTime( int bt ) { mBlendTime = bt; }
int GetBlendTime( void ) const { return( mBlendTime ); }
float GetFrontLerp( void );
void SetEmotion( idStr &str ) { mEmotion = str; }
const idStr &GetEmotion( void ) const { return( mEmotion ); }
void SetLastPhrase( idStr &str ) { mLastPhrase = str; }
const idStr &GetLastPhrase( void ) const { return( mLastPhrase ); }
private:
int mNextTokenTime;
int mFlags;
int mFrame;
int mLastFrame;
int mVisemeStartTime;
int mBlendTime;
idStr mEmotion;
idStr mLastPhrase;
idLexer mLexer;
};
bool FAS_Init( const char *visemes );
void FAS_Shutdown( void );
void FAS_ExtractViseme( class rvLipSyncData *lsd, int time );
class rvLipSyncData *FAS_StartVisemeExtraction( const rvDeclLipSync *ls, int time );
void FAS_EndVisemeExtraction( class rvLipSyncData *lsd );
extern idCVar fas_debug;
extern idCVar fas_timeOffset;
#endif // _LIPSYNC_H_INC_

4386
source/game/Misc.cpp Normal file

File diff suppressed because it is too large Load diff

974
source/game/Misc.h Normal file
View file

@ -0,0 +1,974 @@
#ifndef __GAME_MISC_H__
#define __GAME_MISC_H__
/*
===============================================================================
idSpawnableEntity
A simple, spawnable entity with a model and no functionable ability of it's own.
For example, it can be used as a placeholder during development, for marking
locations on maps for script, or for simple placed models without any behavior
that can be bound to other entities. Should not be subclassed.
===============================================================================
*/
class idSpawnableEntity : public idEntity {
public:
CLASS_PROTOTYPE( idSpawnableEntity );
void Spawn( void );
private:
};
/*
===============================================================================
Potential spawning position for players.
The first time a player enters the game, they will be at an 'initial' spot.
Targets will be fired when someone spawns in on them.
When triggered, will cause player to be teleported to spawn spot.
===============================================================================
*/
class idPlayerStart : public idEntity {
public:
CLASS_PROTOTYPE( idPlayerStart );
enum {
EVENT_TELEPORTPLAYER = idEntity::EVENT_MAXEVENTS,
EVENT_TELEPORTITEM,
EVENT_MAXEVENTS
};
idPlayerStart( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
int teleportStage;
void Event_TeleportEntity( idEntity *activator, bool predicted, idVec3& prevOrigin = vec3_origin );
void Event_Teleport( idEntity *activator );
void Teleport( idEntity* other );
void Event_TeleportStage( idPlayer *player );
void Event_ResetCamera( idPlayer *player );
void TeleportPlayer( idPlayer *player );
};
/*
===============================================================================
Non-displayed entity used to activate triggers when it touches them.
Bind to a mover to have the mover activate a trigger as it moves.
When target by triggers, activating the trigger will toggle the
activator on and off. Check "start_off" to have it spawn disabled.
===============================================================================
*/
class idActivator : public idEntity {
public:
CLASS_PROTOTYPE( idActivator );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
bool stay_on;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
Path entities for monsters to follow.
===============================================================================
*/
class idPathCorner : public idEntity {
public:
CLASS_PROTOTYPE( idPathCorner );
void Spawn( void );
static void DrawDebugInfo( void );
static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore );
private:
void Event_RandomPath( void );
};
// RAVEN BEGIN
// bdube: jump points
/*
===============================================================================
Debug Jump Point
===============================================================================
*/
class rvDebugJumpPoint : public idEntity {
public:
CLASS_PROTOTYPE( rvDebugJumpPoint );
void Spawn();
};
/*
===============================================================================
Object that fires targets and changes shader parms when damaged.
===============================================================================
*/
class idDamagable : public idEntity {
public:
CLASS_PROTOTYPE( idDamagable );
idDamagable( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// RAVEN BEGIN
// abahr:
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
int invincibleTime;
// RAVEN BEGIN
// abahr: changed to protected
protected:
int stage;
int stageNext;
const idDict* stageDict;
int stageEndTime;
int stageEndHealth;
int stageEndSpeed;
//jshepard: used to end a stage if a moveable is on the ground (for falling objects)
bool stageEndOnGround;
//jshepard: we want to activate certain objects when triggered-- falling blocks yes, barrels no.
bool activateStageOnTrigger;
virtual void ExecuteStage ( void );
void UpdateStage ( void );
idVec3 GetStageVector ( const char* key, const char* defaultString = "" ) const;
float GetStageFloat ( const char* key, const char* defaultString = "" ) const;
int GetStageInt ( const char* key, const char* defaultString = "" ) const;
// RAVEN END
int count;
int nextTriggerTime;
void BecomeBroken( idEntity *activator );
void Event_BecomeBroken( idEntity *activator );
void Event_RestoreDamagable( void );
};
/*
===============================================================================
Hidden object that explodes when activated
===============================================================================
*/
class idExplodable : public idEntity {
public:
CLASS_PROTOTYPE( idExplodable );
void Spawn( void );
private:
void Event_Explode( idEntity *activator );
};
/*
===============================================================================
idSpring
===============================================================================
*/
class idSpring : public idEntity {
public:
CLASS_PROTOTYPE( idSpring );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
idEntityPtr<idEntity> ent1;
idEntityPtr<idEntity> ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
void Event_LinkSpring( void );
};
/*
===============================================================================
idForceField
===============================================================================
*/
class idForceField : public idEntity {
public:
CLASS_PROTOTYPE( idForceField );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Think( void );
// RAVEN BEGIN
// kfuller: idDamagable may want to change some things on the fly
void SetExplosion(float force) { forceField.Explosion(force); }
// RAVEN END
// RAVEN BEGIN
// bdube: made force field protected
protected:
idForce_Field forceField;
private:
// RAVEN END
void Toggle( void );
void Event_Activate( idEntity *activator );
void Event_Toggle( void );
void Event_FindTargets( void );
};
// RAVEN BEGIN
// bdube: jump pads
/*
===============================================================================
rvJumpPad
===============================================================================
*/
class rvJumpPad : public idForceField {
public:
CLASS_PROTOTYPE( rvJumpPad );
rvJumpPad ( void );
void Spawn( void );
void Think( void );
private:
int lastEffectTime;
void Event_FindTargets( void );
enum {
EVENT_JUMPFX = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
idMat3 effectAxis;
};
// RAVEN END
/*
===============================================================================
idAnimated
===============================================================================
*/
class idAnimated : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAnimated );
idAnimated();
~idAnimated();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual bool LoadAF( const char* keyname );
bool StartRagdoll( void );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// RAVEN BEGIN
// bdube: script
void Think ( void );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
// RAVEN END
private:
int num_anims;
int current_anim_index;
int anim;
int blendFrames;
jointHandle_t soundJoint;
idEntityPtr<idEntity> activator;
bool activated;
// RAVEN BEGIN
// bdube: script variables
// script control
idThread * scriptThread;
idStr state;
idStr idealState;
int animDoneTime[ANIM_NumAnimChannels];
// Script state management
void UpdateScript( void );
void SetState( const char *statename, int blend );
void CallHandler ( const char* handler );
// RAVEN END
void PlayNextAnim( void );
void Event_Activate( idEntity *activator );
void Event_Start( void );
void Event_StartRagdoll( void );
void Event_AnimDone( int animIndex );
void Event_Footstep( void );
void Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay );
void Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay );
// RAVEN BEGIN
// kfuller: added
void Event_SetAnimState( const char* state, int blendframes );
void Event_PlayAnim( int channel, const char *animname );
void Event_PlayCycle( int channel, const char *animname );
void Event_AnimDone2( int channel, int blendFrames );
// RAVEN END
};
/*
===============================================================================
idStaticEntity
===============================================================================
*/
class idStaticEntity : public idEntity {
public:
CLASS_PROTOTYPE( idStaticEntity );
idStaticEntity( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void ShowEditingDialog( void );
virtual void Hide( void );
virtual void Show( void );
void Fade( const idVec4 &to, float fadeTime );
virtual void Think( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
void Event_Activate( idEntity *activator );
int spawnTime;
bool active;
idVec4 fadeFrom;
idVec4 fadeTo;
int fadeStart;
int fadeEnd;
bool runGui;
};
/*
===============================================================================
idFuncEmitter
===============================================================================
*/
class idFuncEmitter : public idStaticEntity {
public:
CLASS_PROTOTYPE( idFuncEmitter );
idFuncEmitter( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void Event_Activate( idEntity *activator );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
bool hidden;
};
// RAVEN BEGIN
// bdube: not using
#if 0
// RAVEN END
/*
===============================================================================
idFuncSmoke
===============================================================================
*/
class idFuncSmoke : public idEntity {
public:
CLASS_PROTOTYPE( idFuncSmoke );
idFuncSmoke();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void Event_Activate( idEntity *activator );
private:
int smokeTime;
const idDeclParticle * smoke;
bool restart;
};
// RAVEN BEGIN
// bdube: not using
#endif
// RAVEN END
/*
===============================================================================
idFuncSplat
===============================================================================
*/
class idFuncSplat : public idFuncEmitter {
public:
CLASS_PROTOTYPE( idFuncSplat );
idFuncSplat( void );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
void Event_Splat();
};
/*
===============================================================================
idTextEntity
===============================================================================
*/
class idTextEntity : public idEntity {
public:
CLASS_PROTOTYPE( idTextEntity );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void ClientPredictionThink( void );
private:
idStr text;
bool playerOriented;
};
/*
===============================================================================
idLocationEntity
===============================================================================
*/
class idLocationEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationEntity );
void Spawn( void );
const char * GetLocation( void ) const;
private:
};
class idLocationSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationSeparatorEntity );
void Spawn( void );
private:
};
class idVacuumSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idVacuumSeparatorEntity );
idVacuumSeparatorEntity( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Event_Activate( idEntity *activator );
private:
qhandle_t portal;
};
class idVacuumEntity : public idEntity {
public:
CLASS_PROTOTYPE( idVacuumEntity );
void Spawn( void );
private:
};
// RAVEN BEGIN
// abahr
class rvGravitySeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( rvGravitySeparatorEntity );
rvGravitySeparatorEntity( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Event_Activate( idEntity *activator );
private:
qhandle_t portal;
};
class rvGravityArea : public idEntity {
public:
ABSTRACT_PROTOTYPE( rvGravityArea );
void Spawn( void );
virtual int GetArea() const { return area; }
virtual const idVec3 GetGravity( const idVec3& origin, const idMat3& axis, int clipMask, idEntity* passEntity ) const = 0;
virtual const idVec3 GetGravity( const idEntity* ent ) const = 0;
virtual const idVec3 GetGravity( const rvClientEntity* ent ) const = 0;
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
bool IsEqualTo( const rvGravityArea* area ) const;
bool operator==( const rvGravityArea* area ) const;
bool operator==( const rvGravityArea& area ) const;
bool operator!=( const rvGravityArea* area ) const;
bool operator!=( const rvGravityArea& area ) const;
protected:
int area;
};
class rvGravityArea_Static : public rvGravityArea {
public:
CLASS_PROTOTYPE( rvGravityArea_Static );
void Spawn( void );
virtual const idVec3 GetGravity( const idVec3& origin, const idMat3& axis, int clipMask, idEntity* passEntity ) const { return gravity; }
virtual const idVec3 GetGravity( const idEntity* ent ) const { return gravity; }
virtual const idVec3 GetGravity( const rvClientEntity* ent ) const { return gravity; }
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
protected:
idVec3 gravity;
};
class rvGravityArea_SurfaceNormal : public rvGravityArea {
public:
CLASS_PROTOTYPE( rvGravityArea_SurfaceNormal );
virtual const idVec3 GetGravity( const idVec3& origin, const idMat3& axis, int clipMask, idEntity* passEntity ) const;
virtual const idVec3 GetGravity( const idEntity* ent ) const;
virtual const idVec3 GetGravity( const rvClientEntity* ent ) const;
protected:
virtual const idVec3 GetGravity( const idPhysics* physics ) const;
};
// RAVEN END
/*
===============================================================================
idBeam
===============================================================================
*/
class idBeam : public idEntity {
public:
CLASS_PROTOTYPE( idBeam );
idBeam();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void SetMaster( idBeam *masterbeam );
void SetBeamTarget( const idVec3 &origin );
virtual void Show( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
void Event_MatchTarget( void );
void Event_Activate( idEntity *activator );
idEntityPtr<idBeam> target;
idEntityPtr<idBeam> master;
};
/*
===============================================================================
idLiquid
===============================================================================
*/
class idRenderModelLiquid;
class idLiquid : public idEntity {
public:
CLASS_PROTOTYPE( idLiquid );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
void Event_Touch( idEntity *other, trace_t *trace );
idRenderModelLiquid *model;
};
/*
===============================================================================
idShaking
===============================================================================
*/
class idShaking : public idEntity {
public:
CLASS_PROTOTYPE( idShaking );
idShaking();
~idShaking();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idPhysics_Parametric physicsObj;
bool active;
void BeginShaking( void );
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idEarthQuake
===============================================================================
*/
class idEarthQuake : public idEntity {
public:
CLASS_PROTOTYPE( idEarthQuake );
idEarthQuake();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
// RAVEN BEGIN
// kfuller: look for fx entities and the like that may want to be triggered when a mortar round (aka earthquake) goes off
protected:
void AffectNearbyEntities(float affectRadius);
// RAVEN END
private:
int nextTriggerTime;
int shakeStopTime;
float wait;
float random;
bool triggered;
bool playerOriented;
bool disabled;
float shakeTime;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncPortal
===============================================================================
*/
class idFuncPortal : public idEntity {
public:
CLASS_PROTOTYPE( idFuncPortal );
idFuncPortal();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
qhandle_t portal;
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncAASPortal
===============================================================================
*/
class idFuncAASPortal : public idEntity {
public:
CLASS_PROTOTYPE( idFuncAASPortal );
idFuncAASPortal();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncAASObstacle
===============================================================================
*/
class idFuncAASObstacle : public idEntity {
public:
CLASS_PROTOTYPE( idFuncAASObstacle );
idFuncAASObstacle();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetState ( bool _state );
private:
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncRadioChatter
===============================================================================
*/
class idFuncRadioChatter : public idEntity {
public:
CLASS_PROTOTYPE( idFuncRadioChatter );
idFuncRadioChatter();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
static void RepeatLast ( void );
private:
static idEntityPtr<idFuncRadioChatter> lastRadioChatter;
float time;
bool isActive;
void Event_Activate( idEntity *activator );
void Event_ResetRadioHud( idEntity *activator );
void Event_IsActive( void );
};
/*
===============================================================================
idPhantomObjects
===============================================================================
*/
class idPhantomObjects : public idEntity {
public:
CLASS_PROTOTYPE( idPhantomObjects );
idPhantomObjects();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
void Event_Activate( idEntity *activator );
void Event_Throw( void );
void Event_ShakeObject( idEntity *object, int starttime );
int end_time;
float throw_time;
float shake_time;
idVec3 shake_ang;
float speed;
int min_wait;
int max_wait;
idEntityPtr<idActor>target;
idList<int> targetTime;
idList<idVec3> lastTargetPos;
};
/*
===============================================================================
rvFuncSaveGame
===============================================================================
*/
class rvFuncSaveGame : public idEntity {
public:
CLASS_PROTOTYPE( rvFuncSaveGame );
void Spawn( void );
void Event_Activate ( idEntity *activator );
private:
};
#endif /* !__GAME_MISC_H__ */

1347
source/game/Moveable.cpp Normal file

File diff suppressed because it is too large Load diff

179
source/game/Moveable.h Normal file
View file

@ -0,0 +1,179 @@
// RAVEN BEGIN
// bdube: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 06/02/2004
#ifndef __GAME_MOVEABLE_H__
#define __GAME_MOVEABLE_H__
/*
===============================================================================
Entity using rigid body physics.
===============================================================================
*/
extern const idEventDef EV_BecomeNonSolid;
extern const idEventDef EV_IsAtRest;
class idMoveable : public idDamagable {
public:
CLASS_PROTOTYPE( idMoveable );
idMoveable( void );
~idMoveable( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void Hide( void );
virtual void Show( void );
bool AllowStep( void ) const;
void EnableDamage( bool enable, float duration );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
protected:
idPhysics_RigidBody physicsObj; // physics object
idStr brokenModel; // model set when health drops down to or below zero
idStr damage; // if > 0 apply damage to hit entities
int nextCollideFxTime; // next time it is ok to spawn collision fx
float minDamageVelocity; // minimum velocity before moveable applies damage
float maxDamageVelocity; // velocity at which the maximum damage is applied
idCurve_Spline<idVec3> *initialSpline; // initial spline path the moveable follows
idVec3 initialSplineDir; // initial relative direction along the spline path
bool unbindOnDeath; // unbind from master when health drops down to or below zero
bool allowStep; // allow monsters to step on the object
bool canDamage; // only apply damage when this is set
idEntityPtr<idEntity> lastAttacker;
virtual void ExecuteStage ( void );
const idMaterial * GetRenderModelMaterial( void ) const;
void BecomeNonSolid( void );
void InitInitialSpline( int startTime );
bool FollowInitialSplinePath( void );
void Event_Activate( idEntity *activator );
void Event_BecomeNonSolid( void );
void Event_SetOwnerFromSpawnArgs( void );
void Event_IsAtRest( void );
void Event_CanDamage ( float enable );
void Event_SetHealth ( float newHealth );
void Event_RadiusDamage( idEntity *attacker, const char* splash );
};
/*
===============================================================================
A barrel using rigid body physics. The barrel has special handling of
the view model orientation to make it look like it rolls instead of slides.
===============================================================================
*/
class idBarrel : public idMoveable {
public:
CLASS_PROTOTYPE( idBarrel );
idBarrel();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void BarrelThink( void );
virtual void Think( void );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual void ClientPredictionThink( void );
private:
float radius; // radius of barrel
int barrelAxis; // one of the coordinate axes the barrel cylinder is parallel to
idVec3 lastOrigin; // origin of the barrel the last think frame
idMat3 lastAxis; // axis of the barrel the last think frame
float additionalRotation; // additional rotation of the barrel about it's axis
idMat3 additionalAxis; // additional rotation axis
};
/*
===============================================================================
A barrel using rigid body physics and special handling of the view model
orientation to make it look like it rolls instead of slides. The barrel
can burn and explode when damaged.
===============================================================================
*/
class idExplodingBarrel : public idBarrel {
public:
CLASS_PROTOTYPE( idExplodingBarrel );
idExplodingBarrel();
~idExplodingBarrel();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
const char *damageDefName, const float damageScale, const int location );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
typedef enum {
NORMAL = 0,
BURNING,
BURNEXPIRED,
EXPLODING,
EXPLODED
} explode_state_t;
explode_state_t state;
idVec3 spawnOrigin;
idMat3 spawnAxis;
qhandle_t ipsHandle;
qhandle_t lightHandle;
renderEntity_t ipsEntity;
renderLight_t light;
int ipsTime;
int lightTime;
float time;
int explodeFinishTime;
void AddIPS( const char *name, bool burn );
void AddLight( const char *name , bool burn );
void ExplodingEffects( void );
void Event_Activate( idEntity *activator );
void Event_Respawn();
void Event_Explode();
void Event_TriggerTargets();
};
#endif /* !__GAME_MOVEABLE_H__ */
// RAVEN END

5977
source/game/Mover.cpp Normal file

File diff suppressed because it is too large Load diff

707
source/game/Mover.h Normal file
View file

@ -0,0 +1,707 @@
#ifndef __GAME_MOVER_H__
#define __GAME_MOVER_H__
extern const idEventDef EV_TeamBlocked;
extern const idEventDef EV_PartBlocked;
extern const idEventDef EV_ReachedPos;
extern const idEventDef EV_ReachedAng;
// RAVEN BEGIN
// bdube: more externs
extern const idEventDef EV_Door_Lock;
extern const idEventDef EV_Door_IsLocked;
// abahr:
extern const idEventDef EV_GetSplineEntity;
extern const idEventDef EV_MoveAlongVector;
extern const idEventDef EV_Door_Open;
extern const idEventDef EV_Door_Close;
extern const idEventDef EV_Door_IsOpen;
extern const idEventDef EV_Move;
extern const idEventDef EV_RotateOnce;
// twhitaker:
extern const idEventDef EV_Speed;
extern const idEventDef EV_IsActive;
extern const idEventDef EV_IsMoving;
// mekberg: spline sampling
#define SPLINE_SAMPLE_RATE 60.0f
// RAVEN END
/*
===============================================================================
General movers.
===============================================================================
*/
class idMover : public idEntity {
public:
CLASS_PROTOTYPE( idMover );
idMover( void );
~idMover( void );
void Spawn( void );
// RAVEN BEGIN
// mekberg: added
void Think( void );
// RAVEN END
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual void Hide( void );
virtual void Show( void );
void SetPortalState( bool open );
// RAVEN BEGIN
// mekberg: sounds for splines
void UpdateSplineStage ( void );
// RAVEN END
protected:
typedef enum {
ACCELERATION_STAGE,
LINEAR_STAGE,
DECELERATION_STAGE,
FINISHED_STAGE
} moveStage_t;
typedef enum {
MOVER_NONE,
MOVER_ROTATING,
MOVER_MOVING,
MOVER_SPLINE
} moverCommand_t;
//
// mover directions. make sure to change script/doom_defs.script if you add any, or change their order
//
typedef enum {
DIR_UP = -1,
DIR_DOWN = -2,
DIR_LEFT = -3,
DIR_RIGHT = -4,
DIR_FORWARD = -5,
DIR_BACK = -6,
DIR_REL_UP = -7,
DIR_REL_DOWN = -8,
DIR_REL_LEFT = -9,
DIR_REL_RIGHT = -10,
DIR_REL_FORWARD = -11,
DIR_REL_BACK = -12
} moverDir_t;
typedef struct {
moveStage_t stage;
int acceleration;
int movetime;
int deceleration;
idVec3 dir;
} moveState_t;
typedef struct {
moveStage_t stage;
int acceleration;
int movetime;
int deceleration;
idAngles rot;
} rotationState_t;
idPhysics_Parametric physicsObj;
void Event_OpenPortal( void );
void Event_ClosePortal( void );
void Event_PartBlocked( idEntity *blockingEntity );
void MoveToPos( const idVec3 &pos);
void UpdateMoveSound( moveStage_t stage );
void UpdateRotationSound( moveStage_t stage );
void SetGuiStates( const char *state );
void FindGuiTargets( void );
void SetGuiState( const char *key, const char *val ) const;
virtual void DoneMoving( void );
virtual void DoneRotating( void );
virtual void BeginMove( idThread *thread = NULL );
virtual void BeginRotation( idThread *thread, bool stopwhendone );
moveState_t move;
rvStateThread splineStateThread;
float damage;
private:
rotationState_t rot;
int move_thread;
int rotate_thread;
idAngles dest_angles;
idAngles angle_delta;
idVec3 dest_position;
idVec3 move_delta;
float move_speed;
int move_time;
int deceltime;
int acceltime;
bool stopRotation;
bool useSplineAngles;
bool attenuate;
bool useIdleSound;
idEntityPtr<idEntity> splineEnt;
moverCommand_t lastCommand;
qhandle_t areaPortal; // 0 = no portal
// mekberg: attenution and sound additions
float maxAttenuation;
float attenuationScale;
idVec3 lastOrigin;
int lastTime;
int splineStartTime;
// RAVEN END
idList< idEntityPtr<idEntity> > guiTargets;
// RAVEN BEGIN
// abahr:
bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
void MoveAlongVector( const idVec3& vec );
// RAVEN END
void VectorForDir( float dir, idVec3 &vec );
idCurve_Spline<idVec3> *GetSpline( idEntity *splineEntity ) const;
void Event_SetCallback( void );
void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity );
void Event_StopMoving( void );
void Event_StopRotating( void );
void Event_UpdateMove( void );
void Event_UpdateRotation( void );
void Event_SetMoveSpeed( float speed );
void Event_SetMoveTime( float time );
void Event_SetDecelerationTime( float time );
void Event_SetAccellerationTime( float time );
void Event_MoveTo( idEntity *ent );
void Event_MoveToPos( idVec3 &pos );
void Event_MoveDir( float angle, float distance );
void Event_MoveAccelerateTo( float speed, float time );
void Event_MoveDecelerateTo( float speed, float time );
void Event_RotateDownTo( int axis, float angle );
void Event_RotateUpTo( int axis, float angle );
void Event_RotateTo( idAngles &angles );
void Event_Rotate( idAngles &angles );
void Event_RotateOnce( idAngles &angles );
void Event_Bob( float speed, float phase, idVec3 &depth );
void Event_Sway( float speed, float phase, idAngles &depth );
void Event_SetAccelSound( const char *sound );
void Event_SetDecelSound( const char *sound );
// RAVEN BEGIN
// cnicholson: added stop sound support
void Event_SetStoppedSound( const char *sound );
// RAVEN END
void Event_SetMoveSound( const char *sound );
void Event_FindGuiTargets( void );
void Event_InitGuiTargets( void );
void Event_EnableSplineAngles( void );
void Event_DisableSplineAngles( void );
void Event_RemoveInitialSplineAngles( void );
void Event_StartSpline( idEntity *splineEntity );
void Event_StopSpline( void );
void Event_Activate( idEntity *activator );
// RAVEN BEGIN
void Event_PostRestoreExt( int start, int total, int accel, int decel, bool useSplineAng );
// RAVEN END
void Event_IsMoving( void );
void Event_IsRotating( void );
// RAVEN BEGIN
// abahr:
void Event_GetSplineEntity();
void Event_MoveAlongVector( const idVec3& vec );
// mekberg: spline states
CLASS_STATES_PROTOTYPE ( idMover );
stateResult_t State_Accel( const stateParms_t& parms );
stateResult_t State_Linear( const stateParms_t& parms );
stateResult_t State_Decel( const stateParms_t& parms );
// RAVEN END
};
class idSplinePath : public idEntity {
public:
CLASS_PROTOTYPE( idSplinePath );
idSplinePath();
~idSplinePath();
void Spawn( void );
// RAVEN BEGIN
// abahr: so we can ignore these if needed
void Toggle() { SetActive(!active); }
void Activate() { SetActive(true); }
void Deactivate() { SetActive(false); }
bool IsActive() const { return active; }
int SortTargets();
int SortBackwardsTargets();
int SortTargets( idList< idEntityPtr<idEntity> >& list );
void RemoveNullTargets( void );
void ActivateTargets( idEntity *activator ) const;
void RemoveNullTargets( idList< idEntityPtr<idEntity> >& list );
void ActivateTargets( idEntity *activator, const idList< idEntityPtr<idEntity> >& list ) const;
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
idList< idEntityPtr<idEntity> > backwardPathTargets;
// mekberg: spline sampling
float GetSampledTime ( float distance ) const;
protected:
void SetActive( bool activate ) { active = activate; }
virtual void FindTargets();
void Event_Toggle( idEntity* activator ) { Toggle(); }
void Event_IsActive();
// mekberg: spline sampling
void SampleSpline ( void );
protected:
bool active;
// mekberg: sample splines.
float* sampledTimes;
float sampledSpeed;
int numSamples;
// RAVEN END
};
struct floorInfo_s {
idVec3 pos;
idStr door;
int floor;
};
class idElevator : public idMover {
public:
CLASS_PROTOTYPE( idElevator );
idElevator( void );
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool HandleSingleGuiCommand ( idEntity *entityGui, idLexer *src );
floorInfo_s * GetFloorInfo ( int floor );
protected:
virtual void DoneMoving( void );
virtual void BeginMove( idThread *thread = NULL );
void SpawnTrigger( const idVec3 &pos );
void GetLocalTriggerPosition();
void Event_Touch( idEntity *other, trace_t *trace );
// RAVEN BEGIN
// bdube: added
void SetAASAreaState ( bool enable );
void InitStatusGui ( idUserInterface* gui );
void UpdateStatusGui ( idUserInterface* gui );
void UpdateStatusGuis ( void );
void UpdateFloorInfo ( void );
// RAVEN END
private:
typedef enum {
INIT,
IDLE,
WAITING_ON_DOORS
} elevatorState_t;
elevatorState_t state;
idList<floorInfo_s> floorInfo;
int currentFloor;
int pendingFloor;
int lastFloor;
bool controlsDisabled;
// bool waitingForPlayerFollowers;
float returnTime;
int returnFloor;
int lastTouchTime;
class idDoor * GetDoor( const char *name );
void Think( void );
void OpenInnerDoor( void );
void OpenFloorDoor( int floor );
void CloseAllDoors( void );
void DisableAllDoors( void );
void EnableProperDoors( void );
void Event_TeamBlocked ( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_Activate ( idEntity *activator );
void Event_PostFloorArrival ( void );
void Event_GotoFloor ( int floor );
void Event_UpdateFloorInfo ( void );
};
/*
===============================================================================
Binary movers.
===============================================================================
*/
typedef enum {
MOVER_POS1,
MOVER_POS2,
MOVER_1TO2,
MOVER_2TO1
} moverState_t;
class idMover_Binary : public idEntity {
public:
CLASS_PROTOTYPE( idMover_Binary );
idMover_Binary();
~idMover_Binary();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void PreBind( void );
virtual void PostBind( void );
void Enable( bool b );
void InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime );
void InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime );
void GotoPosition1( void );
void GotoPosition2( void );
void Use_BinaryMover( idEntity *activator );
void SetGuiStates( const char *state );
void UpdateBuddies( int val );
idMover_Binary * GetActivateChain( void ) const { return activateChain; }
idMover_Binary * GetMoveMaster( void ) const { return moveMaster; }
void BindTeam( idEntity *bindTo );
void SetBlocked( bool b );
bool IsBlocked( void );
idEntity * GetActivator( void ) const;
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
void SetPortalState( bool open );
protected:
idVec3 pos1;
idVec3 pos2;
moverState_t moverState;
idMover_Binary * moveMaster;
idMover_Binary * activateChain;
int soundPos1;
int sound1to2;
int sound2to1;
int soundPos2;
int soundLoop;
float wait;
float damage;
int duration;
int accelTime;
int decelTime;
idEntityPtr<idEntity> activatedBy;
int stateStartTime;
idStr team;
bool enabled;
bool deferedOpen;
int move_thread;
int updateStatus; // 1 = lock behaviour, 2 = open close status
idStrList buddies;
idPhysics_Parametric physicsObj;
qhandle_t areaPortal; // 0 = no portal
bool blocked;
idList< idEntityPtr<idEntity> > guiTargets;
void MatchActivateTeam( moverState_t newstate, int time );
void JoinActivateTeam( idMover_Binary *master );
void UpdateMoverSound( moverState_t state );
void SetMoverState( moverState_t newstate, int time );
moverState_t GetMoverState( void ) const { return moverState; }
void FindGuiTargets( void );
void SetGuiState( const char *key, const char *val ) const;
void Event_SetCallback( void );
void Event_ReturnToPos1( void );
void Event_Use_BinaryMover( idEntity *activator );
void Event_Reached_BinaryMover( void );
void Event_MatchActivateTeam( moverState_t newstate, int time );
void Event_Enable( void );
void Event_Disable( void );
void Event_OpenPortal( void );
void Event_ClosePortal( void );
void Event_FindGuiTargets( void );
void Event_InitGuiTargets( void );
static void GetMovedir( float dir, idVec3 &movedir );
};
class idDoor : public idMover_Binary {
public:
CLASS_PROTOTYPE( idDoor );
idDoor( void );
~idDoor( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void PreBind( void );
virtual void PostBind( void );
virtual void Hide( void );
virtual void Show( void );
bool IsOpen( void );
bool IsNoTouch( void );
int IsLocked( void );
void Lock( int f );
void Use( idEntity *other, idEntity *activator );
void Close( void );
void Open( void );
void SetCompanion( idDoor *door );
// RAVEN BEGIN
// abahr:
bool IsClosed( void ) const { return moverState == MOVER_POS1; }
void SetDoorFrameController( idEntity* controller );
virtual void ActivateTargets( idEntity *activator ) const;
// RAVEN END
private:
float triggersize;
bool crusher;
bool noTouch;
bool aas_area_closed;
idStr buddyStr;
idClipModel * trigger;
idClipModel * sndTrigger;
int nextSndTriggerTime;
idVec3 localTriggerOrigin;
idMat3 localTriggerAxis;
idStr requires;
int removeItem;
idStr syncLock;
int normalAxisIndex; // door faces X or Y for spectator teleports
idDoor * companionDoor;
// RAVEN BEGIN
// abahr: so we can route calls through a tramGate
idEntityPtr<idEntity> doorFrameController;
// RAVEN END
void SetAASAreaState( bool closed );
void GetLocalTriggerPosition( const idClipModel *trigger );
void CalcTriggerBounds( float size, idBounds &bounds );
void Event_Reached_BinaryMover( void );
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Activate( idEntity *activator );
void Event_StartOpen( void );
void Event_SpawnDoorTrigger( void );
void Event_SpawnSoundTrigger( void );
void Event_Close( void );
void Event_Open( void );
void Event_Lock( int f );
void Event_IsOpen( void );
void Event_Locked( void );
void Event_SpectatorTouch( idEntity *other, trace_t *trace );
void Event_OpenPortal( void );
void Event_ClosePortal( void );
// RAVEN BEGIN
// abahr:
void Event_ReturnToPos1( void );
// RAVEN END
};
class idPlat : public idMover_Binary {
public:
CLASS_PROTOTYPE( idPlat );
idPlat( void );
~idPlat( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void PreBind( void );
virtual void PostBind( void );
private:
idClipModel * trigger;
idVec3 localTriggerOrigin;
idMat3 localTriggerAxis;
void GetLocalTriggerPosition( const idClipModel *trigger );
void SpawnPlatTrigger( idVec3 &pos );
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
void Event_Touch( idEntity *other, trace_t *trace );
};
/*
===============================================================================
Special periodic movers.
===============================================================================
*/
class idMover_Periodic : public idEntity {
public:
CLASS_PROTOTYPE( idMover_Periodic );
idMover_Periodic( void );
~idMover_Periodic( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
protected:
idPhysics_Parametric physicsObj;
float damage;
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
};
class idRotater : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idRotater );
idRotater( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idEntityPtr<idEntity> activatedBy;
void Event_Activate( idEntity *activator );
};
class idBobber : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idBobber );
idBobber( void );
void Spawn( void );
private:
};
class idPendulum : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idPendulum );
idPendulum( void );
void Spawn( void );
private:
};
class idRiser : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idRiser );
idRiser( void );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
};
// RAVEN BEGIN
// bdube: conveyor belts
class rvConveyor : public idEntity {
public:
CLASS_PROTOTYPE( rvConveyor );
rvConveyor ( void );
void Spawn( void );
void Think ( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idVec3 moveDir;
float moveSpeed;
void Event_FindTargets ( void );
};
// nrausch:
class rvPusher : public idMover {
public:
CLASS_PROTOTYPE( rvPusher );
rvPusher( void );
~rvPusher( void );
virtual void Spawn( void );
virtual void Think ( void );
private:
jointHandle_t bindJointHandle;
idEntity *parent;
idVec3 pusherOrigin;
idMat3 pusherAxis;
};
// RAVEN END
#endif /* !__GAME_MOVER_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,928 @@
// RAVEN BEGIN
// ddynerman: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 09/30/2004
#ifndef __MULTIPLAYERGAME_H__
#define __MULTIPLAYERGAME_H__
/*
===============================================================================
Quake IV multiplayer
===============================================================================
*/
#include "mp/Buying.h"
class idPlayer;
class rvCTF_AssaultPoint;
class rvItemCTFFlag;
typedef enum {
GAME_SP,
GAME_DM,
GAME_TOURNEY,
GAME_TDM,
// bdube: added ctf
GAME_CTF,
// ddynerman: new gametypes
GAME_1F_CTF,
GAME_ARENA_CTF,
GAME_ARENA_1F_CTF, // is not used, but leaving it in the list so I don't offset GAME_DEADZONE
// RITUAL BEGIN
// squirrel: added DeadZone multiplayer mode
GAME_DEADZONE,
NUM_GAME_TYPES,
// RITUAL END
} gameType_t;
// ddynerman: teams
typedef enum {
TEAM_NONE = -1,
TEAM_MARINE,
TEAM_STROGG,
TEAM_MAX,
} team_t;
// shouchard: server admin command types
typedef enum {
SERVER_ADMIN_KICK,
SERVER_ADMIN_BAN,
SERVER_ADMIN_REMOVE_BAN,
SERVER_ADMIN_FORCE_SWITCH,
} serverAdmin_t;
// shouchard: vote struct for packing up interface values to be handled later
// note that we have two mechanisms for dealing with vote data that
// should be consolidated: this one that handles the interface and
// multi-field votes and the one that handles console commands and
// single line votes.
struct voteStruct_t {
int m_fieldFlags; // flags for which fields are valid
int m_kick; // id of the player
idStr m_map; // name of the map
int m_gameType; // game type enum
int m_timeLimit;
int m_fragLimit;
int m_tourneyLimit;
int m_captureLimit;
int m_buying;
int m_teamBalance;
int m_controlTime;
// restart is a flag only
// nextmap is a flag only but we don't technically support it (but doom had it so it's here)
};
typedef enum {
VOTEFLAG_RESTART = 0x0001,
VOTEFLAG_BUYING = 0x0002,
VOTEFLAG_TEAMBALANCE = 0x0004,
VOTEFLAG_SHUFFLE = 0x0008,
VOTEFLAG_KICK = 0x0010,
VOTEFLAG_MAP = 0x0020,
VOTEFLAG_GAMETYPE = 0x0040,
VOTEFLAG_TIMELIMIT = 0x0080,
VOTEFLAG_TOURNEYLIMIT = 0x0100,
VOTEFLAG_CAPTURELIMIT = 0x0200,
VOTEFLAG_FRAGLIMIT = 0x0400,
VOTEFLAG_CONTROLTIME = 0x0800,
} voteFlag_t;
#define NUM_VOTES 11
#define MAX_PRINT_LEN 128
// more compact than a chat line
typedef enum {
MSG_SUICIDE = 0,
MSG_KILLED,
MSG_KILLEDTEAM,
MSG_DIED,
MSG_VOTE,
MSG_VOTEPASSED,
MSG_VOTEFAILED,
MSG_SUDDENDEATH,
MSG_FORCEREADY,
MSG_JOINEDSPEC,
MSG_TIMELIMIT,
MSG_FRAGLIMIT,
MSG_CAPTURELIMIT,
MSG_TELEFRAGGED,
MSG_JOINTEAM,
MSG_HOLYSHIT,
MSG_COUNT
} msg_evt_t;
typedef enum {
PLAYER_VOTE_NONE,
PLAYER_VOTE_NO,
PLAYER_VOTE_YES,
PLAYER_VOTE_WAIT // mark a player allowed to vote
} playerVote_t;
typedef enum {
PRM_AUTO,
PRM_SCORE,
PRM_TEAM_SCORE,
PRM_TEAM_SCORE_PLUS_SCORE,
PRM_WINS
} playerRankMode_t;
enum announcerSound_t {
// General announcements
AS_GENERAL_ONE,
AS_GENERAL_TWO,
AS_GENERAL_THREE,
AS_GENERAL_YOU_WIN,
AS_GENERAL_YOU_LOSE,
AS_GENERAL_FIGHT,
AS_GENERAL_SUDDEN_DEATH,
AS_GENERAL_VOTE_FAILED,
AS_GENERAL_VOTE_PASSED,
AS_GENERAL_VOTE_NOW,
AS_GENERAL_ONE_FRAG,
AS_GENERAL_TWO_FRAGS,
AS_GENERAL_THREE_FRAGS,
AS_GENERAL_ONE_MINUTE,
AS_GENERAL_FIVE_MINUTE,
AS_GENERAL_PREPARE_TO_FIGHT,
AS_GENERAL_QUAD_DAMAGE,
AS_GENERAL_REGENERATION,
AS_GENERAL_HASTE,
AS_GENERAL_INVISIBILITY,
// DM announcements
AS_DM_YOU_TIED_LEAD,
AS_DM_YOU_HAVE_TAKEN_LEAD,
AS_DM_YOU_LOST_LEAD,
// Team announcements
AS_TEAM_ENEMY_SCORES,
AS_TEAM_YOU_SCORE,
AS_TEAM_TEAMS_TIED,
AS_TEAM_STROGG_LEAD,
AS_TEAM_MARINES_LEAD,
AS_TEAM_JOIN_MARINE,
AS_TEAM_JOIN_STROGG,
// CTF announcements
AS_CTF_YOU_HAVE_FLAG,
AS_CTF_YOUR_TEAM_HAS_FLAG,
AS_CTF_ENEMY_HAS_FLAG,
AS_CTF_YOUR_TEAM_DROPS_FLAG,
AS_CTF_ENEMY_DROPS_FLAG,
AS_CTF_YOUR_FLAG_RETURNED,
AS_CTF_ENEMY_RETURNS_FLAG,
// Tourney announcements
AS_TOURNEY_ADVANCE,
AS_TOURNEY_JOIN_ARENA_ONE,
AS_TOURNEY_JOIN_ARENA_TWO,
AS_TOURNEY_JOIN_ARENA_THREE,
AS_TOURNEY_JOIN_ARENA_FOUR,
AS_TOURNEY_JOIN_ARENA_FIVE,
AS_TOURNEY_JOIN_ARENA_SIX,
AS_TOURNEY_JOIN_ARENA_SEVEN,
AS_TOURNEY_JOIN_ARENA_EIGHT,
AS_TOURNEY_JOIN_ARENA_WAITING,
AS_TOURNEY_DONE,
AS_TOURNEY_START,
AS_TOURNEY_ELIMINATED,
AS_TOURNEY_WON,
AS_TOURNEY_PRELIMS,
AS_TOURNEY_QUARTER_FINALS,
AS_TOURNEY_SEMI_FINALS,
AS_TOURNEY_FINAL_MATCH,
AS_GENERAL_TEAM_AMMOREGEN,
AS_GENERAL_TEAM_DOUBLER,
AS_NUM_SOUNDS
};
typedef struct mpPlayerState_s {
int ping; // player ping
int fragCount; // kills
int teamFragCount; // teamplay awards
int deadZoneScore; // Score in dead zone
int wins;
playerVote_t vote; // player's vote
bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
bool ingame;
} mpPlayerState_t;
const int MAX_INSTANCES = 8;
const int NUM_CHAT_NOTIFY = 5;
const int CHAT_FADE_TIME = 400;
const int FRAGLIMIT_DELAY = 2000;
const int CAPTURELIMIT_DELAY = 750;
const int MP_PLAYER_MINFRAGS = -100;
const int MP_PLAYER_MAXFRAGS = 999;
const int MP_PLAYER_MAXWINS = 100;
const int MP_PLAYER_MAXPING = 999;
const int MP_PLAYER_MAXKILLS = 999;
const int MP_PLAYER_MAXDEATHS = 999;
const int MAX_AP = 5;
const int CHAT_HISTORY_SIZE = 2048;
const int RCON_HISTORY_SIZE = 4096;
const int KILL_NOTIFICATION_LEN = 256;
//RAVEN BEGIN
//asalmon: update stats for Xenon
#ifdef _XENON
const int XENON_STAT_UPDATE_INTERVAL = 1000;
#endif
const int ASYNC_PLAYER_FRAG_BITS = -idMath::BitsForInteger( MP_PLAYER_MAXFRAGS - MP_PLAYER_MINFRAGS ); // player can have negative frags
const int ASYNC_PLAYER_WINS_BITS = idMath::BitsForInteger( MP_PLAYER_MAXWINS );
const int ASYNC_PLAYER_PING_BITS = idMath::BitsForInteger( MP_PLAYER_MAXPING );
const int ASYNC_PLAYER_INSTANCE_BITS = idMath::BitsForInteger( MAX_INSTANCES );
const int ASYNC_PLAYER_DEATH_BITS = idMath::BitsForInteger( MP_PLAYER_MAXDEATHS );
const int ASYNC_PLAYER_KILL_BITS = idMath::BitsForInteger( MP_PLAYER_MAXKILLS );
//RAVEN END
//RITUAL BEGIN
const int MAX_TEAM_POWERUPS = 5;
//RITUAL END
// ddynerman: game state
#include "mp/GameState.h"
typedef struct mpChatLine_s {
idStr line;
short fade; // starts high and decreases, line is removed once reached 0
} mpChatLine_t;
typedef struct mpBanInfo_s {
idStr name;
char guid[ CLIENT_GUID_LENGTH ];
// unsigned char ip[ 15 ];
} mpBanInfo_t;
class idPhysics_Player;
class idMultiplayerGame {
// rvGameState manages our state
friend class rvGameState;
public:
idMultiplayerGame();
void Shutdown( void );
// resets everything and prepares for a match
void Reset( void );
// RAVEN BEGIN
// mwhitlock: Dynamic memory consolidation
// Made this public so that level heap can be emptied.
void Clear( void );
// RAVEN END
// setup local data for a new player
void SpawnPlayer( int clientNum );
// Run the MP Game
void Run( void );
// Run the local client
void ClientRun( void );
void ClientEndFrame( void );
// Run common code (client & server)
void CommonRun( void );
// draws mp hud, scoredboard, etc..
bool Draw( int clientNum );
// updates a player vote
void PlayerVote( int clientNum, playerVote_t vote );
// updates frag counts and potentially ends the match in sudden death
void PlayerDeath( idPlayer *dead, idPlayer *killer, int methodOfDeath );
void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3)));
// RITUAL BEGIN
// squirrel: Mode-agnostic buymenus
void OnBuyModeTeamVictory( int winningTeam );
// squirrel: added DeadZone multiplayer mode
void OnDeadZoneTeamVictory( int winningTeam );
// RITUAL END
void UpdateMainGui( void );
// RAVEN BEGIN
// bdube: global pickup sounds (powerups, etc)
// Global item acquire sounds
void PlayGlobalItemAcquireSound ( int entityDefIndex );
bool CanTalk( idPlayer *from, idPlayer *to, bool echo );
void ReceiveAndForwardVoiceData( int clientNum, const idBitMsg &inMsg, int messageType );
#ifdef _USE_VOICECHAT
// jscott: game side voice comms
void XmitVoiceData( void );
void ReceiveAndPlayVoiceData( const idBitMsg &inMsg );
#endif
// jshepard: selects a map at random that will run with the current game type
bool PickMap( idStr gameType, bool checkOnly = false );
void ClearVote( int clientNum = -1 );
void ResetRconGuiStatus( void );
// RAVEN END
idUserInterface* StartMenu( void );
const char* HandleGuiCommands( const char *menuCommand );
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &msg );
void ShuffleTeams( void );
void SetGameType( void );
void SetMatchStartedTime( int time ) { matchStartedTime = time; }
rvGameState* GetGameState( void );
void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
void PrintMessage( int to, const char* message );
void DisconnectClient( int clientNum );
static void ForceReady_f( const idCmdArgs &args );
static void DropWeapon_f( const idCmdArgs &args );
static void MessageMode_f( const idCmdArgs &args );
static void VoiceChat_f( const idCmdArgs &args );
static void VoiceChatTeam_f( const idCmdArgs &args );
// RAVEN BEGIN
// shouchard: added console commands to mute/unmute voice chat
static void VoiceMute_f( const idCmdArgs &args );
static void VoiceUnmute_f( const idCmdArgs &args );
// jshepard: command wrappers
static void ForceTeamChange_f( const idCmdArgs& args );
static void RemoveClientFromBanList_f( const idCmdArgs& args );
// autobalance helper for the guis
static void CheckTeamBalance_f( const idCmdArgs &args );
// activates the admin console when a rcon password challenge returns.
void ProcessRconReturn( bool success );
// RAVEN END
typedef enum {
VOTE_RESTART = 0,
VOTE_TIMELIMIT,
VOTE_FRAGLIMIT,
VOTE_GAMETYPE,
VOTE_KICK,
VOTE_MAP,
VOTE_BUYING,
VOTE_NEXTMAP,
// RAVEN BEGIN
// shouchard: added capturelimit, round limit, and autobalance to vote flags
VOTE_CAPTURELIMIT,
VOTE_ROUNDLIMIT,
VOTE_AUTOBALANCE,
VOTE_MULTIFIELD, // all the "packed" vote functions
// RAVEN END
VOTE_CONTROLTIME,
VOTE_COUNT,
VOTE_NONE
} vote_flags_t;
typedef enum {
VOTE_UPDATE,
VOTE_FAILED,
VOTE_PASSED, // passed, but no reset yet
VOTE_ABORTED,
VOTE_RESET // tell clients to reset vote state
} vote_result_t;
// RAVEN BEGIN
// shouchard: added enum to remove magic numbers
typedef enum {
VOTE_GAMETYPE_DM = 0,
VOTE_GAMETYPE_TOURNEY,
VOTE_GAMETYPE_TDM,
VOTE_GAMETYPE_CTF,
VOTE_GAMETYPE_ARENA_CTF,
//RITUAL BEGIN
//
VOTE_GAMETYPE_DEADZONE,
//RITUAL END
VOTE_GAMETYPE_COUNT
} vote_gametype_t;
// RAVEN END
static void Vote_f( const idCmdArgs &args );
static void CallVote_f( const idCmdArgs &args );
void ClientCallVote( vote_flags_t voteIndex, const char *voteValue );
void ServerCallVote( int clientNum, const idBitMsg &msg );
void ClientStartVote( int clientNum, const char *voteString );
void ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue );
// RAVEN BEGIN
// shouchard: multiline vote support
void ClientUpdateVote( vote_result_t result, int yesCount, int noCount, const voteStruct_t &voteData );
// RAVEN END
void CastVote( int clientNum, bool vote );
void ExecuteVote( void );
// RAVEN BEGIN
// shouchard: multiline vote handlers
void ClientCallPackedVote( const voteStruct_t &voteData );
void ServerCallPackedVote( int clientNum, const idBitMsg &msg );
void ClientStartPackedVote( int clientNum, const voteStruct_t &voteData );
void ServerStartPackedVote( int clientNum, const voteStruct_t &voteData );
void ExecutePackedVote( void );
const char * LocalizeGametype( void );
// RAVEN END
void WantKilled( int clientNum );
int NumActualClients( bool countSpectators, int *teamcount = NULL );
void DropWeapon( int clientNum );
void MapRestart( void );
void JoinTeam( const char* team );
// called by idPlayer whenever it detects a team change (init or switch)
void SwitchToTeam( int clientNum, int oldteam, int newteam );
bool IsPureReady( void ) const;
void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
void ProcessVoiceChat( int clientNum, bool team, int index );
// RAVEN BEGIN
// shouchard: added commands to mute/unmute voice chat
void ClientVoiceMute( int clientNum, bool mute );
int GetClientNumFromPlayerName( const char *playerName );
void ServerHandleVoiceMuting( int clientSrc, int clientDest, bool mute );
// shouchard: fixing a bug in multiplayer where round timer sounds (5 minute
// warning, etc.) don't go away at the end of the round.
void ClearAnnouncerSounds( void );
// shouchard: server admin stuff
typedef struct
{
bool restartMap;
idStr mapName;
int gameType;
int captureLimit;
int fragLimit;
int tourneyLimit;
int timeLimit;
int minPlayers;
int controlTime;
bool buying;
bool autoBalance;
bool shuffleTeams;
} serverAdminData_t;
void HandleServerAdminBanPlayer( int clientNum );
void HandleServerAdminRemoveBan( const char * info );
void HandleServerAdminKickPlayer( int clientNum );
void HandleServerAdminForceTeamSwitch( int clientNum );
bool HandleServerAdminCommands( serverAdminData_t &data );
// RAVEN END
// RITUAL BEGIN
typedef struct mpTeamPowerups_s {
int powerup;
int time;
bool update;
int endTime;
} mpTeamPowerups_t;
mpTeamPowerups_t teamPowerups[TEAM_MAX][MAX_TEAM_POWERUPS];
void AddTeamPowerup(int powerup, int time, int team);
void UpdateTeamPowerups();
void SetUpdateForTeamPowerups(int team);
// RITUAL END
void Precache( void );
// throttle UI switch rates
void ThrottleUserInfo( void );
void ToggleSpectate( void );
void ToggleReady( void );
void ToggleTeam( void );
void ClearFrags( int clientNum );
void EnterGame( int clientNum );
bool CanPlay( idPlayer *p );
bool IsInGame( int clientNum );
bool WantRespawn( idPlayer *p );
void ServerWriteInitialReliableMessages( int clientNum );
void ClientReadStartState( const idBitMsg &msg );
void ServerClientConnect( int clientNum );
void PlayerStats( int clientNum, char *data, const int len );
void AddTeamScore ( int team, int amount );
void AddPlayerScore( idPlayer* player, int amount );
void AddPlayerTeamScore( idPlayer* player, int amount );
void AddPlayerWin( idPlayer* player, int amount );
void SetPlayerTeamScore( idPlayer* player, int value );
void SetPlayerDeadZoneScore( idPlayer* player, float value );
void SetPlayerScore( idPlayer* player, int value );
void SetPlayerWin( idPlayer* player, int value );
void SetHudOverlay( idUserInterface* overlay, int duration );
void ClearMap ( void );
void EnableDamage( bool enable = true );
idPlayer* GetRankedPlayer( int i );
int GetRankedPlayerScore( int i );
int GetNumRankedPlayers( void );
idPlayer* GetUnrankedPlayer( int i );
int GetNumUnrankedPlayers( void );
int GetScore( int i );
int GetScore( idPlayer* player );
int GetTeamScore( int i );
int GetTeamScore( idPlayer* player );
int GetWins( int i );
int GetWins( idPlayer* player );
// asalmon: Get the score for a team.
int GetScoreForTeam( int i );
int GetTeamsTotalFrags( int i );
int GetTeamsTotalScore( int i );
idUserInterface *GetMainGUI() {return mainGui;}
float GetPlayerDeadZoneScore(idPlayer* player);
int TeamLeader( void );
int GetPlayerTime( idPlayer* player );
const char* GetLongGametypeName( const char* gametype );
int GameTypeToVote( const char *gameType );
void ReceiveRemoteConsoleOutput( const char* output );
void ClientSetInstance( const idBitMsg& msg );
void ServerSetInstance( int instance );
void AddPrivatePlayer( int clientId );
void RemovePrivatePlayer( int clientId );
//RAVEN BEGIN
//asalmon: Xenon scoreboard update
#ifdef _XENON
void UpdateXenonScoreboard( idUserInterface *scoreBoard );
int lastScoreUpdate;
// mekberg: for selecting local player
void SelectLocalPlayer( idUserInterface *scoreBoard );
#endif
//RAVEN END
int VerifyTeamSwitch( int wantTeam, idPlayer *player );
void RemoveAnnouncerSound( int type );
void RemoveAnnouncerSoundRange( int startType, int endType );
void ScheduleAnnouncerSound ( announcerSound_t sound, float time, int instance = -1, bool allowOverride = false );
void ScheduleTimeAnnouncements( void );
// RAVEN END
void SendDeathMessage( idPlayer *attacker, idPlayer *victim, int methodOfDeath );
void ReceiveDeathMessage( idPlayer *attacker, int attackerScore, idPlayer *victim, int victimScore, int methodOfDeath );
rvCTF_AssaultPoint* NextAP( int team );
int OpposingTeam( int team );
idList<idEntityPtr<rvCTF_AssaultPoint> > assaultPoints;
// Buying Manager - authority for buying system game balance constants (awards,
// costs, etc.)
riBuyingManager mpBuyingManager;
idUserInterface* statSummary; // stat summary
rvTourneyGUI tourneyGUI;
void ShowStatSummary( void );
bool CanCapture( int team );
void FlagCaptured( idPlayer *player );
void UpdatePlayerRanks( playerRankMode_t rankMode = PRM_AUTO );
void UpdateTeamRanks( void );
void UpdateHud( idUserInterface* _mphud );
idPlayer * FragLimitHit( void );
idPlayer * FragLeader( void );
bool TimeLimitHit( void );
int GetCurrentMenu( void ) { return currentMenu; }
void SetFlagEntity( idEntity* ent, int team );
idEntity* GetFlagEntity( int team );
void WriteNetworkInfo( idFile *file, int clientNum );
void ReadNetworkInfo( idFile* file, int clientNum );
void SetShaderParms( renderView_t *view );
// RITUAL BEGIN
// squirrel: added DeadZone multiplayer mode
int NumberOfPlayersOnTeam( int team );
int NumberOfAlivePlayersOnTeam( int team );
void ReportZoneControllingPlayer( idPlayer* player );
void ReportZoneController(int team, int pCount, int situation, idEntity* zoneTrigger = 0);
bool IsValidTeam(int team);
void ControlZoneStateChanged( int team );
int powerupCount;
int prevAnnouncerSnd;
int defaultWinner;
int deadZonePowerupCount;
dzState_t dzState[ TEAM_MAX ];
float marineScoreBarPulseAmount;
float stroggScoreBarPulseAmount;
// RITUAL END
// RITUAL BEGIN
// squirrel: Mode-agnostic buymenus
bool isBuyingAllowedRightNow;
void OpenLocalBuyMenu( void );
void RedrawLocalBuyMenu( void );
void GiveCashToTeam( int team, float cashAmount );
bool IsBuyingAllowedInTheCurrentGameMode( void );
bool IsBuyingAllowedRightNow( void );
// RITUAL END
static const char* teamNames[ TEAM_MAX ];
private:
static const char *MPGuis[];
static const char *ThrottleVars[];
static const char *ThrottleVarsInEnglish[];
static const int ThrottleDelay[];
char killNotificationMsg[ KILL_NOTIFICATION_LEN ];
int pingUpdateTime; // time to update ping
mpPlayerState_t playerState[ MAX_CLIENTS ];
// game state
rvGameState* gameState;
// vote vars
vote_flags_t vote; // active vote or VOTE_NONE
int voteTimeOut; // when the current vote expires
int voteExecTime; // delay between vote passed msg and execute
int yesVotes; // counter for yes votes
int noVotes; // and for no votes
idStr voteValue; // the data voted upon ( server )
idStr voteString; // the vote string ( client )
bool voted; // hide vote box ( client )
int kickVoteMap[ MAX_CLIENTS ];
// RAVEN BEGIN
// shouchard: names for kickVoteMap
idStr kickVoteMapNames[ MAX_CLIENTS ];
voteStruct_t currentVoteData; // used for multi-field votes
// RAVEN END
idStr localisedGametype;
// time related
int matchStartedTime; // time current match started
// guis
// RITUAL BEGIN
// squirrel: added DeadZone multiplayer mode
//int sqRoundNumber; // round number in DeadZone; match expires when this equals "sq_numRoundsPerMatch" (cvar)
// squirrel: Mode-agnostic buymenus
idUserInterface *buyMenu; // buy menu
// RITUAL END
idUserInterface *scoreBoard; // scoreboard
idUserInterface *mainGui; // ready / nick / votes etc.
idListGUI *mapList;
idUserInterface *msgmodeGui; // message mode
int currentMenu; // 0 - none, 1 - mainGui, 2 - msgmodeGui
int nextMenu; // if 0, will do mainGui
bool bCurrentMenuMsg; // send menu state updates to server
enum {
MPLIGHT_CTF_MARINE,
MPLIGHT_CTF_STROGG,
MPLIGHT_QUAD,
MPLIGHT_HASTE,
MPLIGHT_REGEN,
MPLIGHT_MAX
};
int lightHandles[ MPLIGHT_MAX ];
renderLight_t lights[ MPLIGHT_MAX ];
// chat buffer
idStr chatHistory;
// rcon buffer
idStr rconHistory;
//RAVEN BEGIN
//asalmon: Need to refresh stats periodically if the player is looking at stats
int currentStatClient;
int currentStatTeam;
//RAVEN END
public:
// current player rankings
idList<rvPair<idPlayer*, int> > rankedPlayers;
idList<idPlayer*> unrankedPlayers;
rvPair<int, int> rankedTeams[ TEAM_MAX ];
private:
int lastVOAnnounce;
int lastReadyToggleTime;
bool pureReady; // defaults to false, set to true once server game is running with pure checksums
bool currentSoundOverride;
int switchThrottle[ 3 ];
int voiceChatThrottle;
void SetupBuyMenuItems();
idList<int> privateClientIds;
int privatePlayers;
// player who's rank info we're displaying
idEntityPtr<idPlayer> rankTextPlayer;
idEntityPtr<idEntity> flagEntities[ TEAM_MAX ];
idEntityPtr<idPlayer> flagCarriers[ TEAM_MAX ];
// updates the passed gui with current score information
void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
// bdube: test scoreboard
void UpdateTestScoreboard( idUserInterface *scoreBoard );
// ddynerman: gametype specific scoreboard
void UpdateScoreboard( idUserInterface *scoreBoard );
void UpdateDMScoreboard( idUserInterface *scoreBoard );
void UpdateTeamScoreboard( idUserInterface *scoreBoard );
void UpdateSummaryBoard( idUserInterface *scoreBoard );
int GetPlayerRank( idPlayer* player, bool& isTied );
char* GetPlayerRankText( idPlayer* player );
char* GetPlayerRankText( int rank, bool tied, int score );
const char* BuildSummaryListString( idPlayer* player, int rankedScore );
void UpdatePrivatePlayerCount( void );
typedef struct announcerSoundNode_s {
announcerSound_t soundShader;
float time;
idLinkList<announcerSoundNode_s> announcerSoundNode;
int instance;
bool allowOverride;
} announcerSoundNode_t;
idLinkList<announcerSoundNode_t> announcerSoundQueue;
announcerSound_t lastAnnouncerSound;
static const char* announcerSoundDefs[ AS_NUM_SOUNDS ];
float announcerPlayTime;
void PlayAnnouncerSounds ( void );
int teamScore[ TEAM_MAX ];
int teamDeadZoneScore[ TEAM_MAX];
void ClearTeamScores ( void );
void UpdateLeader( idPlayer* oldLeader );
void ClearGuis( void );
void DrawScoreBoard( idPlayer *player );
void CheckVote( void );
bool AllPlayersReady( idStr* reason = NULL );
const char * GameTime( void );
bool EnoughClientsToPlay( void );
void DrawStatSummary( void );
// go through the clients, and see if they want to be respawned, and if the game allows it
// called during normal gameplay for death -> respawn cycles
// and for a spectator who want back in the game (see param)
void CheckRespawns( idPlayer *spectator = NULL );
void FreeLight ( int lightID );
void UpdateLight ( int lightID, idPlayer *player );
void CheckSpecialLights( void );
void ForceReady();
// when clients disconnect or join spectate during game, check if we need to end the game
void CheckAbortGame( void );
void MessageMode( const idCmdArgs &args );
void DisableMenu( void );
void SetMapShot( void );
// scores in TDM
void VoiceChat( const idCmdArgs &args, bool team );
// RAVEN BEGIN
// mekberg: added
void UpdateMPSettingsModel( idUserInterface* currentGui );
// RAVEN END
void WriteStartState( int clientNum, idBitMsg &msg, bool withLocalClient );
};
ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const {
return pureReady;
}
ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
playerState[ clientNum ].fragCount = 0;
}
ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) {
return playerState[ clientNum ].ingame;
}
ID_INLINE int idMultiplayerGame::OpposingTeam( int team ) {
return (team == TEAM_STROGG ? TEAM_MARINE : TEAM_STROGG);
}
ID_INLINE idPlayer* idMultiplayerGame::GetRankedPlayer( int i ) {
if( i >= 0 && i < rankedPlayers.Num() ) {
return rankedPlayers[ i ].First();
} else {
return NULL;
}
}
ID_INLINE int idMultiplayerGame::GetRankedPlayerScore( int i ) {
if( i >= 0 && i < rankedPlayers.Num() ) {
return rankedPlayers[ i ].Second();
} else {
return 0;
}
}
ID_INLINE int idMultiplayerGame::GetNumUnrankedPlayers( void ) {
return unrankedPlayers.Num();
}
ID_INLINE idPlayer* idMultiplayerGame::GetUnrankedPlayer( int i ) {
if( i >= 0 && i < unrankedPlayers.Num() ) {
return unrankedPlayers[ i ];
} else {
return NULL;
}
}
ID_INLINE int idMultiplayerGame::GetNumRankedPlayers( void ) {
return rankedPlayers.Num();
}
ID_INLINE int idMultiplayerGame::GetTeamScore( int i ) {
return playerState[ i ].teamFragCount;
}
ID_INLINE int idMultiplayerGame::GetScore( int i ) {
return playerState[ i ].fragCount;
}
ID_INLINE int idMultiplayerGame::GetWins( int i ) {
return playerState[ i ].wins;
}
ID_INLINE void idMultiplayerGame::ResetRconGuiStatus( void ) {
if( mainGui) {
mainGui->SetStateInt( "password_valid", 0 );
}
}
// asalmon: needed access team scores for rich presence
ID_INLINE int idMultiplayerGame::GetScoreForTeam( int i ) {
if( i < 0 || i > TEAM_MAX ) {
return 0;
}
return teamScore[ i ];
}
ID_INLINE int idMultiplayerGame::TeamLeader( void ) {
if( teamScore[ TEAM_MARINE ] == teamScore[ TEAM_STROGG ] ) {
return -1;
} else {
return ( teamScore[ TEAM_MARINE ] > teamScore[ TEAM_STROGG ] ? TEAM_MARINE : TEAM_STROGG );
}
}
int ComparePlayersByScore( const void* left, const void* right );
int CompareTeamsByScore( const void* left, const void* right );
#endif /* !__MULTIPLAYERGAME_H__ */
// RAVEN END

417
source/game/Playback.cpp Normal file
View file

@ -0,0 +1,417 @@
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "ai/AI.h"
#define RECORD_STATE_TRACE_LEN 2048.0f
class rvGamePlayback
{
public:
rvGamePlayback( void );
~rvGamePlayback( void );
void RecordData( const usercmd_t &cmd, idEntity *source );
private:
int mStartTime;
byte mOldFlags;
idStr mName;
idClipModel *mClipModel;
rvDeclPlayback *mPlayback;
};
idCVar g_recordPlayback( "g_recordPlayback", "0", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "record the player movement in a playback" );
idCVar g_playPlayback( "g_playPlayback", "0", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "plays the current playback in a camera path" );
rvGamePlayback *gamePlayback = NULL;
rvCameraPlayback *playbackCamera = NULL;
rvGamePlayback::rvGamePlayback( void )
{
idStr newName;
const idVec3 trace_mins( -1.0f, -1.0f, -1.0f );
const idVec3 trace_maxs( 1.0f, 1.0f, 1.0f );
const idBounds trace_bounds( trace_mins, trace_maxs );
idTraceModel traceModel( trace_bounds );
mStartTime = gameLocal.time;
mOldFlags = 0;
mClipModel = new idClipModel( traceModel );
if( !g_currentPlayback.GetInteger() )
{
newName = declManager->GetNewName( DECL_PLAYBACK, "playbacks/untitled" );
mPlayback = ( rvDeclPlayback * )declManager->CreateNewDecl( DECL_PLAYBACK, newName, newName + ".playback" );
mPlayback->ReplaceSourceFileText();
mPlayback->Invalidate();
g_currentPlayback.SetInteger( mPlayback->Index() );
}
else
{
mPlayback = ( rvDeclPlayback * )declManager->PlaybackByIndex( g_currentPlayback.GetInteger() );
}
declManager->StartPlaybackRecord( mPlayback );
common->Printf( "Starting playback record to %s type %d\n", mPlayback->GetName(), g_recordPlayback.GetInteger() );
}
rvGamePlayback::~rvGamePlayback( void )
{
declManager->FinishPlayback( mPlayback );
delete mClipModel;
common->Printf( "Stopping playback play/record\n" );
}
void rvGamePlayback::RecordData( const usercmd_t &cmd, idEntity *source )
{
idPlayer *player;
trace_t trace;
idMat3 axis;
idVec3 start, end;
rvDeclPlaybackData info;
info.Init();
switch( g_recordPlayback.GetInteger() )
{
case 1:
info.SetPosition( source->GetPhysics()->GetOrigin() );
info.SetAngles( source->GetPhysics()->GetAxis().ToAngles() );
break;
case 2:
gameLocal.GetPlayerView( start, axis );
end = start + axis[0] * RECORD_STATE_TRACE_LEN;
gameLocal.Translation( gameLocal.GetLocalPlayer(), trace, start, end, mClipModel, mat3_identity, CONTENTS_SOLID | CONTENTS_RENDERMODEL, source );
if( trace.fraction != 1.0f )
{
info.SetPosition( trace.endpos );
info.SetAngles( trace.c.normal.ToAngles() );
}
break;
case 3:
assert( source->IsType( idPlayer::GetClassType() ) );
if( source->IsType( idPlayer::GetClassType() ) )
{
player = static_cast<idPlayer *>( source );
info.SetPosition( player->GetEyePosition() );
info.SetAngles( source->GetPhysics()->GetAxis().ToAngles() );
}
break;
}
// Record buttons
info.SetButtons( cmd.buttons );
// Record impulses
if( ( cmd.flags & UCF_IMPULSE_SEQUENCE ) != ( mOldFlags & UCF_IMPULSE_SEQUENCE ) )
{
info.SetImpulse( cmd.impulse );
}
else
{
info.SetImpulse( 0 );
}
mOldFlags = cmd.flags;
declManager->SetPlaybackData( mPlayback, gameLocal.time - mStartTime, -1, &info );
}
// ================================================================================================
void idGameEdit::DrawPlaybackDebugInfo( void )
{
int duration, time;
rvDeclPlaybackData pbd, pbdOld;
const rvDeclPlayback *pb;
pb = declManager->PlaybackByIndex( g_currentPlayback.GetInteger(), true );
if( pb )
{
duration = SEC2MS( pb->GetDuration() );
pbd.Init();
pbdOld.Init();
declManager->GetPlaybackData( pb, -1, 0, 0, &pbdOld );
for( time = gameLocal.GetMSec(); time < duration; time += gameLocal.GetMSec() * g_showPlayback.GetInteger() )
{
declManager->GetPlaybackData( pb, -1, time, time, &pbd );
gameRenderWorld->DebugArrow( colorGreen, pbdOld.GetPosition(), pbd.GetPosition(), 2 );
pbdOld = pbd;
}
gameRenderWorld->DebugBounds( colorRed, pb->GetBounds(), pb->GetOrigin() );
}
}
void idGameEdit::RecordPlayback( const usercmd_t &cmd, idEntity *source )
{
// Not recording - so instantly exit
if( !g_recordPlayback.GetInteger() && !gamePlayback )
{
return;
}
if( !gamePlayback )
{
gamePlayback = new rvGamePlayback();
}
if( g_recordPlayback.GetInteger() )
{
gamePlayback->RecordData( cmd, source );
}
else
{
delete gamePlayback;
gamePlayback = NULL;
}
}
// ================================================================================================
bool idGameEdit::PlayPlayback( void )
{
// Not playing - so instantly exit
if( !g_playPlayback.GetInteger() && !playbackCamera )
{
return( false );
}
if( !playbackCamera )
{
playbackCamera = static_cast<rvCameraPlayback *>( gameLocal.SpawnEntityType( rvCameraPlayback::GetClassType() ) );
SetCamera( playbackCamera );
common->Printf( "Starting playback play\n" );
}
if( g_currentPlayback.IsModified() )
{
// Spawn is a misnomer - it should be init with new data
playbackCamera->Spawn();
g_currentPlayback.ClearModified();
}
if( !g_playPlayback.GetInteger() )
{
playbackCamera->PostEventMS( &EV_Remove, 0 );
playbackCamera = NULL;
SetCamera( NULL );
}
return( true );
}
// ================================================================================================
void idGameEdit::ShutdownPlaybacks( void )
{
g_recordPlayback.SetInteger( 0 );
g_playPlayback.SetInteger( 0 );
if( gamePlayback )
{
delete gamePlayback;
gamePlayback = NULL;
}
if( playbackCamera )
{
playbackCamera->PostEventMS( &EV_Remove, 0 );
playbackCamera = NULL;
SetCamera( NULL );
}
}
// ================================================================================================
/*
============
rvPlaybackDriver::Start
Start a new playback automatically blending with the old playback (if any) over numFrames
============
*/
bool rvPlaybackDriver::Start( const char *playback, idEntity *owner, int flags, int numFrames )
{
idVec3 startPos;
if( !idStr::Length( playback ) )
{
mPlaybackDecl = NULL;
mOldPlaybackDecl = NULL;
return( true );
}
const rvDeclPlayback *pb = declManager->FindPlayback( playback );
if( g_showPlayback.GetInteger() )
{
common->Printf( "Starting playback: %s\n", pb->GetName() );
}
mOldPlaybackDecl = mPlaybackDecl;
mOldFlags = mFlags;
mOldStartTime = mStartTime;
mOldOffset = mOffset;
mPlaybackDecl = pb;
mFlags = flags;
mStartTime = gameLocal.time;
mOffset.Zero();
if( flags & PBFL_RELATIVE_POSITION )
{
mOffset = owner->GetPhysics()->GetOrigin() - pb->GetOrigin();
}
mTransitionTime = numFrames * gameLocal.GetMSec();
return( true );
}
/*
============
PlaybackCallback
Called whenever a button up or down, or an impulse event is found while getting the playback data
============
*/
void PlaybackCallback( int type, float time, const void *data )
{
const rvDeclPlaybackData *pbd = ( const rvDeclPlaybackData * )data;
idEntity *ent = pbd->GetEntity();
ent->PostEventSec( &EV_PlaybackCallback, time, type, pbd->GetChanged(), pbd->GetImpulse() );
}
/*
============
rvPlaybackDriver::UpdateFrame
Blend two playbacks together
============
*/
bool rvPlaybackDriver::UpdateFrame( idEntity *ent, rvDeclPlaybackData &out )
{
rvDeclPlaybackData pbd, oldPbd;
float blend, invBlend;
idStr ret;
bool expired, oldExpired;
// Get the current playback position
pbd.Init();
pbd.SetCallback( ent, PlaybackCallback );
expired = declManager->GetPlaybackData( mPlaybackDecl, mFlags, gameLocal.time - mStartTime, mLastTime - mStartTime, &pbd );
pbd.SetPosition( pbd.GetPosition() + mOffset );
// Get the playback data we are merging from
oldPbd.Init();
oldExpired = declManager->GetPlaybackData( mOldPlaybackDecl, mOldFlags, gameLocal.time - mOldStartTime, gameLocal.time - mOldStartTime, &oldPbd );
oldPbd.SetPosition( oldPbd.GetPosition() + mOldOffset );
mLastTime = gameLocal.time;
if( g_showPlayback.GetInteger() && mPlaybackDecl )
{
common->Printf( "Running playback: %s at %.1f\n", mPlaybackDecl->GetName(), MS2SEC( gameLocal.time - mStartTime ) );
}
// Fully merged - so delete the old one
if( gameLocal.time > mStartTime + mTransitionTime )
{
oldExpired = true;
}
// Interpolate the result
if( expired && oldExpired )
{
out.Init();
mPlaybackDecl = NULL;
mOldPlaybackDecl = NULL;
}
else if( !expired && oldExpired )
{
out = pbd;
mOldPlaybackDecl = NULL;
}
else if( expired && !oldExpired )
{
out = oldPbd;
mPlaybackDecl = NULL;
}
else
{
// Linear zero to one
blend = idMath::ClampFloat( 0.0f, 1.0f, ( gameLocal.time - mStartTime ) / ( float )mTransitionTime );
// Sinusoidal
blend = idMath::Sin( blend * idMath::HALF_PI );
invBlend = 1.0f - blend;
out.SetPosition( blend * pbd.GetPosition() + invBlend * oldPbd.GetPosition() );
out.SetAngles( blend * pbd.GetAngles() + invBlend * oldPbd.GetAngles() );
out.SetButtons( pbd.GetButtons() );
out.SetImpulse( pbd.GetImpulse() );
}
return( expired );
}
// cnicholson: Begin Added save/restore functionality
/*
============
rvPlaybackDriver::Save
Save all member vars for save/load games
============
*/
void rvPlaybackDriver::Save( idSaveGame *savefile ) const {
savefile->WriteInt( mLastTime ); // cnicholson: Added unsaved var
savefile->WriteInt( mTransitionTime ); // cnicholson: Added unsaved var
savefile->WriteInt( mStartTime ); // cnicholson: Added unsaved var
savefile->WriteInt( mFlags ); // cnicholson: Added unsaved var
// TOSAVE: const rvDeclPlayback *mPlaybackDecl;
savefile->WriteVec3( mOffset ); // cnicholson: Added unsaved var
savefile->WriteInt( mOldStartTime ); // cnicholson: Added unsaved var
savefile->WriteInt( mOldFlags ); // cnicholson: Added unsaved var
// TOSAVE: const rvDeclPlayback *mOldPlaybackDecl;
savefile->WriteVec3( mOldOffset ); // cnicholson: Added unsaved var
}
/*
============
rvPlaybackDriver::Restore
Restore all member vars for save/load games
============
*/
void rvPlaybackDriver::Restore( idRestoreGame *savefile ) {
savefile->ReadInt( mLastTime ); // cnicholson: Added unrestored var
savefile->ReadInt( mTransitionTime ); // cnicholson: Added unrestored var
savefile->ReadInt( mStartTime ); // cnicholson: Added unrestored var
savefile->ReadInt( mFlags ); // cnicholson: Added unrestored var
// TOSAVE: const rvDeclPlayback *mPlaybackDecl;
savefile->ReadVec3( mOffset ); // cnicholson: Added unrestored var
savefile->ReadInt( mOldStartTime ); // cnicholson: Added unrestored var
savefile->ReadInt( mOldFlags ); // cnicholson: Added unrestored var
// TOSAVE: const rvDeclPlayback *mOldPlaybackDecl;
savefile->ReadVec3( mOldOffset ); // cnicholson: Added unrestored var
}
// cnicholson: End Added save/restore functionality
// end

14077
source/game/Player.cpp Normal file

File diff suppressed because it is too large Load diff

1332
source/game/Player.h Normal file

File diff suppressed because it is too large Load diff

784
source/game/PlayerView.cpp Normal file
View file

@ -0,0 +1,784 @@
// RAVEN BEGIN
// bdube: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 07/07/2004
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#if defined(_XENON) && (defined(_PROFILE) || defined(_DEBUG))
#include "../sys/xenon/ProfilingSupport.h"
#endif
const int IMPULSE_DELAY = 150;
/*
==============
idPlayerView::idPlayerView
==============
*/
idPlayerView::idPlayerView() {
memset( screenBlobs, 0, sizeof( screenBlobs ) );
memset( &view, 0, sizeof( view ) );
player = NULL;
dvMaterial = NULL;
dvMaterialBlend = NULL;
tunnelMaterial = NULL;
armorMaterial = NULL;
bloodSprayMaterial = NULL;
bfgVision = false;
dvFinishTime = 0;
tvFinishTime = 0;
tvStartTime = 0;
kickFinishTime = 0;
kickAngles.Zero();
lastDamageTime = 0.0f;
fadeTime = 0;
fadeRate = 0.0;
fadeFromColor.Zero();
fadeToColor.Zero();
fadeColor.Zero();
ClearEffects();
dvScale = 1.0f;
shakeScale = 1.0f;
tvScale = 1.0f;
}
/*
==============
idPlayerView::Save
==============
*/
void idPlayerView::Save( idSaveGame *savefile ) const {
int i;
const screenBlob_t *blob;
blob = &screenBlobs[ 0 ];
for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) {
savefile->WriteMaterial( blob->material );
savefile->WriteFloat( blob->x );
savefile->WriteFloat( blob->y );
savefile->WriteFloat( blob->w );
savefile->WriteFloat( blob->h );
savefile->WriteFloat( blob->s1 );
savefile->WriteFloat( blob->t1 );
savefile->WriteFloat( blob->s2 );
savefile->WriteFloat( blob->t2 );
savefile->WriteInt( blob->finishTime );
savefile->WriteInt( blob->startFadeTime );
savefile->WriteFloat( blob->driftAmount );
}
savefile->WriteInt( dvFinishTime );
savefile->WriteMaterial( dvMaterial );
savefile->WriteMaterial( dvMaterialBlend ); // cnicholson: Added unsaved var
savefile->WriteFloat ( dvScale );
savefile->WriteInt( kickFinishTime );
savefile->WriteAngles( kickAngles );
savefile->WriteBool( bfgVision );
savefile->WriteMaterial( tunnelMaterial );
savefile->WriteMaterial( armorMaterial );
savefile->WriteMaterial( bloodSprayMaterial );
savefile->WriteFloat( lastDamageTime );
savefile->WriteFloat( shakeFinishTime );
savefile->WriteFloat( shakeScale );
savefile->WriteFloat( tvScale );
savefile->WriteInt( tvFinishTime );
savefile->WriteInt( tvStartTime );
savefile->WriteVec4( fadeColor );
savefile->WriteVec4( fadeToColor );
savefile->WriteVec4( fadeFromColor );
savefile->WriteFloat( fadeRate );
savefile->WriteInt( fadeTime );
savefile->WriteObject( player );
savefile->WriteRenderView( view );
}
/*
==============
idPlayerView::Restore
==============
*/
void idPlayerView::Restore( idRestoreGame *savefile ) {
int i;
screenBlob_t *blob;
blob = &screenBlobs[ 0 ];
for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) {
savefile->ReadMaterial( blob->material );
savefile->ReadFloat( blob->x );
savefile->ReadFloat( blob->y );
savefile->ReadFloat( blob->w );
savefile->ReadFloat( blob->h );
savefile->ReadFloat( blob->s1 );
savefile->ReadFloat( blob->t1 );
savefile->ReadFloat( blob->s2 );
savefile->ReadFloat( blob->t2 );
savefile->ReadInt( blob->finishTime );
savefile->ReadInt( blob->startFadeTime );
savefile->ReadFloat( blob->driftAmount );
}
savefile->ReadInt( dvFinishTime );
savefile->ReadMaterial( dvMaterial );
savefile->ReadMaterial( dvMaterialBlend ); // cnicholson: Added unrestored var
savefile->ReadFloat( dvScale );
savefile->ReadInt( kickFinishTime );
savefile->ReadAngles( kickAngles );
savefile->ReadBool( bfgVision );
savefile->ReadMaterial( tunnelMaterial );
savefile->ReadMaterial( armorMaterial );
savefile->ReadMaterial( bloodSprayMaterial );
savefile->ReadFloat( lastDamageTime );
savefile->ReadFloat( shakeFinishTime );
savefile->ReadFloat( shakeScale );
savefile->ReadFloat( tvScale );
savefile->ReadInt( tvFinishTime );
savefile->ReadInt ( tvStartTime );
savefile->ReadVec4( fadeColor );
savefile->ReadVec4( fadeToColor );
savefile->ReadVec4( fadeFromColor );
savefile->ReadFloat( fadeRate );
savefile->ReadInt( fadeTime );
savefile->ReadObject( reinterpret_cast<idClass *&>( player ) );
savefile->ReadRenderView( view );
}
/*
==============
idPlayerView::SetPlayerEntity
==============
*/
void idPlayerView::SetPlayerEntity( idPlayer *playerEnt ) {
player = playerEnt;
const idDict* dict = NULL;
if( !playerEnt ) {
return;
}
dict = gameLocal.FindEntityDefDict( playerEnt->spawnArgs.GetString("def_playerView"), false );
if( dict ) {
dvMaterial = declManager->FindMaterial( dict->GetString("mtr_doubleVision") );
dvMaterialBlend = declManager->FindMaterial( dict->GetString("mtr_doubleVisionBlend") );
tunnelMaterial = declManager->FindMaterial( dict->GetString("mtr_tunnel") );
armorMaterial = declManager->FindMaterial( dict->GetString("mtr_armourEffect") );
bloodSprayMaterial = declManager->FindMaterial( dict->GetString("mtr_bloodspray") );
lagoMaterial = declManager->FindMaterial( LAGO_MATERIAL, false );
}
}
/*
==============
idPlayerView::ClearEffects
==============
*/
void idPlayerView::ClearEffects() {
lastDamageTime = MS2SEC( gameLocal.time - 99999 );
dvFinishTime = ( gameLocal.time - 99999 );
tvFinishTime = ( gameLocal.time - 99999 );
tvStartTime = ( gameLocal.time - 99999 );
kickFinishTime = ( gameLocal.time - 99999 );
shakeFinishTime = gameLocal.time;
for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) {
screenBlobs[i].finishTime = gameLocal.time;
}
fadeTime = 0;
bfgVision = false;
}
/*
==============
idPlayerView::GetScreenBlob
==============
*/
screenBlob_t *idPlayerView::GetScreenBlob() {
screenBlob_t *oldest = &screenBlobs[0];
for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) {
if ( screenBlobs[i].finishTime < oldest->finishTime ) {
oldest = &screenBlobs[i];
}
}
return oldest;
}
/*
==============
idPlayerView::DamageImpulse
LocalKickDir is the direction of force in the player's coordinate system,
which will determine the head kick direction
==============
*/
// RAVEN BEGIN
// jnewquist: Controller rumble
void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef, int damage ) {
//
// double vision effect
//
float tvTime = damageDef->GetFloat( "tv_time" );
if ( tvTime ) {
tvStartTime = gameLocal.time;
tvFinishTime = gameLocal.time + tvTime;
damageDef->GetFloat ( "tv_scale", "1", tvScale );
}
if ( lastDamageTime > 0.0f && SEC2MS( lastDamageTime ) + IMPULSE_DELAY > gameLocal.time ) {
// keep shotgun from obliterating the view
return;
}
//
// double vision effect
//
float dvTime = damageDef->GetFloat( "dv_time" );
if ( dvTime ) {
dvFinishTime = gameLocal.time + (g_dvTime.GetFloat() * dvTime);
damageDef->GetFloat ( "dv_scale", "1", dvScale );
}
//
// head angle kick
//
const float modifierScale = 0.25f;
const float inverseModifier = ( 1.0f - modifierScale );
float modifier = idMath::ClampFloat( 0.0f, inverseModifier, damage / 100.0f * inverseModifier ) + modifierScale;
float kickTime = damageDef->GetFloat( "kick_time" );
if ( kickTime ) {
kickFinishTime = gameLocal.time + g_kickTime.GetFloat() * kickTime;
// forward / back kick will pitch view
kickAngles[0] = localKickDir[0];
// side kick will yaw view
kickAngles[1] = localKickDir[1]*0.5f;
// up / down kick will pitch view
kickAngles[0] += localKickDir[2];
// roll will come from side
kickAngles[2] = localKickDir[1];
float kickAmplitude = damageDef->GetFloat( "kick_amplitude" );
if ( kickAmplitude ) {
kickAngles *= kickAmplitude;
}
if ( modifier < kickAmplitude ) {
modifier = kickAmplitude;
}
}
else {
kickTime = 500;
}
//
// screen blob
//
float blobTime = damageDef->GetFloat( "blob_time" );
if ( blobTime ) {
screenBlob_t *blob = GetScreenBlob();
blob->startFadeTime = gameLocal.time;
blob->finishTime = gameLocal.time + blobTime * g_blobTime.GetFloat();
const char *materialName = damageDef->GetString( "mtr_blob" );
blob->material = declManager->FindMaterial( materialName );
blob->x = damageDef->GetFloat( "blob_x" );
blob->x += ( gameLocal.random.RandomInt()&63 ) - 32;
blob->y = damageDef->GetFloat( "blob_y" );
blob->y += ( gameLocal.random.RandomInt()&63 ) - 32;
float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f;
blob->w = damageDef->GetFloat( "blob_width" ) * g_blobSize.GetFloat() * scale;
blob->h = damageDef->GetFloat( "blob_height" ) * g_blobSize.GetFloat() * scale;
blob->s1 = 0;
blob->t1 = 0;
blob->s2 = 1;
blob->t2 = 1;
}
//
// save lastDamageTime for tunnel vision accentuation
//
lastDamageTime = MS2SEC( gameLocal.time );
}
// RAVEN END
/*
==================
idPlayerView::AddBloodSpray
If we need a more generic way to add blobs then we can do that
but having it localized here lets the material be pre-looked up etc.
==================
*/
void idPlayerView::AddBloodSpray( float duration ) {
/*
if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) {
return;
}
// visit this for chainsaw
screenBlob_t *blob = GetScreenBlob();
blob->startFadeTime = gameLocal.time;
blob->finishTime = gameLocal.time + ( duration * 1000 );
blob->material = bloodSprayMaterial;
blob->x = ( gameLocal.random.RandomInt() & 63 ) - 32;
blob->y = ( gameLocal.random.RandomInt() & 63 ) - 32;
blob->driftAmount = 0.5f + gameLocal.random.CRandomFloat() * 0.5;
float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f;
blob->w = 600 * g_blobSize.GetFloat() * scale;
blob->h = 480 * g_blobSize.GetFloat() * scale;
float s1 = 0.0f;
float t1 = 0.0f;
float s2 = 1.0f;
float t2 = 1.0f;
if ( blob->driftAmount < 0.6 ) {
s1 = 1.0f;
s2 = 0.0f;
} else if ( blob->driftAmount < 0.75 ) {
t1 = 1.0f;
t2 = 0.0f;
} else if ( blob->driftAmount < 0.85 ) {
s1 = 1.0f;
s2 = 0.0f;
t1 = 1.0f;
t2 = 0.0f;
}
blob->s1 = s1;
blob->t1 = t1;
blob->s2 = s2;
blob->t2 = t2;
*/
}
/*
==================
idPlayerView::WeaponFireFeedback
Called when a weapon fires, generates head twitches, etc
==================
*/
void idPlayerView::WeaponFireFeedback( const idDict *weaponDef ) {
int recoilTime;
recoilTime = weaponDef->GetInt( "recoilTime" );
// don't shorten a damage kick in progress
if ( recoilTime && recoilTime > (kickFinishTime - gameLocal.time) ) {
idAngles angles;
weaponDef->GetAngles( "recoilAngles", "5 0 0", angles );
kickAngles = angles;
int finish = gameLocal.time + g_kickTime.GetFloat() * recoilTime;
kickFinishTime = finish;
}
}
/*
===================
idPlayerView::CalculateShake
===================
*/
// RAVEN BEGIN
// jnewquist: Controller rumble
float idPlayerView::CalculateShake( idAngles &shakeAngleOffset ) const {
idVec3 origin, matrix;
float shakeVolume = soundSystem->CurrentShakeAmplitudeForPosition( SOUNDWORLD_GAME, gameLocal.time, player->firstPersonViewOrigin );
//
// shakeVolume should somehow be molded into an angle here
// it should be thought of as being in the range 0.0 -> 1.0, although
// since CurrentShakeAmplitudeForPosition() returns all the shake sounds
// the player can hear, it can go over 1.0 too.
//
shakeAngleOffset[0] = gameLocal.random.CRandomFloat() * shakeVolume;
shakeAngleOffset[1] = gameLocal.random.CRandomFloat() * shakeVolume;
shakeAngleOffset[2] = gameLocal.random.CRandomFloat() * shakeVolume;
return shakeVolume;
}
// RAVEN END
/*
===================
idPlayerView::AngleOffset
kickVector, a world space direction that the attack should
===================
*/
idAngles idPlayerView::AngleOffset() const {
idAngles ang;
ang.Zero();
if ( gameLocal.time < kickFinishTime ) {
float offset = kickFinishTime - gameLocal.time;
ang = kickAngles * offset * offset * g_kickAmplitude.GetFloat();
for ( int i = 0 ; i < 3 ; i++ ) {
if ( ang[i] > 70.0f ) {
ang[i] = 70.0f;
} else if ( ang[i] < -70.0f ) {
ang[i] = -70.0f;
}
}
}
return ang;
}
/*
===================
idPlayerView::ShakeOffsets
===================
*/
// RAVEN BEGIN
// jnewquist: Controller rumble
void idPlayerView::ShakeOffsets( idVec3 &shakeOffset, idAngles &shakeAngleOffset, const idBounds bounds ) const {
float shakeVolume = 0.0f;
shakeOffset.Zero();
shakeAngleOffset.Zero();
if( gameLocal.isMultiplayer ) {
return;
}
shakeVolume = CalculateShake( shakeAngleOffset );
if( gameLocal.time < shakeFinishTime ) {
float offset = ( shakeFinishTime - gameLocal.time ) * shakeScale * 0.001f;
shakeOffset[0] = idMath::ClampFloat( bounds[0][0] - 1.0f, bounds[1][0] + 1.0f, rvRandom::flrand( -offset, offset ) );
shakeOffset[1] = idMath::ClampFloat( bounds[0][1] - 1.0f, bounds[1][1] + 1.0f, rvRandom::flrand( -offset, offset ) );
shakeOffset[2] = idMath::ClampFloat( bounds[0][2] - 1.0f, bounds[1][2] + 1.0f, rvRandom::flrand( -offset, offset ) );
shakeAngleOffset[0] = idMath::ClampFloat( -70.0f, 70.0f, rvRandom::flrand( -offset, offset ) );
shakeAngleOffset[1] = idMath::ClampFloat( -70.0f, 70.0f, rvRandom::flrand( -offset, offset ) );
shakeAngleOffset[2] = idMath::ClampFloat( -70.0f, 70.0f, rvRandom::flrand( -offset, offset ) );
}
}
// RAVEN END
/*
==================
idPlayerView::SingleView
==================
*/
void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view, int renderFlags ) {
// normal rendering
if ( !view ) {
return;
}
if ( !( RF_GUI_ONLY & renderFlags ) ) {
// jscott: portal sky rendering with KRABS
idCamera *portalSky = gameLocal.GetPortalSky();
if( portalSky ) {
renderView_t portalSkyView = *view;
portalSky->GetViewParms( &portalSkyView );
gameRenderWorld->RenderScene( &portalSkyView, ( renderFlags & ( ~RF_PRIMARY_VIEW ) ) | RF_DEFER_COMMAND_SUBMIT | RF_PORTAL_SKY );
}
gameRenderWorld->RenderScene( view, renderFlags | RF_PENUMBRA_MAP );
}
if ( RF_NO_GUI & renderFlags ) {
return;
}
// draw screen blobs
if ( !pm_thirdPerson.GetBool() && !g_skipViewEffects.GetBool() ) {
for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) {
screenBlob_t *blob = &screenBlobs[i];
if ( blob->finishTime <= gameLocal.time ) {
continue;
}
blob->y += blob->driftAmount;
float fade = (float)( blob->finishTime - gameLocal.time ) / ( blob->finishTime - blob->startFadeTime );
if ( fade > 1.0f ) {
fade = 1.0f;
}
if ( fade ) {
renderSystem->SetColor4( 1,1,1,fade );
renderSystem->DrawStretchPic( blob->x, blob->y, blob->w, blob->h,blob->s1, blob->t1, blob->s2, blob->t2, blob->material );
}
}
// Render tunnel vision
if ( gameLocal.time < tvFinishTime ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, tvScale * ((float)(tvFinishTime - gameLocal.time) / (float)(tvFinishTime - tvStartTime)) );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial );
}
player->DrawHUD( hud );
/*
// tunnel vision
float health = 0.0f;
if ( g_testHealthVision.GetFloat() != 0.0f ) {
health = g_testHealthVision.GetFloat();
} else {
health = player->health;
}
float alpha = health / 100.0f;
if ( alpha < 0.0f ) {
alpha = 0.0f;
}
if ( alpha > 1.0f ) {
alpha = 1.0f;
}
if ( alpha < 1.0f ) {
renderSystem->SetColor4( ( player->health <= 0.0f ) ? MS2SEC( gameLocal.time ) : lastDamageTime, 1.0f, 1.0f, ( player->health <= 0.0f ) ? 0.0f : alpha );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial );
}
*/
// Render the object system
// RAVEN BEGIN
// twhitaker: always draw objective system
if ( player->objectiveSystem ) {
player->objectiveSystem->Redraw( gameLocal.time );
}
// RAVEN END
}
// test a single material drawn over everything
if ( g_testPostProcess.GetString()[0] ) {
const idMaterial *mtr = declManager->FindMaterial( g_testPostProcess.GetString(), false );
if ( !mtr ) {
common->Printf( "Material not found.\n" );
g_testPostProcess.SetString( "" );
} else {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr );
}
}
}
/*
===================
idPlayerView::DoubleVision
===================
*/
void idPlayerView::DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ) {
if ( !g_doubleVision.GetBool() ) {
SingleView( hud, view, RF_NO_GUI );
return;
}
float scale = offset * g_dvAmplitude.GetFloat() * dvScale;
if( scale < 0.0f ) {
return;
}
if ( scale > 0.5f ) {
scale = 0.5f;
}
float shift = scale * idMath::Sin( idMath::Sqrt ( offset ) * g_dvFrequency.GetFloat() );
shift = fabs( shift );
// if double vision, render to a texture
renderSystem->CropRenderSize( 512, 256, true );
SingleView( hud, view, RF_NO_GUI );
renderSystem->CaptureRenderToImage( "_scratch" );
renderSystem->UnCrop();
// carry red tint if in berserk mode
idVec4 color(1, 1, 1, 1);
renderSystem->SetColor4( color.x, color.y, color.z, 1.0f );
// RAVEN BEGIN
// jnewquist: Call DrawStretchCopy, which will flip the texcoords for D3D
renderSystem->DrawStretchCopy( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, shift, 1, 1, 0, dvMaterial );
renderSystem->DrawStretchCopy( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1-shift, 0, dvMaterialBlend );
// RAVEN END
}
/*
=================
idPlayerView::Flash
flashes the player view with the given color
=================
*/
void idPlayerView::Flash(idVec4 color, int time ) {
Fade(idVec4(0, 0, 0, 0), time);
fadeFromColor = colorWhite;
}
/*
=================
idPlayerView::Fade
used for level transition fades
assumes: color.w is 0 or 1
=================
*/
void idPlayerView::Fade( idVec4 color, int time ) {
if ( !fadeTime ) {
fadeFromColor.Set( 0.0f, 0.0f, 0.0f, 1.0f - color[ 3 ] );
} else {
fadeFromColor = fadeColor;
}
fadeToColor = color;
if ( time <= 0 ) {
fadeRate = 0;
time = 0;
fadeColor = fadeToColor;
} else {
fadeRate = 1.0f / ( float )time;
}
if ( gameLocal.realClientTime == 0 && time == 0 ) {
fadeTime = 1;
} else {
fadeTime = gameLocal.realClientTime + time;
}
}
/*
=================
idPlayerView::ScreenFade
=================
*/
void idPlayerView::ScreenFade() {
int msec;
float t;
if ( !fadeTime ) {
return;
}
msec = fadeTime - gameLocal.realClientTime;
if ( msec <= 0 ) {
fadeColor = fadeToColor;
if ( fadeColor[ 3 ] == 0.0f ) {
fadeTime = 0;
}
} else {
t = ( float )msec * fadeRate;
fadeColor = fadeFromColor * t + fadeToColor * ( 1.0f - t );
}
if ( fadeColor[ 3 ] != 0.0f ) {
renderSystem->SetColor4( fadeColor[ 0 ], fadeColor[ 1 ], fadeColor[ 2 ], fadeColor[ 3 ] );
renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
}
}
/*
===================
idPlayerView::InfluenceVision
===================
*/
void idPlayerView::InfluenceVision( idUserInterface *hud, const renderView_t *view ) {
float distance = 0.0f;
float pct = 1.0f;
if ( player->GetInfluenceEntity() ) {
distance = ( player->GetInfluenceEntity()->GetPhysics()->GetOrigin() - player->GetPhysics()->GetOrigin() ).Length();
if ( player->GetInfluenceRadius() != 0.0f && distance < player->GetInfluenceRadius() ) {
pct = distance / player->GetInfluenceRadius();
pct = 1.0f - idMath::ClampFloat( 0.0f, 1.0f, pct );
}
}
if ( player->GetInfluenceMaterial() ) {
SingleView( hud, view );
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, pct );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() );
} else if ( player->GetInfluenceEntity() == NULL ) {
SingleView( hud, view, RF_NO_GUI );
return;
} else {
int offset = 25 + idMath::Sin ( gameLocal.time );
DoubleVision( hud, view, pct * offset );
}
}
/*
===================
idPlayerView::RenderPlayerView
===================
*/
void idPlayerView::RenderPlayerView( idUserInterface *hud ) {
if ( !player ) {
return;
}
const renderView_t *view = player->GetRenderView();
if ( !view ) {
return;
}
bool guiRendered = false;
// place the sound origin for the player
soundSystem->PlaceListener( view->vieworg, view->viewaxis, player->entityNumber + 1, gameLocal.time, "Undefined" );
if ( g_skipViewEffects.GetBool() ) {
SingleView( hud, view );
} else {
if ( player->GetInfluenceMaterial() || player->GetInfluenceEntity() ) {
InfluenceVision( hud, view );
guiRendered = true;
} else if ( g_doubleVision.GetBool() && gameLocal.time < dvFinishTime ) {
DoubleVision( hud, view, dvFinishTime - gameLocal.time );
guiRendered = false;
} else {
SingleView( hud, view, RF_NO_GUI | RF_PRIMARY_VIEW );
}
// Now draw GUI's.
if ( !guiRendered ) {
SingleView( hud, view, RF_GUI_ONLY );
}
ScreenFade();
}
if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient && !( gameLocal.GetDemoState() == DEMO_PLAYING && ( gameLocal.IsServerDemo() || gameLocal.IsTimeDemo() ) ) ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial );
}
}
// RAVEN END

143
source/game/PlayerView.h Normal file
View file

@ -0,0 +1,143 @@
// RAVEN BEGIN
// bdube: note that this file is no longer merged with Doom3 updates
//
// MERGE_DATE 07/07/2004
#ifndef __GAME_PLAYERVIEW_H__
#define __GAME_PLAYERVIEW_H__
/*
===============================================================================
Player view.
===============================================================================
*/
// screenBlob_t are for the on-screen damage claw marks, etc
typedef struct {
const idMaterial * material;
float x, y, w, h;
float s1, t1, s2, t2;
int finishTime;
int startFadeTime;
float driftAmount;
} screenBlob_t;
#define MAX_SCREEN_BLOBS 8
class idPlayerView {
public:
idPlayerView();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetPlayerEntity( class idPlayer *playerEnt );
void ClearEffects( void );
// RAVEN BEGIN
// jnewquist: Controller rumble
void DamageImpulse( idVec3 localKickDir, const idDict *damageDef, int damage );
// RAVEN END
void WeaponFireFeedback( const idDict *weaponDef );
idAngles AngleOffset( void ) const; // returns the current kick angle
// RAVEN BEGIN
// jnewquist: Controller rumble
float CalculateShake( idAngles &shakeAngleOffset ) const;
// RAVEN END
// RAVEN BEGIN
// jscott: for screen shake
void ShakeOffsets( idVec3 &shakeOffset, idAngles &shakeAngleOffset, const idBounds bounds ) const;
// RAVEN END
// adds little entities to the renderer for local blood blobs, etc
// this may involve rendering to a texture and displaying
// that with a warp model or in double vision mode
void RenderPlayerView( idUserInterface *hud );
void Fade( idVec4 color, int time );
void Flash( idVec4 color, int time );
void AddBloodSpray( float duration );
// temp for view testing
void EnableBFGVision( bool b ) { bfgVision = b; };
// RAVEN BEGIN
// jscott: accessors required for the fx system
void SetDoubleVisionParms( float time, float scale ) { dvFinishTime = SEC2MS( time ); dvScale = scale; }
void SetShakeParms( float time, float scale ) { shakeFinishTime = SEC2MS( time ); shakeScale = scale; }
void SetTunnelParms( float time, float scale ) { tvStartTime = gameLocal.time; tvFinishTime = tvStartTime + time; tvScale = 1.0f / scale; }
// RAVEN END
private:
// RAVEN BEGIN
// AReis: Modified SingleView() signature to include renderFlags variable.
void SingleView( idUserInterface *hud, const renderView_t *view, int renderFlags = RF_NORMAL );
// RAVEN END
void DoubleVision( idUserInterface *hud, const renderView_t *view, int offset );
void BerserkVision( idUserInterface *hud, const renderView_t *view );
void InfluenceVision( idUserInterface *hud, const renderView_t *view );
void ScreenFade();
screenBlob_t * GetScreenBlob();
screenBlob_t screenBlobs[MAX_SCREEN_BLOBS];
int dvFinishTime; // double vision will be stopped at this time
const idMaterial * dvMaterial; // material to take the double vision screen shot
// RAVEN BEGIN
// jscott: to make double vision work with alpha components
const idMaterial * dvMaterialBlend;
// jscott: for effects
float dvScale;
// RAVEN END
int kickFinishTime; // view kick will be stopped at this time
idAngles kickAngles;
bool bfgVision; //
const idMaterial * tunnelMaterial; // health tunnel vision
const idMaterial * armorMaterial; // armor damage view effect
// RAVEN BEGIN
// bdube: not using these
// const idMaterial * berserkMaterial; // berserk effect
// const idMaterial * irGogglesMaterial; // ir effect
const idMaterial * bloodSprayMaterial; // blood spray
// const idMaterial * bfgMaterial; // when targeted with BFG
// RAVEN END
const idMaterial * lagoMaterial; // lagometer drawing
float lastDamageTime; // accentuate the tunnel effect for a while
// RAVEN BEGIN
// jscott: for effects
float shakeFinishTime;
float shakeScale;
float tvScale;
int tvFinishTime;
int tvStartTime;
// RAVEN END
idVec4 fadeColor; // fade color
idVec4 fadeToColor; // color to fade to
idVec4 fadeFromColor; // color to fade from
float fadeRate; // fade rate
int fadeTime; // fade time
idPlayer * player;
renderView_t view;
};
#endif /* !__GAME_PLAYERVIEW_H__ */
// RAVEN END

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