initial commit

This commit is contained in:
UberGames 2011-06-01 14:20:56 +02:00
parent 377fe84668
commit bbdc52c075
475 changed files with 441155 additions and 0 deletions

331
AnimList.txt Normal file
View file

@ -0,0 +1,331 @@
Common Animations
CODE
BOTH_ACTIVATEBELT1
BOTH_ATTACK1
BOTH_ATTACK3
BOTH_BENCHSIT1_2STAND
BOTH_BENCHSIT1_FIXBOOT
BOTH_BENCHSIT1_IDLE
BOTH_BENCHSTAND2
BOTH_BENCHSTAND2TO1
BOTH_CONSOLE1
BOTH_CONSOLE1IDLE
BOTH_CONSOLE1LEFT
BOTH_CONSOLE1RIGHT
BOTH_CONSOLE2
BOTH_CONSOLE3
BOTH_CONSOLE3IDLE
BOTH_CONSOLE3LEFT
BOTH_CONSOLE3RIGHT
BOTH_CONSOLETOSTAND1/BOTH_CONSTOSTAND1
BOTH_COUCHSIT1_2STAND1
BOTH_COUCHSIT1_GESTURELEFT
BOTH_COUCHSIT1_GESTURERIGHT
BOTH_COUCHSIT1_IDLE
BOTH_COUCHSIT1_TALKGESTURE
BOTH_COVERUP1_START
BOTH_COVERUP1_LOOP
BOTH_COVERUP1_END
BOTH_CRAWLBACK1
BOTH_CROUCH1
BOTH_CROUCH1IDLE
BOTH_CROUCH1WALK
BOTH_CROWDLOOK1
BOTH_CROWDLOOK2
BOTH_DEATH1
BOTH_DEAD1
BOTH_DEATH2
BOTH_DEAD2
BOTH_DEATHBACKWARD1
BOTH_DEADBACKWARD1
BOTH_DEATHBACKWARD2
BOTH_DEADBACKWARD2
BOTH_DEATHFORWARD1
BOTH_DEADFORWARD1
BOTH_DEATHFORWARD2
BOTH_DEADFORWARD2
BOTH_DIVE1
BOTH_DROPANGERWEAP2
BOTH_FALLDEATH1
BOTH_FALLDEATH1INAIR
BOTH_FALLDEATH1LAND
BOTH_FALLDEAD1LAND
BOTH_FLOAT1
BOTH_FLOAT2
BOTH_FLOATCONSOLE1
BOTH_GESTURE1
BOTH_GESTURE2
BOTH_GESTURE3
BOTH_GET_UP1
BOTH_GRAB1
BOTH_GRAB2
BOTH_GRABBED1
BOTH_GRABBED2
BOTH_GROUNDSHAKE1
BOTH_GROUNDSHAKE2
BOTH_GUARD_IDLE1
BOTH_GUARD_LKRT1
BOTH_GUARD_LOOKAROUND1
BOTH_GUILT1
BOTH_HALT1
BOTH_INAIR1
BOTH_INJURED1
BOTH_INJURED3
BOTH_JUMP1
BOTH_JUMPBACK1
BOTH_LADDER_DWN1
BOTH_LADDER_UP1
BOTH_LAND1
BOTH_LANDBACK1
BOTH_LEAN1
BOTH_LEAN1TODROPHELM
BOTH_LYINGDEATH1
BOTH_LYINGDEAD1
BOTH_OFFLADDER_BOT1
BOTH_OFFLADDER_TOP1
BOTH_ONLADDER_BOT1
BOTH_ONLADDER_TOP1
BOTH_PAIN1
BOTH_PAIN2
BOTH_PAIN2WRITHE1
BOTH_PSYCHICSHOCK1
BOTH_PUSHTOSTAND1
BOTH_RUN1
BOTH_RUN1STOP
BOTH_RUN2
BOTH_RUNINJURED1
BOTH_SHIELD1
BOTH_SHIELD2
BOTH_SIT1STAND
BOTH_SIT1TO2
BOTH_SIT1TO3
BOTH_SIT2TO1
BOTH_SIT2TO3
BOTH_SIT3TO1
BOTH_SIT3TO2
BOTH_SIT4TO5
BOTH_SIT4TO6
BOTH_SIT5TO4
BOTH_SIT5TO6
BOTH_SIT6TO4
BOTH_SIT6TO5
BOTH_SIT7
BOTH_SIT7TOSTAND1
BOTH_STAND1
BOTH_STAND1_RANDOM1
BOTH_STAND1_RANDOM2
BOTH_STAND1_RANDOM3
BOTH_STAND1_RANDOM4
BOTH_STAND1_RANDOM5
BOTH_STAND1_RANDOM6
BOTH_STAND1_RANDOM7
BOTH_STAND1_RANDOM8
BOTH_STAND1_RANDOM12
BOTH_STAND2
BOTH_STAND2TO4
BOTH_STAND2_RANDOM1
BOTH_STAND2_RANDOM2
BOTH_STAND2_RANDOM3
BOTH_STAND3
BOTH_STAND4
BOTH_STAND4TO2
BOTH_STAND5
BOTH_STAND6
BOTH_STAND8
BOTH_STAND9
BOTH_STANDTOCONSOLE1
BOTH_STANDTOWALK1
BOTH_SURPRISED1
BOTH_SURPRISED2
BOTH_SURPRISED4
BOTH_SURPRISED5
BOTH_TABLE_EAT1
BOTH_TABLE_GETUP1
BOTH_TABLE_IDLE1
BOTH_TABLE_TALKGESTURE1
BOTH_UNCROUCH1
BOTH_WALK1
BOTH_WALK2
BOTH_WALK3
BOTH_WALK4
BOTH_WALK7
BOTH_WALKPUSH1
BOTH_WALKTORUN1
BOTH_WRITHING1
LEGS_BACKTORSO_COMBADGE1
LEGS_KNEELDOWN1
LEGS_KNEELUP1
LEGS_LEAN_LEFT1
LEGS_LEAN_RIGHT1
LEGS_TURN1
LEGS_TURN2
LEGS_WALKBACK1
TORSO_COMBADGE2
TORSO_COMBADGE3
TORSO_DROPHELMET1
TORSO_DROPWEAP1
TORSO_EQUIPMENT1
TORSO_EQUIPMENT2
TORSO_GRABLBACKL
TORSO_HAND1
TORSO_HAND2
TORSO_HANDGESTURE1
TORSO_HANDGESTURE2
TORSO_HANDGESTURE3
TORSO_HANDGESTURE4
TORSO_HANDGESTURE5
TORSO_HANDGESTURE6
TORSO_HANDGESTURE7
TORSO_HANDGESTURE8
TORSO_HANDGESTURE9
TORSO_HANDGESTURE10
TORSO_HANDGESTURE11
TORSO_HANDGESTURE12
TORSO_HANDGESTURE13
TORSO_HEADNOD1
TORSO_HEADSHAKE1
TORSO_HYPOSPRAY1
TORSO_MEDICORDER1
TORSO_POKERIDLE1
TORSO_POKERIDLE2
TORSO_POKERIDLE3
TORSO_RAISEHELMET1
TORSO_RAISEWEAP1
TORSO_REACHHELMET1
TORSO_SHOUT1
TORSO_SPEECHLESS1
TORSO_SPEECHLESS2
TORSO_TRICORDER1
TORSO_WEAPONIDLE1
TORSO_WEAPONREADY1
TORSO_WEAPONREADY2
Male-only Animations
CODE
BOTH_ACTIVATEMEDKIT1
BOTH_ASSIMILATED1
BOTH_BENCHSIT1TO2
BOTH_BENCHSIT2_IDLE
BOTH_BENCHSIT2STAND
BOTH_BENCHSIT2TO1
BOTH_CATCH1
BOTH_CROUCH2IDLE
BOTH_CROUCH2TOSTAND1
BOTH_CROWDLOOK3
BOTH_CROWDLOOK4
BOTH_FALSEJUMP1
BOTH_HEROSTANCE1
BOTH_HITWALL1
BOTH_INAIR1
BOTH_INJURED2
BOTH_INJURED6
BOTH_INJURED6ATTACKSTART
BOTH_INJURED6ATTACKSTOP
BOTH_INJURED6COMBADGE
BOTH_INJURED6POINT
BOTH_LADDER_IDLE
BOTH_LAUGH1
BOTH_LAUGH2
BOTH_SCARED1
BOTH_SCARED2
BOTH_STAND1_RANDOM11
BOTH_STAND1_RANDOM13
BOTH_STAND7
BOTH_SURPRISED3
BOTH_WRITHING2
LEGS_KNEEL1
TORSO_ATTACK2
TORSO_COFFEE
TORSO_PADD1
TORSO_STAND2TOWEAPONREADY2
TORSO_WRIST1
Female-only Animations
CODE
BOTH_ATTACK2
BOTH_BENCHSTAND1TO2
BOTH_CARRIED1
BOTH_CARRIED2
BOTH_CONSOLE4
BOTH_CONSOLE5
BOTH_COUCHSIT1_TO2
BOTH_COWAR1
BOTH_DEAD1_FLOP
BOTH_DEAD2_FLOP
BOTH_DEAD3_FLOP
BOTH_DEAD4_FLOP
BOTH_DEAD5_FLOP
BOTH_DEAD6_FLOP
BOTH_DEAD7_FLOP
BOTH_DEADBACKWARD1_FLOP
BOTH_DEADBACKWARD2_FLOP
BOTH_DEADFORWARD1_FLOP
BOTH_DEADFORWARD2_FLOP
BOTH_DEATH3
BOTH_DEAD3
BOTH_DEATH4
BOTH_DEAD4
BOTH_DEATH5
BOTH_DEAD5
BOTH_DEATH6
BOTH_DEAD6
BOTH_DEATH7
BOTH_DEAD7
BOTH_FALLDEAD1_FLOP
BOTH_GET_UP2
BOTH_GRAB3
BOTH_GRAB4
BOTH_HELP1
BOTH_KNEELHAND1
BOTH_LIFTED1
BOTH_LYINGDEAD1_FLOP
BOTH_PAIN3
BOTH_POSSESSED1
BOTH_PSYCHICSHOCK2
BOTH_RESTRAINED1
BOTH_RESTRAINED1POINT
BOTH_RUNAWAY1
BOTH_SHOCK1
BOTH_SLEEP1
BOTH_SLEEP1_NOSE
BOTH_SLEEP1GETUP
BOTH_SLEEP2
BOTH_SLEEP2_SHIFT
BOTH_SLEEP2GETUP
BOTH_SLEEP3
BOTH_SLEEP3DEATH
BOTH_SLEEP3DEAD
BOTH_SLEEP3GETUP
BOTH_SNAPTO1
BOTH_STAND1_RANDOM12
BOTH_STAND1_RANDOM14
BOTH_STAND1TO2
BOTH_STAND1TO3
BOTH_STAND2_RANDOM4
BOTH_STAND2_RANDOM5
BOTH_STAND2_RANDOM6
BOTH_STAND2_RANDOM7
BOTH_STAND2TO1
BOTH_STAND3TO1
BOTH_STAND4TO5
BOTH_STAND4TO6
BOTH_STAND5TO4
BOTH_STAND6TO4
BOTH_STANDUP1
BOTH_STEP1
BOTH_TALKGESTURE1
BOTH_TALKGESTURE2
BOTH_TALKGESTURE3
BOTH_TALKGESTURE4
BOTH_TALKGESTURE5
BOTH_TALKGESTURE6
LEGS_JUMPB
LEGS_LANDB
LEGS_RUNBACK2
TORSO_COMBADGE4
TORSO_EQUIPMENT3
TORSO_WEAPONIDLE2
TORSO_WEAPONIDLE3
TORSO_WEAPONREADY3

101
BuildQVM.dsp Normal file
View file

@ -0,0 +1,101 @@
# Microsoft Developer Studio Project File - Name="BuildQVM" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) External Target" 0x0106
CFG=BuildQVM - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "BuildQVM.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "BuildQVM.mak" CFG="BuildQVM - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "BuildQVM - Win32 Release" (based on "Win32 (x86) External Target")
!MESSAGE "BuildQVM - Win32 Debug" (based on "Win32 (x86) External Target")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
!IF "$(CFG)" == "BuildQVM - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Cmd_Line "NMAKE /f BuildQVM.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "BuildQVM.exe"
# PROP BASE Bsc_Name "BuildQVM.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "buildvms.bat"
# PROP Rebuild_Opt ""
# PROP Target_File "..\baseef\game.qvm"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "BuildQVM - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "BuildQVM___Win32_Debug"
# PROP BASE Intermediate_Dir "BuildQVM___Win32_Debug"
# PROP BASE Cmd_Line "NMAKE /f BuildQVM.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "BuildQVM.exe"
# PROP BASE Bsc_Name "BuildQVM.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "BuildQVM___Win32_Debug"
# PROP Intermediate_Dir "BuildQVM___Win32_Debug"
# PROP Cmd_Line "buildvms.bat"
# PROP Rebuild_Opt ""
# PROP Target_File "..\baseef\game.qvm"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ENDIF
# Begin Target
# Name "BuildQVM - Win32 Release"
# Name "BuildQVM - Win32 Debug"
!IF "$(CFG)" == "BuildQVM - Win32 Release"
!ELSEIF "$(CFG)" == "BuildQVM - Win32 Debug"
!ENDIF
# Begin Source File
SOURCE=.\buildvms.bat
!IF "$(CFG)" == "BuildQVM - Win32 Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "BuildQVM - Win32 Debug"
# PROP Intermediate_Dir "Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# End Target
# End Project

58
BuildQVM.vcproj Normal file
View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="BuildQVM"
SccProjectName=""
SccLocalPath=""
Keyword="MakeFileProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="0"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCNMakeTool"
BuildCommandLine="buildvms.bat"
ReBuildCommandLine="buildvms.bat "
Output="..\baseef\game.qvm"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\BuildQVM___Win32_Debug"
IntermediateDirectory=".\BuildQVM___Win32_Debug"
ConfigurationType="0"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCNMakeTool"
BuildCommandLine="buildvms.bat"
ReBuildCommandLine="buildvms.bat "
Output="..\baseef\game.qvm"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="buildvms.bat">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,3 @@
To compile for rpgxEF change the following things:
q_shared.h line 54: #define XTRA 0 to #define XTRA 1
bg_public.h line 6: #define XTRA 0 to #define XTRA 1

View file

@ -0,0 +1,213 @@
***********************************************************
* VERSION CHANGE LOG (DO NOT REMOVE THIS HEADER *
* *
* Add a entry when you reciew the code, adding 1 to the *
* last number on the version, listing any new features *
* and fixes or modifications you have made to the code. *
* Use the format as seen in the other entries. *
* DO NOT make an entry every single time you compile! *
* Only as you add features and fixes. *****
* *
* MAKE SURE THIS IS UP-TO-DATE BEFORE HANDING OVER THE CODE!! *
***************************************************************
v0.1.5 Modified By RedTechie Last Compile Date: 24/07/04 (Model System Dedicated Version)
=========================================================================================
Features Added:
--------------------------------------------
Bugs Found:
--------------------------------------------
Bugs Fixed:
--------------------------------------------
Known Bugs:
---------------------------------------------
Todo:
---------------------------------------------
v0.1.4 Modified By J2J Last Compile Date: 24/07/04 (Model System Dedicated Version)
=========================================================================================
Features Added:
--------------------------------------------
-Secondary Fire on TR-116 activates wireframe view to see thru walls in local area portal. (j2j)
-Changed model loading path to /models/players_rpgx/ (j2j)
-Updated the Animation.cfg parser function, imported string tables from single player, and removed extra info parsing (for now) (j2j)
-Single player model now load succesfully into holomatch game. (j2j)
Bugs Found:
--------------------------------------------
Bugs Fixed:
--------------------------------------------
-TR-116 nullshader tmp fixed by removing the guts of the wall hit function. (j2j)
Known Bugs:
---------------------------------------------
Too many to list.
Todo:
---------------------------------------------
Fix animation that are played with various player movments
Add emote function
Rank System
etc.
v0.1.3 Modified By RedTechie Last Compile Date: 22/07/04
=========================================================================================
Features Added:
--------------------------------------------
-Brand new scoreboard (Also fixed intermission scoreboards)
-New forcefield features(zap sound when touched, cvar controlable damage if 0 no health damage will occure, admins can remove forcefields but shooting at them with a alt grenade, force fields are now non damage taking, forcefields now last forever no time limit)
-added cvar rpg_invisibletripmines when set to 0 turns tripmines into time mines and every one can see them when set to 1 turned to tripmines and only admins can see them and walk threw them
-New health bar added first steps to health system ;)
-Flight and cloak status on left hand side of screen
-New n00b features (ghosted, nocliped, they change to the n00b class without a respawn, N00bs cant chat at all)
-Uncommeted out J2J's drag code probly going to get yelled out but its good code :D (only prob what would be cool is if we could get the play to hover in front of the player dragging him and always stay in front of him....kinda like the force in jk with the grip force) But this code is awsome for throwing N00bs off the map into the void :D
-Medics revive if cvar rpg_medicsrevive is turned on (1 or 0)
-Class selection in team menu now used the new rpg classes
-Cloaked admins have a sprite above there heads that only other admins can see saying there cloacked
Bugs Found:
--------------------------------------------
-nullshader for TR-116 :P (COUGH wallmark texture COUGH)
-Red line for TR-116
Bugs Fixed:
--------------------------------------------
-md5 script removed on J2J's request
-Health bar now uses dat text files
Known Bugs:
---------------------------------------------
-Eng Tool's fire still dosnt remove mines when shooting at one trace won't trace a mind :S
-Shake cmd is not finished (its in g_cmds.c and cg_consolecmds.c) g_cmds.c calls it in cg_consolecmds.c it needs to loop to all clients on the server and that loop code needs to be in g_cmds.c so its not hackable
-Portal camera map entity still fricken sways its not a sea ship its a star ship
-Suicide while rpg_medicsrevive is on (forcekill, kill, forcekillradius) dosnt play death animation
Todo:
---------------------------------------------
-Effects gun
-Toggle switch for drag cmd
-MODEL SYSTEM!
-possibly NPC's :)
-apply the same invisible stuff to regular fire on grenades and also takes sounds out of both except for the explostion sound
-admin cmd to freeentity on all tripmines
-admin cmd to revive all
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
-MODEL SYSTEM!
v0.1.2 Modified By J2J Last Compile Date: 28/06/04
=========================================================================================
Features Added:
--------------------------------------------
Phaser and Phaser Compression Rifle sounds added from Nemisis.
Score Board: Score replace with Client Number (Hey its a rpg, who needs a score, right?)
Bugs Found:
--------------------------------------------
Bugs Fixed:
--------------------------------------------
Cloak and Flight now only availible for Admin class.
Known Bugs:
---------------------------------------------
v0.1.1 Modified By J2J Last Compile Date: 23/06/04
=========================================================================================
Features Added:
--------------------------------------------
(Non-Code) - Swaped primary grenades to the single player version model.[In pak3.pk3, add all new contnent here till next release] -Now using extracted.
Added Easter Egg.
Added yet another mapper (yam) to the credits.
Transporter Tricorder now has personal coordinates
Transporter Power Up now has custom transport points.
Added chat commands to return server exe OS, and direct cmd to shutdown server (due to fuckface carter)
Added Chat to Area function, and made it default chat.
Bugs Found:
--------------------------------------------
Ext. Laser bug: Flash light pile up effect still visible to other players when owner is in spec;
Also it piles up flash lights when in an invalid class, and no class is the right class!
Tripmines crash the server when a player comes into direct contact, assuming ent trace is going through, -causing a error
Cloaking only works if clients health is 40 or more.
Cloaking still availible for marines, possible oversight?
Bugs Fixed:
--------------------------------------------
Trip mines now expload for non admin classes properly, and never for a passing admin;
Trip mines know don't crash the game ever, working perfectly;
Laser/Flashlight Problems fixed, so that admin and marine class can have laser, and no layering of lights.
Noclip spectating nolonger uses doors or transporter entities.
Changed all of Phenix's stricmp functions to Q_stricmp for QVM compile (:P)
Known Bugs:
---------------------------------------------
No clip spectating still jerky.
v0.1.0 Modified By Phenix Last Compile Date: 14/06/04
=========================================================================================
Features Added:
-------------------------------------------
New UI color scheme change;
New UI Main Menu (RPG-X Credits, Player Model);
Version Info / Control;
Development Only: Rcon Get Command for use of selected RPG-X Team member only;
-This has been added due to the recent leak of an older preview version by Fuck-Face Carter
And everything before this.
Bugs Found:
-------------------------------------------
Bug Fixes:
-------------------------------------------
None
Known Bugs:
-------------------------------------------
Tripmines expload at random (mostly when the owner admin is NOT in admin class, then expload at anyone);
Noclip Spectating has jerky movment, still uses door transporter entities;
TR-116 produces 1000s of errors on primary fire, and secondary fire whilst invisible still has effect.
Bugs when using marine laser in admin class, it piles up flash lights. Same in the actual marine class.
Player Model on main menu does not change weapons with the weapon display as it should.

83
MakeAMod_readme.txt Normal file
View file

@ -0,0 +1,83 @@
STEF Game Source. Copyright (C) 1999-2001 Raven Softare
NOTE: The source MUST BE INSTALLED into the \stvoy\ directory. (q3asm will not work otherwise, and you cannot make the vms!)
The Game Source is broken out into 3 areas.
game - governs the game, runs on the server side.
cgame - governs the client side of the game, runs on the client side.
ui - handles the ui on the client side.
Making a quick mod is very straightforward. This document assumes Microsoft Visual C++ v6.xx. It covers making a slight mod to the game source, recompiling for debugging and rebuilding the vm's for distribution.
Slow Stasis Projectiles (Rockets) - TestMod
----------------------
1. Open up the StefGame.dsw in Microsoft Visual C++.
2. Set the "game" project as the active project.
3. Open the "g_local.h" file and change the GAMEVERSION define from "baseef" to "TestMod"
4. Save "g_local.h"
5. Open the "g_missile.c" file.
6. Go to line 557 and change the 900 to 300. The old line reads:
VectorScale( dir, 900, bolt->s.pos.trDelta );
The new line should read
VectorScale( dir, 300, bolt->s.pos.trDelta );
7. Save "g_missile.c"
8. Perform a Build All command and it should build a DLL for the game.
At this point you have two options. You can run the debugger, choosing 'stvoyHM.exe' as the executable host which will load your DLL for debugging or you can build the vm's for distribution. When you release mods, you will want to build new vm's.
Building the vm's requires two things.
1. The files contained in the bin_nt path must be available for execution ( lcc.exe and q3asm.exe )
2. There must be environment variables set for proper lib and include paths. Microsoft Visual C++ installs a batch file that does this for you called "VCVARS32.bat"
To build the sample vm for the slow rocket test, do the following:
1. Open a DOS window.
2. Make sure lcc.exe and q3asm.exe are available on the path.
3. Run VCVARS32.bat
4. Go to your mods game directory and run the 'game.bat' file.
This ultimately produces a 'qagame.qvm' in the \baseef\vm\ path.
5. Make a "TestMod" path under your STEF directory. This will be a sibling to 'baseef'
6. Move 'qagame.qvm' to "\YourSTEFPath\TestMod\vm\"
7. Run STEF with the following command line "stvoyhm +set fs_game TestMod"
8. "TestMod" should be the referenced game and you should be able to catch up with and outrun your rockets.
Each of the areas contain a batch file "game.bat", "cgame.bat", and "ui.bat" which will build the appropriate vm files.
-----------------------------------------------
Using Visual Studio to Build and Debug your Mod
1. Create a directory to hold your Mod in the STEF directory
\YourSTEFPath\TestMod\
2. In VC, open Project->Settings
3. On the Debug tab Category General:
-set the "Executable for debug session" to your stvoyHM.exe
-Set the "Working directory" to the same directory where stvoyHM.exe is
-Set the "Program arguments" to: +set r_fullscreen 0 +set viewlog 1 +set fs_game TestMod
(note, if you don't have the "set fs_game TestMod", you will need to create
a pak0.pk3 file for the mod to show up in the menu - see below)
4. On the link tab, change path of the "Output file name" to your TestMod directory
Do this for each of projects you are making modifications to (cgame, game, ui)
-------------------------------------------------
Making my Mod show up on the Mod list in the game
You need to have a pak0.pk3 file in your mod directory
before it will show up on the in-game menu. Create a "description.txt"
file with some information about your game mod. Use WinZIP to create
the pak0.pk3 file. Add the "description.txt" file without compression
to the pak0.pk3 file and store it in your TestMod directory. You can
now put the .dll files in this directory, or create a "vm" directory
and place the .qvm files in the vm directory.

50
Makefile Normal file
View file

@ -0,0 +1,50 @@
default: qvm
qvm: build_qvm
so: build_so
ZIP = zip
build_qvm:
$(MAKE) -C Code-DM build_qvm
build_so:
$(MAKE) -C Code-DM build_so
clean:
$(MAKE) -C Code-DM clean
rm -f baseef/*.so baseef/*.pk3 baseef/vm/*.qvm
pak: qvm
cd baseef && rm -f pak4.pk3 && $(ZIP) -r pak4.pk3 vm/*
default: build
build_qvm:
$(MAKE) -C game build_qvm
$(MAKE) -C cgame build_qvm
$(MAKE) -C ui build_qvm
build_so:
$(MAKE) -C game build_so
$(MAKE) -C cgame build_so
$(MAKE) -C ui build_so
clean:
$(MAKE) -C game clean
$(MAKE) -C cgame clean
$(MAKE) -C ui clean
default: qvm
qvm: build_qvm
so: build_so
ZIP = zip
build_qvm:
$(MAKE) -C Code-DM build_qvm
build_so:
$(MAKE) -C Code-DM build_so
clean:
$(MAKE) -C Code-DM clean
rm -f baseef/*.so baseef/*.pk3 baseef/vm/*.qvm
pak: qvm
cd baseef && rm -f pak4.pk3 && $(ZIP) -r pak4.pk3 vm/*

142
README.txt Normal file
View file

@ -0,0 +1,142 @@
The Star Trek Voyager: Elite Force codebase project
This project is meant to be a stable codebase with obvious bugs that
Ravensoft left in there removed and a few new features added.
This project was originally started because my modification of the Quake3
engine to run EF turned out to be a bit problematic. The SnapVector macro
yields slightly different results in the virtual machine interpreter of the
newer quake3 compared to the older quake3 eliteforce is based off.
As a result, you cannot jump as high as you could if you set com_maxfps to
some magic values like 74, 85, 125 etc..
To get the same movement as with the original EliteForce in these new engine
releases the multiplayer VM code must be modified to emulate the old
behaviour.
So my goal is that every active player and every server will install these
modifications to allow for smooth movement on both, servers using the new
engine release and for good motion prediction on the client side. I realize
it may well be that this never happens as getting people to install new pak
files would be a major undertaking. I thought, if I attempt to do so in the
first place, I can as well try to get in a few improvements as long as they
don't change gameplay. I am not trying to insert new weapons, models,
gametypes etc...
A few todos:
- Ignoring text messages from players that are a nuisance
- Unlagged code (can be switched on/off with a cvar)
If you have made changes that do *not* change gameplay as mentioned above
and you think it really improves EliteForce, feel free to send the patches
to: arny@ats.s.bawue.de
If your code is reasonably clean, I will definitely add it to the
repository!
Now for the using of this code:
I have left all non-C files from Ravensoft intact. This means, you should
probably be able to build this release under windows like you build the
original EF source released by raven.
For users on unixoid environments, I have included a few Makefiles that make
the job of building easier. The Makefiles are designed to work under Linux
so if you use another OS you may need to edit the three Makefiles included
in the game, cgame and ui directories to make this build properly.
There are two different types of builds, namely the shared library and the
building of QVMs.
Building the shared objects only requires typing in "make so"
in the main directory where this README resides. If you have a working gcc
installation, this is all you need to do. The rest is being handled by the
Makefiles and in the end you should have three resulting files in the baseef
directory.
Building QVMs is easy, too. You need a few special bins, though, namely
q3lcc, q3rcc, q3cpp and q3asm. They can be found when building Quake3 from
icculus.org: http://icculus.org/quake3/
Get the source code, compile it (you may want to only build the dedicated
server if you have no OpenGL support... consult the README in their project
on how this works). When compilation is done, the four required binaries can
be found in code/tools/. Copy the files to the bin/ directory that is in the
same dir with this README.
Now just do: "make qvm" in this dir and all QVMs should be in baseef/vm/.
Careful when compiling both, QVMs and shared objects. gcc and the q3lcc
compiler produce incompatible output.
Make sure to run "make clean" before you change from QVM to shared objects
and vice versa.
And last but not least: I already installed a mechanism to produce a pak
file that only works if you have zip installed.
make pak
will result in all three QVMs being packed into pak4.pk3 in baseef :)
Rename it as you see fit.
- Thilo Schulz, 16.03.2006
The Star Trek Voyager: Elite Force codebase project
This project is meant to be a stable codebase with obvious bugs that
Ravensoft left in there removed and a few new features added.
This project was originally started because my modification of the Quake3
engine to run EF turned out to be a bit problematic. The SnapVector macro
yields slightly different results in the virtual machine interpreter of the
newer quake3 compared to the older quake3 eliteforce is based off.
As a result, you cannot jump as high as you could if you set com_maxfps to
some magic values like 74, 85, 125 etc..
To get the same movement as with the original EliteForce in these new engine
releases the multiplayer VM code must be modified to emulate the old
behaviour.
So my goal is that every active player and every server will install these
modifications to allow for smooth movement on both, servers using the new
engine release and for good motion prediction on the client side. I realize
it may well be that this never happens as getting people to install new pak
files would be a major undertaking. I thought, if I attempt to do so in the
first place, I can as well try to get in a few improvements as long as they
don't change gameplay. I am not trying to insert new weapons, models,
gametypes etc...
A few todos:
- Ignoring text messages from players that are a nuisance
- Unlagged code (can be switched on/off with a cvar)
If you have made changes that do *not* change gameplay as mentioned above
and you think it really improves EliteForce, feel free to send the patches
to: arny@ats.s.bawue.de
If your code is reasonably clean, I will definitely add it to the
repository!
Now for the using of this code:
I have left all non-C files from Ravensoft intact. This means, you should
probably be able to build this release under windows like you build the
original EF source released by raven.
For users on unixoid environments, I have included a few Makefiles that make
the job of building easier. The Makefiles are designed to work under Linux
so if you use another OS you may need to edit the three Makefiles included
in the game, cgame and ui directories to make this build properly.
There are two different types of builds, namely the shared library and the
building of QVMs.
Building the shared objects only requires typing in "make so"
in the main directory where this README resides. If you have a working gcc
installation, this is all you need to do. The rest is being handled by the
Makefiles and in the end you should have three resulting files in the baseef
directory.
Building QVMs is easy, too. You need a few special bins, though, namely
q3lcc, q3rcc, q3cpp and q3asm. They can be found when building Quake3 from
icculus.org: http://icculus.org/quake3/
Get the source code, compile it (you may want to only build the dedicated
server if you have no OpenGL support... consult the README in their project
on how this works). When compilation is done, the four required binaries can
be found in code/tools/. Copy the files to the bin/ directory that is in the
same dir with this README.
Now just do: "make qvm" in this dir and all QVMs should be in baseef/vm/.
Careful when compiling both, QVMs and shared objects. gcc and the q3lcc
compiler produce incompatible output.
Make sure to run "make clean" before you change from QVM to shared objects
and vice versa.
And last but not least: I already installed a mechanism to produce a pak
file that only works if you have zip installed.
make pak
will result in all three QVMs being packed into pak4.pk3 in baseef :)
Rename it as you see fit.
- Thilo Schulz, 16.03.2006

39
RPG-X Lua Doc.txt Normal file
View file

@ -0,0 +1,39 @@
library entity:
Avaible:
entity.FindNumber(int num) --> finds and returns an entity by it's entity index number
entity.Find(string targetname) --> finds and returns an entity by it's targetname
entity.FindBModel(string bmodel) --> Find an entity by its brush model
entity.Target(entity ent) --> returns one of the targets of an entity
entity.Teleport(entity ent, entity target) --> Teleports a player to an other entity
entity.IsRocket(entity ent) --> Checks if an entity is a rocket
entity.IsGrenade(entity ent) --> Checks if an entity is a grenade
entity.Spawn(void) --> Spawn a new entity if possible
entity.GetNumber(entity ent) --> Returns an entities index number
entity.IsClient(entity ent) --> Checks if an entity is a client
entity.GetClientName(entity ent) --> Returns the display name of a client
entity.Print -->
entity.CenterPrint -->
entity.GetClassname(entity ent) --> Returns the classname of an entity
entity.SetClassname(entity ent, string name) --> Sets the classname of an entity to namer
entity.GetTargetname(entity ent) --> Returns the targetname of an entity
entity.Rotate(entity ent, vector dir --> Rotates an entity in the specified directions
entity.__tostring(entity ent) --> Prints an entity as string
entity.CallSpawn(entity ent) --> Calls the spawn function for an entity
entity.Remove(entity ent) --> Removes an entity if it is not protected (eg. Players)
ToDo:
entity.SetField(entity ent, string field) --> Set a field of an entity to a new value
entity.SetValue(entity ent, string value) --> Set a member of gentity_s to new value (for members that are not in fields_t)
library qmath:
Avaible:
qmath.fabs(float num) --> Returns the integer part of a floating point number
qmath.sin(float degree) --> Implementation of Sinus function, takes degree as argument not radian
qmath.cos(float degree) --> Implementation of Cosinus function, takes degree as argument not radian
qmath.tan(float degree) --> Implementation of Tan function, takes degree as argument not radian
qmath.asin(float number) --> ~
qmath.acos(float number) --> ~
qmath.atan(float number) --> ~
qmath.ceil(float number) --> rounds up
qmath.floor(float number) --> rounds down

View file

@ -0,0 +1,279 @@
\relax
\catcode`"\active
\select@language{ngerman}
\@writefile{toc}{\select@language{ngerman}}
\@writefile{lof}{\select@language{ngerman}}
\@writefile{lot}{\select@language{ngerman}}
\@writefile{toc}{\contentsline {chapter}{\numberline {1}Einf\IeC {\"u}hrung}{7}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{intro}{{1}{7}}
\@writefile{toc}{\contentsline {section}{\numberline {1.1}Grundlegende Informationen}{7}}
\newlabel{gen-info}{{1.1}{7}}
\@writefile{toc}{\contentsline {section}{\numberline {1.2}Vorvereinbarungen}{7}}
\newlabel{preq}{{1.2}{7}}
\@writefile{toc}{\contentsline {chapter}{\numberline {2}Lua Hooks}{9}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{lua-hooks}{{2}{9}}
\@writefile{toc}{\contentsline {section}{\numberline {2.1}Was ist ein Lua Hook}{9}}
\newlabel{wia-lh}{{2.1}{9}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Statische Lua Hooks}{9}}
\newlabel{s-lh}{{2.2}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}InitGame}{9}}
\newlabel{init-game}{{2.2.1}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}ShutdownGame}{9}}
\newlabel{shutdown-game}{{2.2.2}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.3}RunFrame}{10}}
\newlabel{run-frame}{{2.2.3}{10}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.4}GClientPrint}{10}}
\newlabel{cli-print}{{2.2.4}{10}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.5}GPrint}{10}}
\newlabel{g-print}{{2.2.5}{10}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Dynamische Lua Hooks}{11}}
\newlabel{dyn-lh}{{2.3}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.1}luaThink}{11}}
\newlabel{luaThink}{{2.3.1}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.2}luaTouch}{11}}
\newlabel{luaTouch}{{2.3.2}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.3}luaUse}{11}}
\newlabel{luaUse}{{2.3.3}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.4}luaHurt}{11}}
\newlabel{luaHurt}{{2.3.4}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.5}luaDie}{11}}
\newlabel{luaDie}{{2.3.5}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.6}luaFree}{12}}
\newlabel{luaFree}{{2.3.6}{12}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.7}luaReached}{12}}
\newlabel{luaReached}{{2.3.7}{12}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.8}luaReachedAngular}{12}}
\newlabel{luaReachedAngular}{{2.3.8}{12}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.9}luaTrigger}{12}}
\newlabel{luaTrigger}{{2.3.9}{12}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.10}luaSpawn}{12}}
\newlabel{luaSpawn}{{2.3.10}{12}}
\@writefile{toc}{\contentsline {chapter}{\numberline {3}RPG-X2 Map Scripting}{13}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{rpgx2-mapscripting}{{3}{13}}
\@writefile{toc}{\contentsline {section}{\numberline {3.1}Map scripts}{13}}
\newlabel{map-scripts}{{3.1}{13}}
\@writefile{toc}{\contentsline {section}{\numberline {3.2}Aufruf von Funktionen}{13}}
\newlabel{map-callingfunction}{{3.2}{13}}
\@writefile{toc}{\contentsline {chapter}{\numberline {4}RPG-X2 Lua Bibliotheken}{15}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{rpgx2-llibs}{{4}{15}}
\@writefile{toc}{\contentsline {section}{\numberline {4.1}game}{15}}
\newlabel{g}{{4.1}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.1}game.Print}{15}}
\newlabel{g-prnt}{{4.1.1}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.2}game.ClientPrint}{15}}
\newlabel{g-clientprint}{{4.1.2}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.3}game.CenterPrint}{15}}
\newlabel{g-centerprint}{{4.1.3}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.4}game.MessagePrint}{15}}
\newlabel{g-messagepritn}{{4.1.4}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.5}game.LevelTime}{16}}
\newlabel{g-leveltime}{{4.1.5}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.6}game.SetGlobal}{16}}
\newlabel{g-setglobal}{{4.1.6}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.7}game.GetGlobal}{16}}
\newlabel{g-getglobal}{{4.1.7}{16}}
\@writefile{toc}{\contentsline {section}{\numberline {4.2}qmath}{17}}
\newlabel{qmath}{{4.2}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.1}qmath.abs}{17}}
\newlabel{qm-abs}{{4.2.1}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.2}qmath.sin}{17}}
\newlabel{qm-sin}{{4.2.2}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.3}qmath.cos}{17}}
\newlabel{qm-cos}{{4.2.3}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.4}qmath.tan}{17}}
\newlabel{qm-tan}{{4.2.4}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.5}qmath.asin}{17}}
\newlabel{qm-asin}{{4.2.5}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.6}qmath.acos}{17}}
\newlabel{qm-acos}{{4.2.6}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.7}qmath.atan}{17}}
\newlabel{qm-atan}{{4.2.7}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.8}qmath.floor}{17}}
\newlabel{qm-floor}{{4.2.8}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.9}qmath.ceil}{18}}
\newlabel{qm-ceil}{{4.2.9}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.10}qmath.fmod}{18}}
\newlabel{qm-fmod}{{4.2.10}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.11}qmath.modf}{18}}
\newlabel{qm-modf}{{4.2.11}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.12}qmath.sqrt}{18}}
\newlabel{qm-sqrt}{{4.2.12}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.13}qmath.log}{18}}
\newlabel{qm-log}{{4.2.13}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.14}qmath.log10}{18}}
\newlabel{qm-log10}{{4.2.14}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.15}qmath.deg}{18}}
\newlabel{qm-deg}{{4.2.15}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.16}qmath.rad}{18}}
\newlabel{qm-rad}{{4.2.16}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.17}qmath.frexp}{18}}
\newlabel{qm-frexp}{{4.2.17}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.18}qmath.ldexp}{19}}
\newlabel{qm-ldexp}{{4.2.18}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.19}qmath.min}{19}}
\newlabel{qm-min}{{4.2.19}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.20}qmath.max}{19}}
\newlabel{qm-max}{{4.2.20}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.21}qmath.random}{19}}
\newlabel{qm-random}{{4.2.21}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.22}qmath.crandom}{19}}
\newlabel{qm-crandom}{{4.2.22}{19}}
\@writefile{toc}{\contentsline {section}{\numberline {4.3}vector}{20}}
\newlabel{vect}{{4.3}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.1}vector.New}{20}}
\newlabel{vect-new}{{4.3.1}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.2}vector.Construct}{20}}
\newlabel{vect-cons}{{4.3.2}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.3}vector.Set}{20}}
\newlabel{vect-set}{{4.3.3}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.4}vector.clear}{20}}
\newlabel{vect-clear}{{4.3.4}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.5}vector.Add}{20}}
\newlabel{vect-add}{{4.3.5}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.6}vector.Substract}{20}}
\newlabel{vect-sub}{{4.3.6}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.7}vector.Scale}{20}}
\newlabel{vect-scale}{{4.3.7}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.8}vector.Length}{21}}
\newlabel{vect-length}{{4.3.8}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.9}vector.Normalize}{21}}
\newlabel{vect-norm}{{4.3.9}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.10}vector.RotateAroundPoint}{21}}
\newlabel{vect-rotarndpnt}{{4.3.10}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.11}vector.Perpendicular}{21}}
\newlabel{vect-Perpendicular}{{4.3.11}{21}}
\@writefile{toc}{\contentsline {section}{\numberline {4.4}entity}{22}}
\newlabel{enty}{{4.4}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.1}entity.Find}{22}}
\newlabel{enty-find}{{4.4.1}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.2}entity.FindNumber}{22}}
\newlabel{enty.findnumber}{{4.4.2}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.3}entity.FindBModel}{22}}
\newlabel{enty-findbmodel}{{4.4.3}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.4}ent.GetNumber}{22}}
\newlabel{enty-getnumber}{{4.4.4}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.5}ent.SetKeyValue}{22}}
\newlabel{enty-setkeyvalue}{{4.4.5}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.6}entity.Remove}{22}}
\newlabel{enty-remove}{{4.4.6}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.7}ent.GetOrigin}{23}}
\newlabel{enty-getorigin}{{4.4.7}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.8}ent.IsClient}{23}}
\newlabel{enty-isclient}{{4.4.8}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.9}ent.GetClientname}{23}}
\newlabel{enty-getclientname}{{4.4.9}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.10}ent.GetClassname}{23}}
\newlabel{enty-getclassname}{{4.4.10}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.11}ent.SetClassname}{23}}
\newlabel{enty-setclassname}{{4.4.11}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.12}ent.GetTargetname}{23}}
\newlabel{enty-gettargetname}{{4.4.12}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.13}ent.SetupTrigger}{23}}
\newlabel{enty-setuptrigger}{{4.4.13}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.14}entity.GetTarget}{23}}
\newlabel{enty-gettarget}{{4.4.14}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.15}entity.Use}{23}}
\newlabel{enty-use}{{4.4.15}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.16}entity.Spawn}{24}}
\newlabel{enty-spawn}{{4.4.16}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.17}entiy.CallSpawn}{24}}
\newlabel{enty-callspawn}{{4.4.17}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.18}entity.DelayedCallSpawn}{24}}
\newlabel{enty-delayedcallspawn}{{4.4.18}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.19}entity.RemoveSpawns}{24}}
\newlabel{enty-removespawns}{{4.4.19}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.20}ent.Lock}{24}}
\newlabel{enty-lock}{{4.4.20}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.21}ent.Unlock}{24}}
\newlabel{enty-unlock}{{4.4.21}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.22}ent.IsLocked}{24}}
\newlabel{enty-locked}{{4.4.22}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.23}ent.GetParm}{24}}
\newlabel{enty-getparm}{{4.4.23}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.24}ent.SetParm}{25}}
\newlabel{enty-setparm}{{4.4.24}{25}}
\@writefile{toc}{\contentsline {section}{\numberline {4.5}mover}{26}}
\newlabel{mver}{{4.5}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.1}mover.Halt}{26}}
\newlabel{mver-halt}{{4.5.1}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.2}mover.HaltAngles}{26}}
\newlabel{mver-haltangles}{{4.5.2}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.3}mover.AsTrain}{26}}
\newlabel{mver-astrain}{{4.5.3}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.4}mover.SetAngles}{26}}
\newlabel{mver-setangles}{{4.5.4}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.5}mover.SetPosition}{26}}
\newlabel{mver-setposition}{{4.5.5}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.6}mover.ToAngles}{26}}
\newlabel{mver-toangles}{{4.5.6}{26}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.7}mover.ToPosition}{27}}
\newlabel{mver-toposition}{{4.5.7}{27}}
\@writefile{toc}{\contentsline {section}{\numberline {4.6}sound}{28}}
\newlabel{sound}{{4.6}{28}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6.1}Sound Kan\IeC {\"a}le}{28}}
\newlabel{sound-chan}{{4.6.1}{28}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6.2}sound.PlaySound}{28}}
\newlabel{snd-playsnd}{{4.6.2}{28}}
\@writefile{toc}{\contentsline {chapter}{\numberline {5}Beispiele}{29}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{examples}{{5}{29}}
\@writefile{toc}{\contentsline {section}{\numberline {5.1}Beispiel 1 - Hallo Welt}{29}}
\newlabel{example1}{{5.1}{29}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.1}Hallo Welt f\IeC {\"u}r game}{29}}
\newlabel{example11}{{5.1.1}{29}}
\newlabel{helloworldgame}{{5.1}{29}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.1}Hallo Welt f\IeC {\"u}r game}{29}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.2}Hallo Welt f\IeC {\"u}r einen Spieler}{29}}
\newlabel{example12}{{5.1.2}{29}}
\newlabel{helloworldclient}{{5.2}{29}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.2}Hallo Welt f\IeC {\"u}r Spieler}{29}}
\newlabel{helloworldclient1}{{5.3}{30}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.3}First function}{30}}
\newlabel{helloworldclient2}{{5.4}{30}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.4}Second function}{30}}
\newlabel{helloworldclient3}{{5.5}{30}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.5}Third function}{30}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.3}Hallo Welt f\IeC {\"u}r alle Spieler}{30}}
\newlabel{example13}{{5.1.3}{30}}
\newlabel{helloworldclientall}{{5.6}{30}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.6}Hallo Welt f\IeC {\"u}r alle Spieler}{30}}
\@writefile{toc}{\contentsline {section}{\numberline {5.2}Beispiel 2 - Entities Finden}{30}}
\newlabel{example2}{{5.2}{30}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.1}Entities \IeC {\"u}ber ihren targetname finden}{31}}
\newlabel{example21}{{5.2.1}{31}}
\newlabel{findents1}{{5.7}{31}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.7}Entity \IeC {\"u}ber ihren targername finden}{31}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.2}Entities \IeC {\"u}ber ihre Entitynummer finden}{31}}
\newlabel{example22}{{5.2.2}{31}}
\newlabel{findents2}{{5.8}{31}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.8}Entities \IeC {\"u}ber ihre Entitynummer finden}{31}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.3}Entities \IeC {\"u}ber ihr Brush Modell finden}{31}}
\newlabel{example23}{{5.2.3}{31}}
\newlabel{findents3}{{5.9}{31}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.9}Entities \IeC {\"u}ber ihr Brush Modell finden}{31}}
\@writefile{toc}{\contentsline {section}{\numberline {5.3}Beispiel 3 - Entities Spawnen}{31}}
\newlabel{spawnents}{{5.10}{32}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.10}Eine Entity Spawnen}{32}}
\@writefile{toc}{\contentsline {chapter}{\numberline {6}Wie man ...}{35}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{howto}{{6}{35}}
\@writefile{toc}{\contentsline {section}{\numberline {6.1}Turbolifte zu \IeC {\"a}lteren RPG-X Maps hinzuf\IeC {\"u}gt}{35}}
\newlabel{howto-x2turbo}{{6.1}{35}}
\@writefile{toc}{\contentsline {section}{\numberline {6.2}Transporter die das ui\_transporter benutzen zu \IeC {\"a}lteren Maps hinzuf\IeC {\"u}gt}{35}}
\newlabel{howto-uitrans}{{6.2}{35}}
\@writefile{toc}{\contentsline {section}{\numberline {6.3}func\_usable zu func\_forcefield konvertiert}{35}}
\newlabel{howto-usabletoforcefield}{{6.3}{35}}
\newlabel{fustoff}{{6.1}{36}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.1}Beispiel 1}{36}}
\newlabel{fustoff2}{{6.2}{36}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.2}Beispiel 2}{36}}

View file

@ -0,0 +1,536 @@
This is pdfTeX, Version 3.1415926-1.40.11 (MiKTeX 2.9) (preloaded format=pdflatex 2010.12.30) 30 DEC 2010 13:11
entering extended mode
**C:/stvoy/Code-DM/RPG-X2*Lua*Documentation/RPG-X2*Lua*Documentation*Deu.tex
("C:/stvoy/Code-DM/RPG-X2 Lua Documentation/RPG-X2 Lua Documentation Deu.tex"
LaTeX2e <2009/09/24>
Babel <v3.8l> and hyphenation patterns for english, afrikaans, ancientgreek, ar
abic, armenian, assamese, basque, bengali, bokmal, bulgarian, catalan, coptic,
croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, ga
lician, german, german-x-2009-06-19, greek, gujarati, hindi, hungarian, iceland
ic, indonesian, interlingua, irish, italian, kannada, kurmanji, lao, latin, lat
vian, lithuanian, malayalam, marathi, mongolian, mongolianlmc, monogreek, ngerm
an, ngerman-x-2009-06-19, nynorsk, oriya, panjabi, pinyin, polish, portuguese,
romanian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, swis
sgerman, tamil, telugu, turkish, turkmen, ukenglish, ukrainian, uppersorbian, u
senglishmax, welsh, loaded.
("C:\Program Files\MiKTeX 2.9\tex\latex\base\book.cls"
Document Class: book 2007/10/19 v1.4h Standard LaTeX document class
("C:\Program Files\MiKTeX 2.9\tex\latex\base\bk11.clo"
File: bk11.clo 2007/10/19 v1.4h Standard LaTeX file (size option)
)
\c@part=\count79
\c@chapter=\count80
\c@section=\count81
\c@subsection=\count82
\c@subsubsection=\count83
\c@paragraph=\count84
\c@subparagraph=\count85
\c@figure=\count86
\c@table=\count87
\abovecaptionskip=\skip41
\belowcaptionskip=\skip42
\bibindent=\dimen102
)
("C:\Program Files\MiKTeX 2.9\tex\latex\base\inputenc.sty"
Package: inputenc 2008/03/30 v1.1d Input encoding file
\inpenc@prehook=\toks14
\inpenc@posthook=\toks15
("C:\Program Files\MiKTeX 2.9\tex\latex\base\utf8.def"
File: utf8.def 2008/04/05 v1.1m UTF-8 support for inputenc
Now handling font encoding OML ...
... no UTF-8 mapping file for font encoding OML
Now handling font encoding T1 ...
... processing UTF-8 mapping file for font encoding T1
("C:\Program Files\MiKTeX 2.9\tex\latex\base\t1enc.dfu"
File: t1enc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A1 (decimal 161)
defining Unicode char U+00A3 (decimal 163)
defining Unicode char U+00AB (decimal 171)
defining Unicode char U+00BB (decimal 187)
defining Unicode char U+00BF (decimal 191)
defining Unicode char U+00C0 (decimal 192)
defining Unicode char U+00C1 (decimal 193)
defining Unicode char U+00C2 (decimal 194)
defining Unicode char U+00C3 (decimal 195)
defining Unicode char U+00C4 (decimal 196)
defining Unicode char U+00C5 (decimal 197)
defining Unicode char U+00C6 (decimal 198)
defining Unicode char U+00C7 (decimal 199)
defining Unicode char U+00C8 (decimal 200)
defining Unicode char U+00C9 (decimal 201)
defining Unicode char U+00CA (decimal 202)
defining Unicode char U+00CB (decimal 203)
defining Unicode char U+00CC (decimal 204)
defining Unicode char U+00CD (decimal 205)
defining Unicode char U+00CE (decimal 206)
defining Unicode char U+00CF (decimal 207)
defining Unicode char U+00D0 (decimal 208)
defining Unicode char U+00D1 (decimal 209)
defining Unicode char U+00D2 (decimal 210)
defining Unicode char U+00D3 (decimal 211)
defining Unicode char U+00D4 (decimal 212)
defining Unicode char U+00D5 (decimal 213)
defining Unicode char U+00D6 (decimal 214)
defining Unicode char U+00D8 (decimal 216)
defining Unicode char U+00D9 (decimal 217)
defining Unicode char U+00DA (decimal 218)
defining Unicode char U+00DB (decimal 219)
defining Unicode char U+00DC (decimal 220)
defining Unicode char U+00DD (decimal 221)
defining Unicode char U+00DE (decimal 222)
defining Unicode char U+00DF (decimal 223)
defining Unicode char U+00E0 (decimal 224)
defining Unicode char U+00E1 (decimal 225)
defining Unicode char U+00E2 (decimal 226)
defining Unicode char U+00E3 (decimal 227)
defining Unicode char U+00E4 (decimal 228)
defining Unicode char U+00E5 (decimal 229)
defining Unicode char U+00E6 (decimal 230)
defining Unicode char U+00E7 (decimal 231)
defining Unicode char U+00E8 (decimal 232)
defining Unicode char U+00E9 (decimal 233)
defining Unicode char U+00EA (decimal 234)
defining Unicode char U+00EB (decimal 235)
defining Unicode char U+00EC (decimal 236)
defining Unicode char U+00ED (decimal 237)
defining Unicode char U+00EE (decimal 238)
defining Unicode char U+00EF (decimal 239)
defining Unicode char U+00F0 (decimal 240)
defining Unicode char U+00F1 (decimal 241)
defining Unicode char U+00F2 (decimal 242)
defining Unicode char U+00F3 (decimal 243)
defining Unicode char U+00F4 (decimal 244)
defining Unicode char U+00F5 (decimal 245)
defining Unicode char U+00F6 (decimal 246)
defining Unicode char U+00F8 (decimal 248)
defining Unicode char U+00F9 (decimal 249)
defining Unicode char U+00FA (decimal 250)
defining Unicode char U+00FB (decimal 251)
defining Unicode char U+00FC (decimal 252)
defining Unicode char U+00FD (decimal 253)
defining Unicode char U+00FE (decimal 254)
defining Unicode char U+00FF (decimal 255)
defining Unicode char U+0102 (decimal 258)
defining Unicode char U+0103 (decimal 259)
defining Unicode char U+0104 (decimal 260)
defining Unicode char U+0105 (decimal 261)
defining Unicode char U+0106 (decimal 262)
defining Unicode char U+0107 (decimal 263)
defining Unicode char U+010C (decimal 268)
defining Unicode char U+010D (decimal 269)
defining Unicode char U+010E (decimal 270)
defining Unicode char U+010F (decimal 271)
defining Unicode char U+0110 (decimal 272)
defining Unicode char U+0111 (decimal 273)
defining Unicode char U+0118 (decimal 280)
defining Unicode char U+0119 (decimal 281)
defining Unicode char U+011A (decimal 282)
defining Unicode char U+011B (decimal 283)
defining Unicode char U+011E (decimal 286)
defining Unicode char U+011F (decimal 287)
defining Unicode char U+0130 (decimal 304)
defining Unicode char U+0131 (decimal 305)
defining Unicode char U+0132 (decimal 306)
defining Unicode char U+0133 (decimal 307)
defining Unicode char U+0139 (decimal 313)
defining Unicode char U+013A (decimal 314)
defining Unicode char U+013D (decimal 317)
defining Unicode char U+013E (decimal 318)
defining Unicode char U+0141 (decimal 321)
defining Unicode char U+0142 (decimal 322)
defining Unicode char U+0143 (decimal 323)
defining Unicode char U+0144 (decimal 324)
defining Unicode char U+0147 (decimal 327)
defining Unicode char U+0148 (decimal 328)
defining Unicode char U+014A (decimal 330)
defining Unicode char U+014B (decimal 331)
defining Unicode char U+0150 (decimal 336)
defining Unicode char U+0151 (decimal 337)
defining Unicode char U+0152 (decimal 338)
defining Unicode char U+0153 (decimal 339)
defining Unicode char U+0154 (decimal 340)
defining Unicode char U+0155 (decimal 341)
defining Unicode char U+0158 (decimal 344)
defining Unicode char U+0159 (decimal 345)
defining Unicode char U+015A (decimal 346)
defining Unicode char U+015B (decimal 347)
defining Unicode char U+015E (decimal 350)
defining Unicode char U+015F (decimal 351)
defining Unicode char U+0160 (decimal 352)
defining Unicode char U+0161 (decimal 353)
defining Unicode char U+0162 (decimal 354)
defining Unicode char U+0163 (decimal 355)
defining Unicode char U+0164 (decimal 356)
defining Unicode char U+0165 (decimal 357)
defining Unicode char U+016E (decimal 366)
defining Unicode char U+016F (decimal 367)
defining Unicode char U+0170 (decimal 368)
defining Unicode char U+0171 (decimal 369)
defining Unicode char U+0178 (decimal 376)
defining Unicode char U+0179 (decimal 377)
defining Unicode char U+017A (decimal 378)
defining Unicode char U+017B (decimal 379)
defining Unicode char U+017C (decimal 380)
defining Unicode char U+017D (decimal 381)
defining Unicode char U+017E (decimal 382)
defining Unicode char U+200C (decimal 8204)
defining Unicode char U+2013 (decimal 8211)
defining Unicode char U+2014 (decimal 8212)
defining Unicode char U+2018 (decimal 8216)
defining Unicode char U+2019 (decimal 8217)
defining Unicode char U+201A (decimal 8218)
defining Unicode char U+201C (decimal 8220)
defining Unicode char U+201D (decimal 8221)
defining Unicode char U+201E (decimal 8222)
defining Unicode char U+2030 (decimal 8240)
defining Unicode char U+2031 (decimal 8241)
defining Unicode char U+2039 (decimal 8249)
defining Unicode char U+203A (decimal 8250)
defining Unicode char U+2423 (decimal 9251)
)
Now handling font encoding OT1 ...
... processing UTF-8 mapping file for font encoding OT1
("C:\Program Files\MiKTeX 2.9\tex\latex\base\ot1enc.dfu"
File: ot1enc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A1 (decimal 161)
defining Unicode char U+00A3 (decimal 163)
defining Unicode char U+00B8 (decimal 184)
defining Unicode char U+00BF (decimal 191)
defining Unicode char U+00C5 (decimal 197)
defining Unicode char U+00C6 (decimal 198)
defining Unicode char U+00D8 (decimal 216)
defining Unicode char U+00DF (decimal 223)
defining Unicode char U+00E6 (decimal 230)
defining Unicode char U+00EC (decimal 236)
defining Unicode char U+00ED (decimal 237)
defining Unicode char U+00EE (decimal 238)
defining Unicode char U+00EF (decimal 239)
defining Unicode char U+00F8 (decimal 248)
defining Unicode char U+0131 (decimal 305)
defining Unicode char U+0141 (decimal 321)
defining Unicode char U+0142 (decimal 322)
defining Unicode char U+0152 (decimal 338)
defining Unicode char U+0153 (decimal 339)
defining Unicode char U+2013 (decimal 8211)
defining Unicode char U+2014 (decimal 8212)
defining Unicode char U+2018 (decimal 8216)
defining Unicode char U+2019 (decimal 8217)
defining Unicode char U+201C (decimal 8220)
defining Unicode char U+201D (decimal 8221)
)
Now handling font encoding OMS ...
... processing UTF-8 mapping file for font encoding OMS
("C:\Program Files\MiKTeX 2.9\tex\latex\base\omsenc.dfu"
File: omsenc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A7 (decimal 167)
defining Unicode char U+00B6 (decimal 182)
defining Unicode char U+00B7 (decimal 183)
defining Unicode char U+2020 (decimal 8224)
defining Unicode char U+2021 (decimal 8225)
defining Unicode char U+2022 (decimal 8226)
)
Now handling font encoding OMX ...
... no UTF-8 mapping file for font encoding OMX
Now handling font encoding U ...
... no UTF-8 mapping file for font encoding U
defining Unicode char U+00A9 (decimal 169)
defining Unicode char U+00AA (decimal 170)
defining Unicode char U+00AE (decimal 174)
defining Unicode char U+00BA (decimal 186)
defining Unicode char U+02C6 (decimal 710)
defining Unicode char U+02DC (decimal 732)
defining Unicode char U+200C (decimal 8204)
defining Unicode char U+2026 (decimal 8230)
defining Unicode char U+2122 (decimal 8482)
defining Unicode char U+2423 (decimal 9251)
))
("C:\Program Files\MiKTeX 2.9\tex\generic\babel\babel.sty"
Package: babel 2008/07/06 v3.8l The Babel package
*************************************
* Local config file bblopts.cfg used
*
("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\bblopts.cfg"
File: bblopts.cfg 2006/07/31 v1.0 MiKTeX 'babel' configuration
)
("C:\Program Files\MiKTeX 2.9\tex\generic\babel\ngermanb.ldf"
Language: ngermanb 2008/07/06 v2.6n new German support from the babel system
("C:\Program Files\MiKTeX 2.9\tex\generic\babel\babel.def"
File: babel.def 2008/07/06 v3.8l Babel common definitions
\babel@savecnt=\count88
\U@D=\dimen103
)
\l@naustrian = a dialect from \language\l@ngerman
Package babel Info: Making " an active character on input line 92.
))
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphicx.sty"
Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\keyval.sty"
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
\KV@toks@=\toks16
)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphics.sty"
Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\trig.sty"
Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
)
("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\graphics.cfg"
File: graphics.cfg 2007/01/18 v1.5 graphics configuration of teTeX/TeXLive
)
Package graphics Info: Driver file: pdftex.def on input line 91.
("C:\Program Files\MiKTeX 2.9\tex\latex\pdftex-def\pdftex.def"
File: pdftex.def 2010/09/14 v0.05b Graphics/color for pdfTeX
\Gread@gobject=\count89
))
\Gin@req@height=\dimen104
\Gin@req@width=\dimen105
)
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.sty"
\lst@mode=\count90
\lst@gtempboxa=\box26
\lst@token=\toks17
\lst@length=\count91
\lst@currlwidth=\dimen106
\lst@column=\count92
\lst@pos=\count93
\lst@lostspace=\dimen107
\lst@width=\dimen108
\lst@newlines=\count94
\lst@lineno=\count95
\lst@maxwidth=\dimen109
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\lstmisc.sty"
File: lstmisc.sty 2007/02/22 1.4 (Carsten Heinz)
\c@lstnumber=\count96
\lst@skipnumbers=\count97
\lst@framebox=\box27
)
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.cfg"
File: listings.cfg 2007/02/22 1.4 listings configuration
))
Package: listings 2007/02/22 1.4 (Carsten Heinz)
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation Deu.aux")
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 47.
LaTeX Font Info: ... okay on input line 47.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 47.
LaTeX Font Info: ... okay on input line 47.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 47.
LaTeX Font Info: ... okay on input line 47.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 47.
LaTeX Font Info: ... okay on input line 47.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 47.
LaTeX Font Info: ... okay on input line 47.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 47.
LaTeX Font Info: ... okay on input line 47.
("C:\Program Files\MiKTeX 2.9\tex\context\base\supp-pdf.mkii"
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count98
\scratchdimen=\dimen110
\scratchbox=\box28
\nofMPsegments=\count99
\nofMParguments=\count100
\everyMPshowfont=\toks18
\MPscratchCnt=\count101
\MPscratchDim=\dimen111
\MPnumerator=\count102
\everyMPtoPDFconversion=\toks19
)
\c@lstlisting=\count103
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <12> on input line 54.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <8> on input line 54.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <6> on input line 54.
[1
{C:/ProgramData/MiKTeX/2.9/pdftex/config/pdftex.map}] [2
]
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation Deu.toc"
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <10.95> on input line 3.
[3] [4] [5])
\tf@toc=\write3
[6]
Kapitel 1.
LaTeX Font Info: Try loading font information for OMS+cmr on input line 65.
("C:\Program Files\MiKTeX 2.9\tex\latex\base\omscmr.fd"
File: omscmr.fd 1999/05/25 v2.5h Standard LaTeX font definitions
)
LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <10.95> not available
(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 65.
Overfull \hbox (67.23381pt too wide) in paragraph at lines 67--68
[]\OT1/cmr/m/n/10.95 Funktionsaufrufe der Lua Ba-sis Bi-blio-the-ken (Bei-spiel
: \OT1/cmr/bx/n/10.95 to-string(clientNum)\OT1/cmr/m/n/10.95 ).
[]
Overfull \hbox (28.80782pt too wide) in paragraph at lines 70--71
\OT1/cmr/m/n/10.95 ers-te Ar-gu-ment ist \OT1/cmr/bx/n/10.95 var.function(var)
\OT1/cmr/m/n/10.95 k[]onnen auch als \OT1/cmr/bx/n/10.95 var:function()
[]
[7
] [8
]
Kapitel 2.
[9] [10] [11] [12]
Kapitel 3.
[13
] [14
]
Kapitel 4.
[15] [16] [17] [18] [19] [20] [21]
Overfull \hbox (48.76537pt too wide) in paragraph at lines 473--476
\OT1/cmr/bx/n/10.95 ent.SetKeyValue(\OT1/cmr/m/it/10.95 entity \OT1/cmr/bx/n/10
.95 ent, \OT1/cmr/m/it/10.95 string \OT1/cmr/bx/n/10.95 key, \OT1/cmr/m/it/10.9
5 string \OT1/cmr/bx/n/10.95 va-lue) \OT1/cmr/m/n/10.95 or \OT1/cmr/bx/n/10.95
ent:SetKeyValue(\OT1/cmr/m/it/10.95 string
[]
[22] [23] [24] [25]
Overfull \hbox (0.82597pt too wide) in paragraph at lines 602--605
\OT1/cmr/bx/n/10.95 mover.SetAngles(\OT1/cmr/m/it/10.95 entity \OT1/cmr/bx/n/10
.95 ent, \OT1/cmr/m/it/10.95 vec-tor \OT1/cmr/bx/n/10.95 angles) \OT1/cmr/m/n/1
0.95 or \OT1/cmr/bx/n/10.95 mo-ver.SetAngles(\OT1/cmr/m/it/10.95 entity
[]
Overfull \hbox (1.09969pt too wide) in paragraph at lines 607--610
\OT1/cmr/bx/n/10.95 mover.SetPosition(\OT1/cmr/m/it/10.95 entity \OT1/cmr/bx/n/
10.95 ent, \OT1/cmr/m/it/10.95 vec-tor \OT1/cmr/bx/n/10.95 pos) \OT1/cmr/m/n/10
.95 or \OT1/cmr/bx/n/10.95 mo-ver.SetPosition(\OT1/cmr/m/it/10.95 entity
[]
Overfull \hbox (54.56422pt too wide) in paragraph at lines 612--615
\OT1/cmr/bx/n/10.95 mover.ToAngles\OT1/cmr/m/n/10.95 (\OT1/cmr/m/it/10.95 entit
y \OT1/cmr/bx/n/10.95 ent, \OT1/cmr/m/it/10.95 float \OT1/cmr/bx/n/10.95 speed,
\OT1/cmr/m/it/10.95 vec-tor \OT1/cmr/bx/n/10.95 angles) \OT1/cmr/m/n/10.95 or
\OT1/cmr/bx/n/10.95 mo-ver.ToAngles(\OT1/cmr/m/it/10.95 entity
[]
[26] [27]
Underfull \hbox (badness 10000) in paragraph at lines 628--632
[]
[28]
Kapitel 5.
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldGame.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient.lua"
Overfull \hbox (1.35376pt too wide) in paragraph at lines 3--4
[][][][][][][][][][][][][][][]
[]
Overfull \hbox (1.35376pt too wide) in paragraph at lines 5--6
[][][][][][][][][][][][][][][]
[]
Overfull \hbox (1.35376pt too wide) in paragraph at lines 7--8
[][][][][][][][][][][][][][][]
[]
) [29
]
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient1.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient2.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient3.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClientAll.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts1.lua" [30])
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts2.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts3.lua")
Overfull \hbox (9.8063pt too wide) in paragraph at lines 707--708
\OT1/cmr/m/n/10.95 Dar[]uber hin-aus kann man ei-ni-ge En-ti-ties spaw-nen die
Brush Mo-dells ben[]otigen
[]
[31] ("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/SpawningEnts.lua")
[32]
Underfull \hbox (badness 10000) in paragraph at lines 710--712
[]
Underfull \hbox (badness 10000) in paragraph at lines 715--717
[]
Underfull \hbox (badness 10000) in paragraph at lines 720--722
[]
Underfull \hbox (badness 10000) in paragraph at lines 725--727
[]
Underfull \hbox (badness 10000) in paragraph at lines 730--732
[]
[33] [34
]
Kapitel 6.
[35] ("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/fusToff.lua"
Overfull \hbox (7.92383pt too wide) in paragraph at lines 5--6
[][][][][][][][][][][][][][][][][]
[]
) ("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/fusToff2.lua"
Overfull \hbox (7.92383pt too wide) in paragraph at lines 5--6
[][][][][][][][][][][][][][][][][]
[]
) [36]
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation Deu.aux")
)
Here is how much of TeX's memory you used:
3541 strings out of 494019
46593 string characters out of 3146494
117528 words of memory out of 3000000
6792 multiletter control sequences out of 15000+200000
10722 words of font info for 37 fonts, out of 3000000 for 9000
714 hyphenation exceptions out of 8191
28i,8n,40p,502b,1642s stack positions out of 5000i,500n,10000p,200000b,50000s
<C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmbx10.pfb><C:/Pro
gram Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmbx12.pfb><C:/Program Fil
es/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmex10.pfb><C:/Program Files/MiKTe
X 2.9/fonts/type1/public/amsfonts/cm/cmmi10.pfb><C:/Program Files/MiKTeX 2.9/fo
nts/type1/public/amsfonts/cm/cmmi8.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1
/public/amsfonts/cm/cmr10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/a
msfonts/cm/cmr12.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/c
m/cmr17.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmr6.pf
b><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmsl10.pfb><C:/Pr
ogram Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmsy10.pfb><C:/Program Fi
les/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmti10.pfb>
Output written on "RPG-X2 Lua Documentation Deu.pdf" (36 pages, 221543 bytes).
PDF statistics:
165 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)

View file

@ -0,0 +1,768 @@
\documentclass[11pt,a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{listings}
% -*- latex -*-
% Definition of the Lua language for the listings package
% Time-stamp: <2008-11-30 15:27:16 rsmith>
% Written by Roland Smith <rsmith@xs4all.nl> and hereby placed in the public
% domain.
\lstdefinelanguage{lua}
{morekeywords={and,break,do,else,elseif,end,false,for,function,if,in,local,
nil,not,or,repeat,return,then,true,until,while},
morekeywords={[2]arg,assert,collectgarbage,dofile,error,_G,getfenv,
getmetatable,ipairs,load,loadfile,loadstring,next,pairs,pcall,print,
rawequal,rawget,rawset,select,setfenv,setmetatable,tonumber,tostring,
type,unpack,_VERSION,xpcall},
morekeywords={[2]coroutine.create,coroutine.resume,coroutine.running,
coroutine.status,coroutine.wrap,coroutine.yield},
morekeywords={[2]module,require,package.cpath,package.load,package.loaded,
package.loaders,package.loadlib,package.path,package.preload,
package.seeall},
morekeywords={[2]string.byte,string.char,string.dump,string.find,
string.format,string.gmatch,string.gsub,string.len,string.lower,
string.match,string.rep,string.reverse,string.sub,string.upper},
morekeywords={[2]table.concat,table.insert,table.maxn,table.remove,
table.sort},
morekeywords={[2]math.abs,math.acos,math.asin,math.atan,math.atan2,
math.ceil,math.cos,math.cosh,math.deg,math.exp,math.floor,math.fmod,
math.frexp,math.huge,math.ldexp,math.log,math.log10,math.max,math.min,
math.modf,math.pi,math.pow,math.rad,math.random,math.randomseed,math.sin,
math.sinh,math.sqrt,math.tan,math.tanh},
morekeywords={[2]io.close,io.flush,io.input,io.lines,io.open,io.output,
io.popen,io.read,io.tmpfile,io.type,io.write,file:close,file:flush,
file:lines,file:read,file:seek,file:setvbuf,file:write},
morekeywords={[2]os.clock,os.date,os.difftime,os.execute,os.exit,os.getenv,
os.remove,os.rename,os.setlocale,os.time,os.tmpname},
sensitive=true,
morecomment=[l]{--},
morecomment=[s]{--[[}{]]--},
morestring=[b]",
morestring=[d]'
}
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt}
\lstset{language=lua}
\begin{document}
\title{
\Huge RPG-X2 Lua Dokumentation
\author{
Ubergames
Walter Julius 'GSIO01' Hennecke}
}
\maketitle
\newpage
\tableofcontents
\chapter{Einführung}
\label{intro}
\section{Grundlegende Informationen}
\label{gen-info}
Die RPG-X2 Lua Dokumentation dokumentiert und beschreibt alle Lua Funktionen die in RPG-X2 verfügbar sind. Die version die Sie gerade lesen ist für die \textbf{RPG-X2 Version 2.2 beta 4.4.5}. Die RPG-X2 Lua Dokumentation wird mit dem Erscheinen jeder neuen RPG-X Version aktualisiert.
\section{Vorvereinbarungen}
\label{preq}
\begin{itemize}
\item In Lua werden Variablen nicht mit ihrem Typ deklariert. Um Sie dennoch über den Typ einer Variablen informieren zu können werden die Typangaben Kursiv vor die Variablen geschrieben (Beispiel: \textit{integer} \textbf{clientNum}).
\item Es gibt in RPG-X2 Lua drei verschiedene Funktionsaufrufe.\begin{itemize}
\item Funktionsaufrufe der Lua Basis Bibliotheken (Beispiel: \textbf{\textbf{tostring(clientNum)}}).
\item Funktionsaufrufe der RPG-X2 Bibliotheken, welche den Bibliotheksnamen vorangestellt haben (Beispiel: \textbf{entity.Spawn()}).
\item Funktionsaufrufe über Variablen. Dies geht zum Beispiel mit Entities und Vectoren (Beispiel: \textbf{ent.Remove(ent)}).
\item Funktionsaufrufe über Variablen bei denen die Variable selber das erste Argument ist \textbf{var.function(var)} können auch als \textbf{var:function()} geschrieben werden (Beispiel: \textbf{ent.Remove(ent)} is the same as \textbf{ent:Remove()}).
\end{itemize}
\end{itemize}
\chapter{Lua Hooks}
\label{lua-hooks}
\section{Was ist ein Lua Hook}
\label{wia-lh}
Ein Lua Hook ist eine Funktion die aufgerufen wird wenn ein spezifisches Ereignis in der Spiellogik eintritt. So wird zum Beispiel beim initialisieren der Spiellogik die Funktion G\_InitGame aufgerufen. Diese Funktion besitzt einen Lua Hook, was bedeutet das beim Aufruf von G\_InitGame auch eine Lua Funktion aufgerufen wird. In RPG-X2 Lua gibt es Lua Hooks mit festen und Lua Hooks mit dynamischen Namen.
\section{Statische Lua Hooks}
\label{s-lh}
Statische Lua Hooks haben einen festen Namen.
\subsection{InitGame}
\label{init-game}
\textbf{InitGame(}\textit{integer} \textbf{leveltime,} \textit{integer} \textbf{randomssed, }\textit{integer} \textbf{restart)}
\newline
Wird nach dem Spielstart oder nach dem benutzen des map\_restart Kommandos aufgerufen.
\newline
\textbf{leveltime} die aktuelle Levelzeit in Millisekunden
\newline
\textbf{restart} ist 1 bei einem map\_restart und ansonsten 0
\subsection{ShutdownGame}
\label{shutdown-game}
\textbf{ShutdownGame(}\textit{integer} \textbf{restart)}
\newline
Wird beim Beenden des Spiels aufgerufen, dies kann sein bei disconnect, schließen des Spiels, Map wechsel, map\_restart.
\newline
\textbf{restart} ist 1 bei einem map\_restart und ansonsten 0
\subsection{RunFrame}
\label{run-frame}
\textbf{RunFrame(}\textit{integer} \textbf{leveltime)}
\newline
Wird jeden Frame aufgerufen. Diese Funktion sollte wenn dann nur mit äußerster Vorsicht verwendet werden, da Zeit zwischen Frames nur 50 ms beträgt.
\newline
\textbf{leveltime} aktuelle Levelzeit in Millisekunden
\subsection{GClientPrint}
\label{cli-print}
\textbf{GClientPrint(}\textit{string} \textbf{text, }\textit{entity }\textbf{client)}
\newline
Wird beim Aufruf der Spiellogikfunktion G\_PrintfClient aufgerufen.
\newline
\textbf{text} der ausgegeben wird
\newline
\textbf{client} Client bei dem der Text ausgegeben wird.
\subsection{GPrint}
\label{g-print}
\textbf{GPrint(}\textit{string}\textbf{ text)}
\newline
Wird beim Aufruf der Spiellogikfunktion G\_Print aufgerufen.
\newline
\textbf{text} der in die Spielkonsole ausgegeben wird. (Achtung die Spielkonsole ist die des Servers nicht die des Client!)
\newpage
\section{Dynamische Lua Hooks}
\label{dyn-lh}
Diese Lua Hook können verschiedene Namen haben. Sie sind alle Lua Hooks für Entities. Die Funktionenamen für diese Lua Hooks werden im Radiant mit Hilfe von Schlüssel-Wert-Paaren definiert.
Da die Funktionsnamen dieser Lua Hooks von diesen Paaren abhängen werden in dieser Dokumentation die Schlüssel als Funktionsnamen verwendet, die den Namen der entsprechenden Funktion enthalten.
\subsection{luaThink}
\label{luaThink}
\textbf{luaThink(}\textit{entity}\textbf{ ent)}
\newline
Wird jedes mal aufgerufen wenn die Entity denkt.
\newline
\textbf{ent} die Entity selbst
\subsection{luaTouch}
\label{luaTouch}
Wird jedes mal aufgerufen wenn die Entity berührt wird.
\newline
\textbf{ent} die Entity selbst
\newline
\textbf{other} die Entity welche die Entity \textbf{ent} berührt hat.
\subsection{luaUse}
\label{luaUse}
\textbf{luaUse(}\textit{entity}\textbf{ ent),}\textit{entity} \textbf{other,} \textit{entity} \textbf{activator)}
\newline
Wird jedes mal aufgerufen wenn die Entity benutzt wird.
\newline
\textbf{ent} die entity selbst
\newline
\textbf{activator} die Entity welche die Entity \textbf{ent} benutzt hat.
\subsection{luaHurt}
\label{luaHurt}
\textbf{luaHurt(}\textit{entity}\textbf{ ent, }\textit{entity}\textbf{ inflictor,}\textit{entity}\textbf{attacker)}
\newline
Wird jedes mal aufgerufen wenn der Entity Schaden zugefügt wird.
\newline
\textbf{ent} die Entity selbst
\newline
\textbf{inflictor} der Infliktor
\newline
\textbf{attacker} der Angreifer
\subsection{luaDie}
\label{luaDie}
\textbf{luaDie(}\textit{entity} \textbf{ent,} \textit{entity} \textbf{inflictor,} \textit{entity} \textbf{attacker,} \textit{integer} \textbf{dmg,} \textit{integer}\textbf{ mod)}
\newline
Wird jedes mal aufgerufen wenn die Entiy stirbt.
\newline
\textbf{ent} die Entity selbst
\newline
\textbf{inflictor} der Infliktor
\newline
\textbf{attacker} der Angreifer
\newline
\textbf{dmg} menge des Schadens
\newline
\textbf{mod} Gründe des Todes
\subsection{luaFree}
\label{luaFree}
\textbf{luaFree(}\textit{entity} \textbf{ent)}
\newline
Wird aufgerufen wenn die Entity freigegeben wird was gleichbedeutend mit deren Löschung ist.
\newline
\textbf{ent} die Entity selbst
\subsection{luaReached}
\label{luaReached}
\textbf{luaReached(}\textit{entity }\textbf{ent)}
\newline
Wird aufgerufen wenn die Bewegung einer Entity ihren Endpunkt erreicht.
\newline
\textbf{ent} die Entity selbst
\subsection{luaReachedAngular}
\label{luaReachedAngular}
\textbf{luaReachedAngular(}\textit{entity }\textbf{ent)}
\newline
Wird aufgerufen wenn die Drehbewegung einer Entity ihren Endpunkt erreicht.
\newline
\textbf{ent} die Entity selbst
\subsection{luaTrigger}
\label{luaTrigger}
\textbf{luaTrigger(}\textit{entity}\textbf{ ent, }\textit{entity}\textbf{ other)}
\newline
Wird aufgerufen wenn eine Entity getriggered wird. Man beachte das dies nicht das gleiche ist wie die Benutzung einer Entity. Dieser Lua Hook ist für trigger\_* Entities gedacht.
\newline
\textbf{ent} die Entity selbst
\newline
\textbf{other} die Entity die das Triggerereignis ausgelöst hat
\subsection{luaSpawn}
\label{luaSpawn}
\textbf{lauSpawn(}\textit{entity}\textbf{ ent)}
\newline
Wird aufgerufen wenn die Spawnfunktion einer Entity aufgerufen wird.
\newline
\textbf{ent} die Entity selbst
\newpage
\chapter{RPG-X2 Map Scripting}
\label{rpgx2-mapscripting}
\section{Map scripts}
\label{map-scripts}
Im moment kann genau ein Scriptdatei je Map geladen werden. Diese Scriptdatei muss im Ordner \textit{scripts/lua/<mapname>} sein und den Namen \textit{<mapname>.lua} haben.
\section{Aufruf von Funktionen}
\label{map-callingfunction}
Es gibt dynamische Lua Hooks für die Verwendung im Radiant (siehe Dynamische Lua Hooks). Sie könne diese Lua Hooks für Entites verwenden, in dem Sie das entsprechende Schlüssel-Wert-Paar zu der Entity hinzufügen.
\newline
Soll zum Beispiel eine Funktion \textit{PrintText} aufgerufen werden wenn eine \textit{func\_usable} benutzt wird so müssen die zu der Entity die Schlüssel \textit{luaUse} und den Wrt \textit{PrintText} hinzufügen.
\newpage
\chapter{RPG-X2 Lua Bibliotheken}
\label{rpgx2-llibs}
\section{game}
\label{g}
Diese Bibliothek ermöglicht Zugriff auf einige Spiellogikfunktionen wie zum Beispiel G\_Printf und G\_ClientPrintf.
\subsection{game.Print}
\label{g-prnt}
\textbf{game.Print(}\textit{string}\textbf{ text)}
\newline
Gibt \textbf{text} in der Spielkonsole(Serverkonsole) aus.
\subsection{game.ClientPrint}
\label{g-clientprint}
\textbf{game.ClientPrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Gibt \textbf{text} in der Konsole tes Client mit der Clientnummer \textbf{clientNum} aus. Falls \textbf{clientNum} gleich -1 ist wird der Text in den Konsolen aller Spieler ausgegeben.
\subsection{game.CenterPrint}
\label{g-centerprint}
\textbf{game.CenterPrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Gibt \textbf{text} auf der Mitte des Bildschirmes des Spielers mit der Clientnummer \textbf{clientNum} aus. Falls \textbf{clientNum} gleich -1 ist erfolgt die Ausgabe bei allen Spielern.
\subsection{game.MessagePrint}
\label{g-messagepritn}
\textbf{game.MessagePrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Gibt \textbf{text} in der rechten unteren Ecke des Bildschirmes des Spielers mit der Clientennummer \textbf{clientNum} aus. Falls \textbf{clientNum} gleicht -1 ist erfolgt die Ausgabe bei allen Spielern.
\subsection{game.LevelTime}
\label{g-leveltime}
\textbf{game.LevelTime()}
Gibt die aktuelle Levelzeit in Millisekunden zurück.
\subsection{game.SetGlobal}
\label{g-setglobal}
\textbf{game.SetGlobal(}\textit{string}\textbf{ name, value)}
\newline
Setzt eine globale Lua Variable mit den Namen \textbf{name} und dem Wert \textbf{value}, welche dann über alle Funktionen hinweg verfügbar ist.
\subsection{game.GetGlobal}
\label{g-getglobal}
\textbf{game.GetGlobal(}\textit{string}\textbf{ name)}
\newline
Gibt den Wert eine globalen Variable mit dem Namen \textbf{name} zurück falls diese existiert.
\newpage
\section{qmath}
\label{qmath}
Diese Bibliothek ermöglicht den Zugriff auf mehrere mathematische Funktionen die in der Spiellogik verfügbar sind.
\subsection{qmath.abs}
\label{qm-abs}
\textbf{qmath.abs(}\textit{float}\textbf{ f)}
\newline
Gibt den ganzzahligen Wert von \textbf{f} zurück.
\subsection{qmath.sin}
\label{qm-sin}
\textbf{qmath.sin(}\textit{float}\textbf{ degree)}
\newline
Gibt den sinus von \textbf{degree} zurück.
\subsection{qmath.cos}
\label{qm-cos}
\textbf{qmath.cos(}\textit{float}\textbf{ degree)}
\newline
Gibt den cosinus von \textbf{degree} zurück.
\subsection{qmath.tan}
\label{qm-tan}
\textbf{qmath.tan(}\textit{float}\textbf{ degree)}
\newline
Gibt den tangenz von \textbf{degree} zurück.
\subsection{qmath.asin}
\label{qm-asin}
\textbf{qmath.asin(}\textit{float}\textbf{ f)}
\newline
Gibt den arsinus von \textbf{f} zurück.
\subsection{qmath.acos}
\label{qm-acos}
\textbf{qmath.acos(}\textit{float}\textbf{ f)}
\newline
Gibt den arcosinus von \textbf{f} zurück.
\subsection{qmath.atan}
\label{qm-atan}
\textbf{qmath.atan(}\textit{float}\textbf{ f)}
\newline
Gibt den artangenz von \textbf{f} zurück.
\subsection{qmath.floor}
\label{qm-floor}
\textbf{qmath.floor(}\textit{float}\textbf{ f)}
\newline
Gibt den abgerundeten Wert von \textbf{f} zurück.
\subsection{qmath.ceil}
\label{qm-ceil}
\textbf{qath.ceil(}\textit{float}\textbf{ f)}
\newline
Gibt den aufgerundeten Wert von \textbf{f} zurück.
\subsection{qmath.fmod}
\label{qm-fmod}
\textbf{qmath.fmod(}\textit{float}\textbf{ f, }\textit{float}\textbf{ n)}
\newline
Gibt den Rest von \begin{math}f/n.\end{math} zurück.
\subsection{qmath.modf}
\label{qm-modf}
\textbf{qmath.modf(}\textit{float}\textbf{ f)}
\newline
Zerlegt \begin{math}f\end{math} in einen ganzzahligen und einen fraktionalen Teil. Der fraktionale Teil wird zurückgegeben und der ganzzahlige Teil in \begin{math}f\end{math} gespeichert.
\subsection{qmath.sqrt}
\label{qm-sqrt}
\textbf{qmath.sqrt(}\textit{float}\textbf{ f)}
\newline
Gibt die Wurzel aus \textbf{f} zurück.
\subsection{qmath.log}
\label{qm-log}
\textbf{qmath.log(}\textit{float}\textbf{ f)}
\newline
Gibt den Logarithmus von \textbf{f} zurück.
\subsection{qmath.log10}
\label{qm-log10}
\textbf{qmath.log10(}\textit{float}\textbf{ f)}
\newline
Gibt den Logarithmus von \textbf{f} zur Basis 10 zurück.
\subsection{qmath.deg}
\label{qm-deg}
\textbf{qmath.deg(}\textit{float}\textbf{ radian)}
\newline
Konvertiert Bogenmaß zu grad.
\subsection{qmath.rad}
\label{qm-rad}
\textbf{qmath.rad(}\textit{float}\textbf{ degree)}
\newline
Konvertiert Grad zu Bogenmaß.
\subsection{qmath.frexp}
\label{qm-frexp}
\textbf{qmath.frexp(}\textit{float}\textbf{ f)}
\newline
Zerlegt \textbf{f} in seine binäre Signifikante und einen integralen Exponenten von 2, so dass gilt:
\newline
\begin{math}x=Signifikante*2^Exponent\end{math}
\subsection{qmath.ldexp}
\label{qm-ldexp}
\textbf{qmath.ldexp(}\textit{float}\textbf{ f, }\textit{float}\textbf{ n)}
\newline
Gibt das Resultat der Multiplikation von \textbf{f} mit 2 potenziert mit \textbf{n} zurück.
\subsection{qmath.min}
\label{qm-min}
\textbf{qmath.min(}\textit{integer}\textbf{ array[])}
\newline
Gibt \textbf{array[]}.
\subsection{qmath.max}
\label{qm-max}
\textbf{qmath.max(}\textit{integer}\textbf{ array[])}
\newline
Gibt den höchsten Wert aus \textbf{array[]} zurück.
\subsection{qmath.random}
\label{qm-random}
\textbf{qmath.random()}
\newline
Gibt zufällige ganzzahlige Werte zurück.
\subsection{qmath.crandom}
\label{qm-crandom}
\textbf{qmath.crandom()}
\newline
Gibt zufällige Gleitkommazahlen zurück (Bei der Generierung wird die sogenannte crazy random function verwendet).
\newpage
\section{vector}
\label{vect}
Diese Bibliothek implementiert einen neuen Variablentyp vector sowie mathematische Funktonen zum Rechnen mit Vektoren.
\subsection{vector.New}
\label{vect-new}
\textbf{vector.New()}
\newline
Erzeugt einen neuen Vektor \begin{math}\left(\begin{array}{c} 0 \\ 0 \\ 0 \\ \end{array}\right)\end{math}.
\subsection{vector.Construct}
\label{vect-cons}
\textbf{vector.Construct(}\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Erzeugt einen neuen Vektor \begin{math}\left(\begin{array}{c} x \\ y \\ z \\ \end{array}\right)\end{math}.
\subsection{vector.Set}
\label{vect-set}
\textbf{vector.Set(}\textit{vector}\textbf{ v, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Setzt einen Vektor \textbf{v} auf die angegeben Werte.
\subsection{vector.clear}
\label{vect-clear}
\textbf{vector.Clear(}\textit{vector}\textbf{ v)}
\newline
Säubert einen \textbf{vector} indem er auf \begin{math}\left(\begin{array}{c} 0 \\ 0 \\ 0 \\ \end{array}\right)\end{math} gesetzt wird.
\subsection{vector.Add}
\label{vect-add}
\textbf{vector.Add(}\textit{vector}\textbf{ a, }\textit{vector}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Bildet die Summer von \textbf{a} und \textbf{b} und speichert das Ergebnis in \textbf{c}.
\subsection{vector.Substract}
\label{vect-sub}
\textbf{vector.Subtract(}\textit{vector}\textbf{ a, }\textit{vector}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Subtrahiert \textbf{b} von \textbf{a} und speichert das Ergebis in \textbf{c}.
\subsection{vector.Scale}
\label{vect-scale}
\textbf{vector.Scale(}\textit{vector}\textbf{ a, }\textit{float}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Skaliert \textbf{a} um den Faktor \textbf{b} und speichert das Ergebnis in \textbf{c}.
\subsection{vector.Length}
\label{vect-length}
\textbf{vector.Length(}\textit{vector}\textbf{ a)}
\newline
Gibt die Länge von \textbf{a} zurück.
\subsection{vector.Normalize}
\label{vect-norm}
\textbf{vector.Normalize(}\textit{vector}\textbf{ a)}
\newline
Normalisiert \textbf{a}.
\subsection{vector.RotateAroundPoint}
\label{vect-rotarndpnt}
\textbf{vector.RotateAroundPoint(}\textit{vector}\textbf{ dest, }\textit{vector}\textbf{ dir, }\textit{vector}\textbf{ point, }\textit{float}\textbf{ degrees)}
\newline
Rotiert einen Punkt \textbf{point} um einen gegebene Vektor.
\newline
\textbf{dir} Normalisierter Vektor um den rotiert werden soll.
\newline
\textbf{point} Punkt der rotiert werden soll
\newline
\textbf{degrees} um wieviel Grad rotiert werden soll
\newline
\textbf{dst} der Punkt point nach der Drehung
\subsection{vector.Perpendicular}
\label{vect-Perpendicular}
\textbf{vector.Perpendicular(}\textit{vector}\textbf{ dest, }\textit{vector}\textbf{ src)}
\newline
Findet einen zum Quellvektor senkrechten Zielvektor.
\textbf{src} Quellvektor
\textbf{dest} Ein zum Quellvektor senkrechter Vektor (das Ergebnis)
\newpage
\section{entity}
\label{enty}
Diese Bibliothek enthält Funktionen für Entities. Alle Funktionen mit vorangestellten \textit{entity} sind Funktionsaufrufe über dei Bibliothek. Alle Funktionen mit vorangestellten \textit{ent} sind Funktionsaufrufe auf einer Entity.
\subsection{entity.Find}
\label{enty-find}
\textbf{entity.Find(}\textit{string}\textbf{ targetname)}
\newline
Gibt die erste gefundene Entity zurück deren targetname dem gesuchten targetname entspricht.
\subsection{entity.FindNumber}
\label{enty.findnumber}
\textbf{entity.FindNumber(}\textit{integer}\textbf{ entnum)}
\newline
Gibt die Entity mit der Entitynummer\textbf{entnum} zurück.
\subsection{entity.FindBModel}
\label{enty-findbmodel}
\textbf{entity.FindBModel(}\textit{integer}\textbf{ bmodelnum)}
\newline
Gibt die Entity mit dem brush model *\textbf{bmodelnumber} zurück. Dies ist der einzig sichere weg eine Brushentity ohne targetname zu finden, da sich de Entitynummern abhängig davon verändern ob eine Map lokal geladen wird, auf einen lokalen server läuft oder auf einem dedizierten Internetserver läuft ändern.
\subsection{ent.GetNumber}
\label{enty-getnumber}
\textbf{ent.GetNumber(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetNumber()}
\newline
Gibt die Entitynummer einer Entity zurück.
\subsection{ent.SetKeyValue}
\label{enty-setkeyvalue}
\textbf{ent.SetKeyValue(}\textit{entity}\textbf{ ent, }\textit{string}\textbf{ key, }\textit{string}\textbf{ value)} or \textbf{ent:SetKeyValue(}\textit{string}\textbf{ key, }\textit{string}\textbf{ value)}
\newline
Setzt ein Schlüssel-Wert-Paar für \textbf{ent} wie im Radiant. Dies Funktioniert aber nur wenn der Schlüssel \textit{key} ein Teil von \textit{fields\_t} ist, welche die vordefinierten Schlüssel enthält.
\subsection{entity.Remove}
\label{enty-remove}
\textbf{entity.Remove(}\textit{entity}\textbf{ ent)}
\newline
Entfernt die Entity \textbf{ent}.
\subsection{ent.GetOrigin}
\label{enty-getorigin}
\textbf{ent.GetOrigin(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetOrigin()}
\newline
Gibt die Origin von \textbf{ent} als vector zurück.
\subsection{ent.IsClient}
\label{enty-isclient}
\textbf{ent.IsClient(}\textit{entity}\textbf{ ent)} or \textbf{ent:IsClient()}
\newline
Gibt einen boolean zurück. Ist wahr wenn \textbf{ent} ein Spieler ist.
\subsection{ent.GetClientname}
\label{enty-getclientname}
\textbf{ent.GetClientname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetClientname()}
\newline
Gibt den clientname von \textbf{ent} zurück.
\subsection{ent.GetClassname}
\label{enty-getclassname}
\textbf{ent.GetClassname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetClassname()}
\newline
Gibt den Klassennamen von \textbf{ent} zurück.
\subsection{ent.SetClassname}
\label{enty-setclassname}
\textbf{ent.SetClassname(}\textit{entity}\textbf{ ent, }\textit{string}\textbf{ classname)} or
\newline
\textbf{ent:SetClassname(}\textit{string}\textbf{ classname)}
\newline
Setzt den Klassennamen von \textbf{ent} auf \textbf{classname}.
\subsection{ent.GetTargetname}
\label{enty-gettargetname}
\textbf{ent.GetTargetname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetTargetname()}
\newline
Gibt den targetname von\textbf{ent} zurück.
\subsection{ent.SetupTrigger}
\label{enty-setuptrigger}
\textbf{ent.SetupTrigger(}\textit{enttiy}\textbf{ ent)} or \textbf{ent:SetupTrigger()}
\newline
Grundlegende Initialisierung für im Scripting gespawnte trigger\_* Entities.
\subsection{entity.GetTarget}
\label{enty-gettarget}
\textbf{entity.GetTarget(}\textit{entity}\textbf{ ent)}
Gibt das target von \textbf{ent} zurück.
\subsection{entity.Use}
\label{enty-use}
\textbf{entity.Use(}\textit{entity}\textbf{ ent)}
\newline
Benutzt \textbf{ent}.
\subsection{entity.Spawn}
\label{enty-spawn}
\textbf{entity.spawn()}
\newline
Versucht eine neue Entity zu spawnen und gibt diese bei Erfolg zurück, sonst wird \textit{nil} zurückgegeben.
\subsection{entiy.CallSpawn}
\label{enty-callspawn}
\textbf{entity.CallSpawn(}\textit{entity}\textbf{ ent)}
\newline
Ruft die Spawnfunktion der Spiellogik für \textbf{ent} auf.
\subsection{entity.DelayedCallSpawn}
\label{enty-delayedcallspawn}
\textbf{entity.DelayedCallSpawn(}\textit{entity}\textbf{ ent, }\textit{integer}\textbf{ delay)}
\newline
Tut das gleiche wie CallSpawn wartet aber eine mit \textbf{delay} festgelegte Zeit bis die Funktion aufgerufen wird.
\textbf{delay} Zeit in Millisekunden die gewartet werden soll.
\subsection{entity.RemoveSpawns}
\label{enty-removespawns}
\textbf{entity.RemoveSpawns()}
\newline
Löscht alle Spawnpunkte der Map.
\subsection{ent.Lock}
\label{enty-lock}
\textbf{ent.Lock(}\textit{entity}\textbf{ ent)}
\newline
Sperrt/Verschließt die Entity. Funktioniert mit allen Entities die gesperrt/verschlossen werden können (Türen, Turbolifte, Usables, ...).
\subsection{ent.Unlock}
\label{enty-unlock}
\textbf{ent.Unlock(}\textit{entity}\textbf{ ent)}
\newline
Entsperrt/Öffnet die Entity. Funktioniert mit allen Entities die gespettz/verschlossen werden können (Türen, Turbolifte, Usables, ...).
\subsection{ent.IsLocked}
\label{enty-locked}
\textbf{ent.IsLocked(}\textit{entity}\textbf{ ent)}
\newline
Gibt \textbf{wahr} zurück falls eine entity Gesperrt/Verschlossen ist ansonsten wird \textbf{falsch} zurückgegeben.
\subsection{ent.GetParm}
\label{enty-getparm}
\textbf{ent.GetParm(}\textit{entity}\textbf{ ent, }\textit{integer}\textbf{ parm)}
\newline
Gibt den Wert für einen der luaParms der Entity \textbf{ent} als string zurück. Sollte der Wert nicht gesetzt sein wird \textbf{nil} zurückgegeben.
\newline
\textbf{parm} der gewünschte Wert (1 bis 4)
\subsection{ent.SetParm}
\label{enty-setparm}
\textbf{ent.SetParm(}\textit{entity }\textbf{ent, }\textit{integer }\textbf{parm, }\textit{string }\textbf{value)}
\newline
Setz einen gewünschten luaParm auf den Wert \textbf{value}.
\newline
\textbf{parm} gwünschter parm der gesetzt werden soll
\newline
\textbf{value} Wert auf den der parm gesetzt werden soll
\newpage
\section{mover}
\label{mver}
Wichtige Bemerkung: Sie sollten immer mover.Halt bzw. mover.HaltAngles aufrufen bevor Sie einen mover wieder durch Aufruf einer entsprechenden Funktion bewegen. Ansonsten wird die Bewegung der Entity nicht korrekt funktionieren.
\subsection{mover.Halt}
\label{mver-halt}
\textbf{mover.Halt(}\textit{entity}\textbf{ ent)}
\newline
Stoppt sofort jegliche Bewegung (ausgenommen Drehungen).
\subsection{mover.HaltAngles}
\label{mver-haltangles}
\textbf{mover.HaltAngles(}\textit{entity}\textbf{ ent)}
\newline
Stoppt sofort jegliche Drehung.
\subsection{mover.AsTrain}
\label{mver-astrain}
\textbf{mover.AsTrain(}\textit{entity}\textbf{ mover, }\textit{entity}\textbf{ target, }\textit{float}\textbf{ speed)}
\newline
Bewegt die Entity wie ein\textit{func\_train}. Ziel muss ein \textit{path\_corner} sein.
\newline
\textbf{target} die erste \textit{path\_corner}
\subsection{mover.SetAngles}
\label{mver-setangles}
\textbf{mover.SetAngles(}\textit{entity}\textbf{ ent, }\textit{vector}\textbf{ angles)} or \textbf{mover.SetAngles(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Setzt die angles von \textbf{ent} zu dem angegebenen Wert(en).
\subsection{mover.SetPosition}
\label{mver-setposition}
\textbf{mover.SetPosition(}\textit{entity}\textbf{ ent, }\textit{vector}\textbf{ pos)} or \textbf{mover.SetPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Set die Origin von \textbf{ent} zu den angegebenen Wert(en) und bewegt sie sofort dort hin.
\subsection{mover.ToAngles}
\label{mver-toangles}
\textbf{mover.ToAngles}(\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{vector}\textbf{ angles)} or \textbf{mover.ToAngles(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Rotiert \textbf{ent} zu den angegebenen angles.
\subsection{mover.ToPosition}
\label{mver-toposition}
\textbf{mover.ToPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{vector}\textbf{ angles)} or
\newline
\textbf{mover.ToPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Bewegt \textbf{ent} zu angegebenen Position.
\newpage
\section{sound}
\label{sound}
Diese Bibliothek fügt die Möglichkeit hinzu Sounds abzuspielen sowie zu Verwalten.
\subsection{Sound Kanäle}
\label{sound-chan}
Einige Funktionen dieser Bibliothek haben einen Audiokanal als Parameter. Im Normalfall wird es reichen den Kanal CHAN\_AUTO zu benutzen der die Engine die Auswahl treffen lässt. Dennoch besteht die Möglichkeit den Kanal selbst zu wählen.
\newline
Hier ist eine Tabelle mit den verschiedenen Kanälen und ihrer Werte für den Funktionsparameter:
\newline
\begin{center}
\begin{tabular}[c]{| c | c |}
\hline
CHAN\_AUTO & 0 \\
\hline
CHAN\_LOCAL & 1 \\
\hline
CHAN\_WEAPON & 2 \\
\hline
CHAN\_VOICE & 3 \\
\hline
CHAN\_ITEM & 4 \\
\hline
CHAN\_BODY & 5 \\
\hline
CHAN\_LOCAL\_SOUND & 6 \\
\hline
CHAN\_ANNOUNCER & 7 \\
\hline
CHAN\_MENU1 & 8 \\
\hline
\end{tabular}
\end{center}
\subsection{sound.PlaySound}
\label{snd-playsnd}
\textbf{sound.PlaySound(}\textit{entity}\textbf{ ent, }\textit{integer}\textbf{ chan, }\textit{string}\textbf{ sound)}
\newline
Versucht eine Audiodatei \textbf{sound} auf dem Kanal \textbf{chan} auf der Entity \textbf{ent} abzuspielen.
\newpage
\chapter{Beispiele}
\label{examples}
Dieses Kapitel der Dokumentation enthält Beispiele welche dazu hilfreich sein könnten einige Funktionen besser zu verstehen.
\section{Beispiel 1 - Hallo Welt}
\label{example1}
Das ist ein Beispiel das einfach bei jeder Programmiersprache Pflicht ist.
\subsection{Hallo Welt für game}
\label{example11}
\lstinputlisting[frame=single, label=helloworldgame, caption=Hallo Welt für game]{examples/HelloWorldGame.lua}
Wie Sie vielleicht erkennen ist die eine Funktion für luaUse (Man kann das am Funktionskopf sehen).
\subsection{Hallo Welt für einen Spieler}
\label{example12}
\lstinputlisting[frame=single, label=helloworldclient, caption=Hallo Welt für Spieler]{examples/HelloWorldClient.lua}
Wie Sie vielleicht erkennen ist die eine Funktion für luaUse (Man kann das am Funktionskopf sehen).
\lstinputlisting[frame=single, label=helloworldclient1, caption=First function]{examples/HelloWorldClient1.lua}
Diese Funktion gibt eine Nachricht in die Spielerkonsole aus.
\newline
\lstinline|activator:GetNumber()| holt die Entitynummer zurück welches in diesem Fall auch die Clientnummer ist.
\newline
\lstinline|activator:GetClientname()| holt den Namen des Spielers
\lstinputlisting[frame=single, label=helloworldclient2, caption=Second function]{examples/HelloWorldClient2.lua}
Diese Funktion gibt eine Nachricht auf der Mitte des Bildschirm eines Spielers aus.
\lstinputlisting[frame=single, label=helloworldclient3, caption=Third function]{examples/HelloWorldClient3.lua}
Diese Funktion gibt eine Nachricht in der unteren rechten Ecke des Bildschirmes eines Spielers aus.
\subsection{Hallo Welt für alle Spieler}
\label{example13}
\lstinputlisting[frame=single, label=helloworldclientall, caption=Hallo Welt für alle Spieler]{examples/HelloWorldClientAll.lua}
Dieses Beispielt ähnelt dem vorherigen sehr stark, der einzige Unterschied liegt darin das anstatt einer Clientnummer die -1 das erste argument ist. Dies führt dazu das die Nachricht für alle Spieler ausgegeben wird.
\section{Beispiel 2 - Entities Finden}
\label{example2}
Diese Beispiele werden die verschiedenen Wege zeigen eine Entity zu finden.
\subsection{Entities über ihren targetname finden}
\label{example21}
\lstinputlisting[frame=single, label=findents1, caption=Entity über ihren targername finden]{examples/FindingEnts1.lua}
Zu beachten ist das \lstinline|entity.Find()| immer nur die erste Entity zurück gibt die gefunden wird. Das bedeutet das wenn es mehrere Entities mit dem selben targetname gibt es passieren kann das Sie die Entity die Sie suchen auf diese weiße nicht finden können.
\newline
Neben dem Suchen nach einer Entity zeigt dieses Beispiel auch wie man lokale Variablen benutzt.
\subsection{Entities über ihre Entitynummer finden}
\label{example22}
\lstinputlisting[frame=single, label=findents2, caption=Entities über ihre Entitynummer finden]{examples/FindingEnts2.lua}
Dies ist ein fast absolut sicherer Weg eine Entity zu finden, man muss aber folgendes beachten: Die Entitynummer für eine Entity ist unterschiedlich je nachdem ob man eine map lokal oder auf einem Server lädt.
\subsection{Entities über ihr Brush Modell finden}
\label{example23}
\lstinputlisting[frame=single, label=findents3, caption=Entities über ihr Brush Modell finden]{examples/FindingEnts3.lua}
Absolut eindeutiger Weg eine Entity zu finden, funktioniert allerdings nur für Brushentities.
\section{Beispiel 3 - Entities Spawnen}
Dieses Beispielt zeigt wie man Entities über das Scripting spawnen kann. Es is möglich fast alle Entities zu spawnen die kein Brush Modell haben. Darüber hinaus kann man einige Entities spawnen die Brush Modells benötigen sofern diese nicht sichtbar sind (zum Beispiel trigger\_* Entities).
\lstinputlisting[frame=single, label=spawnents, caption=Eine Entity Spawnen]{examples/SpawningEnts.lua}
\newpage
Also was wird getan und warum?
\newline
\begin{lstlisting}
local ent = entity.Spawn()
\end{lstlisting}
Versucht eine neue Entity zu spawnen und sie \lstinline|ent| zuzuweisen.
\newline
\begin{lstlisting}
if ent == nil then return
\end{lstlisting}
Dies überprüft ob das Spawnen der Entity erfolgreich war. Sollte dies nicht der Fall sein wird die weitere Abarbeitung der Funktion verhindert.
\newline
\begin{lstlisting}
ent:SetKeyValue("classname", "info_notnull");
\end{lstlisting}
Setzt den Klassennamen der Entity und macht sie damit zu einer Entity eines bestimmten Typs.
\newline
\begin{lstlisting}
mover:SetPosition(0, 0, 0);
\end{lstlisting}
Setzt die Origin der Entity.
\newline
\begin{lstlisting}
entity.CallSpawn(ent);
\end{lstlisting}
Sorgt für den Aufruf der Spawnfunktion der Entity in der Spiellogik.
\chapter{Wie man ...}
\label{howto}
\section{Turbolifte zu älteren RPG-X Maps hinzufügt}
\label{howto-x2turbo}
Kommt demnächst ...
\section{Transporter die das ui\_transporter benutzen zu älteren Maps hinzufügt}
\label{howto-uitrans}
Kommt demnächst ...
\section{func\_usable zu func\_forcefield konvertiert}
\label{howto-usabletoforcefield}
Hier wird gezeigt wie man eine func\_usable in ein func\_forcefield konvertiert. Bevor wir beginnen müssen wir aber erstmal einige Dinge herausfinden:
\begin{itemize}
\item Wie man eine func\_usable garantiert und fehlerfrei findet.
\item Wie die momentanen Spawnfalgs der Entity sind.
\end{itemize}
An diese informationen kommt man wie folgt:
\begin{itemize}
\item RPG-X2 starten und die Map laden.
\item Als Admin einloggen oder in die Adminklasse wechseln.
\item Zur func\_usable gehen und sicherstellen das die sichtbar ist.
\item Sie mit den Fadenkreuz anvisieren.
\item Konsole öffnen und folgendes Kommando eingeben: \textbf{getEntInfo}.
\end{itemize}
Man bekommt eine Liste mit nützlichen Informationen. Sollte die Entity einen targetname muss man überprüfen ob sie die einzige mit diesem Namen ist. Das tut man indem man \textbf{getEntByTargetname} gefolgt vom targetname eingibt. Falls nur eine Entity aufgelistet wird heißt dies das es nur diese eine Entity mit diesem targetname gibt. Damit sind wir fertig mit diesem Schritt.
\newline
Sollte es aber mehrere Entities mit diesem targetname geben verwendet man das Brush Modell der Entity um sie zu finden. Der Name des Brush Modells wurde bereits beim ausführen von \textbf{getEntInfo} angezeigt.
\newline
Der nächste Schritt ist es die Spawnflags dahingehen zu überprüfen ob sie dem entsprechen was man für das func\_forcefield braucht. Was zu tun ist für den Fall das die Spawnflags nicht passen werden wir unten sehen.
\newline
Nun fangen wir mit dem Scripting an. Der beste platz um eine Entitykonversion durchzuführen ist \textbf{InitGame}, da diese Funktion bereits bei jedem Mapanfang ausgeführt wird.
\lstinputlisting[frame=single, label=fustoff, caption=Beispiel 1]{examples/fusToff.lua}
\lstinputlisting[frame=single, label=fustoff2, caption=Beispiel 2]{examples/fusToff2.lua}
\end{document}

View file

@ -0,0 +1,120 @@
\select@language {ngerman}
\contentsline {chapter}{\numberline {1}Einf\IeC {\"u}hrung}{7}
\contentsline {section}{\numberline {1.1}Grundlegende Informationen}{7}
\contentsline {section}{\numberline {1.2}Vorvereinbarungen}{7}
\contentsline {chapter}{\numberline {2}Lua Hooks}{9}
\contentsline {section}{\numberline {2.1}Was ist ein Lua Hook}{9}
\contentsline {section}{\numberline {2.2}Statische Lua Hooks}{9}
\contentsline {subsection}{\numberline {2.2.1}InitGame}{9}
\contentsline {subsection}{\numberline {2.2.2}ShutdownGame}{9}
\contentsline {subsection}{\numberline {2.2.3}RunFrame}{10}
\contentsline {subsection}{\numberline {2.2.4}GClientPrint}{10}
\contentsline {subsection}{\numberline {2.2.5}GPrint}{10}
\contentsline {section}{\numberline {2.3}Dynamische Lua Hooks}{11}
\contentsline {subsection}{\numberline {2.3.1}luaThink}{11}
\contentsline {subsection}{\numberline {2.3.2}luaTouch}{11}
\contentsline {subsection}{\numberline {2.3.3}luaUse}{11}
\contentsline {subsection}{\numberline {2.3.4}luaHurt}{11}
\contentsline {subsection}{\numberline {2.3.5}luaDie}{11}
\contentsline {subsection}{\numberline {2.3.6}luaFree}{12}
\contentsline {subsection}{\numberline {2.3.7}luaReached}{12}
\contentsline {subsection}{\numberline {2.3.8}luaReachedAngular}{12}
\contentsline {subsection}{\numberline {2.3.9}luaTrigger}{12}
\contentsline {subsection}{\numberline {2.3.10}luaSpawn}{12}
\contentsline {chapter}{\numberline {3}RPG-X2 Map Scripting}{13}
\contentsline {section}{\numberline {3.1}Map scripts}{13}
\contentsline {section}{\numberline {3.2}Aufruf von Funktionen}{13}
\contentsline {chapter}{\numberline {4}RPG-X2 Lua Bibliotheken}{15}
\contentsline {section}{\numberline {4.1}game}{15}
\contentsline {subsection}{\numberline {4.1.1}game.Print}{15}
\contentsline {subsection}{\numberline {4.1.2}game.ClientPrint}{15}
\contentsline {subsection}{\numberline {4.1.3}game.CenterPrint}{15}
\contentsline {subsection}{\numberline {4.1.4}game.MessagePrint}{15}
\contentsline {subsection}{\numberline {4.1.5}game.LevelTime}{16}
\contentsline {subsection}{\numberline {4.1.6}game.SetGlobal}{16}
\contentsline {subsection}{\numberline {4.1.7}game.GetGlobal}{16}
\contentsline {section}{\numberline {4.2}qmath}{17}
\contentsline {subsection}{\numberline {4.2.1}qmath.abs}{17}
\contentsline {subsection}{\numberline {4.2.2}qmath.sin}{17}
\contentsline {subsection}{\numberline {4.2.3}qmath.cos}{17}
\contentsline {subsection}{\numberline {4.2.4}qmath.tan}{17}
\contentsline {subsection}{\numberline {4.2.5}qmath.asin}{17}
\contentsline {subsection}{\numberline {4.2.6}qmath.acos}{17}
\contentsline {subsection}{\numberline {4.2.7}qmath.atan}{17}
\contentsline {subsection}{\numberline {4.2.8}qmath.floor}{17}
\contentsline {subsection}{\numberline {4.2.9}qmath.ceil}{18}
\contentsline {subsection}{\numberline {4.2.10}qmath.fmod}{18}
\contentsline {subsection}{\numberline {4.2.11}qmath.modf}{18}
\contentsline {subsection}{\numberline {4.2.12}qmath.sqrt}{18}
\contentsline {subsection}{\numberline {4.2.13}qmath.log}{18}
\contentsline {subsection}{\numberline {4.2.14}qmath.log10}{18}
\contentsline {subsection}{\numberline {4.2.15}qmath.deg}{18}
\contentsline {subsection}{\numberline {4.2.16}qmath.rad}{18}
\contentsline {subsection}{\numberline {4.2.17}qmath.frexp}{18}
\contentsline {subsection}{\numberline {4.2.18}qmath.ldexp}{19}
\contentsline {subsection}{\numberline {4.2.19}qmath.min}{19}
\contentsline {subsection}{\numberline {4.2.20}qmath.max}{19}
\contentsline {subsection}{\numberline {4.2.21}qmath.random}{19}
\contentsline {subsection}{\numberline {4.2.22}qmath.crandom}{19}
\contentsline {section}{\numberline {4.3}vector}{20}
\contentsline {subsection}{\numberline {4.3.1}vector.New}{20}
\contentsline {subsection}{\numberline {4.3.2}vector.Construct}{20}
\contentsline {subsection}{\numberline {4.3.3}vector.Set}{20}
\contentsline {subsection}{\numberline {4.3.4}vector.clear}{20}
\contentsline {subsection}{\numberline {4.3.5}vector.Add}{20}
\contentsline {subsection}{\numberline {4.3.6}vector.Substract}{20}
\contentsline {subsection}{\numberline {4.3.7}vector.Scale}{20}
\contentsline {subsection}{\numberline {4.3.8}vector.Length}{21}
\contentsline {subsection}{\numberline {4.3.9}vector.Normalize}{21}
\contentsline {subsection}{\numberline {4.3.10}vector.RotateAroundPoint}{21}
\contentsline {subsection}{\numberline {4.3.11}vector.Perpendicular}{21}
\contentsline {section}{\numberline {4.4}entity}{22}
\contentsline {subsection}{\numberline {4.4.1}entity.Find}{22}
\contentsline {subsection}{\numberline {4.4.2}entity.FindNumber}{22}
\contentsline {subsection}{\numberline {4.4.3}entity.FindBModel}{22}
\contentsline {subsection}{\numberline {4.4.4}ent.GetNumber}{22}
\contentsline {subsection}{\numberline {4.4.5}ent.SetKeyValue}{22}
\contentsline {subsection}{\numberline {4.4.6}entity.Remove}{22}
\contentsline {subsection}{\numberline {4.4.7}ent.GetOrigin}{23}
\contentsline {subsection}{\numberline {4.4.8}ent.IsClient}{23}
\contentsline {subsection}{\numberline {4.4.9}ent.GetClientname}{23}
\contentsline {subsection}{\numberline {4.4.10}ent.GetClassname}{23}
\contentsline {subsection}{\numberline {4.4.11}ent.SetClassname}{23}
\contentsline {subsection}{\numberline {4.4.12}ent.GetTargetname}{23}
\contentsline {subsection}{\numberline {4.4.13}ent.SetupTrigger}{23}
\contentsline {subsection}{\numberline {4.4.14}entity.GetTarget}{23}
\contentsline {subsection}{\numberline {4.4.15}entity.Use}{23}
\contentsline {subsection}{\numberline {4.4.16}entity.Spawn}{24}
\contentsline {subsection}{\numberline {4.4.17}entiy.CallSpawn}{24}
\contentsline {subsection}{\numberline {4.4.18}entity.DelayedCallSpawn}{24}
\contentsline {subsection}{\numberline {4.4.19}entity.RemoveSpawns}{24}
\contentsline {subsection}{\numberline {4.4.20}ent.Lock}{24}
\contentsline {subsection}{\numberline {4.4.21}ent.Unlock}{24}
\contentsline {subsection}{\numberline {4.4.22}ent.IsLocked}{24}
\contentsline {subsection}{\numberline {4.4.23}ent.GetParm}{24}
\contentsline {subsection}{\numberline {4.4.24}ent.SetParm}{25}
\contentsline {section}{\numberline {4.5}mover}{26}
\contentsline {subsection}{\numberline {4.5.1}mover.Halt}{26}
\contentsline {subsection}{\numberline {4.5.2}mover.HaltAngles}{26}
\contentsline {subsection}{\numberline {4.5.3}mover.AsTrain}{26}
\contentsline {subsection}{\numberline {4.5.4}mover.SetAngles}{26}
\contentsline {subsection}{\numberline {4.5.5}mover.SetPosition}{26}
\contentsline {subsection}{\numberline {4.5.6}mover.ToAngles}{26}
\contentsline {subsection}{\numberline {4.5.7}mover.ToPosition}{27}
\contentsline {section}{\numberline {4.6}sound}{28}
\contentsline {subsection}{\numberline {4.6.1}Sound Kan\IeC {\"a}le}{28}
\contentsline {subsection}{\numberline {4.6.2}sound.PlaySound}{28}
\contentsline {chapter}{\numberline {5}Beispiele}{29}
\contentsline {section}{\numberline {5.1}Beispiel 1 - Hallo Welt}{29}
\contentsline {subsection}{\numberline {5.1.1}Hallo Welt f\IeC {\"u}r game}{29}
\contentsline {subsection}{\numberline {5.1.2}Hallo Welt f\IeC {\"u}r einen Spieler}{29}
\contentsline {subsection}{\numberline {5.1.3}Hallo Welt f\IeC {\"u}r alle Spieler}{30}
\contentsline {section}{\numberline {5.2}Beispiel 2 - Entities Finden}{30}
\contentsline {subsection}{\numberline {5.2.1}Entities \IeC {\"u}ber ihren targetname finden}{31}
\contentsline {subsection}{\numberline {5.2.2}Entities \IeC {\"u}ber ihre Entitynummer finden}{31}
\contentsline {subsection}{\numberline {5.2.3}Entities \IeC {\"u}ber ihr Brush Modell finden}{31}
\contentsline {section}{\numberline {5.3}Beispiel 3 - Entities Spawnen}{31}
\contentsline {chapter}{\numberline {6}Wie man ...}{35}
\contentsline {section}{\numberline {6.1}Turbolifte zu \IeC {\"a}lteren RPG-X Maps hinzuf\IeC {\"u}gt}{35}
\contentsline {section}{\numberline {6.2}Transporter die das ui\_transporter benutzen zu \IeC {\"a}lteren Maps hinzuf\IeC {\"u}gt}{35}
\contentsline {section}{\numberline {6.3}func\_usable zu func\_forcefield konvertiert}{35}

View file

@ -0,0 +1,280 @@
\relax
\@writefile{toc}{\contentsline {chapter}{\numberline {1}Introduction}{5}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{intro}{{1}{5}}
\@writefile{toc}{\contentsline {section}{\numberline {1.1}General Information}{5}}
\newlabel{gen-info}{{1.1}{5}}
\@writefile{toc}{\contentsline {section}{\numberline {1.2}Prerequisites}{5}}
\newlabel{preq}{{1.2}{5}}
\@writefile{toc}{\contentsline {chapter}{\numberline {2}Lua Hooks}{6}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{lua-hooks}{{2}{6}}
\@writefile{toc}{\contentsline {section}{\numberline {2.1}What is a Lua Hook}{6}}
\newlabel{wia-lh}{{2.1}{6}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Static Lua Hooks}{6}}
\newlabel{s-lh}{{2.2}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}InitGame}{6}}
\newlabel{init-game}{{2.2.1}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}ShutdownGame}{6}}
\newlabel{shutdown-game}{{2.2.2}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.3}RunFrame}{6}}
\newlabel{run-frame}{{2.2.3}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.4}GClientPrint}{6}}
\newlabel{cli-print}{{2.2.4}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.5}GPrint}{7}}
\newlabel{g-print}{{2.2.5}{7}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Dynamic Lua Hooks}{8}}
\newlabel{dyn-lh}{{2.3}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.1}luaThink}{8}}
\newlabel{luaThink}{{2.3.1}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.2}luaTouch}{8}}
\newlabel{luaTouch}{{2.3.2}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.3}luaUse}{8}}
\newlabel{luaUse}{{2.3.3}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.4}luaHurt}{8}}
\newlabel{luaHurt}{{2.3.4}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.5}luaDie}{8}}
\newlabel{luaDie}{{2.3.5}{8}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.6}luaFree}{9}}
\newlabel{luaFree}{{2.3.6}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.7}luaReached}{9}}
\newlabel{luaReached}{{2.3.7}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.8}luaReachedAngular}{9}}
\newlabel{luaReachedAngular}{{2.3.8}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.9}luaTrigger}{9}}
\newlabel{luaTrigger}{{2.3.9}{9}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.10}luaSpawn}{9}}
\newlabel{luaSpawn}{{2.3.10}{9}}
\@writefile{toc}{\contentsline {chapter}{\numberline {3}RPG-X2 Map Scripting}{10}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{rpgx2-mapscripting}{{3}{10}}
\@writefile{toc}{\contentsline {section}{\numberline {3.1}Map scripts}{10}}
\newlabel{map-scripts}{{3.1}{10}}
\@writefile{toc}{\contentsline {section}{\numberline {3.2}Calling Functions}{10}}
\newlabel{map-callingfunction}{{3.2}{10}}
\@writefile{toc}{\contentsline {chapter}{\numberline {4}RPG-X2 Lua Libraries}{11}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{rpgx2-llibs}{{4}{11}}
\@writefile{toc}{\contentsline {section}{\numberline {4.1}game}{11}}
\newlabel{g}{{4.1}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.1}game.Print}{11}}
\newlabel{g-prnt}{{4.1.1}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.2}game.ClientPrint}{11}}
\newlabel{g-clientprint}{{4.1.2}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.3}game.CenterPrint}{11}}
\newlabel{g-centerprint}{{4.1.3}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.4}game.MessagePrint}{11}}
\newlabel{g-messagepritn}{{4.1.4}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.5}game.LevelTime}{11}}
\newlabel{g-leveltime}{{4.1.5}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.6}game.SetGlobal}{11}}
\newlabel{g-setglobal}{{4.1.6}{11}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1.7}game.GetGlobal}{12}}
\newlabel{g-getglobal}{{4.1.7}{12}}
\@writefile{toc}{\contentsline {section}{\numberline {4.2}qmath}{13}}
\newlabel{qmath}{{4.2}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.1}qmath.abs}{13}}
\newlabel{qm-abs}{{4.2.1}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.2}qmath.sin}{13}}
\newlabel{qm-sin}{{4.2.2}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.3}qmath.cos}{13}}
\newlabel{qm-cos}{{4.2.3}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.4}qmath.tan}{13}}
\newlabel{qm-tan}{{4.2.4}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.5}qmath.asin}{13}}
\newlabel{qm-asin}{{4.2.5}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.6}qmath.acos}{13}}
\newlabel{qm-acos}{{4.2.6}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.7}qmath.atan}{13}}
\newlabel{qm-atan}{{4.2.7}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.8}qmath.floor}{13}}
\newlabel{qm-floor}{{4.2.8}{13}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.9}qmath.ceil}{14}}
\newlabel{qm-ceil}{{4.2.9}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.10}qmath.fmod}{14}}
\newlabel{qm-fmod}{{4.2.10}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.11}qmath.modf}{14}}
\newlabel{qm-modf}{{4.2.11}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.12}qmath.sqrt}{14}}
\newlabel{qm-sqrt}{{4.2.12}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.13}qmath.log}{14}}
\newlabel{qm-log}{{4.2.13}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.14}qmath.log10}{14}}
\newlabel{qm-log10}{{4.2.14}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.15}qmath.deg}{14}}
\newlabel{qm-deg}{{4.2.15}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.16}qmath.rad}{14}}
\newlabel{qm-rad}{{4.2.16}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.17}qmath.frexp}{14}}
\newlabel{qm-frexp}{{4.2.17}{14}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.18}qmath.ldexp}{15}}
\newlabel{qm-ldexp}{{4.2.18}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.19}qmath.min}{15}}
\newlabel{qm-min}{{4.2.19}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.20}qmath.max}{15}}
\newlabel{qm-max}{{4.2.20}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.21}qmath.random}{15}}
\newlabel{qm-random}{{4.2.21}{15}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2.22}qmath.crandom}{15}}
\newlabel{qm-crandom}{{4.2.22}{15}}
\@writefile{toc}{\contentsline {section}{\numberline {4.3}vector}{16}}
\newlabel{vect}{{4.3}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.1}vector.New}{16}}
\newlabel{vect-new}{{4.3.1}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.2}vector.Construct}{16}}
\newlabel{vect-cons}{{4.3.2}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.3}vector.Set}{16}}
\newlabel{vect-set}{{4.3.3}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.4}vector.clear}{16}}
\newlabel{vect-clear}{{4.3.4}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.5}vector.Add}{16}}
\newlabel{vect-add}{{4.3.5}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.6}vector.Substract}{16}}
\newlabel{vect-sub}{{4.3.6}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.7}vector.Scale}{16}}
\newlabel{vect-scale}{{4.3.7}{16}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.8}vector.Length}{17}}
\newlabel{vect-length}{{4.3.8}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.9}vector.Normalize}{17}}
\newlabel{vect-norm}{{4.3.9}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.10}vector.RotateAroundPoint}{17}}
\newlabel{vect-rotarndpnt}{{4.3.10}{17}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.11}vector.Perpendicular}{17}}
\newlabel{vect-Perpendicular}{{4.3.11}{17}}
\@writefile{toc}{\contentsline {section}{\numberline {4.4}entity}{18}}
\newlabel{enty}{{4.4}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.1}entity.Find}{18}}
\newlabel{enty-find}{{4.4.1}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.2}entity.FindNumber}{18}}
\newlabel{enty.findnumber}{{4.4.2}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.3}entity.FindBModel}{18}}
\newlabel{enty-findbmodel}{{4.4.3}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.4}ent.GetNumber}{18}}
\newlabel{enty-getnumber}{{4.4.4}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.5}ent.SetKeyValue}{18}}
\newlabel{enty-setkeyvalue}{{4.4.5}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.6}entity.Remove}{18}}
\newlabel{enty-remove}{{4.4.6}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.7}ent.GetOrigin}{18}}
\newlabel{enty-getorigin}{{4.4.7}{18}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.8}ent.IsClient}{19}}
\newlabel{enty-isclient}{{4.4.8}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.9}ent.GetClientname}{19}}
\newlabel{enty-getclientname}{{4.4.9}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.10}ent.GetClassname}{19}}
\newlabel{enty-getclassname}{{4.4.10}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.11}ent.SetClassname}{19}}
\newlabel{enty-setclassname}{{4.4.11}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.12}ent.GetTargetname}{19}}
\newlabel{enty-gettargetname}{{4.4.12}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.13}ent.SetupTrigger}{19}}
\newlabel{enty-setuptrigger}{{4.4.13}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.14}entity.GetTarget}{19}}
\newlabel{enty-gettarget}{{4.4.14}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.15}entity.Use}{19}}
\newlabel{enty-use}{{4.4.15}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.16}entity.Spawn}{19}}
\newlabel{enty-spawn}{{4.4.16}{19}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.17}entiy.CallSpawn}{20}}
\newlabel{enty-callspawn}{{4.4.17}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.18}entity.DelayedCallSpawn}{20}}
\newlabel{enty-delayedcallspawn}{{4.4.18}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.19}entity.RemoveSpawns}{20}}
\newlabel{enty-removespawns}{{4.4.19}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.20}ent.Lock}{20}}
\newlabel{enty-lock}{{4.4.20}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.21}ent.Unlock}{20}}
\newlabel{enty-unlock}{{4.4.21}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.22}ent.IsLocked}{20}}
\newlabel{enty-locked}{{4.4.22}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.23}ent.GetParm}{20}}
\newlabel{enty-getparm}{{4.4.23}{20}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.24}ent.SetParm}{20}}
\newlabel{enty-setparm}{{4.4.24}{20}}
\@writefile{toc}{\contentsline {section}{\numberline {4.5}mover}{21}}
\newlabel{mver}{{4.5}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.1}mover.Halt}{21}}
\newlabel{mver-halt}{{4.5.1}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.2}mover.HaltAngles}{21}}
\newlabel{mver-haltangles}{{4.5.2}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.3}mover.AsTrain}{21}}
\newlabel{mver-astrain}{{4.5.3}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.4}mover.SetAngles}{21}}
\newlabel{mver-setangles}{{4.5.4}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.5}mover.SetPosition}{21}}
\newlabel{mver-setposition}{{4.5.5}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.6}mover.ToAngles}{21}}
\newlabel{mver-toangles}{{4.5.6}{21}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5.7}mover.ToPosition}{21}}
\newlabel{mver-toposition}{{4.5.7}{21}}
\@writefile{toc}{\contentsline {section}{\numberline {4.6}sound}{22}}
\newlabel{sound}{{4.6}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6.1}Sound Channels}{22}}
\newlabel{sound-chan}{{4.6.1}{22}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6.2}sound.PlaySound}{22}}
\newlabel{snd-playsnd}{{4.6.2}{22}}
\@writefile{toc}{\contentsline {chapter}{\numberline {5}Examples}{23}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{examples}{{5}{23}}
\@writefile{toc}{\contentsline {section}{\numberline {5.1}Example 1 - HelloWorld}{23}}
\newlabel{example1}{{5.1}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.1}Hello World for game}{23}}
\newlabel{example11}{{5.1.1}{23}}
\newlabel{helloworldgame}{{5.1}{23}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.1}Hello World for game}{23}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.2}Hello World for a client}{23}}
\newlabel{example12}{{5.1.2}{23}}
\newlabel{helloworldclient}{{5.2}{23}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.2}Hello World for client}{23}}
\newlabel{helloworldclient1}{{5.3}{23}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.3}First function}{23}}
\newlabel{helloworldclient2}{{5.4}{24}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.4}Second function}{24}}
\newlabel{helloworldclient3}{{5.5}{24}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.5}Third function}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1.3}Hello World for all clients}{24}}
\newlabel{example13}{{5.1.3}{24}}
\newlabel{helloworldclientall}{{5.6}{24}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.6}Hello World for all client}{24}}
\@writefile{toc}{\contentsline {section}{\numberline {5.2}Example 2 - Finding Entities}{24}}
\newlabel{example2}{{5.2}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.1}Finding entities by their targetnames}{24}}
\newlabel{example21}{{5.2.1}{24}}
\newlabel{findents1}{{5.7}{24}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.7}Find an entity by its targetname}{24}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.2}Finding entities by their entity number}{25}}
\newlabel{example22}{{5.2.2}{25}}
\newlabel{findents2}{{5.8}{25}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.8}Find an entity by its entity number}{25}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2.3}Finding entities by thier brush model}{25}}
\newlabel{example23}{{5.2.3}{25}}
\newlabel{findents3}{{5.9}{25}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.9}Find an entity by its brush model}{25}}
\@writefile{toc}{\contentsline {section}{\numberline {5.3}Example 3 - Spawning entities}{25}}
\newlabel{spawnents}{{5.10}{25}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5.10}Spawning an entity}{25}}
\@writefile{toc}{\contentsline {chapter}{\numberline {6}How to ...}{27}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\addvspace {10\p@ }}
\newlabel{howto}{{6}{27}}
\@writefile{toc}{\contentsline {section}{\numberline {6.1}add RPG-X2 Turbolifts to older maps}{27}}
\newlabel{howto-x2turbo}{{6.1}{27}}
\@writefile{toc}{\contentsline {section}{\numberline {6.2}add Transporters with ui\_transporter to older maps}{27}}
\newlabel{howto-uitrans}{{6.2}{27}}
\@writefile{toc}{\contentsline {section}{\numberline {6.3}convert func\_usable force field from older maps to func\_forcefield}{27}}
\newlabel{howto-usabletoforcefield}{{6.3}{27}}
\newlabel{fustoff}{{6.1}{28}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.1}Example 1}{28}}
\newlabel{fustoff2}{{6.2}{28}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.2}Example 2}{28}}

Binary file not shown.

View file

@ -0,0 +1,312 @@
This is pdfTeX, Version 3.1415926-1.40.11 (MiKTeX 2.9) (preloaded format=pdflatex 2010.12.30) 30 DEC 2010 13:17
entering extended mode
**C:/stvoy/Code-DM/RPG-X2*Lua*Documentation/RPG-X2*Lua*Documentation.tex
("C:/stvoy/Code-DM/RPG-X2 Lua Documentation/RPG-X2 Lua Documentation.tex"
LaTeX2e <2009/09/24>
Babel <v3.8l> and hyphenation patterns for english, afrikaans, ancientgreek, ar
abic, armenian, assamese, basque, bengali, bokmal, bulgarian, catalan, coptic,
croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, ga
lician, german, german-x-2009-06-19, greek, gujarati, hindi, hungarian, iceland
ic, indonesian, interlingua, irish, italian, kannada, kurmanji, lao, latin, lat
vian, lithuanian, malayalam, marathi, mongolian, mongolianlmc, monogreek, ngerm
an, ngerman-x-2009-06-19, nynorsk, oriya, panjabi, pinyin, polish, portuguese,
romanian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, swis
sgerman, tamil, telugu, turkish, turkmen, ukenglish, ukrainian, uppersorbian, u
senglishmax, welsh, loaded.
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrreprt.cls"
Document Class: scrreprt 2010/09/17 v3.07 KOMA-Script document class (report)
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrkbase.sty"
Package: scrkbase 2010/09/17 v3.07 KOMA-Script package (KOMA-Script-dependent b
asics and keyval usage)
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrbase.sty"
Package: scrbase 2010/09/17 v3.07 KOMA-Script package (KOMA-Script-independent
basics and keyval usage)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\keyval.sty"
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
\KV@toks@=\toks14
)
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrlfile.sty"
Package: scrlfile 2009/03/25 v3.03 KOMA-Script package (loading files)
Package scrlfile, 2009/03/25 v3.03 KOMA-Script package (loading files)
Copyright (C) Markus Kohm
))) ("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\tocbasic.sty"
Package: tocbasic 2010/09/14 v3.06a KOMA-Script package (handling toc-files)
)
Package tocbasic Info: omitting babel extension for `toc'
(tocbasic) because of feature `nobabel' available
(tocbasic) for `toc' on input line 117.
Package tocbasic Info: omitting babel extension for `lof'
(tocbasic) because of feature `nobabel' available
(tocbasic) for `lof' on input line 118.
Package tocbasic Info: omitting babel extension for `lot'
(tocbasic) because of feature `nobabel' available
(tocbasic) for `lot' on input line 119.
Class scrreprt Info: File `scrsize11pt.clo' used instead of
(scrreprt) file `scrsize11.clo' to setup font sizes on input line 131
0.
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrsize11pt.clo"
File: scrsize11pt.clo 2010/09/17 v3.07 KOMA-Script font size class option (11pt
)
)
("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\typearea.sty"
Package: typearea 2010/09/17 v3.07 KOMA-Script package (type area)
Package typearea, 2010/09/17 v3.07 KOMA-Script package (type area)
Copyright (C) Frank Neukam, 1992-1994
Copyright (C) Markus Kohm, 1994-
\ta@bcor=\skip41
\ta@div=\count79
\ta@hblk=\skip42
\ta@vblk=\skip43
\ta@temp=\skip44
Package typearea Info: These are the values describing the layout:
(typearea) DIV = 10
(typearea) BCOR = 0.0pt
(typearea) \paperwidth = 597.50793pt
(typearea) \textwidth = 418.25555pt
(typearea) DIV departure = -6%
(typearea) \evensidemargin = 17.3562pt
(typearea) \oddsidemargin = 17.3562pt
(typearea) \paperheight = 845.04694pt
(typearea) \textheight = 595.80026pt
(typearea) \topmargin = -25.16531pt
(typearea) \headheight = 17.0pt
(typearea) \headsep = 20.40001pt
(typearea) \topskip = 11.0pt
(typearea) \footskip = 47.60002pt
(typearea) \baselineskip = 13.6pt
(typearea) on input line 1134.
)
\c@part=\count80
\c@chapter=\count81
\c@section=\count82
\c@subsection=\count83
\c@subsubsection=\count84
\c@paragraph=\count85
\c@subparagraph=\count86
\abovecaptionskip=\skip45
\belowcaptionskip=\skip46
\c@pti@nb@sid@b@x=\box26
\c@figure=\count87
\c@table=\count88
\bibindent=\dimen102
) ("C:\Program Files\MiKTeX 2.9\tex\latex\base\inputenc.sty"
Package: inputenc 2008/03/30 v1.1d Input encoding file
\inpenc@prehook=\toks15
\inpenc@posthook=\toks16
("C:\Program Files\MiKTeX 2.9\tex\latex\base\latin1.def"
File: latin1.def 2008/03/30 v1.1d Input encoding file
))
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphicx.sty"
Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphics.sty"
Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\trig.sty"
Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
)
("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\graphics.cfg"
File: graphics.cfg 2007/01/18 v1.5 graphics configuration of teTeX/TeXLive
)
Package graphics Info: Driver file: pdftex.def on input line 91.
("C:\Program Files\MiKTeX 2.9\tex\latex\pdftex-def\pdftex.def"
File: pdftex.def 2010/09/14 v0.05b Graphics/color for pdfTeX
\Gread@gobject=\count89
))
\Gin@req@height=\dimen103
\Gin@req@width=\dimen104
)
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.sty"
\lst@mode=\count90
\lst@gtempboxa=\box27
\lst@token=\toks17
\lst@length=\count91
\lst@currlwidth=\dimen105
\lst@column=\count92
\lst@pos=\count93
\lst@lostspace=\dimen106
\lst@width=\dimen107
\lst@newlines=\count94
\lst@lineno=\count95
\lst@maxwidth=\dimen108
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\lstmisc.sty"
File: lstmisc.sty 2007/02/22 1.4 (Carsten Heinz)
\c@lstnumber=\count96
\lst@skipnumbers=\count97
\lst@framebox=\box28
)
("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.cfg"
File: listings.cfg 2007/02/22 1.4 listings configuration
))
Package: listings 2007/02/22 1.4 (Carsten Heinz)
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation.aux")
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 46.
LaTeX Font Info: ... okay on input line 46.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 46.
LaTeX Font Info: ... okay on input line 46.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 46.
LaTeX Font Info: ... okay on input line 46.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 46.
LaTeX Font Info: ... okay on input line 46.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 46.
LaTeX Font Info: ... okay on input line 46.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 46.
LaTeX Font Info: ... okay on input line 46.
("C:\Program Files\MiKTeX 2.9\tex\context\base\supp-pdf.mkii"
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count98
\scratchdimen=\dimen109
\scratchbox=\box29
\nofMPsegments=\count99
\nofMParguments=\count100
\everyMPshowfont=\toks18
\MPscratchCnt=\count101
\MPscratchDim=\dimen110
\MPnumerator=\count102
\everyMPtoPDFconversion=\toks19
)
\c@lstlisting=\count103
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <14.4> on input line 54.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <7> on input line 54.
[1
{C:/ProgramData/MiKTeX/2.9/pdftex/config/pdftex.map}]
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation.toc"
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <10.95> on input line 2.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <8> on input line 2.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <6> on input line 2.
[2
] [3])
\tf@toc=\write3
[4]
Chapter 1.
Class scrreprt Warning: \float@addtolists detected!
(scrreprt) You should use the features of package `tocbasic'
(scrreprt) instead of \float@addtolists.
(scrreprt) Support for \float@addtolists may be removed from
(scrreprt) `scrreprt' soon .
LaTeX Font Info: Try loading font information for OMS+cmr on input line 64.
("C:\Program Files\MiKTeX 2.9\tex\latex\base\omscmr.fd"
File: omscmr.fd 1999/05/25 v2.5h Standard LaTeX font definitions
)
LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <10.95> not available
(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 64.
Overfull \hbox (31.01999pt too wide) in paragraph at lines 69--70
\OT1/cmr/bx/n/10.95 var.function(var) \OT1/cmr/m/n/10.95 can be writ-ten as \OT
1/cmr/bx/n/10.95 var:function() \OT1/cmr/m/n/10.95 (ex-am-ple: \OT1/cmr/bx/n/10
.95 ent.Remove(ent)
[]
[5
]
Chapter 2.
[6
] [7] [8] [9]
Chapter 3.
[10
]
Chapter 4.
[11
] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21]
Underfull \hbox (badness 10000) in paragraph at lines 626--630
[]
[22]
Chapter 5.
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldGame.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient1.lua")
[23
] ("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient2.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClient3.lua") ("
C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/HelloWorldClientAll.lua") ("
C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts1.lua")
[24] ("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts2.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/FindingEnts3.lua")
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/SpawningEnts.lua")
[25]
Underfull \hbox (badness 10000) in paragraph at lines 708--710
[]
Underfull \hbox (badness 10000) in paragraph at lines 713--715
[]
Underfull \hbox (badness 10000) in paragraph at lines 718--720
[]
Underfull \hbox (badness 10000) in paragraph at lines 723--725
[]
Underfull \hbox (badness 10000) in paragraph at lines 728--730
[]
[26]
Chapter 6.
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/fusToff.lua" [27
])
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\examples/fusToff2.lua") [28]
("C:\stvoy\Code-DM\RPG-X2 Lua Documentation\RPG-X2 Lua Documentation.aux") )
Here is how much of TeX's memory you used:
4061 strings out of 494019
59081 string characters out of 3146494
150299 words of memory out of 3000000
7318 multiletter control sequences out of 15000+200000
9721 words of font info for 34 fonts, out of 3000000 for 9000
714 hyphenation exceptions out of 8191
35i,8n,40p,515b,1631s stack positions out of 5000i,500n,10000p,200000b,50000s
<C:
/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmbx10.pfb><C:/Program
Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmex10.pfb><C:/Program Files/M
iKTeX 2.9/fonts/type1/public/amsfonts/cm/cmmi10.pfb><C:/Program Files/MiKTeX 2.
9/fonts/type1/public/amsfonts/cm/cmmi8.pfb><C:/Program Files/MiKTeX 2.9/fonts/t
ype1/public/amsfonts/cm/cmr10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/publ
ic/amsfonts/cm/cmr12.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfon
ts/cm/cmr6.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmss
bx10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmsy10.pfb
><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmti10.pfb>
Output written on "RPG-X2 Lua Documentation.pdf" (28 pages, 179749 bytes).
PDF statistics:
132 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)

View file

@ -0,0 +1,93 @@
[Files\0]
ActiveFilters=
Bookmark#0=648
Bookmark#1=675
Bookmark#2=0
Bookmark#3=0
Bookmark#4=0
Bookmark#5=0
Bookmark#6=0
Bookmark#7=0
Bookmark#8=0
Bookmark#9=0
CaretPos.X=64
CaretPos.Y=730
CharSet=def
FileName=rpg-x2 lua documentation.tex
FoldedLines=
IsMainFile=yes
Opened=yes
ScrollPos.X=0
ScrollPos.Y=845
SearchListCount=0
ShowSyntax=yes
SpellChecking=yes
TabOrder=0
UseThesaurus=yes
WrapLine=yes
[Files]
Count=1
[Project]
ActiveFilters=
[Project\Archive]
AutoArchive=no
AutoSet=1
Components=as*.gpr;*.lpr:as*.tex;*.sty;*.cls;*.bib;*.mp;*.undo:as*.eps
Compression=1
Dir=<PROJECTDIR>\Backup
Name=<PROJECTNAME><DATE>.zip
[Project\DVI\10]
Page=0
Zoom=9
[Project\DVI\1]
Page=0
Zoom=9
[Project\DVI\2]
Page=0
Zoom=9
[Project\DVI\3]
Page=0
Zoom=9
[Project\DVI\4]
Page=0
Zoom=9
[Project\DVI\5]
Page=0
Zoom=9
[Project\DVI\6]
Page=0
Zoom=9
[Project\DVI\7]
Page=0
Zoom=9
[Project\DVI\8]
Page=0
Zoom=9
[Project\DVI\9]
Page=0
Zoom=9
[Project\DVI]
FileName=1
FirstPage=0
Magnifier=5
Page=1
PaperHeight=297
PaperWidth=210
Zoom=11
[Template]
Id=1

Binary file not shown.

View file

@ -0,0 +1,763 @@
\documentclass{scrreprt}
\usepackage[latin1]{inputenc}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{listings}
% -*- latex -*-
% Definition of the Lua language for the listings package
% Time-stamp: <2008-11-30 15:27:16 rsmith>
% Written by Roland Smith <rsmith@xs4all.nl> and hereby placed in the public
% domain.
\lstdefinelanguage{lua}
{morekeywords={and,break,do,else,elseif,end,false,for,function,if,in,local,
nil,not,or,repeat,return,then,true,until,while},
morekeywords={[2]arg,assert,collectgarbage,dofile,error,_G,getfenv,
getmetatable,ipairs,load,loadfile,loadstring,next,pairs,pcall,print,
rawequal,rawget,rawset,select,setfenv,setmetatable,tonumber,tostring,
type,unpack,_VERSION,xpcall},
morekeywords={[2]coroutine.create,coroutine.resume,coroutine.running,
coroutine.status,coroutine.wrap,coroutine.yield},
morekeywords={[2]module,require,package.cpath,package.load,package.loaded,
package.loaders,package.loadlib,package.path,package.preload,
package.seeall},
morekeywords={[2]string.byte,string.char,string.dump,string.find,
string.format,string.gmatch,string.gsub,string.len,string.lower,
string.match,string.rep,string.reverse,string.sub,string.upper},
morekeywords={[2]table.concat,table.insert,table.maxn,table.remove,
table.sort},
morekeywords={[2]math.abs,math.acos,math.asin,math.atan,math.atan2,
math.ceil,math.cos,math.cosh,math.deg,math.exp,math.floor,math.fmod,
math.frexp,math.huge,math.ldexp,math.log,math.log10,math.max,math.min,
math.modf,math.pi,math.pow,math.rad,math.random,math.randomseed,math.sin,
math.sinh,math.sqrt,math.tan,math.tanh},
morekeywords={[2]io.close,io.flush,io.input,io.lines,io.open,io.output,
io.popen,io.read,io.tmpfile,io.type,io.write,file:close,file:flush,
file:lines,file:read,file:seek,file:setvbuf,file:write},
morekeywords={[2]os.clock,os.date,os.difftime,os.execute,os.exit,os.getenv,
os.remove,os.rename,os.setlocale,os.time,os.tmpname},
sensitive=true,
morecomment=[l]{--},
morecomment=[s]{--[[}{]]--},
morestring=[b]",
morestring=[d]'
}
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt}
\lstset{language=lua}
\begin{document}
\title{
\Huge RPG-X2 Lua Documentation
\author{
Ubergames
Walter Julius 'GSIO01' Hennecke}
}
\maketitle
\newpage
\tableofcontents
\chapter{Introduction}
\label{intro}
\section{General Information}
\label{gen-info}
The RPG-X2 Lua Documentation documents and describes all Lua functions avaible in RPG-X2. The version you are reading right now is for \textbf{RPG-X2 version 2.2 beta 4.4.5}. The RPG-X2 Lua Documentation will be updated with every new release of RPG-X2.
\section{Prerequisites}
\label{preq}
\begin{itemize}
\item In Lua variables are not declared with their type. In order to provid you information of what type a variable is the types will be written infront of variables in italic (example: \textit{integer} \textbf{clientNum}).
\item There are three different types of function calls in RPG-X2 Lua.\begin{itemize}
\item Function calls from Lua base libraries (example: \textbf{\textbf{tostring(clientNum)}}).
\item Function calls from RPG-X2 libraries which have the library name infront \textbf{library.function()} (example: \textbf{entity.Spawn()}).
\item Function calls on variables. This is possible on entities and vectors for example (example: \textbf{ent.Remove(ent)}).
\item Function calls where the variable a function is called on is the first argument \textbf{var.function(var)} can be written as \textbf{var:function()} (example: \textbf{ent.Remove(ent)} is the same as \textbf{ent:Remove()}).
\end{itemize}
\end{itemize}
\chapter{Lua Hooks}
\label{lua-hooks}
\section{What is a Lua Hook}
\label{wia-lh}
A Lua Hook is a function that gets called when a specific event in the game logic happens. For example if the game is iniatialized in the game logic G\_InitGame function gets called. This function has a Lua Hook which means when the G\_InitGame function is called in the game logic the corresponding Lua function gets called as well. There are Lua Hooks with static function names and Lua Hooks with dynamic function names.
\section{Static Lua Hooks}
\label{s-lh}
Static Lua hooks always have the same function name.
\subsection{InitGame}
\label{init-game}
\textbf{InitGame(}\textit{integer} \textbf{leveltime,} \textit{integer} \textbf{randomssed, }\textit{integer} \textbf{restart)}
\newline
Gets called at game start or after a map\_restart command was issued.
\newline
\textbf{leveltime} current level time in milliseconds
\newline
\textbf{restart} is 1 when call is result of a map\_restart
\subsection{ShutdownGame}
\label{shutdown-game}
\textbf{ShutdownGame(}\textit{integer} \textbf{restart)}
\newline
Gets called when the game shuts down (disconnect, game is closed, map change, map restart).
\newline
\textbf{restart} is 1 when call is result of a map\_restart
\subsection{RunFrame}
\label{run-frame}
\textbf{RunFrame(}\textit{integer} \textbf{leveltime)}
\newline
Gets called everyframe. Should be used with cation because this is called every frame and the frametime is 50ms.
\newline
\textbf{leveltime} current leveltime in milliseconds
\subsection{GClientPrint}
\label{cli-print}
\textbf{GClientPrint(}\textit{string} \textbf{text, }\textit{entity }\textbf{client)}
\newline
Gets called when the game logic function G\_PrintfClient gets called.
\newline
\textbf{text} text that gets printed
\newline
\textbf{client} the client the text gets printed for
\subsection{GPrint}
\label{g-print}
\textbf{GPrint(}\textit{string}\textbf{ text)}
\newline
Gets called when the game logic function G\_Print is called.
\newline
\textbf{text} text that gets printed to the game console
\newpage
\section{Dynamic Lua Hooks}
\label{dyn-lh}
These hooks can have different functions names. All of the hooks are for etities. The function names for these are defined in radiant by key-value pairs.
As the function names depend on these pairs the function names for these hooks in this documentation are the keys that are used to define the function names in Radiant.
\subsection{luaThink}
\label{luaThink}
\textbf{luaThink(}\textit{entity}\textbf{ ent)}
\newline
Gets called each time the entity thinks.
\newline
\textbf{ent} the entity itself
\subsection{luaTouch}
\label{luaTouch}
Gets called each time the entity is touched.
\newline
\textbf{ent} the entity itself
\newline
\textbf{other} the entity that touched \textbf{ent}
\subsection{luaUse}
\label{luaUse}
Gets called each time the entity is used.
\newline
\textbf{ent} the entity itself
\newline
\textbf{activator} the entity that used \textbf{ent}
\subsection{luaHurt}
\label{luaHurt}
\textbf{luaHurt(}\textit{entity}\textbf{ ent, }\textit{entity}\textbf{ inflictor,}\textit{entity}\textbf{attacker)}
\newline
Gets called each time the entity gets hurt.
\newline
\textbf{ent} the entity itself
\newline
\textbf{inflictor} the inflictor
\newline
\textbf{attacker} the attacker
\subsection{luaDie}
\label{luaDie}
\textbf{luaDie(}\textit{entity} \textbf{ent,} \textit{entity} \textbf{inflictor,} \textit{entity} \textbf{attacker,} \textit{integer} \textbf{dmg,} \textit{integer}\textbf{ mod)}
\newline
Gets called when the entity dies.
\newline
\textbf{ent} the entity itself
\newline
\textbf{inflictor} the inflictor
\newline
\textbf{attacker} the attacker
\newline
\textbf{dmg} the ammount of damage
\newline
\textbf{mod} the means of death
\subsection{luaFree}
\label{luaFree}
\textbf{luaFree(}\textit{entity} \textbf{ent)}
\newline
Gets called when the entity is freed which means it is removed.
\newline
\textbf{ent} the entity itself
\subsection{luaReached}
\label{luaReached}
\textbf{luaReached(}\textit{entity }\textbf{ent)}
\newline
Gets called when movement of the entity has reached its endpoint.
\newline
\textbf{ent} the entity itself
\subsection{luaReachedAngular}
\label{luaReachedAngular}
\textbf{luaReachedAngular(}\textit{entity }\textbf{ent)}
\newline
Gets called when angular movement of the entity has reached its endangles.
\newline
\textbf{ent} the entity itself
\subsection{luaTrigger}
\label{luaTrigger}
\textbf{luaTrigger(}\textit{entity}\textbf{ ent, }\textit{entity}\textbf{ other)}
\newline
Gets called when the entity is triggered. Note that this is not the same as when the entity is used this is for trigger entities.
\newline
\textbf{ent} the entity itself
\newline
\textbf{other} the entity that triggerd \textbf{ent}
\subsection{luaSpawn}
\label{luaSpawn}
\textbf{lauSpawn(}\textit{entity}\textbf{ ent)}
\newline
Gets called when the entities spawn function is called.
\newline
\textbf{ent} the entity itself.
\newpage
\chapter{RPG-X2 Map Scripting}
\label{rpgx2-mapscripting}
\section{Map scripts}
\label{map-scripts}
Currently on script file can be loaded for each map. This script file has to be located in \textit{scripts/lua/<mapname>} and must have the name \textit{<mapname>.lua}. \textit{<mapname>} is the name of the .map file and .bsp file.
\section{Calling Functions}
\label{map-callingfunction}
There are Dynamic Lua Hooks for use in Radiant (listed below und Dynamic Lua Hooks in this ducumentation). You can use these hooks on entities by adding the corresponding Lua Hook key and the function name as value to an entity.
\newline
For example if you want a function \textit{PrintText} to be called when a \textit{func\_usable} is used you have to add the key \textit{luaUse} and the value \textit{PrintText} to this entity.
\newpage
\chapter{RPG-X2 Lua Libraries}
\label{rpgx2-llibs}
\section{game}
\label{g}
This library provides acces to some game logic function such as G\_Printf \newline
and G\_ClientPrintf.
\subsection{game.Print}
\label{g-prnt}
\textbf{game.Print(}\textit{string}\textbf{ text)}
\newline
Prints \textbf{text} to the game console (the server console).
\subsection{game.ClientPrint}
\label{g-clientprint}
\textbf{game.ClientPrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Prints \textbf{text} to the clients console that has the client number \textbf{clientNum}. If \textbf{clientNum} is -1 the text gets printed to all clients consoles.
\subsection{game.CenterPrint}
\label{g-centerprint}
\textbf{game.CenterPrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Prints \textbf{text} to the center of the screen of the client with client number \textbf{clientNum}. If \textbf{clientNum} is -1 the text gets printed for all clients.
\subsection{game.MessagePrint}
\label{g-messagepritn}
\textbf{game.MessagePrint(}\textit{integer}\textbf{ clientNum, }\textit{string}\textbf{ text)}
\newline
Prints \textbf{text} to the lower right corner of the screen of the client with client number \textbf{clientNum}. If \textbf{clientNum} is -1 the text gets printed for all cleints.
\subsection{game.LevelTime}
\label{g-leveltime}
\textbf{game.LevelTime()}
Returns the curreten level time in milliseconds.
\subsection{game.SetGlobal}
\label{g-setglobal}
\textbf{game.SetGlobal(}\textit{string}\textbf{ name, value)}
\newline
Sets a global lua varible which is called \textbf{name} to \textbf{value}. Creates a new global variable if a variable of \textbf{name} does not exist. \textbf{value} can be of any type.
\subsection{game.GetGlobal}
\label{g-getglobal}
\textbf{game.GetGlobal(}\textit{string}\textbf{ name)}
\newline
Returns the value of the global variable \textbf{name}. Returns \textit{nil} if the variable does not exist.
\newpage
\section{qmath}
\label{qmath}
This library provides access to mathematical functions avaible in the game code.
\subsection{qmath.abs}
\label{qm-abs}
\textbf{qmath.abs(}\textit{float}\textbf{ f)}
\newline
Returns the integer part of \textbf{f}.
\subsection{qmath.sin}
\label{qm-sin}
\textbf{qmath.sin(}\textit{float}\textbf{ degree)}
\newline
Returns the sine of \textbf{degree}.
\subsection{qmath.cos}
\label{qm-cos}
\textbf{qmath.cos(}\textit{float}\textbf{ degree)}
\newline
Returns the cosine of \textbf{degree}.
\subsection{qmath.tan}
\label{qm-tan}
\textbf{qmath.tan(}\textit{float}\textbf{ degree)}
\newline
Returns the tangent of \textbf{degree}.
\subsection{qmath.asin}
\label{qm-asin}
\textbf{qmath.asin(}\textit{float}\textbf{ f)}
\newline
Returns the arcsine of \textbf{f}.
\subsection{qmath.acos}
\label{qm-acos}
\textbf{qmath.acos(}\textit{float}\textbf{ f)}
\newline
Returns the arccosine of \textbf{f}.
\subsection{qmath.atan}
\label{qm-atan}
\textbf{qmath.atan(}\textit{float}\textbf{ f)}
\newline
Returns the arctangent of \textbf{f}.
\subsection{qmath.floor}
\label{qm-floor}
\textbf{qmath.floor(}\textit{float}\textbf{ f)}
\newline
Returns the floored value of \textbf{f}.
\subsection{qmath.ceil}
\label{qm-ceil}
\textbf{qath.ceil(}\textit{float}\textbf{ f)}
\newline
Returns the ceiled value of \textbf{f}.
\subsection{qmath.fmod}
\label{qm-fmod}
\textbf{qmath.fmod(}\textit{float}\textbf{ f, }\textit{float}\textbf{ n)}
\newline
Returns the remainder of \begin{math}f/n.\end{math}
\subsection{qmath.modf}
\label{qm-modf}
\textbf{qmath.modf(}\textit{float}\textbf{ f)}
\newline
Breaks \begin{math}f\end{math} apart into its integer par and its fractional part. The fractional part is returned while the integer part is assigned to \begin{math}f\end{math}
\subsection{qmath.sqrt}
\label{qm-sqrt}
\textbf{qmath.sqrt(}\textit{float}\textbf{ f)}
\newline
Returns the square root of \textbf{f}.
\subsection{qmath.log}
\label{qm-log}
\textbf{qmath.log(}\textit{float}\textbf{ f)}
\newline
Returns the logarithm of \textbf{f}.
\subsection{qmath.log10}
\label{qm-log10}
\textbf{qmath.log10(}\textit{float}\textbf{ f)}
\newline
Returns the logarithm to the base of 10 of \textbf{f}.
\subsection{qmath.deg}
\label{qm-deg}
\textbf{qmath.deg(}\textit{float}\textbf{ radian)}
\newline
Converts from radian to degrees.
\subsection{qmath.rad}
\label{qm-rad}
\textbf{qmath.rad(}\textit{float}\textbf{ degree)}
\newline
Converts from degree to radian.
\subsection{qmath.frexp}
\label{qm-frexp}
\textbf{qmath.frexp(}\textit{float}\textbf{ f)}
\newline
Breaks \textbf{f} into its binary significand and an integral exponent for 2.
\newline
\begin{math}x=significand*2^exponent\end{math}
\subsection{qmath.ldexp}
\label{qm-ldexp}
\textbf{qmath.ldexp(}\textit{float}\textbf{ f, }\textit{float}\textbf{ n)}
\newline
Returns the result from multiplying \textbf{f} by 2 raised to the power of \textbf{n}.
\subsection{qmath.min}
\label{qm-min}
\textbf{qmath.min(}\textit{integer}\textbf{ array[])}
\newline
Return the lowest value in \textbf{array[]}.
\subsection{qmath.max}
\label{qm-max}
\textbf{qmath.max(}\textit{integer}\textbf{ array[])}
\newline
Return the highest value in \textbf{array[]}.
\subsection{qmath.random}
\label{qm-random}
\textbf{qmath.random()}
\newline
Returns random integers.
\subsection{qmath.crandom}
\label{qm-crandom}
\textbf{qmath.crandom()}
\newline
Returns random floats (crazy random function).
\newpage
\section{vector}
\label{vect}
This provides a new type vector along with mathematical functions for it.
\subsection{vector.New}
\label{vect-new}
\textbf{vector.New()}
\newline
Allocates and returns a new vector \begin{math}\left(\begin{array}{c} 0 \\ 0 \\ 0 \\ \end{array}\right)\end{math}.
\subsection{vector.Construct}
\label{vect-cons}
\textbf{vector.Construct(}\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Allocates and return a new vector \begin{math}\left(\begin{array}{c} x \\ y \\ z \\ \end{array}\right)\end{math}.
\subsection{vector.Set}
\label{vect-set}
\textbf{vector.Set(}\textit{vector}\textbf{ v, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Set the vector \textbf{v} to the specified values.
\subsection{vector.clear}
\label{vect-clear}
\textbf{vector.Clear(}\textit{vector}\textbf{ v)}
\newline
Clears \textbf{vector} by setting it to \begin{math}\left(\begin{array}{c} 0 \\ 0 \\ 0 \\ \end{array}\right)\end{math}.
\subsection{vector.Add}
\label{vect-add}
\textbf{vector.Add(}\textit{vector}\textbf{ a, }\textit{vector}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Adds \textbf{a} and \textbf{b} ans stores the result in \textbf{c}.
\subsection{vector.Substract}
\label{vect-sub}
\textbf{vector.Subtract(}\textit{vector}\textbf{ a, }\textit{vector}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Subtracts \textbf{b} from \textbf{a} and stores the result in \textbf{c}.
\subsection{vector.Scale}
\label{vect-scale}
\textbf{vector.Scale(}\textit{vector}\textbf{ a, }\textit{float}\textbf{ b, }\textit{vector}\textbf{ c)}
\newline
Scales \textbf{a} by the value of \textbf{b} and stores the result in \textbf{c}.
\subsection{vector.Length}
\label{vect-length}
\textbf{vector.Length(}\textit{vector}\textbf{ a)}
\newline
Returns the length of \textbf{a}.
\subsection{vector.Normalize}
\label{vect-norm}
\textbf{vector.Normalize(}\textit{vector}\textbf{ a)}
\newline
Normalizes \textbf{a}.
\subsection{vector.RotateAroundPoint}
\label{vect-rotarndpnt}
\textbf{vector.RotateAroundPoint(}\textit{vector}\textbf{ dest, }\textit{vector}\textbf{ dir, }\textit{vector}\textbf{ point, }\textit{float}\textbf{ degrees)}
\newline
Rotates \textbf{point} around a given vector.
\newline
\textbf{dir} vector around which to rotate (must be normalized)
\newline
\textbf{point} point to be rotated
\newline
\textbf{degrees} how many degrees to rotate the point by
\newline
\textbf{dst} point after totation
\subsection{vector.Perpendicular}
\label{vect-Perpendicular}
\textbf{vector.Perpendicular(}\textit{vector}\textbf{ dest, }\textit{vector}\textbf{ src)}
\newline
Finds a vector perpendicular to the source vector.
\textbf{src} source vector
\textbf{dest} a vector that is perpendicular to \textbf{src} (the result is stored here)
\newpage
\section{entity}
\label{enty}
This library holds function for entities. All functions listed with entity infront here are calls from the library. All functions listed with ent are called on a variable of the type entity.
\subsection{entity.Find}
\label{enty-find}
\textbf{entity.Find(}\textit{string}\textbf{ targetname)}
\newline
Returns the first entity found that has a targetname of \textbf{targetname}.
\subsection{entity.FindNumber}
\label{enty.findnumber}
\textbf{entity.FindNumber(}\textit{integer}\textbf{ entnum)}
\newline
Returns the entity with the entity number \textbf{entnum}.
\subsection{entity.FindBModel}
\label{enty-findbmodel}
\textbf{entity.FindBModel(}\textit{integer}\textbf{ bmodelnum)}
\newline
Returns the entity with the brush model *\textbf{bmodelnumber}. This is the only failsafe way to find brush entities as the entity number is diffrent when you load a map local or join a server.
\subsection{ent.GetNumber}
\label{enty-getnumber}
\textbf{ent.GetNumber(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetNumber()}
\newline
Returns the entity number of the entity.
\subsection{ent.SetKeyValue}
\label{enty-setkeyvalue}
\textbf{ent.SetKeyValue(}\textit{entity}\textbf{ ent, }\textit{string}\textbf{ key, }\textit{string}\textbf{ value)} or \textbf{ent:SetKeyValue(}\textit{string}\textbf{ key, }\textit{string}\textbf{ value)}
\newline
Sets a key-value pair for \textbf{ent} like in Radiant. Only works if the \textit{key} is part of \textit{fields\_t} (predefined keys).
\subsection{entity.Remove}
\label{enty-remove}
\textbf{entity.Remove(}\textit{entity}\textbf{ ent)}
\newline
Removes/frees \textbf{ent}.
\subsection{ent.GetOrigin}
\label{enty-getorigin}
\textbf{ent.GetOrigin(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetOrigin()}
\newline
Returns the origin of \textbf{ent} as vector.
\subsection{ent.IsClient}
\label{enty-isclient}
\textbf{ent.IsClient(}\textit{entity}\textbf{ ent)} or \textbf{ent:IsClient()}
\newline
Returns boolean. True if \textbf{ent} is a client.
\subsection{ent.GetClientname}
\label{enty-getclientname}
\textbf{ent.GetClientname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetClientname()}
\newline
Returns the clientname of \textbf{ent}.
\subsection{ent.GetClassname}
\label{enty-getclassname}
\textbf{ent.GetClassname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetClassname()}
\newline
Returns the classname of \textbf{ent}.
\subsection{ent.SetClassname}
\label{enty-setclassname}
\textbf{ent.SetClassname(}\textit{entity}\textbf{ ent, }\textit{string}\textbf{ classname)} or
\newline
\textbf{ent:SetClassname(}\textit{string}\textbf{ classname)}
\newline
Sets the classname of \textbf{ent} to \textbf{classname}.
\subsection{ent.GetTargetname}
\label{enty-gettargetname}
\textbf{ent.GetTargetname(}\textit{entity}\textbf{ ent)} or \textbf{ent:GetTargetname()}
\newline
Returns the targetname of \textbf{ent}.
\subsection{ent.SetupTrigger}
\label{enty-setuptrigger}
\textbf{ent.SetupTrigger(}\textit{enttiy}\textbf{ ent)} or \textbf{ent:SetupTrigger()}
\newline
Does some setup for entities spawned by script that are to be used as trigger.
\subsection{entity.GetTarget}
\label{enty-gettarget}
\textbf{entity.GetTarget(}\textit{entity}\textbf{ ent)}
Returns the target of \textbf{ent}.
\subsection{entity.Use}
\label{enty-use}
\textbf{entity.Use(}\textit{entity}\textbf{ ent)}
\newline
Uses \textbf{ent}.
\subsection{entity.Spawn}
\label{enty-spawn}
\textbf{entity.spawn()}
\newline
Tries to spawn a new entity and returns it. If no new entity can be spawned \textit{nil} is returned.
\subsection{entiy.CallSpawn}
\label{enty-callspawn}
\textbf{entity.CallSpawn(}\textit{entity}\textbf{ ent)}
\newline
Calls the game logic spawn function for the class of \textbf{ent}.
\subsection{entity.DelayedCallSpawn}
\label{enty-delayedcallspawn}
\textbf{entity.DelayedCallSpawn(}\textit{entity}\textbf{ ent, }\textit{integer}\textbf{ delay)}
\newline
Calls the game logic spawn function for the class of \textbf{ent} after a delay.
\textbf{delay} delay in milliseconds
\subsection{entity.RemoveSpawns}
\label{enty-removespawns}
\textbf{entity.RemoveSpawns()}
\newline
Removes all spawn points from the map.
\subsection{ent.Lock}
\label{enty-lock}
\textbf{ent.Lock(}\textit{entity}\textbf{ ent)}
\newline
Looks the entity. Works with anything that can be locked (doors, turbolifts, usables, ...).
\subsection{ent.Unlock}
\label{enty-unlock}
\textbf{ent.Unlock(}\textit{entity}\textbf{ ent)}
\newline
Unlocks the entity. Works with anything that can be locked (doors, turbolifts, usables, ...).
\subsection{ent.IsLocked}
\label{enty-locked}
\textbf{ent.IsLocked(}\textit{entity}\textbf{ ent)}
\newline
Returns \textbf{true} if entity is locked else it returns \textbf{false}.
\subsection{ent.GetParm}
\label{enty-getparm}
\textbf{ent.GetParm(}\textit{entity }\textbf{ent, }\textit{integer }\textbf{parm)}
\newline
Returns one of the four luaParms of an entity as string. Returns \textbf{nil} if the choosen luaParm is not set.
\newline
\textbf{parm} to return (number between 1 and 4)
\subsection{ent.SetParm}
\label{enty-setparm}
\textbf{ent.SetParm(}\textit{entity }\textbf{ent, }\textit{integer }\textbf{parm, }\textit{string }\textbf{value)}
\newline
Sets one oth the four luaParms of an entity to \textbf{value}.
\newline
\textbf{parm} parm to be set (number between 1 and 4)
\newline
\textbf{value} value to set the parm to
\newpage
\section{mover}
\label{mver}
Important note: always call mover.Halt or mover.HaltAngles before you move a mover again otherwise the movement wont work correctly.
\subsection{mover.Halt}
\label{mver-halt}
\textbf{mover.Halt(}\textit{entity}\textbf{ ent)}
\newline
Stops movement immediately.
\subsection{mover.HaltAngles}
\label{mver-haltangles}
\textbf{mover.HaltAngles(}\textit{entity}\textbf{ ent)}
\newline
Stops angular movement immediately.
\subsection{mover.AsTrain}
\label{mver-astrain}
\textbf{mover.AsTrain(}\textit{entity}\textbf{ mover, }\textit{entity}\textbf{ target, }\textit{float}\textbf{ speed)}
\newline
Moves an entity like a \textit{func\_train} entity. Targets have to be \textit{path\_corner} entities.
\newline
\textbf{target} the first \textit{path\_corner} to move to.
\subsection{mover.SetAngles}
\label{mver-setangles}
\textbf{mover.SetAngles(}\textit{entity}\textbf{ ent, }\textit{vector}\textbf{ angles)} or \textbf{mover.SetAngles(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Sets the angles of \textbf{ent} to the secified value(s).
\subsection{mover.SetPosition}
\label{mver-setposition}
\textbf{mover.SetPosition(}\textit{entity}\textbf{ ent, }\textit{vector}\textbf{ pos)} or \textbf{mover.SetPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Set the position of \textbf{ent} to the specified value(s).
\subsection{mover.ToAngles}
\label{mver-toangles}
\textbf{mover.ToAngles}(\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{vector}\textbf{ angles)} or \textbf{mover.ToAngles(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Rotates \textbf{ent} to the specified angles.
\subsection{mover.ToPosition}
\label{mver-toposition}
\textbf{mover.ToPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{vector}\textbf{ angles)} or
\newline
\textbf{mover.ToPosition(}\textit{entity}\textbf{ ent, }\textit{float}\textbf{ speed, }\textit{float}\textbf{ x, }\textit{float}\textbf{ y, }\textit{float}\textbf{ z)}
\newline
Moves \textbf{ent} to the specified position.
\newpage
\section{sound}
\label{sound}
This library adds function to play and handle sounds.
\subsection{Sound Channels}
\label{sound-chan}
In some function of the sound library you will be asked to specify a sound channel. Genral it will be ok to use CHAN\_AUTO and let the engine choose the channel. Anyway you will be able to choose channels yourself.
\newline
Here is a table with the diffrent channels and their numbers to use in functions:
\newline
\begin{center}
\begin{tabular}[c]{| c | c |}
\hline
CHAN\_AUTO & 0 \\
\hline
CHAN\_LOCAL & 1 \\
\hline
CHAN\_WEAPON & 2 \\
\hline
CHAN\_VOICE & 3 \\
\hline
CHAN\_ITEM & 4 \\
\hline
CHAN\_BODY & 5 \\
\hline
CHAN\_LOCAL\_SOUND & 6 \\
\hline
CHAN\_ANNOUNCER & 7 \\
\hline
CHAN\_MENU1 & 8 \\
\hline
\end{tabular}
\end{center}
\subsection{sound.PlaySound}
\label{snd-playsnd}
\textbf{sound.PlaySound(}\textit{entity}\textbf{ ent, }\textit{integer}\textbf{ chan, }\textit{string}\textbf{ sound)}
\newline
Plays the sound file \textbf{sound} using the channel \textbf{chan} on the entity \textbf{ent}.
\newpage
\chapter{Examples}
\label{examples}
This section of the manual contains script examples which may help you to understand how certain functions should be used.
\section{Example 1 - HelloWorld}
\label{example1}
This is a must have example I think as it always is there for any programming language you learn.
\subsection{Hello World for game}
\label{example11}
\lstinputlisting[frame=single, label=helloworldgame, caption=Hello World for game]{examples/HelloWorldGame.lua}
As you might not this is a function for luaUse (you can tell that from the function head).
\subsection{Hello World for a client}
\label{example12}
\lstinputlisting[frame=single, label=helloworldclient, caption=Hello World for client]{examples/HelloWorldClient.lua}
As you might not this is a function for luaUse (you can tell that from the function head).
\lstinputlisting[frame=single, label=helloworldclient1, caption=First function]{examples/HelloWorldClient1.lua}
This function prints a message to the clients console.
\newline
\lstinline|activator:GetNumber()| gets the entity number of the activator which in this case is the client number as well.
\newline
\lstinline|activator:GetClientname()| gets the clients clientname.
\lstinputlisting[frame=single, label=helloworldclient2, caption=Second function]{examples/HelloWorldClient2.lua}
This function prints a message to the center of the screen of a client.
\lstinputlisting[frame=single, label=helloworldclient3, caption=Third function]{examples/HelloWorldClient3.lua}
This function prints a message to the lower right corner of the clients screen.
\subsection{Hello World for all clients}
\label{example13}
\lstinputlisting[frame=single, label=helloworldclientall, caption=Hello World for all client]{examples/HelloWorldClientAll.lua}
This is very similar to the previous example the only difference is that instead of a client number -1 is the first arguments which results in the message to be printed to all clients.
\section{Example 2 - Finding Entities}
\label{example2}
These examples will show the different ways of finding an entity.
\subsection{Finding entities by their targetnames}
\label{example21}
\lstinputlisting[frame=single, label=findents1, caption=Find an entity by its targetname]{examples/FindingEnts1.lua}
You should note that \lstinline|entity.Find()| only returns the first entity found which means if there are multiple entities with the same targetname and the one found first isn't yours you'll be unable to find the wanted entity by this way.
\newline
Also besides showing you how to find an entity you also can see howto use local variables in function here.
\subsection{Finding entities by their entity number}
\label{example22}
\lstinputlisting[frame=single, label=findents2, caption=Find an entity by its entity number]{examples/FindingEnts2.lua}
This is a quite failsafe way to find an entity there is just one thing you have to note: The entity number for an entity when the map is loaded locally is not the same as the entity number for an entity when running a dedicated server.
\subsection{Finding entities by thier brush model}
\label{example23}
\lstinputlisting[frame=single, label=findents3, caption=Find an entity by its brush model]{examples/FindingEnts3.lua}
This only works for brush entities of course but for these it is absolutly failsafe.
\section{Example 3 - Spawning entities}
This example shows you how to spawn entities from scripting. You can spawn almost all non brush entities as well as some brush entities that don't require a visible brush model (e.g. triggers).
\lstinputlisting[frame=single, label=spawnents, caption=Spawning an entity]{examples/SpawningEnts.lua}
\newpage
So what does what and why?
\newline
\begin{lstlisting}
local ent = entity.Spawn()
\end{lstlisting}
This tries to spawn a new entity and assign it to \lstinline|ent|.
\newline
\begin{lstlisting}
if ent == nil then return
\end{lstlisting}
This is a check to make sure that a new entity was sucessfully spawned. If that is not the case the further execution of the function is stopped.
\newline
\begin{lstlisting}
ent:SetKeyValue("classname", "info_notnull");
\end{lstlisting}
This sets the classname and by this the entity is turned to an entity of a specific type.
\newline
\begin{lstlisting}
mover:SetPosition(0, 0, 0);
\end{lstlisting}
This sets the origin of the entity.
\newline
\begin{lstlisting}
entity.CallSpawn(ent);
\end{lstlisting}
This calls the spawn function of the entity.
\chapter{How to ...}
\label{howto}
\section{add RPG-X2 Turbolifts to older maps}
\label{howto-x2turbo}
Comming soon ...
\section{add Transporters with ui\_transporter to older maps}
\label{howto-uitrans}
Comming soon ...
\section{convert func\_usable force field from older maps to func\_forcefield}
\label{howto-usabletoforcefield}
This HowTo shows you how you can convert a func\_usable to a func\_forcefield. Before we can start scripting we need to find out some things about the usable:
\begin{itemize}
\item How can you identify the usable 100 per cent failsafe.
\item What are the current spawnflags of the entity.
\end{itemize}
You can obtain the information by doing the following things.
\begin{itemize}
\item Start RPG-X2 and laod the map.
\item Login as admin or change to admin class.
\item Goto the func\_usable and make sure it is visible (the force field is activated.
\item Target the usable with your crosshair.
\item Open console and type \textbf{getEntInfo}.
\end{itemize}
You'll get a list of usefull information. Now if the entity has a targetname the next thing to do is to check if it is the only one with it. While you are still in console type \textbf{getEntByTargetname} followed by the targetname.
If only one entity is listed the func\_usable is the only one with this targetname and you are done otherwise just use the brushmodel of the func\_usable.
The next step is to see if the spawnflags are ok for your needs. This means check if any spawnflags of func\_forcefield are included you don't want or if some are missing.
No you start scripting. The best place to do this entity conversion is the \textbf{InitGame} function because this function is already called during map loading.
\lstinputlisting[frame=single, label=fustoff, caption=Example 1]{examples/fusToff.lua}
\lstinputlisting[frame=single, label=fustoff2, caption=Example 2]{examples/fusToff2.lua}
\end{document}

View file

@ -0,0 +1,119 @@
\contentsline {chapter}{\numberline {1}Introduction}{5}
\contentsline {section}{\numberline {1.1}General Information}{5}
\contentsline {section}{\numberline {1.2}Prerequisites}{5}
\contentsline {chapter}{\numberline {2}Lua Hooks}{6}
\contentsline {section}{\numberline {2.1}What is a Lua Hook}{6}
\contentsline {section}{\numberline {2.2}Static Lua Hooks}{6}
\contentsline {subsection}{\numberline {2.2.1}InitGame}{6}
\contentsline {subsection}{\numberline {2.2.2}ShutdownGame}{6}
\contentsline {subsection}{\numberline {2.2.3}RunFrame}{6}
\contentsline {subsection}{\numberline {2.2.4}GClientPrint}{6}
\contentsline {subsection}{\numberline {2.2.5}GPrint}{7}
\contentsline {section}{\numberline {2.3}Dynamic Lua Hooks}{8}
\contentsline {subsection}{\numberline {2.3.1}luaThink}{8}
\contentsline {subsection}{\numberline {2.3.2}luaTouch}{8}
\contentsline {subsection}{\numberline {2.3.3}luaUse}{8}
\contentsline {subsection}{\numberline {2.3.4}luaHurt}{8}
\contentsline {subsection}{\numberline {2.3.5}luaDie}{8}
\contentsline {subsection}{\numberline {2.3.6}luaFree}{9}
\contentsline {subsection}{\numberline {2.3.7}luaReached}{9}
\contentsline {subsection}{\numberline {2.3.8}luaReachedAngular}{9}
\contentsline {subsection}{\numberline {2.3.9}luaTrigger}{9}
\contentsline {subsection}{\numberline {2.3.10}luaSpawn}{9}
\contentsline {chapter}{\numberline {3}RPG-X2 Map Scripting}{10}
\contentsline {section}{\numberline {3.1}Map scripts}{10}
\contentsline {section}{\numberline {3.2}Calling Functions}{10}
\contentsline {chapter}{\numberline {4}RPG-X2 Lua Libraries}{11}
\contentsline {section}{\numberline {4.1}game}{11}
\contentsline {subsection}{\numberline {4.1.1}game.Print}{11}
\contentsline {subsection}{\numberline {4.1.2}game.ClientPrint}{11}
\contentsline {subsection}{\numberline {4.1.3}game.CenterPrint}{11}
\contentsline {subsection}{\numberline {4.1.4}game.MessagePrint}{11}
\contentsline {subsection}{\numberline {4.1.5}game.LevelTime}{11}
\contentsline {subsection}{\numberline {4.1.6}game.SetGlobal}{11}
\contentsline {subsection}{\numberline {4.1.7}game.GetGlobal}{12}
\contentsline {section}{\numberline {4.2}qmath}{13}
\contentsline {subsection}{\numberline {4.2.1}qmath.abs}{13}
\contentsline {subsection}{\numberline {4.2.2}qmath.sin}{13}
\contentsline {subsection}{\numberline {4.2.3}qmath.cos}{13}
\contentsline {subsection}{\numberline {4.2.4}qmath.tan}{13}
\contentsline {subsection}{\numberline {4.2.5}qmath.asin}{13}
\contentsline {subsection}{\numberline {4.2.6}qmath.acos}{13}
\contentsline {subsection}{\numberline {4.2.7}qmath.atan}{13}
\contentsline {subsection}{\numberline {4.2.8}qmath.floor}{13}
\contentsline {subsection}{\numberline {4.2.9}qmath.ceil}{14}
\contentsline {subsection}{\numberline {4.2.10}qmath.fmod}{14}
\contentsline {subsection}{\numberline {4.2.11}qmath.modf}{14}
\contentsline {subsection}{\numberline {4.2.12}qmath.sqrt}{14}
\contentsline {subsection}{\numberline {4.2.13}qmath.log}{14}
\contentsline {subsection}{\numberline {4.2.14}qmath.log10}{14}
\contentsline {subsection}{\numberline {4.2.15}qmath.deg}{14}
\contentsline {subsection}{\numberline {4.2.16}qmath.rad}{14}
\contentsline {subsection}{\numberline {4.2.17}qmath.frexp}{14}
\contentsline {subsection}{\numberline {4.2.18}qmath.ldexp}{15}
\contentsline {subsection}{\numberline {4.2.19}qmath.min}{15}
\contentsline {subsection}{\numberline {4.2.20}qmath.max}{15}
\contentsline {subsection}{\numberline {4.2.21}qmath.random}{15}
\contentsline {subsection}{\numberline {4.2.22}qmath.crandom}{15}
\contentsline {section}{\numberline {4.3}vector}{16}
\contentsline {subsection}{\numberline {4.3.1}vector.New}{16}
\contentsline {subsection}{\numberline {4.3.2}vector.Construct}{16}
\contentsline {subsection}{\numberline {4.3.3}vector.Set}{16}
\contentsline {subsection}{\numberline {4.3.4}vector.clear}{16}
\contentsline {subsection}{\numberline {4.3.5}vector.Add}{16}
\contentsline {subsection}{\numberline {4.3.6}vector.Substract}{16}
\contentsline {subsection}{\numberline {4.3.7}vector.Scale}{16}
\contentsline {subsection}{\numberline {4.3.8}vector.Length}{17}
\contentsline {subsection}{\numberline {4.3.9}vector.Normalize}{17}
\contentsline {subsection}{\numberline {4.3.10}vector.RotateAroundPoint}{17}
\contentsline {subsection}{\numberline {4.3.11}vector.Perpendicular}{17}
\contentsline {section}{\numberline {4.4}entity}{18}
\contentsline {subsection}{\numberline {4.4.1}entity.Find}{18}
\contentsline {subsection}{\numberline {4.4.2}entity.FindNumber}{18}
\contentsline {subsection}{\numberline {4.4.3}entity.FindBModel}{18}
\contentsline {subsection}{\numberline {4.4.4}ent.GetNumber}{18}
\contentsline {subsection}{\numberline {4.4.5}ent.SetKeyValue}{18}
\contentsline {subsection}{\numberline {4.4.6}entity.Remove}{18}
\contentsline {subsection}{\numberline {4.4.7}ent.GetOrigin}{18}
\contentsline {subsection}{\numberline {4.4.8}ent.IsClient}{19}
\contentsline {subsection}{\numberline {4.4.9}ent.GetClientname}{19}
\contentsline {subsection}{\numberline {4.4.10}ent.GetClassname}{19}
\contentsline {subsection}{\numberline {4.4.11}ent.SetClassname}{19}
\contentsline {subsection}{\numberline {4.4.12}ent.GetTargetname}{19}
\contentsline {subsection}{\numberline {4.4.13}ent.SetupTrigger}{19}
\contentsline {subsection}{\numberline {4.4.14}entity.GetTarget}{19}
\contentsline {subsection}{\numberline {4.4.15}entity.Use}{19}
\contentsline {subsection}{\numberline {4.4.16}entity.Spawn}{19}
\contentsline {subsection}{\numberline {4.4.17}entiy.CallSpawn}{20}
\contentsline {subsection}{\numberline {4.4.18}entity.DelayedCallSpawn}{20}
\contentsline {subsection}{\numberline {4.4.19}entity.RemoveSpawns}{20}
\contentsline {subsection}{\numberline {4.4.20}ent.Lock}{20}
\contentsline {subsection}{\numberline {4.4.21}ent.Unlock}{20}
\contentsline {subsection}{\numberline {4.4.22}ent.IsLocked}{20}
\contentsline {subsection}{\numberline {4.4.23}ent.GetParm}{20}
\contentsline {subsection}{\numberline {4.4.24}ent.SetParm}{20}
\contentsline {section}{\numberline {4.5}mover}{21}
\contentsline {subsection}{\numberline {4.5.1}mover.Halt}{21}
\contentsline {subsection}{\numberline {4.5.2}mover.HaltAngles}{21}
\contentsline {subsection}{\numberline {4.5.3}mover.AsTrain}{21}
\contentsline {subsection}{\numberline {4.5.4}mover.SetAngles}{21}
\contentsline {subsection}{\numberline {4.5.5}mover.SetPosition}{21}
\contentsline {subsection}{\numberline {4.5.6}mover.ToAngles}{21}
\contentsline {subsection}{\numberline {4.5.7}mover.ToPosition}{21}
\contentsline {section}{\numberline {4.6}sound}{22}
\contentsline {subsection}{\numberline {4.6.1}Sound Channels}{22}
\contentsline {subsection}{\numberline {4.6.2}sound.PlaySound}{22}
\contentsline {chapter}{\numberline {5}Examples}{23}
\contentsline {section}{\numberline {5.1}Example 1 - HelloWorld}{23}
\contentsline {subsection}{\numberline {5.1.1}Hello World for game}{23}
\contentsline {subsection}{\numberline {5.1.2}Hello World for a client}{23}
\contentsline {subsection}{\numberline {5.1.3}Hello World for all clients}{24}
\contentsline {section}{\numberline {5.2}Example 2 - Finding Entities}{24}
\contentsline {subsection}{\numberline {5.2.1}Finding entities by their targetnames}{24}
\contentsline {subsection}{\numberline {5.2.2}Finding entities by their entity number}{25}
\contentsline {subsection}{\numberline {5.2.3}Finding entities by thier brush model}{25}
\contentsline {section}{\numberline {5.3}Example 3 - Spawning entities}{25}
\contentsline {chapter}{\numberline {6}How to ...}{27}
\contentsline {section}{\numberline {6.1}add RPG-X2 Turbolifts to older maps}{27}
\contentsline {section}{\numberline {6.2}add Transporters with ui\_transporter to older maps}{27}
\contentsline {section}{\numberline {6.3}convert func\_usable force field from older maps to func\_forcefield}{27}

View file

@ -0,0 +1,4 @@
function Example()
local ent;
ent = entity.Find("doorbell");
end

View file

@ -0,0 +1,4 @@
function Example()
local ent;
ent = entity.FindNumber(22);
end

View file

@ -0,0 +1,4 @@
function Example()
local ent;
ent = entity.FindBModel(22);
end

View file

@ -0,0 +1,8 @@
function HelloWorld(ent, other, activator)
game.ClientPrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());
game.CenterPrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());
game.MessagePrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());
end

View file

@ -0,0 +1,2 @@
game.ClientPrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());

View file

@ -0,0 +1,2 @@
game.CenterPrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());

View file

@ -0,0 +1,2 @@
game.MessagePrint(activator:GetNumber(),
"Hello " .. activator:GetClientname());

View file

@ -0,0 +1,5 @@
function HelloWorld(ent, other, activator)
game.ClientPrint(-1, "Hello all");
game.CenterPrint(-1, "Hello all");
game.MessagePrint(-1, "Hello all");
end

View file

@ -0,0 +1,3 @@
function HelloWorld(ent, other, activator)
game.Print("Hello World");
end

View file

@ -0,0 +1,7 @@
function Example()
local ent = entity.Spawn()
if ent == nil then return;
ent:SetKeyValue("classname", "info_notnull");
mover:SetPosition(0, 0, 0);
entity.CallSpawn(ent);
end

View file

@ -0,0 +1,10 @@
function InitGame(levelTime, randomSeed, restart)
-- adjust the targetname
local ent = entity.Find("forcefield1");
if ent == nil then return;
ent:SetKeyValue("classname", "func_forcefield");
-- setting the spawnflags is optional
-- only change them if you have to
ent:SetKeyValue("spawnflags", "0")
entity.CallSpawn(ent);
end

View file

@ -0,0 +1,10 @@
function InitGame(levelTime, randomSeed, restart)
-- adjust the model number
local ent = entity.FindBModel(22);
if ent == nil then return;
ent:SetKeyValue("classname", "func_forcefield");
-- setting the spawnflags is optional
-- only change them if you have to
ent:SetKeyValue("spawnflags", "0")
entity.CallSpawn(ent);
end

Binary file not shown.

56
StefGame Dll.sln.old Normal file
View file

@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BuildQVM", "BuildQVM.vcproj", "{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgame", "cgame\cgame.vcproj", "{F2DB4789-20EE-4355-9844-0DEC8C2D262E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game", "game\game.vcproj", "{A1C15954-78A8-45B5-844D-9070B2D2FB74}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ui", "ui\ui.vcproj", "{B7430F82-6210-41D4-8F07-F46B0012948F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug DLL|Win32 = Debug DLL|Win32
Debug|Win32 = Debug|Win32
Release DLL|Win32 = Release DLL|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Debug|Win32.ActiveCfg = Debug|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Debug|Win32.Build.0 = Debug|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Release DLL|Win32.ActiveCfg = Release|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Release DLL|Win32.Build.0 = Release|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Release|Win32.ActiveCfg = Release|Win32
{2318F64E-DE7F-40F8-BA7F-A5952F2C1E02}.Release|Win32.Build.0 = Release|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Debug|Win32.ActiveCfg = Debug|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Debug|Win32.Build.0 = Debug|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Release DLL|Win32.Build.0 = Release DLL|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Release|Win32.ActiveCfg = Release|Win32
{F2DB4789-20EE-4355-9844-0DEC8C2D262E}.Release|Win32.Build.0 = Release|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Debug|Win32.ActiveCfg = Debug|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Debug|Win32.Build.0 = Debug|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Release DLL|Win32.Build.0 = Release DLL|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Release|Win32.ActiveCfg = Release|Win32
{A1C15954-78A8-45B5-844D-9070B2D2FB74}.Release|Win32.Build.0 = Release|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Debug|Win32.ActiveCfg = Debug|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Debug|Win32.Build.0 = Debug|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Release DLL|Win32.Build.0 = Release DLL|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Release|Win32.ActiveCfg = Release|Win32
{B7430F82-6210-41D4-8F07-F46B0012948F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

29
buildqvm.dsw Normal file
View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "BuildQVM"=".\buildqvm.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
buildqvm.opt Normal file

Binary file not shown.

14
buildvms.bat Normal file
View file

@ -0,0 +1,14 @@
@echo off
echo.
cd game
pause
if exist game.bat call game
pause
cd ..\cgame
if exist cgame.bat call cgame
pause
cd ..\ui
if exist ui.bat call ui
pause
cd ..
echo Finished.

1066
cg_view_bak.c Normal file

File diff suppressed because it is too large Load diff

134
cgame/Makefile Normal file
View file

@ -0,0 +1,134 @@
default: so
so: build_so
# compiler to use for building shared objects
CC = gcc
# determine arch and platform
ARCH=$(shell uname -m | sed -e s/i.86/i386/)
PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]')
# cflags for the compiler
ifeq ($(PLATFORM), mingw32)
SOCFLAGS = $(CFLAGS)
else
SOCFLAGS = $(CFLAGS) -fPIC
endif
# set extension
ifeq ($(PLATFORM), mingw32)
EXT=dll
ARCH=x86
else
EXT=so
endif
# cgame objects
OBJ = \
fx_transporter.o \
fx_tetrion.o \
fx_stasis.o \
fx_scavenger.o \
fx_quantum.o \
fx_phaser.o \
fx_misc.o \
fx_lib.o \
fx_item.o \
fx_imod.o \
fx_grenade.o \
fx_dreadnought.o \
fx_compression.o \
fx_borg.o \
cg_weapons.o \
cg_view.o \
cg_snapshot.o \
cg_servercmds.o \
cg_screenfx.o \
cg_scoreboard.o \
cg_predict.o \
cg_playerstate.o \
cg_players.o \
cg_marks.o \
cg_main.o \
cg_localents.o \
cg_info.o \
cg_event.o \
cg_env.o \
cg_ents.o \
cg_effects.o \
cg_drawtools.o \
cg_draw.o \
cg_consolecmds.o
# depency objects from game
OBJDEP = \
q_shared.o \
q_math.o \
bg_misc.o \
bg_pmove.o \
bg_slidemove.o
# object for syscalls to the engine
SOOBJ = \
cg_syscalls.o
# do cc for shared library
DO_SOCC = $(CC) $(SOCFLAGS) -o $@ -c $<
build_so: DO_CC=$(DO_SOCC)
# cgame
cg_consolecmds.o : cg_consolecmds.c; $(DO_CC)
cg_draw.o : cg_draw.c; $(DO_CC)
cg_drawtools.o : cg_drawtools.c; $(DO_CC)
cg_effects.o : cg_effects.c; $(DO_CC)
cg_ents.o : cg_ents.c; $(DO_CC)
cg_env.o : cg_env.c; $(DO_CC)
cg_event.o : cg_event.c; $(DO_CC)
cg_info.o : cg_info.c; $(DO_CC)
cg_localents.o : cg_localents.c; $(DO_CC)
cg_main.o : cg_main.c; $(DO_CC)
cg_marks.o : cg_marks.c; $(DO_CC)
cg_players.o : cg_players.c; $(DO_CC)
cg_playerstate.o : cg_playerstate.c; $(DO_CC)
cg_predict.o : cg_predict.c; $(DO_CC)
cg_scoreboard.o : cg_scoreboard.c; $(DO_CC)
cg_screenfx.o : cg_screenfx.c; $(DO_CC)
cg_servercmds.o : cg_servercmds.c; $(DO_CC)
cg_snapshot.o : cg_snapshot.c; $(DO_CC)
cg_view.o : cg_view.c; $(DO_CC)
cg_weapons.o : cg_weapons.c; $(DO_CC)
fx_borg.o : fx_borg.c; $(DO_CC)
fx_compression.o : fx_compression.c; $(DO_CC)
fx_dreadnought.o : fx_dreadnought.c; $(DO_CC)
fx_grenade.o : fx_grenade.c; $(DO_CC)
fx_imod.o : fx_imod.c; $(DO_CC)
fx_item.o : fx_item.c; $(DO_CC)
fx_lib.o : fx_lib.c; $(DO_CC)
fx_misc.o : fx_misc.c; $(DO_CC)
fx_phaser.o : fx_phaser.c; $(DO_CC)
fx_quantum.o : fx_quantum.c; $(DO_CC)
fx_scavenger.o : fx_scavenger.c; $(DO_CC)
fx_stasis.o : fx_stasis.c; $(DO_CC)
fx_tetrion.o : fx_tetrion.c; $(DO_CC)
fx_transporter.o : fx_transporter.c; $(DO_CC)
# dependencies from game
q_shared.o: ../game/q_shared.c; $(DO_CC)
q_math.o: ../game/q_math.c; $(DO_CC)
bg_misc.o: ../game/bg_misc.c; $(DO_CC)
bg_pmove.o: ../game/bg_pmove.c; $(DO_CC)
bg_slidemove.o: ../game/bg_slidemove.c; $(DO_CC)
# cgame syscalls
cg_syscalls.o : cg_syscalls.c; $(DO_CC)
build_so: $(OBJDEP) $(OBJ) $(SOOBJ)
ifeq ($(PLATFORM), mingw32)
$(CC) -shared -Wl,--export-all-symbols,-soname,cgame$(ARCH).$(EXT) -o cgame$(ARCH).$(EXT) $(OBJ) $(OBJDEP) $(SOOBJ)
else
$(CC) -shared -Wl,--export-dynamic,-soname,cgame$(ARCH).$(EXT) -o cgame$(ARCH).$(EXT) $(OBJ) $(OBJDEP) $(SOOBJ)
endif
clean:
rm -f *.o *.$(EXT)

1798
cgame/cg_anims.h Normal file

File diff suppressed because it is too large Load diff

1065
cgame/cg_consolecmds.c Normal file

File diff suppressed because it is too large Load diff

5084
cgame/cg_draw.c Normal file

File diff suppressed because it is too large Load diff

1878
cgame/cg_drawtools.c Normal file

File diff suppressed because it is too large Load diff

609
cgame/cg_effects.c Normal file
View file

@ -0,0 +1,609 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_effects.c -- these functions generate localentities, usually as a result
// of event processing
#include "cg_local.h"
#include "fx_local.h"
/*
==================
CG_BubbleTrail
Bullets shot underwater
==================
*/
void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
vec3_t move;
vec3_t vec;
float len;
int i;
VectorCopy (start, move);
VectorSubtract (end, start, vec);
len = VectorNormalize (vec);
// advance a random amount first
i = rand() % (int)spacing;
VectorMA( move, i, vec, move );
VectorScale (vec, spacing, vec);
for ( ; i < len; i += spacing ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = LEF_PUFF_DONT_SCALE;
le->leType = LE_MOVE_SCALE_FADE;
le->startTime = cg.time;
le->endTime = cg.time + 1000 + random() * 250;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
re = &le->refEntity;
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
re->reType = RT_SPRITE;
re->data.sprite.rotation = 0;
re->data.sprite.radius = 3;
re->customShader = cgs.media.waterBubbleShader;
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
re->shaderRGBA[3] = 0xff;
le->color[3] = 1.0;
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
VectorCopy( move, le->pos.trBase );
le->pos.trDelta[0] = crandom()*5;
le->pos.trDelta[1] = crandom()*5;
le->pos.trDelta[2] = crandom()*5 + 6;
VectorAdd (move, vec, move);
}
}
/*
=====================
CG_SmokePuff
Adds a smoke puff or blood trail localEntity.
=====================
*/
localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
float radius,
float r, float g, float b, float a,
float duration,
int startTime,
int leFlags,
qhandle_t hShader ) {
static int seed = 0x92;
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = leFlags;
le->data.sprite.radius = radius;
re = &le->refEntity;
re->data.sprite.rotation = Q_random( &seed ) * 360;
re->data.sprite.radius = radius;
//re->shaderTime = startTime / 1000.0f;
re->shaderTime = startTime * 0.001f;
le->leType = LE_MOVE_SCALE_FADE;
le->startTime = startTime;
le->endTime = startTime + duration;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = r;
le->color[1] = g;
le->color[2] = b;
le->color[3] = a;
le->pos.trType = TR_LINEAR;
le->pos.trTime = startTime;
VectorCopy( vel, le->pos.trDelta );
VectorCopy( p, le->pos.trBase );
VectorCopy( p, re->origin );
re->customShader = hShader;
// rage pro can't alpha fade, so use a different shader
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
re->customShader = cgs.media.smokePuffRageProShader;
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
re->shaderRGBA[3] = 0xff;
} else {
re->shaderRGBA[0] = le->color[0] * 0xff;
re->shaderRGBA[1] = le->color[1] * 0xff;
re->shaderRGBA[2] = le->color[2] * 0xff;
re->shaderRGBA[3] = 0xff;
}
re->reType = RT_SPRITE;
re->data.sprite.radius = le->data.sprite.radius;
return le;
}
/*
==================
CG_SpawnEffect
Player teleporting in or out
RPG-X: RedTechie Added refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head
==================
*/
void CG_SpawnEffect( vec3_t org, refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head ) {
localEntity_t *le;
refEntity_t *re;
FX_Transporter(org);
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_FADE_RGB;
le->startTime = cg.time;
le->endTime = cg.time + 500;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
//RPG-X: RedTechie - Added for better trans effect - dosnt work right now
//ent_legs->shaderTime = cg.time / 1000.0f;
//ent_head->shaderTime = cg.time / 1000.0f;
//ent_torso->shaderTime = cg.time / 1000.0f;
//ent_legs->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_legs );
//ent_head->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_head );
//ent_torso->customShader = cgs.media.teleportEffectShader;
//trap_R_AddRefEntityToScene( ent_torso );
//RPG-X: RedTechie - Playing with transporter crap
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
re = &le->refEntity;
re->reType = RT_MODEL;
//re->shaderTime = cg.time / 1000.0f;
re->shaderTime = cg.time * 0.001f;
re->customShader = cgs.media.teleportEffectShader;
re->hModel = cgs.media.teleportEffectModel;
AxisClear( re->axis );
VectorCopy( org, re->origin );
re->origin[2] -= 24;
}
void CG_QFlashEvent( vec3_t org ) {
localEntity_t *le;
/*refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = LEF_SINE_SCALE;
le->leType = LE_PARTICLE;
le->startTime = cg.time;
le->endTime = cg.time + 600;
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0f;
le->data.particle.radius = 30;
le->data.particle.dradius = 5;
re = &le->refEntity;
re->customShader = cgs.media.qFlashSprite;
VectorCopy( org, re->origin );
VectorCopy( org, re->oldorigin );*/
le = FX_AddParticle( org, vec3_origin, qfalse, 110.0f, 109.0f,
1.0f, 1.0f, 0, 0,
290, cgs.media.qFlashSprite, 0 );
le->leFlags = LEF_SINE_SCALE | LEF_REVERSE_SCALE;
le->refEntity.renderfx |= RF_DEPTHHACK;
}
/*
====================
CG_MakeExplosion
====================
*/
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
qhandle_t hModel, qhandle_t shader,
int msec, float scale, qboolean isSprite ) {
float ang;
localEntity_t *ex;
int offset;
vec3_t tmpVec, newOrigin;
if ( msec <= 0 ) {
CG_Error( "CG_MakeExplosion: msec = %i", msec );
}
// skew the time a bit so they aren't all in sync
offset = rand() & 63;
ex = CG_AllocLocalEntity();
if ( isSprite ) {
ex->leType = LE_SPRITE_EXPLOSION;
// randomly rotate sprite orientation
ex->refEntity.data.sprite.rotation = rand() % 360;
VectorScale( dir, 16, tmpVec );
VectorAdd( tmpVec, origin, newOrigin );
} else {
ex->leType = LE_EXPLOSION;
VectorCopy( origin, newOrigin );
// set axis with random rotate
if ( !dir ) {
AxisClear( ex->refEntity.axis );
} else {
ang = rand() % 360;
VectorCopy( dir, ex->refEntity.axis[0] );
RotateAroundDirection( ex->refEntity.axis, ang );
}
}
ex->startTime = cg.time - offset;
ex->endTime = ex->startTime + msec;
// bias the time so all shader effects start correctly
//ex->refEntity.shaderTime = ex->startTime / 1000.0f;
ex->refEntity.shaderTime = ex->startTime * 0.001f;
ex->refEntity.hModel = hModel;
ex->refEntity.customShader = shader;
// set origin
VectorCopy( newOrigin, ex->refEntity.origin );
VectorCopy( newOrigin, ex->refEntity.oldorigin );
//Scale the explosion
if (scale != 1) {
ex->refEntity.nonNormalizedAxes = qtrue;
VectorScale( ex->refEntity.axis[0], scale, ex->refEntity.axis[0] );
VectorScale( ex->refEntity.axis[1], scale, ex->refEntity.axis[1] );
VectorScale( ex->refEntity.axis[2], scale, ex->refEntity.axis[2] );
}
ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
return ex;
}
localEntity_t *CG_MakeExplosion2( vec3_t origin, vec3_t dir,
qhandle_t hModel, int numFrames, qhandle_t shader,
int msec, qboolean isSprite, float scale, int flags) {
float ang;
localEntity_t *ex;
int offset;
vec3_t tmpVec, newOrigin;
if ( msec <= 0 ) {
CG_Error( "CG_MakeExplosion: msec = %i", msec );
}
// skew the time a bit so they aren't all in sync
offset = rand() & 63;
ex = CG_AllocLocalEntity();
if ( isSprite ) {
ex->leType = LE_SPRITE_EXPLOSION;
// randomly rotate sprite orientation
ex->refEntity.data.sprite.rotation = rand() % 360;
VectorScale( dir, 16, tmpVec );
VectorAdd( tmpVec, origin, newOrigin );
} else {
ex->leType = LE_EXPLOSION;
VectorCopy( origin, newOrigin );
// set axis with random rotate
if ( !dir ) {
AxisClear( ex->refEntity.axis );
} else {
ang = rand() % 360;
VectorCopy( dir, ex->refEntity.axis[0] );
RotateAroundDirection( ex->refEntity.axis, ang );
}
}
ex->startTime = cg.time - offset;
ex->endTime = ex->startTime + msec;
// bias the time so all shader effects start correctly
//ex->refEntity.shaderTime = ex->startTime / 1000.0f;
ex->refEntity.shaderTime = ex->startTime * 0.001f;
ex->refEntity.hModel = hModel;
ex->refEntity.customShader = shader;
ex->lifeRate = (float)numFrames / msec;
ex->leFlags = flags;
//Scale the explosion
if (scale != 1) {
ex->refEntity.nonNormalizedAxes = qtrue;
VectorScale( ex->refEntity.axis[0], scale, ex->refEntity.axis[0] );
VectorScale( ex->refEntity.axis[1], scale, ex->refEntity.axis[1] );
VectorScale( ex->refEntity.axis[2], scale, ex->refEntity.axis[2] );
}
// set origin
VectorCopy( newOrigin, ex->refEntity.origin );
VectorCopy( newOrigin, ex->refEntity.oldorigin );
ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
return ex;
}
/*
=================
CG_Bleed
This is the spurt of blood when a character gets hit
=================
*/
/*void CG_Bleed( vec3_t origin, int entityNum ) {
localEntity_t *ex;
if ( !cg_blood.integer ) {
return;
}
ex = CG_AllocLocalEntity();
ex->leType = LE_EXPLOSION;
ex->startTime = cg.time;
ex->endTime = ex->startTime + 500;
VectorCopy ( origin, ex->refEntity.origin);
ex->refEntity.reType = RT_SPRITE;
ex->refEntity.data.sprite.rotation = rand() % 360;
ex->refEntity.data.sprite.radius = 16;
ex->refEntity.customShader = cgs.media.bloodExplosionShader;
// don't show player's own blood in view
if ( entityNum == cg.snap->ps.clientNum ) {
ex->refEntity.renderfx |= RF_THIRD_PERSON;
}
}*/
/*
-------------------------
CG_ExplosionEffects
Used to find the player and shake the camera if close enough
intensity ranges from 1 (minor tremble) to 16 (major quake)
-------------------------
*/
void CG_ExplosionEffects( vec3_t origin, int intensity, int radius)
{
//FIXME: When exactly is the vieworg calculated in relation to the rest of the frame?s
vec3_t dir;
float dist, intensityScale;
float realIntensity;
VectorSubtract( cg.refdef.vieworg, origin, dir );
dist = VectorNormalize( dir );
//Use the dir to add kick to the explosion
if ( dist > radius )
return;
intensityScale = 1 - ( dist / (float) radius );
realIntensity = intensity * intensityScale;
CG_CameraShake( realIntensity, 500, qfalse );
}
/*
=================
CG_Seeker
=================
*/
/*void CG_Seeker( centity_t *cent )
{
refEntity_t re;
vec3_t seekerOrg, viewAng;
float angle;
angle = cg.time/100.0f;
seekerOrg[0] = cent->lerpOrigin[0] + 18 * cos(angle);
seekerOrg[1] = cent->lerpOrigin[1] + 18 * sin(angle);
seekerOrg[2] = cent->lerpOrigin[2] + cg.predictedPlayerState.viewheight + 8 + (3*cos(cg.time/150.0f));
memset( &re, 0, sizeof( re ) );
re.reType = RT_MODEL;
VectorCopy ( seekerOrg, re.origin);
re.hModel = cgs.media.seekerModel;
re.shaderTime = (cg.time / 1000.0f);
VectorCopy (cent->lerpAngles , viewAng); // so the seeker faces the same direction the player is
viewAng[0] = -90; // but, we don't want the seeker facing up or down, always horizontal
AnglesToAxis( viewAng, re.axis );
VectorScale(re.axis[0], 0.5, re.axis[0]);
VectorScale(re.axis[1], 0.5, re.axis[1]);
VectorScale(re.axis[2], 0.5, re.axis[2]);
re.nonNormalizedAxes=qtrue;
trap_R_AddRefEntityToScene( &re );
}*/
/*
-------------------------
CG_Smoke
TiM: Ported from EF SP
-------------------------
*/
//void CG_Smoke( vec3_t origin, vec3_t dir, float radius, float speed, qhandle_t shader )
//{
// vec3_t velocity/*, accel*/;
// int i;
// for ( i = 0; i < 3; i++ )
// {
// velocity[i] = dir[i] + ( 0.2f * crandom());
// }
// VectorScale( velocity, speed, velocity );
//VectorScale( velocity, -0.25f, accel );
//accel[2] = random() * 12.0f + 6.0f;
// FX_AddSprite( origin,
// velocity,
// qfalse, //accel
// radius + (crandom() * radius * 0.5f ),
// radius + (crandom() * radius),
// 0.9f + crandom(),
// 0.0f,
// 16.0f + random() * 45.0f,
// 0.5f,
// 2000,
// shader ); //flags
//}
qboolean SmokeThink( localEntity_t *le )
{
vec3_t velocity/*, accel*/;
vec3_t origin;
vec3_t dir;
float speed;
int i;
VectorCopy( le->data.spawner.dir, dir );
//clamp the smoke vector
//Smoke should always go up
dir[2] = Com_Clamp( 0.85f, 1.0f, dir[2] );
for ( i = 0; i < 3; i++ )
{
velocity[i] = dir[i] + ( 0.2f * crandom());
}
VectorMA( le->refEntity.origin, 1, le->data.spawner.dir, origin);
//slow down the smoke the smaller it gets
//else it scatters too much
speed = le->data.spawner.data1 * 2.4;
VectorScale( velocity, speed, velocity ); //speed
//VectorScale( velocity, -0.25f, accel );
//accel[2] = random() * 12.0f + 6.0f;
FX_AddSprite( origin,
velocity,
qfalse, //accel
le->data.spawner.data1 + (crandom() * le->data.spawner.data1 * 0.5f ),
le->data.spawner.data1 + (crandom() * le->data.spawner.data1),
0.8 /*+ crandom()*/,
0.0,
16.0f + random() * 45.0f,
0.5f,
7000,
cgs.media.smokeShader ); //flags
return qtrue;
}
/*
======================
CG_Smoke
Creates a smoke effect
======================
*/
void CG_Smoke( vec3_t position, vec3_t dir, int killTime, int radius )
{
//CG_Printf( " %f %f %f\n", dir[0], dir[1], dir[2] );
// give it a lifetime of 10 seconds because the refresh thinktime in g_fx.c is 10 seconds
FX_AddSpawner( position, dir, NULL, NULL, qfalse, 0, 0.15, killTime, SmokeThink, radius ); //
}
/*
======================
FireThink
Engage fire effect
RPG-X | Marcin | 24/12/2008
======================
*/
qboolean FireThink( localEntity_t *le )
{
vec3_t direction;
vec3_t origin;
VectorCopy( le->data.spawner.dir, direction );
VectorMA( le->refEntity.origin, 1, direction, origin );
origin[2] += 60.0f / (80.0f / le->data.spawner.data1); // extra offset
FX_AddSprite( origin,
0,
qfalse,
le->data.spawner.data1,
0,
1.0f,
0.0f,
0,
0.5f,
600,
cgs.media.fireShader );
return qtrue;
}
/*
======================
CG_Fire
Creates a fire effect
RPG-X | Marcin | 24/12/2008
======================
*/
void CG_Fire( vec3_t position, vec3_t direction, int killTime, int radius, int fxEnt )
{
if(fxEnt)
FX_AddSpawner( position, direction, NULL, NULL, qfalse, 500, 0, killTime + 1000, FireThink, radius );
else
FX_AddSpawner( position, direction, NULL, NULL, qfalse, 500, 0, killTime, FireThink, radius );
}
//localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
// float startalpha, float endalpha, float roll, float elasticity,
// float killTime, qhandle_t shader)

1192
cgame/cg_ents.c Normal file

File diff suppressed because it is too large Load diff

1178
cgame/cg_env.c Normal file

File diff suppressed because it is too large Load diff

1792
cgame/cg_event.c Normal file

File diff suppressed because it is too large Load diff

871
cgame/cg_info.c Normal file
View file

@ -0,0 +1,871 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_info.c -- display information while data is being loading
#include "cg_local.h"
#include "cg_text.h"
#define MAX_LOADING_PLAYER_ICONS 16
#define MAX_LOADING_ITEM_ICONS 26
static qhandle_t loadingPlayerIcon;
static qhandle_t loadingItemIcon;
void CG_LoadBar(void);
/*
===================
CG_DrawLoadingIcons
===================
*/
static void CG_DrawLoadingIcons( void ) {
// int n;
int x, y;
trap_R_SetColor( colorTable[CT_WHITE]);
x= 500;
y = 342;
if (loadingPlayerIcon)
{
CG_DrawPic( x, y, 64, 64, loadingPlayerIcon );
}
else if (loadingItemIcon)
{
trap_R_SetColor(colorTable[CT_LTPURPLE1]);
CG_DrawPic( x, y, 64, 64, cgs.media.weaponbox2 );
trap_R_SetColor( NULL);
CG_DrawPic( x, y, 64, 64, loadingItemIcon );
}
}
/*
======================
CG_LoadingString
======================
*/
void CG_LoadingString( const char *s ) {
Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) );
trap_UpdateScreen();
}
/*
===================
CG_LoadingItem
===================
*/
void CG_LoadingItem( int itemNum ) {
gitem_t *item;
item = &bg_itemlist[itemNum];
if ( item->icon ) {
loadingItemIcon = trap_R_RegisterShaderNoMip( item->icon );
}
CG_LoadingString( item->pickup_name );
}
/*
===================
CG_LoadingClient
===================
*/
void CG_LoadingClient( int clientNum ) {
const char *info;
char *skin;
char personality[MAX_QPATH];
char model[MAX_QPATH];
char iconName[MAX_QPATH];
info = CG_ConfigString( CS_PLAYERS + clientNum );
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = strchr( model, '/' );
if ( skin ) {
//*skin++ = '\0';
//} else {
// skin = "default";
model[strlen(model) - strlen(skin)] = '\0';
}
//RPG-X: MODEL SYSTEM CHANGE
Com_sprintf( iconName, MAX_QPATH, "models/players_rpgx/%s/model_icon.jpg", model );
//Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.jpg", model, skin );
//CG_Printf( S_COLOR_RED "Loading %s\n", iconName );
loadingPlayerIcon = trap_R_RegisterShaderNoMip( iconName ); //iconName;
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
Q_CleanStr( personality );
if( cgs.gametype == GT_SINGLE_PLAYER ) {
trap_S_RegisterSound( va( "sound/voice/computer/misc/%s.wav", model ) ); //not exactly right since it'll miss subskins, but better than using personality
}//precache sound played in g_bot.c, PlayerIntroSound
CG_LoadingString( personality );
}
/*
====================
CG_DrawInformation
Draw all the status / pacifier stuff during level loading
this overlays the ui version in ui_connect.c, UI_DrawConnectScreen
====================
*/
extern void CG_AddGameModNameToGameName( char *gamename );
void CG_DrawInformation( void ) {
const char *s;
const char *info;
const char *sysInfo;
int y,x;
// int value;
qhandle_t levelshot;
// qhandle_t detail;
char buf[1024];
int strlength,length;
//trap_Cvar_Set ("rpg_playIntro", "1");
info = CG_ConfigString( CS_SERVERINFO );
sysInfo = CG_ConfigString( CS_SYSTEMINFO );
s = Info_ValueForKey( info, "mapname" );
levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
if ( !levelshot ) {
levelshot = trap_R_RegisterShaderNoMip( "levelshots/unknownmap" );
}
cgs.widescreen.state = WIDESCREEN_NONE;
trap_R_SetColor( colorTable[CT_BLACK] );
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, cgs.media.whiteShader );
cgs.widescreen.state = WIDESCREEN_CENTER;
trap_R_SetColor( colorTable[CT_DKGREY] );
CG_DrawPic( 11, 60, 260, 196, cgs.media.whiteShader );
trap_R_SetColor( NULL );
CG_DrawPic( 13, 62, 256, 192, levelshot ); //correct aspect
// trap_R_SetColor( colorTable[CT_LTGREY] );
// CG_DrawPic( 418, 82, 132, 132, cgs.media.whiteShader );
// trap_R_SetColor( NULL );
// CG_DrawPic( 420, 84, 128, 128, levelshot );
// blend a detail texture over it
// detail = trap_R_RegisterShader( "levelShotDetail" );
// trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 1, 1, detail );
UI_DrawProportionalString( 10, 10, ingame_text[IGT_HOLODECKSIMULATION], UI_BIGFONT, colorTable[CT_LTORANGE] );
strlength = UI_ProportionalStringWidth(ingame_text[IGT_HOLODECKSIMULATION],UI_BIGFONT);
length = 582 - (strlength + 6);
trap_R_SetColor( colorTable[CT_DKORANGE]);
CG_DrawPic( 10 + strlength + 6, 11, length, 22,cgs.media.whiteShader);
// CG_DrawPic( 224, 11, 368, 22,cgs.media.whiteShader);
CG_DrawPic( 595, 11, 32, 32,cgs.media.halfroundr_22); // Right End
trap_R_SetColor( colorTable[CT_DKPURPLE1]);
CG_DrawPic( 274+333, 232, -32, 32,cgs.media.corner_12_18); // LR
CG_DrawPic( 274+333, 84, -32, -32,cgs.media.corner_12_18); // UR
CG_DrawPic( 274, 60, 314, 18,cgs.media.whiteShader); // Top
CG_DrawPic( 274, 238, 314, 18,cgs.media.whiteShader); //Bottom
CG_DrawPic( 274, 75, 10, 170,cgs.media.whiteShader); // Left
CG_DrawPic( 274+321, 78, 12, 162,cgs.media.whiteShader); // Right
CG_LoadBar();
// draw the icons of thiings as they are loaded
CG_DrawLoadingIcons();
// the first 150 rows are reserved for the client connection
// screen to write into
if ( cg.infoScreenText[0] ) {
UI_DrawProportionalString( 320, 442, va("%s ... %s", ingame_text[IGT_LOADING], cg.infoScreenText),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_LTGOLD1]);
} else {
UI_DrawProportionalString( 320, 442, va("%s...", ingame_text[IGT_SNAPSHOT]),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_LTGOLD1] );
}
// draw info string information
y = 107;
x = 288;
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
if ( !atoi( buf ) ) {
// server hostname
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf);
UI_DrawProportionalString( x, y, buf, UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
// pure server
s = Info_ValueForKey( sysInfo, "sv_pure" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( x, y, ingame_text[IGT_PURESERVER],
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// server-specific message of the day
s = CG_ConfigString( CS_MOTD );
if ( s[0] ) {
UI_DrawProportionalString(320, y, s,
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// some extra space after hostname and motd
y += 10;
}
// map-specific message (long map name)
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
UI_DrawProportionalString( x, y, s,
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// cheats warning
s = Info_ValueForKey( sysInfo, "sv_cheats" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( x, y, ingame_text[IGT_CHEATSAREENABLED],
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// RPG-X | Marcin | 24/12/2008
// privacy thing :p
// translate later
s = Info_ValueForKey( info, "rpg_respectPrivacy" );
if ( atoi( s ) != 0 ) {
UI_DrawProportionalString( x, y, "PRIVACY MODE ^5ON",
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
} else {
UI_DrawProportionalString( x, y, "PRIVACY MODE ^1OFF",
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
// game type
switch ( cgs.gametype )
{
case GT_FFA:
s = ingame_text[IGT_GAME_FREEFORALL];
break;
case GT_SINGLE_PLAYER:
s = ingame_text[IGT_GAME_SINGLEPLAYER];
break;
case GT_TOURNAMENT:
s = ingame_text[IGT_GAME_TOURNAMENT];
break;
case GT_TEAM:
s = ingame_text[IGT_GAME_TEAMHOLOMATCH];
break;
case GT_CTF:
s = ingame_text[IGT_GAME_CAPTUREFLAG];
break;
default:
s = ingame_text[IGT_GAME_UNKNOWN];
break;
}
{
char gamename[1024];
Q_strncpyz( gamename, s, sizeof(gamename) );
CG_AddGameModNameToGameName( gamename );
UI_DrawProportionalString( x, y, gamename, UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
}
y += PROP_HEIGHT;
/* value = atoi( Info_ValueForKey( info, "timelimit" ) );
if ( value ) {
UI_DrawProportionalString( x, y, va( "%s %i",ingame_text[IGT_TIME_LIMIT], value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
if (cgs.gametype != GT_CTF) {
value = atoi( Info_ValueForKey( info, "fraglimit" ) );
if ( value ) {
UI_DrawProportionalString( x, y, va( "%s %i", ingame_text[IGT_POINT_LIMIT],value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
}
if (cgs.gametype == GT_CTF) {
value = atoi( Info_ValueForKey( info, "capturelimit" ) );
if ( value ) {
UI_DrawProportionalString( x, y, va( "%s %i",ingame_text[IGT_CAPTURE_LIMIT], value ),
UI_SMALLFONT|UI_DROPSHADOW, colorTable[CT_VLTGOLD1] );
y += PROP_HEIGHT;
}
}*/
cgs.widescreen.state = WIDESCREEN_NONE;
}
/*
====================
CG_LoadBar
====================
*/
void CG_LoadBar(void)
{
int x,y,pad;
// Round LCARS buttons
y = 309;
x = 10;
pad = 22;
// First Bit (0987)
if (cg.loadLCARSStage < 1)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //PURPLE3]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14, ingame_text[IGT_REPLICATION_MATRIX],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //VLTPURPLE3]);
}
CG_DrawPic( x + 18, y +102, 128, 64,cgs.media.loading1);
if (cg.loadLCARSStage < 2)
{
trap_R_SetColor( colorTable[CT_VDKBLUE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBLUE1]);
}
CG_DrawPic( x, y + 37, 64, 64,cgs.media.loading2);
if (cg.loadLCARSStage < 3)
{
trap_R_SetColor( colorTable[CT_DKGOLD1]); //VDKPURPLE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad, ingame_text[IGT_HOLOGRAPHIC_PROJECTORS],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTGOLD1]); //LTPURPLE1]);
}
CG_DrawPic( x + 17, y, 128, 64,cgs.media.loading3);
if (cg.loadLCARSStage < 4)
{
trap_R_SetColor( colorTable[CT_VDKBLUE1]); //VDKPURPLE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBLUE1]); //PURPLE2]);
}
CG_DrawPic( x + 99, y, 128, 128,cgs.media.loading4);
if (cg.loadLCARSStage < 5)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //BLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad + pad, ingame_text[IGT_SIMULATION_DATA_BASE],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //VLTBLUE2]);
}
CG_DrawPic( x +137, y + 81, 64, 64,cgs.media.loading5);
if (cg.loadLCARSStage < 6)
{
trap_R_SetColor( colorTable[CT_VDKRED1]); //ORANGE]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_DKRED1]); //LTORANGE]);
}
CG_DrawPic( x + 45, y + 99, 128, 64,cgs.media.loading6);
if (cg.loadLCARSStage < 7)
{
trap_R_SetColor( colorTable[CT_VDKRED1]); //BLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad+pad, 16, 16,cgs.media.circle2);
UI_DrawProportionalString( x + 222, y + 14 + pad + pad + pad, ingame_text[IGT_SAFETY_LOCKS],UI_SMALLFONT, colorTable[CT_VLTGOLD1]);
trap_R_SetColor( colorTable[CT_DKRED1]); //LTBLUE2]);
}
CG_DrawPic( x + 38, y + 24, 64, 128,cgs.media.loading7);
if (cg.loadLCARSStage < 8)
{
trap_R_SetColor( colorTable[CT_VDKBROWN1]); //PURPLE1]);
}
else
{
trap_R_SetColor( colorTable[CT_VLTGOLD1]);
CG_DrawPic( x + 222 - 20,y + 14+pad+pad+pad, 16, 16,cgs.media.circle);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //PURPLE1]);
}
CG_DrawPic( x + 78, y + 20, 128, 64,cgs.media.loading8);
if (cg.loadLCARSStage < 9)
{
trap_R_SetColor( colorTable[CT_VDKBLUE2]); //VDKBROWN1]);
}
else
{
trap_R_SetColor( colorTable[CT_DKBLUE2]); //VLTBROWN1]);
}
CG_DrawPic( x +112, y + 66, 64, 128,cgs.media.loading9);
if (cg.loadLCARSStage < 9)
{
trap_R_SetColor( colorTable[CT_VDKORANGE]); //DKBLUE2]);
}
else
{
trap_R_SetColor( colorTable[CT_LTORANGE]); //LTBLUE2]);
}
CG_DrawPic( x + 62, y + 44, 128, 128,cgs.media.loadingcircle); // Center arrows
cg.loadLCARScnt++;
if (cg.loadLCARScnt > 3)
{
cg.loadLCARScnt = 0;
}
trap_R_SetColor( colorTable[CT_VDKBLUE1]); //DKPURPLE2]);
CG_DrawPic( x + 61, y + 43, 32, 32,cgs.media.loadingquarter); // Quad UL
CG_DrawPic( x + 135, y + 43, -32, 32,cgs.media.loadingquarter); // Quad UR
CG_DrawPic( x + 135, y +117, -32, -32,cgs.media.loadingquarter); // Quad LR
CG_DrawPic( x + 61, y +117, 32, -32,cgs.media.loadingquarter); // Quad LL
trap_R_SetColor( colorTable[CT_LTBLUE1]); //LTPURPLE2]);
switch (cg.loadLCARScnt)
{
case 0 :
CG_DrawPic( x + 61, y + 43, 32, 32,cgs.media.loadingquarter); // Quad UL
break;
case 1 :
CG_DrawPic( x + 135, y + 43, -32, 32,cgs.media.loadingquarter); // Quad UR
break;
case 2 :
CG_DrawPic( x + 135, y +117, -32, -32,cgs.media.loadingquarter); // Quad LR
break;
case 3 :
CG_DrawPic( x + 61, y +117, 32, -32,cgs.media.loadingquarter); // Quad LL
break;
}
UI_DrawProportionalString( x + 21, y + 150, "0987",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 3, y + 90, "18",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 24, y + 20, "7",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 93, y + 5, "51",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 103, y + 5, "35",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 165, y + 83, "21",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 101, y + 149, "67",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 123, y + 36, "8",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 90, y + 65, "1",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 105, y + 65, "2",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 105, y + 87, "3",UI_TINYFONT, colorTable[CT_BLACK]);
UI_DrawProportionalString( x + 91, y + 87, "4",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
trap_R_SetColor( colorTable[CT_DKGOLD1]); //DKBROWN1]);
y +=10;
CG_DrawPic( x + 130, y - 10 , 64, 16,cgs.media.loadingtrim);
CG_DrawPic( x + 130, y + 150, 64, -16,cgs.media.loadingtrim);
CG_DrawPic( x + 150, y - 10, 432, 8, cgs.media.whiteShader); // Top line
CG_DrawPic( x + 150, y + 142, 432, 8, cgs.media.whiteShader); // Bottom line
CG_DrawPic( x + 583, y - 7, 16, 151, cgs.media.whiteShader); // Side line
CG_DrawPic( x + 580, y + 1, 32, -16,cgs.media.loadingcorner);
CG_DrawPic( x + 580, y + 139, 32, 16,cgs.media.loadingcorner);
}
static int missionYcnt;
static int missionYpos;
static int missionInfoScreenY;
#define OBJ_HORIZONTAL_BORDER_X 15 // Where graphic starts
#define OBJ_HORIZONTAL_BORDER_WIDTH 30 // Thickness of graphic
#define OBJ_TEXT_X_BORDER_LEFT 10 // Distance from right edge of graphic to circle graphic
#define OBJ_TEXT_X_BORDER_RIGHT 10 // Distance from right edge of text to right edge of screen
#define OBJ_CIRCLE_SIZE 16 // Size of circle graphic
#define OBJ_CIRCLE_TEXT_MARGIN 4 // Distance between circle and text
#define OBJ_TEXT_XPOS (OBJ_HORIZONTAL_BORDER_X + OBJ_HORIZONTAL_BORDER_WIDTH + OBJ_TEXT_X_BORDER_LEFT)
#define OBJ_SCREEN_HEIGHT 428
#define OBJ_SCREEN_YMARGIN 8
#define OBJ_SCREEN_Y2MARGIN 4
#define OBJ_SCREEN_YBORDERTOP 20
#define OBJ_SCREEN_YBORDERBOT 8
#define OBJ_NORMAL_LINE_HEIGHT (PROP_HEIGHT * 1.15)
#define OBJ_ADDITIONAL_LINE_HEIGHT .20
/*
====================
ObjectivePrint_Line
====================
*/
static void ObjectivePrint_Line(int strIndex,int color,centity_t *cent)
{
char *str,*strBegin;
int y,pixelLen,charLen;
char holdText[1024], holdText2[2];
char finalText[MAX_OBJ_LENGTH];
int len,len_s,maxPixLength,charHeight;
#ifndef Q3_VM
assert(cgs.objectives[strIndex].text);
#endif
str = cgs.objectives[strIndex].text;
len = strlen(str);
len++;
Q_strncpyz(finalText,str,len);
len_s = strlen(str);
pixelLen = UI_ProportionalStringWidth(finalText,UI_SMALLFONT);
str = finalText;
maxPixLength = SCREEN_WIDTH - (OBJ_TEXT_XPOS + OBJ_TEXT_X_BORDER_RIGHT + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN);
charHeight = OBJ_NORMAL_LINE_HEIGHT;
if (missionYcnt) // Not the very first objective to be printed?
{
missionYpos += (PROP_HEIGHT * OBJ_ADDITIONAL_LINE_HEIGHT); // Add a little space between objective lines
}
y =missionYpos + (charHeight * (missionYcnt));
trap_R_SetColor( colorTable[color]);
if (cgs.objectives[strIndex].complete)
{
CG_DrawPic( OBJ_TEXT_XPOS,y, OBJ_CIRCLE_SIZE, OBJ_CIRCLE_SIZE,cgs.media.circle);
}
else
{
CG_DrawPic( OBJ_TEXT_XPOS,y, OBJ_CIRCLE_SIZE, OBJ_CIRCLE_SIZE,cgs.media.circle2);
}
if (pixelLen < maxPixLength) // One shot - small enough to print entirely on one line
{
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y,str, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
}
// Text is too long, break into lines.
else
{
pixelLen = 0;
charLen = 0;
holdText2[1] = '\0';
strBegin = str;
while( *str )
{
holdText2[0] = *str;
pixelLen += UI_ProportionalStringWidth(holdText2,UI_SMALLFONT);
pixelLen += 2; // For kerning
++charLen;
if (pixelLen > maxPixLength )
{ //Reached max length of this line
//step back until we find a space
while ((charLen) && (*str != ' ' ))
{
--str;
--charLen;
}
if (*str==' ')
{
++str; // To get past space
}
Q_strncpyz( holdText, strBegin, charLen);
holdText[charLen] = '\0';
strBegin = str;
pixelLen = 0;
charLen = 1;
y = missionYpos + (charHeight * missionYcnt);
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y, holdText, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
}
else if (*(str+1) == '\0')
{
++charLen;
y = missionYpos + (charHeight * missionYcnt);
Q_strncpyz( holdText, strBegin, charLen);
UI_DrawProportionalString(OBJ_TEXT_XPOS + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN, y, holdText, UI_SMALLFONT, colorTable[color] );
++missionYcnt;
break;
}
++str;
}
}
}
static int Objective_LineCnt(int strIndex,centity_t *cent)
{
char *str,*strBegin;
int pixelLen,charLen;
char holdText[1024], holdText2[2];
char finalText[MAX_OBJ_LENGTH];
int len,len_s,maxPixLength;
int lineCnt;
#ifndef Q3_VM
assert(cgs.objectives[strIndex].text);
#endif
str = cgs.objectives[strIndex].text;
len = strlen(str);
len++;
Q_strncpyz(finalText,str,len);
len_s = strlen(str);
pixelLen = UI_ProportionalStringWidth(finalText,UI_SMALLFONT);
lineCnt = 0;
maxPixLength = SCREEN_WIDTH - (OBJ_TEXT_XPOS + OBJ_TEXT_X_BORDER_RIGHT + OBJ_CIRCLE_SIZE + OBJ_CIRCLE_TEXT_MARGIN);
str = finalText;
if (pixelLen < maxPixLength) // One shot - small enough to print entirely on one line
{
lineCnt = 1;
}
// Text is too long, break into lines.
else
{
pixelLen = 0;
charLen = 0;
holdText2[1] = '\0';
strBegin = str;
while( *str )
{
holdText2[0] = *str;
pixelLen += UI_ProportionalStringWidth(holdText2,UI_SMALLFONT);
pixelLen += 2; // For kerning
++charLen;
if (pixelLen > maxPixLength )
{ //Reached max length of this line
//step back until we find a space
while ((charLen) && (*str != ' ' ))
{
--str;
--charLen;
}
if (*str==' ')
{
++str; // To get past space
}
Q_strncpyz( holdText, strBegin, charLen);
holdText[charLen] = '\0';
strBegin = str;
pixelLen = 0;
charLen = 1;
lineCnt++;
}
else if (*(str+1) == '\0')
{
++charLen;
lineCnt++;
break;
}
++str;
}
}
return (lineCnt);
}
/*
====================
Objectives_Draw
====================
*/
static void Objectives_Draw( centity_t *cent )
{
int objCnt,i,lineCnt,maxLines;
int total,textYCnt,length,color;
vec4_t newColor;
objCnt=0;
for (i=0;i<MAX_OBJECTIVES;i++)
{
if (cgs.objectives[i].text[0])
{
objCnt++;
}
}
lineCnt = 0;
// Count the number of lines.
for (i=0;i<objCnt;i++)
{
if (cgs.objectives[i].text[0])
{
lineCnt += Objective_LineCnt(i,cent);
}
}
maxLines = OBJ_SCREEN_HEIGHT /OBJ_NORMAL_LINE_HEIGHT;
if (lineCnt > maxLines) // Too many lines?
{
lineCnt = maxLines;
}
if (lineCnt==0) // Show there are no objectives
{
Q_strncpyz(cgs.objectives[0].text,ingame_text[IGT_NONETEXT],sizeof(cgs.objectives[0].text));
}
textYCnt = lineCnt * OBJ_NORMAL_LINE_HEIGHT;
// For the space between objectives
textYCnt += (objCnt-1) * (OBJ_ADDITIONAL_LINE_HEIGHT * PROP_HEIGHT);
// Calc starting Y of text
total = OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YMARGIN + OBJ_SCREEN_Y2MARGIN + OBJ_SCREEN_Y2MARGIN +
OBJ_SCREEN_YBORDERTOP + OBJ_SCREEN_YBORDERBOT + textYCnt;
if (OBJ_SCREEN_HEIGHT < total) // This should never happen (but just in case)
{
total = OBJ_SCREEN_HEIGHT;
}
missionInfoScreenY = ((OBJ_SCREEN_HEIGHT - total) /2) + (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP);
missionYcnt = 0;
missionYpos = missionInfoScreenY;
// Print top of frame
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X + 10, missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP) ,
SCREEN_WIDTH - (OBJ_HORIZONTAL_BORDER_X + OBJ_TEXT_X_BORDER_RIGHT + 10), OBJ_SCREEN_YBORDERTOP, cgs.media.whiteShader); // Middle column
// Print bottom of frame
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X + 10, missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN),
SCREEN_WIDTH - (OBJ_HORIZONTAL_BORDER_X + OBJ_TEXT_X_BORDER_RIGHT + 10), OBJ_SCREEN_YBORDERBOT, cgs.media.whiteShader); // Middle column
length = (missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN)) - (missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP)) - 15;
// Print left hand column of frame
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X, (missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP)) + 10,
OBJ_HORIZONTAL_BORDER_WIDTH, length, cgs.media.whiteShader); // Middle column
// Top corner
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X,
missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP),
32, 32, cgs.media.corner_ul_20_30); // Top corner
// Bottom corner
CG_DrawPic( OBJ_HORIZONTAL_BORDER_X,
(missionInfoScreenY - OBJ_SCREEN_YMARGIN + textYCnt + (2 * OBJ_SCREEN_YMARGIN))-5,
32, 32, cgs.media.corner_ll_8_30); // Bottom corner
UI_DrawProportionalString( OBJ_HORIZONTAL_BORDER_X + 30, missionInfoScreenY - (OBJ_SCREEN_YMARGIN + OBJ_SCREEN_YBORDERTOP) + 2, ingame_text[IGT_OBJECTIVES],UI_SMALLFONT, colorTable[CT_BLACK]);
// Print the background
newColor[0] = colorTable[CT_BLACK][0];
newColor[1] = colorTable[CT_BLACK][1];
newColor[2] = colorTable[CT_BLACK][2];
newColor[3] = 0.5;
trap_R_SetColor(newColor);
CG_DrawPic( (OBJ_TEXT_XPOS - OBJ_TEXT_X_BORDER_LEFT), missionInfoScreenY - OBJ_SCREEN_YMARGIN, SCREEN_WIDTH - ((OBJ_TEXT_XPOS - OBJ_TEXT_X_BORDER_LEFT)+OBJ_TEXT_X_BORDER_RIGHT) , textYCnt + (2 * OBJ_SCREEN_YMARGIN), cgs.media.whiteShader);
// Print the lines
for (i=0;i<objCnt;i++)
{
if (cgs.objectives[i].text[0])
{
if (cgs.objectives[i].complete)
{
color = CT_DKGOLD1;
}
else
{
color = CT_VLTGOLD1;
}
ObjectivePrint_Line(i,color,cent);
}
}
}
/*
====================
CG_DrawObjectiveInformation
====================
*/
void CG_DrawObjectiveInformation( void )
{
centity_t *cent;
// Don't show if dead
if (cg.predictedPlayerState.pm_type == PM_DEAD)
{
return;
}
cent = &cg_entities[cg.snap->ps.clientNum];
Objectives_Draw(cent);
}

25
cgame/cg_lensflares.c Normal file
View file

@ -0,0 +1,25 @@
/***************************************************
Copyright TiM - UberGames, 2005
cg_lensflares.c - Stores all of the functions
required to draw a dynamic lensflare ingame
The flare is broken up and drawn in separate passes:
Ambient Glow - Colored hazy glow (controlled by a vec4_t)
that expands around the core
Direct Glow - Much stronger glow that surrounds the
core directly
White Core - The actual white, focussed part of the flare
Anamorphic Streak - Horizontal line running through
the flare (Current rage in lensflare FX)
Lens Reflections - Circular parts that go in the opposite dir
of the flare itself
***************************************************/
//#include "cg_local.h"
//#include "cg_text.h"

2480
cgame/cg_local.h Normal file

File diff suppressed because it is too large Load diff

1309
cgame/cg_localents.c Normal file

File diff suppressed because it is too large Load diff

2333
cgame/cg_main.c Normal file

File diff suppressed because it is too large Load diff

1792
cgame/cg_main.c.orig Normal file

File diff suppressed because it is too large Load diff

277
cgame/cg_marks.c Normal file
View file

@ -0,0 +1,277 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_marks.c -- wall marks
#include "cg_local.h"
/*
===================================================================
MARK POLYS
===================================================================
*/
markPoly_t cg_activeMarkPolys; // double linked list
markPoly_t *cg_freeMarkPolys; // single linked list
markPoly_t cg_markPolys[MAX_MARK_POLYS];
/*
===================
CG_InitMarkPolys
This is called at startup and for tournement restarts
===================
*/
void CG_InitMarkPolys( void ) {
int i;
memset( cg_markPolys, 0, sizeof(cg_markPolys) );
cg_activeMarkPolys.nextMark = &cg_activeMarkPolys;
cg_activeMarkPolys.prevMark = &cg_activeMarkPolys;
cg_freeMarkPolys = cg_markPolys;
for ( i = 0 ; i < MAX_MARK_POLYS - 1 ; i++ ) {
cg_markPolys[i].nextMark = &cg_markPolys[i+1];
}
}
/*
==================
CG_FreeMarkPoly
==================
*/
void CG_FreeMarkPoly( markPoly_t *le ) {
if ( !le->prevMark ) {
CG_Error( "CG_FreeLocalEntity: not active" );
}
// remove from the doubly linked active list
le->prevMark->nextMark = le->nextMark;
le->nextMark->prevMark = le->prevMark;
// the free list is only singly linked
le->nextMark = cg_freeMarkPolys;
cg_freeMarkPolys = le;
}
/*
===================
CG_AllocMark
Will allways succeed, even if it requires freeing an old active mark
===================
*/
markPoly_t *CG_AllocMark( void ) {
markPoly_t *le;
int time;
if ( !cg_freeMarkPolys ) {
// no free entities, so free the one at the end of the chain
// remove the oldest active entity
time = cg_activeMarkPolys.prevMark->time;
while (cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time) {
CG_FreeMarkPoly( cg_activeMarkPolys.prevMark );
}
}
le = cg_freeMarkPolys;
cg_freeMarkPolys = cg_freeMarkPolys->nextMark;
memset( le, 0, sizeof( *le ) );
// link into the active list
le->nextMark = cg_activeMarkPolys.nextMark;
le->prevMark = &cg_activeMarkPolys;
cg_activeMarkPolys.nextMark->prevMark = le;
cg_activeMarkPolys.nextMark = le;
return le;
}
/*
=================
CG_ImpactMark
origin should be a point within a unit of the plane
dir should be the plane normal
temporary marks will not be stored or randomly oriented, but immediately
passed to the renderer.
=================
*/
#define MAX_MARK_FRAGMENTS 128
#define MAX_MARK_POINTS 384
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
float orientation, float red, float green, float blue, float alpha,
qboolean alphaFade, float radius, qboolean temporary ) {
vec3_t axis[3];
float texCoordScale;
vec3_t originalPoints[4];
byte colors[4];
int i, j;
int numFragments;
markFragment_t markFragments[MAX_MARK_FRAGMENTS], *mf;
vec3_t markPoints[MAX_MARK_POINTS];
vec3_t projection;
#ifdef _DEBUG
if (!markShader)
{
Com_Printf("CG_ImpactMark: NULL shader\n");
}
#endif
if ( !cg_addMarks.integer ) {
return;
}
if ( radius <= 0 ) {
//CG_Error( "CG_ImpactMark called with <= 0 radius" );
return;
}
// create the texture axis
VectorNormalize2( dir, axis[0] );
PerpendicularVector( axis[1], axis[0] );
RotatePointAroundVector( axis[2], axis[0], axis[1], orientation );
CrossProduct( axis[0], axis[2], axis[1] );
texCoordScale = 0.5 * 1.0 / radius;
// create the full polygon
for ( i = 0 ; i < 3 ; i++ ) {
originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i];
originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i];
originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i];
originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i];
}
// get the fragments
VectorScale( dir, -20, projection );
numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints,
projection, MAX_MARK_POINTS, markPoints[0],
MAX_MARK_FRAGMENTS, markFragments );
colors[0] = red * 255;
colors[1] = green * 255;
colors[2] = blue * 255;
colors[3] = alpha * 255;
for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) {
polyVert_t *v;
polyVert_t verts[MAX_VERTS_ON_POLY];
markPoly_t *mark;
// we have an upper limit on the complexity of polygons
// that we store persistantly
if ( mf->numPoints > MAX_VERTS_ON_POLY ) {
mf->numPoints = MAX_VERTS_ON_POLY;
}
for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) {
vec3_t delta;
VectorCopy( markPoints[mf->firstPoint + j], v->xyz );
VectorSubtract( v->xyz, origin, delta );
v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale;
v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale;
*(int *)v->modulate = *(int *)colors;
}
// if it is a temporary (shadow) mark, add it immediately and forget about it
if ( temporary ) {
trap_R_AddPolyToScene( markShader, mf->numPoints, verts );
continue;
}
// otherwise save it persistantly
mark = CG_AllocMark();
mark->time = cg.time;
mark->alphaFade = alphaFade;
mark->markShader = markShader;
mark->poly.numVerts = mf->numPoints;
mark->color[0] = red;
mark->color[1] = green;
mark->color[2] = blue;
mark->color[3] = alpha;
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
}
}
/*
===============
CG_AddMarks
===============
*/
#define MARK_TOTAL_TIME 500000
#define MARK_FADE_TIME 50000
#define MARK_DIV_3000 1.0/3000.0
void CG_AddMarks( void ) {
int j;
markPoly_t *mp, *next;
int t;
int fade;
if ( !cg_addMarks.integer ) {
return;
}
mp = cg_activeMarkPolys.nextMark;
for ( ; mp != &cg_activeMarkPolys ; mp = next ) {
// grab next now, so if the local entity is freed we
// still have it
next = mp->nextMark;
// see if it is time to completely remove it
if ( cg.time > mp->time + MARK_TOTAL_TIME ) {
CG_FreeMarkPoly( mp );
continue;
}
// fade out the energy bursts
if ( mp->markShader == cgs.media.energyMarkShader ) {
fade = 450 - 450 * ( (cg.time - mp->time ) * MARK_DIV_3000 );
if ( fade < 255 ) {
if ( fade < 0 ) {
fade = 0;
}
if ( mp->verts[0].modulate[0] != 0 ) {
for ( j = 0 ; j < mp->poly.numVerts ; j++ ) {
mp->verts[j].modulate[0] = mp->color[0] * fade;
mp->verts[j].modulate[1] = mp->color[1] * fade;
mp->verts[j].modulate[2] = mp->color[2] * fade;
}
}
}
}
// fade all marks out with time
t = mp->time + MARK_TOTAL_TIME - cg.time;
if ( t < MARK_FADE_TIME ) {
fade = 255 * t / MARK_FADE_TIME;
if ( mp->alphaFade ) {
for ( j = 0 ; j < mp->poly.numVerts ; j++ ) {
mp->verts[j].modulate[3] = fade;
}
} else {
for ( j = 0 ; j < mp->poly.numVerts ; j++ ) {
mp->verts[j].modulate[0] = mp->color[0] * fade;
mp->verts[j].modulate[1] = mp->color[1] * fade;
mp->verts[j].modulate[2] = mp->color[2] * fade;
}
}
}
trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts );
}
}

84
cgame/cg_motionblur.c Normal file
View file

@ -0,0 +1,84 @@
#include "cg_local.h"
#define MAX_MOTIONBLURDOTS 20
typedef struct motionblurDot_s {
qboolean active;
refEntity_t refEnt;
int startTime;
int lifeTime;
} motionblurDot_t;
//static motionblurDot_t cg_motionblurDots[MAX_MOTIONBLURDOTS];
void CG_MotionBlur(void) {
//motionblurDot_t *dot;
//vec3_t pos, axis[3];
//int i;
/*if ( !cg.snap->ps.powerups[PW_BOOST] && cg.snap->ps.timers[tmZanzoken] < 1 && !cg.snap->ps.timers[tmTransform]) {
cg.refdef.rdflags &= ~RDF_MOTIONBLUR;
//for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
// cg_motionblurDots[i].active = qfalse;
//}
return;
}*/
cg.refdef.rdflags |= RDF_MOTIONBLUR;
/*
// Destroy dots over lifetime
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->lifeTime + dot->startTime < cg.time ) {
dot->active = qfalse;
}
}
// Create new dots
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->active )
continue;
VectorCopy( cg.predictedPlayerEntity.lerpOrigin, pos );
VectorNormalize2( cg.predictedPlayerState.velocity, axis[0] );
VectorMA( pos, 300, axis[0], pos );
RotateAroundDirection( axis, crandom() * 360 );
VectorMA( pos, 120, axis[2], pos );
memset( &(dot->refEnt), 0, sizeof(refEntity_t));
dot->refEnt.reType = RT_SPRITE;
dot->refEnt.radius = 2;
dot->refEnt.customShader = cgs.media.whiteShader;
dot->refEnt.shaderRGBA[0] = 255;
dot->refEnt.shaderRGBA[1] = 255;
dot->refEnt.shaderRGBA[2] = 255;
dot->refEnt.shaderRGBA[3] = 128;
VectorCopy( pos, dot->refEnt.origin );
dot->lifeTime = 250 + crandom() * 100;
dot->startTime = cg.time + crandom() * 150;
dot->active = qtrue;
}
// Render dots
for ( i = 0; i < MAX_MOTIONBLURDOTS; i++ ) {
dot = &cg_motionblurDots[i];
if ( dot->startTime > cg.time )
continue;
trap_R_AddRefEntityToScene( &(dot->refEnt));
}
*/
}

5314
cgame/cg_players.c Normal file

File diff suppressed because it is too large Load diff

500
cgame/cg_playerstate.c Normal file
View file

@ -0,0 +1,500 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_playerstate.c -- this file acts on changes in a new playerState_t
// With normal play, this will be done after local prediction, but when
// following another player or playing back a demo, it will be checked
// when the snapshot transitions like all the other entities
#include "cg_local.h"
/*
==============
CG_CheckAmmo
If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
int i;
int total;
int previous;
int weapons;
if ( cg.lowAmmoWarning > 2 )
{//a timed message, draws for a specific amount of time
if ( cg.lowAmmoWarning > cg.frametime )
{
cg.lowAmmoWarning -= cg.frametime;
}
else
{
cg.lowAmmoWarning = 0;
}
return;
}
// see about how many seconds of ammo we have remaining
weapons = cg.snap->ps.stats[ STAT_WEAPONS ];
total = 0;
//TiM
//for ( i = WP_PHASER ; i < WP_NUM_WEAPONS ; i++ ) {
for ( i = WP_NULL_HAND ; i < WP_NUM_WEAPONS ; i++ ) {
if ( ! ( weapons & ( 1 << i ) ) ) {
continue;
}
switch ( i ) {
case WP_DISRUPTOR:
case WP_GRENADE_LAUNCHER:
case WP_NULL_HAND:
case WP_COMPRESSION_RIFLE:
total += cg.snap->ps.ammo[i] * 1000;
break;
default:
total += cg.snap->ps.ammo[i] * 200;
break;
}
if ( total >= 5000 ) {
cg.lowAmmoWarning = 0;
return;
}
}
previous = cg.lowAmmoWarning;
if ( total == 0 ) {
cg.lowAmmoWarning = 2;
} else {
cg.lowAmmoWarning = 1;
}
// play a sound on transitions
// RPG-X | Phenix | 13/02/2005
/*if ( cg.lowAmmoWarning != previous ) {
trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
}*/
}
/*
==============
CG_DamageFeedback
==============
*/
void CG_DamageFeedback( int yawByte, int pitchByte, int damage, int shielddamage ) {
float left, front, up;
float kick;
int health;
float scale;
vec3_t dir;
vec3_t angles;
float dist;
float yaw, pitch;
// show the attacking player's head and name in corner
cg.attackerTime = cg.time;
// the lower on health you are, the greater the view kick will be
health = cg.snap->ps.stats[STAT_HEALTH];
if ( health < 40 ) {
scale = 1;
} else {
scale = 40.0 / health;
}
kick = (damage + shielddamage*0.5) * scale;
if (kick < 5)
kick = 5;
if (kick > 10)
kick = 10;
// if yaw and pitch are both 255, make the damage always centered (falling, etc)
if ( yawByte == 255 && pitchByte == 255 ) {
cg.damageX = 0;
cg.damageY = 0;
cg.v_dmg_roll = 0;
cg.v_dmg_pitch = -kick;
} else {
// positional
pitch = pitchByte / 255.0 * 360;
yaw = yawByte / 255.0 * 360;
angles[PITCH] = pitch;
angles[YAW] = yaw;
angles[ROLL] = 0;
AngleVectors( angles, dir, NULL, NULL );
VectorSubtract( vec3_origin, dir, dir );
front = DotProduct (dir, cg.refdef.viewaxis[0] );
left = DotProduct (dir, cg.refdef.viewaxis[1] );
up = DotProduct (dir, cg.refdef.viewaxis[2] );
dir[0] = front;
dir[1] = left;
dir[2] = 0;
dist = VectorLength( dir );
if ( dist < 0.1 ) {
dist = 0.1;
}
cg.v_dmg_roll = kick * left;
cg.v_dmg_pitch = -kick * front;
if ( front <= 0.1 ) {
front = 0.1;
}
cg.damageX = -left / front;
cg.damageY = up / dist;
}
// clamp the position
if ( cg.damageX > 1.0 ) {
cg.damageX = 1.0;
}
if ( cg.damageX < - 1.0 ) {
cg.damageX = -1.0;
}
if ( cg.damageY > 1.0 ) {
cg.damageY = 1.0;
}
if ( cg.damageY < - 1.0 ) {
cg.damageY = -1.0;
}
cg.damageValue = damage * scale;
if (cg.damageValue > 10)
{
cg.damageValue = 1.0;
}
else
{
cg.damageValue *= 0.1;
}
cg.damageShieldValue = shielddamage;
if (cg.damageShieldValue > 10)
{
cg.damageShieldValue = 1.0;
}
else
{
cg.damageShieldValue *= 0.1;
}
cg.v_dmg_time = cg.time + DAMAGE_TIME;
cg.damageTime = cg.snap->serverTime;
}
/*
================
CG_Respawn
A respawn happened this snapshot
================
*/
void CG_Respawn( void ) {
// no error decay on player movement
cg.thisFrameTeleport = qtrue;
// display weapons available
cg.weaponSelectTime = cg.time;
// select the weapon the server says we are using
cg.weaponSelect = cg.snap->ps.weapon;
}
/*
==============
CG_CheckPlayerstateEvents
==============
*/
void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops ) {
int i;
int event;
centity_t *cent;
if ( ps->externalEvent && ps->externalEvent != ops->externalEvent ) {
cent = &cg_entities[ ps->clientNum ];
cent->currentState.event = ps->externalEvent;
cent->currentState.eventParm = ps->externalEventParm;
CG_EntityEvent( cent, cent->lerpOrigin );
}
cent = &cg.predictedPlayerEntity; // cg_entities[ ps->clientNum ];
// go through the predictable events buffer
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
// if we have a new predictable event
if ( i >= ops->eventSequence
// or the server told us to play another event instead of a predicted event we already issued
// or something the server told us changed our prediction causing a different event
|| (i > ops->eventSequence - MAX_PS_EVENTS && ps->events[i & (MAX_PS_EVENTS-1)] != ops->events[i & (MAX_PS_EVENTS-1)]) ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
// cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
// cg.eventSequence++;
}
}
}
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
{
// int highScore;
// The most important thing to know is if you are doing damage.
//RPG-X - TiM
/*if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] )
{
int diffhit, diffshields;
diffhit = ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
diffshields = ps->persistant[PERS_SHIELDS] - ops->persistant[PERS_SHIELDS];
if (diffshields > diffhit/2)
{ // We also hit shields along the way, so consider them "pierced".
trap_S_StartLocalSound( cgs.media.shieldPierceSound, CHAN_LOCAL_SOUND );
}
else
{ // Shields didn't really stand in our way.
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
}
}
// The second most important thing to worry about is whether you hurt a friend.
else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] )
{
trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
}
// Finally if all this damage bounced off the shields, indicate this.
else if (ps->persistant[PERS_SHIELDS] > ops->persistant[PERS_SHIELDS])
{
// hit shields and the damage didn't go through
trap_S_StartLocalSound( cgs.media.shieldHitSound, CHAN_LOCAL_SOUND );
}*/
// health changes of more than -1 should make pain sounds
if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
if ( ps->stats[STAT_HEALTH] > 0 ) {
CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH] );
}
}
// if we are going into the intermission, don't start any voices
if ( cg.intermissionStarted ) {
return;
}
// reward sounds
//RPG-X: RedTechie - No reward or frag limit sounds
/*if ( ps->persistant[PERS_REWARD_COUNT] > ops->persistant[PERS_REWARD_COUNT] ) {
switch ( ps->persistant[PERS_REWARD] ) {
case REWARD_IMPRESSIVE:
trap_S_StartLocalSound( cgs.media.rewardImpressiveSound, CHAN_ANNOUNCER );
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalImpressive;
cg.rewardCount = ps->persistant[PERS_IMPRESSIVE_COUNT];
break;
case REWARD_EXCELLENT:
trap_S_StartLocalSound( cgs.media.rewardExcellentSound, CHAN_ANNOUNCER );
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalExcellent;
cg.rewardCount = ps->persistant[PERS_EXCELLENT_COUNT];
break;
case REWARD_DENIED:
trap_S_StartLocalSound( cgs.media.rewardDeniedSound, CHAN_ANNOUNCER );
break;
case REWARD_FIRST_STRIKE:
trap_S_StartLocalSound( cgs.media.rewardFirstStrikeSound, CHAN_ANNOUNCER);
cg.rewardTime = cg.time;
cg.rewardShader = cgs.media.medalFirstStrike;
cg.rewardCount = 1;
break;
case REWARD_STREAK:
// Play a different sound depending on how long the streak is.
cg.rewardTime = cg.time;
cg.rewardCount = 1;
if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_CHAMPION)
{
trap_S_StartLocalSound( cgs.media.rewardChampionSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalChampion;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_MASTER)
{
trap_S_StartLocalSound( cgs.media.rewardMasterSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalMaster;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_EXPERT)
{
trap_S_StartLocalSound( cgs.media.rewardExpertSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalExpert;
}
else if (ps->persistant[PERS_STREAK_COUNT] >= STREAK_ACE)
{
trap_S_StartLocalSound( cgs.media.rewardAceSound, CHAN_ANNOUNCER);
cg.rewardShader = cgs.media.medalAce;
}
break;
default:
CG_Error( "Bad reward_t" );
}
} else {
// lead changes (only if no reward)
if ( !cg.warmup && !(cg.predictedPlayerState.introTime > cg.time) )
{
// never play lead changes during warmup or holo doors
if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
if ( cgs.gametype >= GT_TEAM ) {
if ( ps->persistant[PERS_RANK] == 2 ) {
trap_S_StartLocalSound( cgs.media.teamsTiedSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == 0 ) {
trap_S_StartLocalSound( cgs.media.redLeadsSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == 1 ) {
trap_S_StartLocalSound( cgs.media.blueLeadsSound, CHAN_ANNOUNCER );
}
} else {
if ( ps->persistant[PERS_RANK] == 0 ) {
trap_S_StartLocalSound( cgs.media.takenLeadSound, CHAN_ANNOUNCER );
} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
trap_S_StartLocalSound( cgs.media.tiedLeadSound, CHAN_ANNOUNCER );
} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
trap_S_StartLocalSound( cgs.media.lostLeadSound, CHAN_ANNOUNCER );
}
}
}
}
}
// timelimit warnings
if ( cgs.timelimit > 0 ) {
int msec;
msec = cg.time - cgs.levelStartTime;
if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
cg.timelimitWarnings |= 1;
trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
}
if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
cg.timelimitWarnings |= 2;
trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
}
if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
cg.timelimitWarnings |= 4;
trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
}
}
// fraglimit warnings
if ( cgs.fraglimit > 0 && cgs.gametype != GT_CTF ) {
highScore = cgs.scores1;
if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
cg.fraglimitWarnings |= 1;
trap_S_StartLocalSound( cgs.media.threeFragSound, CHAN_ANNOUNCER );
}
if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
cg.fraglimitWarnings |= 2;
trap_S_StartLocalSound( cgs.media.twoFragSound, CHAN_ANNOUNCER );
}
if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
cg.fraglimitWarnings |= 4;
trap_S_StartLocalSound( cgs.media.oneFragSound, CHAN_ANNOUNCER );
}
}*/
}
void CG_CheckDamageDealt(playerState_t *ps, playerState_t *ops)
{
static int damagetime;
static int damageamount;
if (cg_reportDamage.integer)
{
if (ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS])
{ // We did some damage this frame.
if (damagetime+1000 < cg.time)
{ // Start a new tally.
damageamount = ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
damagetime = cg.time;
}
else
{ // Add to a tally that's already here.
damageamount += ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];
}
}
// Report the sum of damage done this second.
if (damageamount > 0 && (damagetime+1000 <= cg.time))
{
Com_Printf("Damage this second: %d\n", damageamount);
damageamount = 0;
}
}
}
/*
===============
CG_TransitionPlayerState
===============
*/
void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
// check for changing follow mode
if ( ps->clientNum != ops->clientNum ) {
cg.thisFrameTeleport = qtrue;
// make sure we don't get any unwanted transition effects
*ops = *ps;
}
// damage events (player is getting wounded)
if ( ps->damageEvent != ops->damageEvent && (ps->damageCount || ps->damageShieldCount)) {
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount, ps->damageShieldCount);
}
// respawning
if ( ps->persistant[PERS_SPAWN_COUNT] != ops->persistant[PERS_SPAWN_COUNT] ) {
CG_Respawn();
}
/* if ( cg.mapRestart ) { //q3 update -not tested yet
CG_Respawn();
cg.mapRestart = qfalse;
}
*/
if ( cg.snap->ps.pm_type != PM_INTERMISSION
&& ps->persistant[PERS_TEAM] != TEAM_SPECTATOR /*&& !(ps->eFlags&EF_ELIMINATED)*/) {
CG_CheckLocalSounds( ps, ops );
}
// check for going low on ammo
CG_CheckAmmo();
// run events
CG_CheckPlayerstateEvents( ps, ops );
// smooth the ducking viewheight change
if ( ps->viewheight != ops->viewheight ) {
cg.duckChange = ps->viewheight - ops->viewheight;
cg.duckTime = cg.time;
}
#ifdef _DEBUG
CG_CheckDamageDealt(ps, ops);
#endif //_DEBUG
}

693
cgame/cg_predict.c Normal file
View file

@ -0,0 +1,693 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_predict.c -- this file generates cg.predictedPlayerState by either
// interpolating between snapshots from the server or locally predicting
// ahead the client's movement.
// It also handles local physics interaction, like fragments bouncing off walls
#include "cg_local.h"
static pmove_t cg_pmove;
static int cg_numSolidEntities;
static centity_t *cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT];
static int cg_numTriggerEntities;
static centity_t *cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT];
/*
====================
CG_BuildSolidList
When a new cg.snap has been set, this function builds a sublist
of the entities that are actually solid, to make for more
efficient collision detection
====================
*/
void CG_BuildSolidList( void ) {
int i;
centity_t *cent;
snapshot_t *snap;
entityState_t *ent;
cg_numSolidEntities = 0;
cg_numTriggerEntities = 0;
if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
snap = cg.nextSnap;
} else {
snap = cg.snap;
}
for ( i = 0 ; i < snap->numEntities ; i++ ) {
cent = &cg_entities[ snap->entities[ i ].number ];
ent = &cent->currentState;
if ( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER ) {
cg_triggerEntities[cg_numTriggerEntities] = cent;
cg_numTriggerEntities++;
continue;
}
if ( cent->nextState.solid ) {
cg_solidEntities[cg_numSolidEntities] = cent;
cg_numSolidEntities++;
continue;
}
}
}
/*
====================
CG_ClipMoveToEntities
====================
*/
#define SHIELD_HALFTHICKNESS 4 // should correspond with the #define in g_active.c
static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask, trace_t *tr ) {
int i, x, zd, zu;
trace_t trace;
entityState_t *ent;
clipHandle_t cmodel;
vec3_t bmins, bmaxs;
vec3_t origin, angles;
centity_t *cent;
for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
cent = cg_solidEntities[ i ];
ent = &cent->currentState;
if ( ent->number == skipNumber ) {
continue;
}
if ( ent->solid == SOLID_BMODEL ) {
// special value for bmodel
cmodel = trap_CM_InlineModel( ent->modelindex );
VectorCopy( cent->lerpAngles, angles );
BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
}
else if (ent->eFlags & EF_SHIELD_BOX_X)
{ // "specially" encoded bbox for x-axis aligned shield
//CG_Printf( S_COLOR_RED "Mins[ %d %d %d ] Maxs[ %d %d %d ]\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] );
//this is a bit of a hack. Only deny entry to elements
//that do not specifiy collision boundaries.
//This will mean things like players won't be affected
//(there'll be a slight jerk as the server boots them back)
//but any FX like phaser beams will be.
if ( !mins || !VectorCompare( mins, vec3_origin ) || !VectorCompare( maxs, vec3_origin ) )
continue;
/*x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255); // k on server side*/
x = (ent->time2 & 1023); // i on server side
zd = ((ent->time2>>10) & 1023); // j on server side
zu = ((ent->time2>>20) & 1023); // k on server side
bmins[0] = -x; //-zd
bmaxs[0] = zd; //x
bmins[1] = -SHIELD_HALFTHICKNESS;
bmaxs[1] = SHIELD_HALFTHICKNESS;
bmins[2] = 0;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
//CG_Printf( S_COLOR_RED "X Aligned! Bmins = [ %f %f %f ],\nBMaxs = [%f %f %f]\n", bmins[0], bmins[1], bmins[2], bmaxs[0],bmaxs[1],bmaxs[2] );
}
else if (ent->eFlags & EF_SHIELD_BOX_Y)
{ // "specially" encoded bbox for y-axis aligned shield
/*x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255); // k on server side*/
if ( !VectorCompare( mins, vec3_origin ) || !VectorCompare( maxs, vec3_origin ) )
continue;
x = (ent->time2 & 1023); // i on server side
zd = ((ent->time2>>10) & 1023); // j on server side
zu = ((ent->time2>>20) & 1023); // k on server side
bmins[1] = -x;
bmaxs[1] = zd;
bmins[0] = -SHIELD_HALFTHICKNESS;
bmaxs[0] = SHIELD_HALFTHICKNESS;
bmins[2] = 0;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
}
else
{
// encoded bbox
x = (ent->solid & 255); // i on server side
zd = ((ent->solid>>8) & 255); // j on server side
zu = ((ent->solid>>16) & 255) - 32; // k on server side
bmins[0] = bmins[1] = -x;
bmaxs[0] = bmaxs[1] = x;
bmins[2] = -zd;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
}
trap_CM_TransformedBoxTrace ( &trace, start, end,
mins, maxs, cmodel, mask, origin, angles);
if (trace.allsolid || trace.fraction < tr->fraction) {
trace.entityNum = ent->number;
*tr = trace;
} else if (trace.startsolid) {
tr->startsolid = qtrue;
}
if ( tr->allsolid ) {
return;
}
}
}
/*
================
CG_Trace
================
*/
void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask ) {
trace_t t;
trap_CM_BoxTrace ( &t, start, end, mins, maxs, 0, mask);
t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
// check all other solid models
CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t);
*result = t;
}
/*
================
CG_PointContents
================
*/
int CG_PointContents( const vec3_t point, int passEntityNum ) {
int i;
entityState_t *ent;
centity_t *cent;
clipHandle_t cmodel;
int contents;
contents = trap_CM_PointContents (point, 0);
for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
cent = cg_solidEntities[ i ];
ent = &cent->currentState;
if ( ent->number == passEntityNum ) {
continue;
}
if (ent->solid != SOLID_BMODEL) { // special value for bmodel
continue;
}
cmodel = trap_CM_InlineModel( ent->modelindex );
if ( !cmodel ) {
continue;
}
contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
}
return contents;
}
/*
========================
CG_InterpolatePlayerState
Generates cg.predictedPlayerState by interpolating between
cg.snap->player_state and cg.nextFrame->player_state
========================
*/
static void CG_InterpolatePlayerState( qboolean grabAngles ) {
float f;
int i;
playerState_t *out;
snapshot_t *prev, *next;
out = &cg.predictedPlayerState;
prev = cg.snap;
next = cg.nextSnap;
*out = cg.snap->ps;
// if we are still allowing local input, short circuit the view angles
if ( grabAngles ) {
usercmd_t cmd;
int cmdNum;
cmdNum = trap_GetCurrentCmdNumber();
trap_GetUserCmd( cmdNum, &cmd );
PM_UpdateViewAngles( out, &cmd );
}
// if the next frame is a teleport, we can't lerp to it
if ( cg.nextFrameTeleport ) {
return;
}
if ( !next || next->serverTime <= prev->serverTime ) {
return;
}
f = (float)( cg.time - prev->serverTime ) / ( next->serverTime - prev->serverTime );
i = next->ps.bobCycle;
if ( i < prev->ps.bobCycle ) {
i += 256; // handle wraparound
}
out->bobCycle = prev->ps.bobCycle + f * ( i - prev->ps.bobCycle );
for ( i = 0 ; i < 3 ; i++ ) {
out->origin[i] = prev->ps.origin[i] + f * (next->ps.origin[i] - prev->ps.origin[i] );
if ( !grabAngles ) {
out->viewangles[i] = LerpAngle(
prev->ps.viewangles[i], next->ps.viewangles[i], f );
}
out->velocity[i] = prev->ps.velocity[i] +
f * (next->ps.velocity[i] - prev->ps.velocity[i] );
}
}
/*
===================
CG_TouchItem
===================
*/
static void CG_TouchItem( centity_t *cent ) {
gitem_t *item;
//RPG-X | Marcin | 03/12/2008
//this can't be predicted because as don't know whether USE was pressed...
if (qtrue) {
return;
}
if ( !cg_predictItems.integer ) {
return;
}
// never pick an item up twice in a prediction
if ( cent->miscTime == cg.time ) {
return;
}
if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, &cent->currentState, cg.time ) ) {
return;
}
// RPG-X: Marcin: Can't predict this any more sorry - 30/12/2008
if ( 0 ) /* ( !BG_CanItemBeGrabbed( &cent->currentState, &cg.predictedPlayerState ) ) */ {
return; // can't hold it
}
item = &bg_itemlist[ cent->currentState.modelindex ];
// Special case for flags.
// We don't predict touching our own flag
if (item->giType == IT_TEAM)
{ // NOTE: This code used to JUST check giTag. The problem is that the giTag for PW_REDFLAG
// is the same as WP_QUANTUM_BURST. The giTag should be a SUBCHECK after giType.
/*if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED &&
item->giTag == PW_REDFLAG)
return;*/
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_BLUE &&
item->giTag == PW_BORG_ADAPT)
return;
}
if (!(cent->currentState.eFlags & (EF_ITEMPLACEHOLDER | EF_NODRAW)))
{
// grab it
BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.predictedPlayerState);
// Draw the techy-itemplaceholder for weapons and powerups, not ammo, etc.
if (item->giType == IT_WEAPON || item->giType == IT_POWERUP)
{ // draw it "gridded out"
cent->currentState.eFlags |= EF_ITEMPLACEHOLDER;
}
else
{ // remove it from the frame so it won't be drawn
cent->currentState.eFlags |= EF_NODRAW;
// kef -- special client-only flag to prevent double pickup sounds
//cent->currentState.eFlags |= EF_CLIENT_NODRAW;
}
// if its a weapon, give them some predicted ammo so the autoswitch will work
if ( item->giType == IT_WEAPON )
{
cg.predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag;
if ( !cg.predictedPlayerState.ammo[ item->giTag ] ) {
cg.predictedPlayerState.ammo[ item->giTag ] = 1;
}
}
}
// don't touch it again this prediction
cent->miscTime = cg.time;
}
/*
=========================
CG_TouchTriggerPrediction
Predict push triggers and items
=========================
*/
static void CG_TouchTriggerPrediction( void ) {
int i;
trace_t trace;
entityState_t *ent;
clipHandle_t cmodel;
centity_t *cent;
qboolean spectator;
// dead clients don't activate triggers
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
return;
}
spectator = ( cg.predictedPlayerState.pm_type == PM_SPECTATOR );
if ( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator ) {
return;
}
for ( i = 0 ; i < cg_numTriggerEntities ; i++ ) {
cent = cg_triggerEntities[ i ];
ent = &cent->currentState;
if ( ent->eType == ET_ITEM && !spectator ) {
CG_TouchItem( cent );
continue;
}
if ( ent->solid != SOLID_BMODEL ) {
continue;
}
cmodel = trap_CM_InlineModel( ent->modelindex );
if ( !cmodel ) {
continue;
}
trap_CM_BoxTrace( &trace, cg.predictedPlayerState.origin, cg.predictedPlayerState.origin,
cg_pmove.mins, cg_pmove.maxs, cmodel, -1 );
if ( !trace.startsolid ) {
continue;
}
if ( ent->eType == ET_TELEPORT_TRIGGER ) {
//cg.hyperspace = qtrue;
continue;
} else {
float s;
vec3_t dir;
// we hit this push trigger
if ( spectator ) {
continue;
}
// flying characters don't hit bounce pads
if ( cg.predictedPlayerState.powerups[PW_FLIGHT] ) {
continue;
}
// if we are already flying along the bounce direction, don't play sound again
VectorNormalize2( ent->origin2, dir );
s = DotProduct( cg.predictedPlayerState.velocity, dir );
if ( s < 500 ) {
// don't play the event sound again if we are in a fat trigger
BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, 0, &cg.predictedPlayerState );
}
VectorCopy( ent->origin2, cg.predictedPlayerState.velocity );
}
}
}
/*
=================
CG_PredictPlayerState
Generates cg.predictedPlayerState for the current cg.time
cg.predictedPlayerState is guaranteed to be valid after exiting.
For demo playback, this will be an interpolation between two valid
playerState_t.
For normal gameplay, it will be the result of predicted usercmd_t on
top of the most recent playerState_t received from the server.
Each new snapshot will usually have one or more new usercmd over the last,
but we simulate all unacknowledged commands each time, not just the new ones.
This means that on an internet connection, quite a few pmoves may be issued
each frame.
OPTIMIZE: don't re-simulate unless the newly arrived snapshot playerState_t
differs from the predicted one. Would require saving all intermediate
playerState_t during prediction.
We detect prediction errors and allow them to be decayed off over several frames
to ease the jerk.
=================
*/
void CG_PredictPlayerState( void ) {
int cmdNum, current;
playerState_t oldPlayerState;
qboolean moved;
usercmd_t oldestCmd;
usercmd_t latestCmd;
char temp_string[200];
cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
// if this is the first frame we must guarantee
// predictedPlayerState is valid even if there is some
// other error condition
if ( !cg.validPPS ) {
cg.validPPS = qtrue;
cg.predictedPlayerState = cg.snap->ps;
// if we need to, we should check our model cvar and update it with the right value from the userinfo strings
// since it may have been modified by the server
Com_sprintf(temp_string, sizeof(temp_string), "%s/%s/%s", cgs.clientinfo[cg.predictedPlayerState.clientNum].charName, cgs.clientinfo[cg.predictedPlayerState.clientNum].modelName,
cgs.clientinfo[cg.predictedPlayerState.clientNum].skinName);
updateSkin(cg.predictedPlayerState.clientNum, temp_string);
}
// demo playback just copies the moves
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ) {
CG_InterpolatePlayerState( qfalse );
return;
}
// non-predicting local movement will grab the latest angles
if ( cg_nopredict.integer || cg_synchronousClients.integer ) {
CG_InterpolatePlayerState( qtrue );
return;
}
// prepare for pmove
cg_pmove.ps = &cg.predictedPlayerState;
cg_pmove.trace = CG_Trace;
cg_pmove.pointcontents = CG_PointContents;
cg_pmove.admin = cgs.clientinfo[cg.snap->ps.clientNum].isAdmin;
cg_pmove.medic = cgs.classData[cgs.clientinfo[cg.snap->ps.clientNum].pClass].isMedic;
cg_pmove.borg = cgs.classData[cgs.clientinfo[cg.snap->ps.clientNum].pClass].isBorg;
if ( cg_pmove.ps->pm_type == PM_DEAD ) {
cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
}
else {
cg_pmove.tracemask = MASK_PLAYERSOLID;
}
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR /*|| (cg.snap->ps.eFlags&EF_ELIMINATED)*/ ) {
cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
}
cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
cg_pmove.pModDisintegration = cgs.pModDisintegration > 0;
// save the state before the pmove so we can detect transitions
oldPlayerState = cg.predictedPlayerState;
current = trap_GetCurrentCmdNumber();
// if we don't have the commands right after the snapshot, we
// can't accurately predict a current position, so just freeze at
// the last good position we had
cmdNum = current - CMD_BACKUP + 1;
trap_GetUserCmd( cmdNum, &oldestCmd );
if ( oldestCmd.serverTime > cg.snap->ps.commandTime
&& oldestCmd.serverTime < cg.time ) { // special check for map_restart
if ( cg_showmiss.integer ) {
CG_Printf ("exceeded PACKET_BACKUP on commands\n");
}
return;
}
// get the latest command so we can know which commands are from previous map_restarts
trap_GetUserCmd( current, &latestCmd );
// get the most recent information we have, even if
// the server time is beyond our current cg.time,
// because predicted player positions are going to
// be ahead of everything else anyway
if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
cg.predictedPlayerState = cg.nextSnap->ps;
cg.physicsTime = cg.nextSnap->serverTime;
} else {
cg.predictedPlayerState = cg.snap->ps;
cg.physicsTime = cg.snap->serverTime;
}
// run cmds
moved = qfalse;
for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
// don't do anything if the time is before the snapshot player time
if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
continue;
}
// don't do anything if the command was from a previous map_restart
if ( cg_pmove.cmd.serverTime > latestCmd.serverTime ) {
continue;
}
/*if (cg.predictedPlayerState.introTime > cg.time) //what's this for? TiM: I think it's for the holoIntro...
{
cg_pmove.cmd.buttons = 0;
cg_pmove.cmd.weapon = 0;
// cg_pmove.cmd.angles[0] = cg_pmove.cmd.angles[1] = cg_pmove.cmd.angles[2] = 0;
cg_pmove.cmd.forwardmove = cg_pmove.cmd.rightmove = cg_pmove.cmd.upmove = 0;
}*/
// check for a prediction error from last frame
// on a lan, this will often be the exact value
// from the snapshot, but on a wan we will have
// to predict several commands to get to the point
// we want to compare
if ( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime ) {
vec3_t delta;
float len;
if ( cg.thisFrameTeleport ) {
// a teleport will not cause an error decay
VectorClear( cg.predictedError );
if ( cg_showmiss.integer ) {
CG_Printf( "PredictionTeleport\n" );
}
cg.thisFrameTeleport = qfalse;
} else {
vec3_t adjusted;
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
if ( cg_showmiss.integer ) {
if (!VectorCompare( oldPlayerState.origin, adjusted )) {
CG_Printf("prediction error\n");
}
}
VectorSubtract( oldPlayerState.origin, adjusted, delta );
len = VectorLength( delta );
if ( len > 0.1 ) {
if ( cg_showmiss.integer ) {
CG_Printf("Prediction miss: %f\n", len);
}
if ( cg_errorDecay.integer ) {
int t;
float f;
t = cg.time - cg.predictedErrorTime;
f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
if ( f < 0 ) {
f = 0;
}
if ( f > 0 && cg_showmiss.integer ) {
CG_Printf("Double prediction decay: %f\n", f);
}
VectorScale( cg.predictedError, f, cg.predictedError );
} else {
VectorClear( cg.predictedError );
}
VectorAdd( delta, cg.predictedError, cg.predictedError );
cg.predictedErrorTime = cg.oldTime;
}
}
}
Pmove (&cg_pmove);
moved = qtrue;
// add push trigger movement effects
CG_TouchTriggerPrediction();
}
if ( cg_showmiss.integer > 1 ) {
CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
}
if ( !moved ) {
if ( cg_showmiss.integer ) {
CG_Printf( "not moved\n" );
}
return;
}
// adjust for the movement of the groundentity
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
cg.predictedPlayerState.groundEntityNum,
cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
if ( cg_showmiss.integer ) {
if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
CG_Printf("WARNING: dropped event\n");
}
}
// fire events and other transition triggered things
CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
/* if ( cg_showmiss.integer ) {
if (cg.eventSequence > cg.predictedPlayerState.eventSequence) {
CG_Printf("WARNING: double event\n");
cg.eventSequence = cg.predictedPlayerState.eventSequence;
}
}
*/
}

183
cgame/cg_public.h Normal file
View file

@ -0,0 +1,183 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// rpgxEF?
#define XTRA 1
#define CMD_BACKUP 64
#define CMD_MASK (CMD_BACKUP - 1)
// allow a lot of command backups for very fast systems
// multiple commands may be combined into a single packet, so this
// needs to be larger than PACKET_BACKUP
#define MAX_ENTITIES_IN_SNAPSHOT 256
// snapshots are a view of the server at a given time
// Snapshots are generated at regular time intervals by the server,
// but they may not be sent if a client's rate level is exceeded, or
// they may be dropped by the network.
typedef struct {
int snapFlags; // SNAPFLAG_RATE_DELAYED, etc
int ping;
int serverTime; // server time the message is valid for (in msec)
byte areamask[MAX_MAP_AREA_BYTES]; // portalarea visibility bits
playerState_t ps; // complete information about the current player at this time
int numEntities; // all of the entities that need to be presented
entityState_t entities[MAX_ENTITIES_IN_SNAPSHOT]; // at the time of this snapshot
int numServerCommands; // text based server commands to execute when this
int serverCommandSequence; // snapshot becomes current
} snapshot_t;
/*
==================================================================
functions imported from the main executable
==================================================================
*/
#define CGAME_IMPORT_API_VERSION 3
//these must match up with cg_syscalls.asm
typedef enum {
CG_PRINT,
CG_ERROR,
CG_MILLISECONDS,
CG_CVAR_REGISTER,
CG_CVAR_UPDATE,
CG_CVAR_SET,
CG_CVAR_VARIABLESTRINGBUFFER,
CG_ARGC,
CG_ARGV,
CG_ARGS,
CG_FS_FOPENFILE,
CG_FS_READ,
CG_FS_WRITE,
CG_FS_FCLOSEFILE,
CG_SENDCONSOLECOMMAND,
CG_ADDCOMMAND,
CG_SENDCLIENTCOMMAND,
CG_UPDATESCREEN,
CG_CM_LOADMAP,
CG_CM_NUMINLINEMODELS,
CG_CM_INLINEMODEL,
CG_CM_LOADMODEL,
CG_CM_TEMPBOXMODEL,
CG_CM_POINTCONTENTS,
CG_CM_TRANSFORMEDPOINTCONTENTS,
CG_CM_BOXTRACE,
CG_CM_TRANSFORMEDBOXTRACE,
CG_CM_MARKFRAGMENTS,
CG_S_STARTSOUND,
CG_S_STARTLOCALSOUND,
CG_S_CLEARLOOPINGSOUNDS,
CG_S_ADDLOOPINGSOUND,
CG_S_UPDATEENTITYPOSITION,
CG_S_RESPATIALIZE,
CG_S_REGISTERSOUND,
CG_S_STARTBACKGROUNDTRACK,
CG_R_LOADWORLDMAP,
CG_R_REGISTERMODEL,
CG_R_REGISTERSKIN,
CG_R_REGISTERSHADER,
CG_R_CLEARSCENE,
CG_R_ADDREFENTITYTOSCENE,
CG_R_ADDPOLYTOSCENE,
CG_R_ADDLIGHTTOSCENE,
CG_R_RENDERSCENE,
CG_R_SETCOLOR,
CG_R_DRAWSTRETCHPIC,
CG_R_MODELBOUNDS,
CG_R_LERPTAG,
CG_GETGLCONFIG,
CG_GETGAMESTATE,
CG_GETCURRENTSNAPSHOTNUMBER,
CG_GETSNAPSHOT,
CG_GETSERVERCOMMAND,
CG_GETCURRENTCMDNUMBER,
CG_GETUSERCMD,
CG_SETUSERCMDVALUE,
CG_R_REGISTERSHADERNOMIP,
CG_MEMORY_REMAINING, //58
CG_R_REGISTERSHADER3D, //59
CG_CVAR_SET_NO_MODIFY, // 60
//these must match up with cg_syscalls.asm - add more traps HERE!
CG_MEMSET = 100,
CG_MEMCPY,
CG_STRNCPY,
CG_SIN,
CG_COS,
CG_ATAN2,
CG_SQRT,
CG_FLOOR,
CG_CEIL,
CG_TESTPRINTINT,
CG_TESTPRINTFLOAT
#ifdef XTRA
,
CG_R_REMAP_SHADER = 200,
CG_R_ADDPOLYSTOSCENE
#endif
} cgameImport_t;
//these must match up with cg_syscalls.asm
/*
==================================================================
functions exported to the main executable
==================================================================
*/
typedef enum {
CG_INIT,
// void CG_Init( int serverMessageNum, int serverCommandSequence )
// called when the level loads or when the renderer is restarted
// all media should be registered at this time
// cgame will display loading status by calling SCR_Update, which
// will call CG_DrawInformation during the loading process
// reliableCommandSequence will be 0 on fresh loads, but higher for
// demos, tourney restarts, or vid_restarts
CG_SHUTDOWN,
// void (*CG_Shutdown)( void );
// oportunity to flush and close any open files
CG_CONSOLE_COMMAND,
// qboolean (*CG_ConsoleCommand)( void );
// a console command has been issued locally that is not recognized by the
// main game system.
// use Cmd_Argc() / Cmd_Argv() to read the command, return qfalse if the
// command is not known to the game
CG_DRAW_ACTIVE_FRAME,
// void (*CG_DrawActiveFrame)( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );
// Generates and draws a game scene and status information at the given time.
// If demoPlayback is set, local movement prediction will not be enabled
CG_CROSSHAIR_PLAYER,
// int (*CG_CrosshairPlayer)( void );
CG_LAST_ATTACKER
// int (*CG_LastAttacker)( void );
} cgameExport_t;
//----------------------------------------------

2639
cgame/cg_scoreboard.c Normal file

File diff suppressed because it is too large Load diff

434
cgame/cg_screenfx.c Normal file
View file

@ -0,0 +1,434 @@
#include "cg_local.h"
#include "cg_screenfx.h"
// this is the list of currently drawing fx and their start times and end times
screenFX_t theScreenFX;
int CG_GetScreenEffectEndTime(int event)
{
switch (event)
{
case SCREENFX_TRANSPORTER:
return cg.time + 1000;
case SCREENFX_SP_TRANSPORTER_IN:
return cg.time + 4000;
case SCREENFX_SP_TRANSPORTER_OUT:
return cg.time + 8000;
default:
return 0;
}
}
// maybe play a sound or something?
void CG_BeginScreenEffect(int event)
{
switch (event)
{
case SCREENFX_TRANSPORTER:
break;
default:
break;
}
}
// when adding a new effect, we'll either take an empty slot in theScreenFX or
//overwrite the oldest effect
void CG_AddFullScreenEffect(int screenfx, int clientNum)
{
int i = 0, oldestTime = cg.time, oldestEffect = 0;
if (clientNum != cg.predictedPlayerState.clientNum)
{ // only add screen effects for our client
return;
}
for (i = 0; i < MAX_SCREENFX; i++)
{
// if we already have one of these effects going, just add to the duration of
//the existing one...don't create a new instance of the same effect
if (theScreenFX.events[i] == screenfx)
{
theScreenFX.cgStartTimes[i] = cg.time;
theScreenFX.cgEndTimes[i] = CG_GetScreenEffectEndTime(screenfx);
return;
}
else if (theScreenFX.cgStartTimes[i])
{
if (theScreenFX.cgStartTimes[i] < oldestTime)
{
oldestTime = theScreenFX.cgStartTimes[i];
oldestEffect = i;
}
}
//Hack-didily-ack - TiM: If were already one powerup, switch to the next
else if ( screenfx == SCREENFX_SP_TRANSPORTER_OUT ) {
if ( theScreenFX.events[i] == SCREENFX_SP_TRANSPORTER_IN ) {
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
}
else if ( screenfx == SCREENFX_SP_TRANSPORTER_IN ) {
if ( theScreenFX.events[i] == SCREENFX_SP_TRANSPORTER_OUT ) {
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
}
else
{
oldestTime = theScreenFX.cgStartTimes[i];
oldestEffect = i;
}
}
theScreenFX.events[oldestEffect] = screenfx;
theScreenFX.cgStartTimes[oldestEffect] = cg.time;
theScreenFX.cgEndTimes[oldestEffect] = CG_GetScreenEffectEndTime(screenfx);
CG_BeginScreenEffect(screenfx);
}
/*
===============
CG_DrawScreenQuad
===============
*/
static void CG_DrawScreenQuad(float alpha, qhandle_t screenshader)
{
refEntity_t ent;
float radius;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
if (cg.refdef.fov_x > 120)
{
return; // Too wide to show this.
}
else if (cg.refdef.fov_x > 80)
{
radius = 8.0 + (cg.refdef.fov_x - 80)*0.2;
}
else
{
radius = 8.0;
}
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_SPRITE;
ent.renderfx = RF_FIRST_PERSON;
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin );
ent.data.sprite.radius = radius;
ent.customShader = screenshader;
ent.shaderRGBA[0] = alpha * 255;
ent.shaderRGBA[1] = alpha * 255;
ent.shaderRGBA[2] = alpha * 255;
ent.shaderRGBA[3] = 255;
trap_R_AddRefEntityToScene( &ent );
}
/*
static void CG_DrawDirectionalScreenQuad(float alpha, qhandle_t screenshader)
{
refEntity_t ent;
vec3_t screencenter;
byte topleft, topright, lowleft, lowright, top, low, left, right;
float val;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
// Set up all the basic info about this refentity
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], screencenter);
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_ALPHAVERTPOLY;
ent.renderfx = RF_FIRST_PERSON;
ent.data.sprite.radius = 4;
ent.customShader = screenshader;
* (unsigned int *) ent.shaderRGBA = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[0] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[1] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[2] = 0xffffffff;
* (unsigned int *) ent.data.sprite.vertRGBA[3] = 0xffffffff;
// left
val = alpha*(0.5 + 0.5*(cg.damageX - fabs(cg.damageY)));
if (val<0)
left=0;
else if (val>1.0)
left=255;
else
left=255.0*val;
// upper left
val = alpha*(0.5*(cg.damageX + cg.damageY));
if (val<0)
topleft=0;
else if (val>1.0)
topleft=255;
else
topleft=255.0*val;
// top
val = alpha*(0.5 + 0.5*(-fabs(cg.damageX) + cg.damageY));
if (val<0)
top=0;
else if (val>1.0)
top=255;
else
top=255.0*val;
// upper right
val = alpha*(0.5*(-cg.damageX + cg.damageY));
if (val<0)
topright=0;
else if (val>1.0)
topright=255;
else
topright=255.0*val;
// right
val = alpha*(0.5 + 0.5*(-cg.damageX - fabs(cg.damageY)));
if (val<0)
right=0;
else if (val>1.0)
right=255;
else
right=255.0*val;
// lower right
val = alpha*(0.5*(-cg.damageX - cg.damageY));
if (val<0)
lowright=0;
else if (val>1.0)
lowright=255;
else
lowright=255.0*val;
// bottom
val = alpha*(0.5 + 0.5*(-fabs(cg.damageX) - cg.damageY));
if (val<0)
low=0;
else if (val>1.0)
low=255;
else
low=255.0*val;
// lower left
val = alpha*(0.5*(cg.damageX - cg.damageY));
if (val<0)
lowleft=0;
else if (val>1.0)
lowleft=255;
else
lowleft=255.0*val;
// Draw the upper left corner
VectorMA(screencenter, 4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, 4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = topleft;
ent.data.sprite.vertRGBA[1][3] = top;
ent.data.sprite.vertRGBA[2][3] = 0;
ent.data.sprite.vertRGBA[3][3] = left;
trap_R_AddRefEntityToScene( &ent );
// Draw topper right corner
VectorMA(screencenter, -4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, 4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = top;
ent.data.sprite.vertRGBA[1][3] = topright;
ent.data.sprite.vertRGBA[2][3] = right;
ent.data.sprite.vertRGBA[3][3] = 0;
trap_R_AddRefEntityToScene( &ent );
// Draw lower right corner
VectorMA(screencenter, -4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, -4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = 0;
ent.data.sprite.vertRGBA[1][3] = right;
ent.data.sprite.vertRGBA[2][3] = lowright;
ent.data.sprite.vertRGBA[3][3] = low;
trap_R_AddRefEntityToScene( &ent );
// Draw lower left corner
VectorMA(screencenter, 4, cg.refdef.viewaxis[1], ent.origin);
VectorMA(ent.origin, -4, cg.refdef.viewaxis[2], ent.origin);
ent.data.sprite.vertRGBA[0][3] = left;
ent.data.sprite.vertRGBA[1][3] = 0;
ent.data.sprite.vertRGBA[2][3] = low;
ent.data.sprite.vertRGBA[3][3] = lowleft;
trap_R_AddRefEntityToScene( &ent );
}
*/
static void CG_DrawScreenBlob(float redalpha, float greenalpha)
{
refEntity_t ent;
float alphascale;
float bluealpha = 0;
// ragePro systems can't fade blends, so don't obscure the screen
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
return;
}
memset( &ent, 0, sizeof( ent ) );
ent.reType = RT_SPRITE;
ent.renderfx = RF_FIRST_PERSON;
// Available input:
// cg.damageValue: Range from 0 to 1, indicating the amount of damage.
// cg.damageX and cg_damageY: Range from -1 to 1, indicating the location of the damage.
VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[0], ent.origin );
VectorMA( ent.origin, cg.damageX * -8, cg.refdef.viewaxis[1], ent.origin );
VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin );
// Here's the scoop: The closer we are to the center, the more transparent this blob is.
alphascale = (2*fabs(cg.damageX)+fabs(cg.damageY))/3.0;
redalpha *= alphascale;
greenalpha *= alphascale;
if (redalpha > greenalpha)
{
ent.data.sprite.radius = cg.damageValue * 15 * redalpha;
}
else
{
ent.data.sprite.radius = cg.damageShieldValue * 15 * greenalpha;
}
/* if (redalpha < 0.01)
{ // Just shield damage
ent.customShader = cgs.media.shieldBlobShader;
// Set all colors to the same as green, since the shader is green
redalpha = bluealpha = greenalpha;
}
else*/ if (greenalpha < 0.01)
{ // Just pain damage
ent.customShader = cgs.media.painBlobShader;
// Set all colors to the same as red, since the shader is red
greenalpha = bluealpha = redalpha;
}
else
{ // Both
ent.customShader = cgs.media.painShieldBlobShader;
}
ent.shaderRGBA[0] = 0xff * redalpha;
ent.shaderRGBA[1] = 0xff * greenalpha;
ent.shaderRGBA[2] = 0xff * bluealpha;
ent.shaderRGBA[3] = 0xff;
trap_R_AddRefEntityToScene( &ent );
}
void CG_DrawFullScreenEffect(int screenfx, int start, int end)
{
float alpha, alpha2 = 0.0; //TiM - second alpha
int end2, start2;
alpha = (float)(end-cg.time)/(float)(end-start);
switch (screenfx)
{
case SCREENFX_TRANSPORTER:
CG_DrawScreenQuad(alpha, cgs.media.teleportEffectShader);
break;
case SCREENFX_SP_TRANSPORTER_IN:
end2=end - 2500;
CG_DrawScreenQuad( alpha, cgs.media.teleportEffectShader);
//Fade in a white quad a little later
if (cg.time <= end2 ) {
alpha2 = (float)(end2-cg.time)/(float)(end2-start);
CG_DrawScreenQuad( alpha2, cgs.media.white2Shader);
}
break;
case SCREENFX_SP_TRANSPORTER_OUT:
start2=start+2500;
end2=end - 4000;
alpha = (float)(end2-cg.time)/(float)(end2-start);
CG_DrawScreenQuad(( 1.0f - alpha), cgs.media.teleportEffectShader);
if ( cg.time >= start2 ) {
alpha2 = (float)(end2-cg.time)/(float)(end2-start2);
if ( cg.time >= end2 )
alpha2=0.0f;
CG_DrawScreenQuad( ( 1.0f - alpha2), cgs.media.white2Shader);
}
break;
default:
break;
}
}
void CG_DrawFullScreenFX( void )
{
int i = 0, t;
float alpha, redalpha, greenalpha;
if ( (cg.snap->ps.clientNum != cg.predictedPlayerState.clientNum) || cg.renderingThirdPerson )
{
return;
}
t = cg.time - cg.damageTime;
if ( t > 0 && t < DAMAGE_TIME)
{ // Draw the blobs.
alpha = 1.0 - ((float)t / (float)DAMAGE_TIME);
redalpha = alpha*cg.damageValue*1.5;
if (redalpha > 1.0)
{
redalpha = 1.0;
}
greenalpha = alpha*cg.damageShieldValue*1.5;
if (greenalpha > 1.0)
{
greenalpha = 1.0;
}
CG_DrawScreenBlob(redalpha, greenalpha);
}
for (i = 0; i < MAX_SCREENFX; i++)
{
if (theScreenFX.cgEndTimes[i])
{
if (theScreenFX.cgEndTimes[i] <= cg.time)
{
// remove this effect
theScreenFX.events[i] = 0;
theScreenFX.cgStartTimes[i] = 0;
theScreenFX.cgEndTimes[i] = 0;
}
else
{
// still drawing this effect
CG_DrawFullScreenEffect(theScreenFX.events[i],theScreenFX.cgStartTimes[i],theScreenFX.cgEndTimes[i]);
}
}
}
}

28
cgame/cg_screenfx.h Normal file
View file

@ -0,0 +1,28 @@
//
// full-screen effects like beaming in/out, static from being hit, etc.
//
enum screenfx_e
{
SCREENFX_HIT,
SCREENFX_HALFSHIELDHIT,
SCREENFX_FULLSHIELDHIT,
SCREENFX_TRANSPORTER,
SCREENFX_SP_TRANSPORTER_IN,
SCREENFX_SP_TRANSPORTER_OUT,
MAX_SCREENFX
};
typedef struct screenFX_s
{
int events[MAX_SCREENFX];
int cgStartTimes[MAX_SCREENFX];
int cgEndTimes[MAX_SCREENFX];
} screenFX_t;
extern screenFX_t theScreenFX;
void CG_AddFullScreenEffect(int screenfx, int clientNum);
void CG_DrawFullScreenFX();

931
cgame/cg_servercmds.c Normal file
View file

@ -0,0 +1,931 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_servercmds.c -- reliably sequenced text commands sent by the server
// these are processed at snapshot transition time, so there will definately
// be a valid snapshot this frame
#include "cg_local.h"
#define MAX_LOCAL_ENTITIES 512
extern localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES];
/*
=================
CG_ParseScores
=================
*/
static void CG_ParseScores( void ) {
int i, powerups, eliminated;
cg.numScores = atoi( CG_Argv( 1 ) );
if ( cg.numScores > MAX_CLIENTS ) {
cg.numScores = MAX_CLIENTS;
}
cg.teamScores[0] = atoi( CG_Argv( 2 ) );
cg.teamScores[1] = atoi( CG_Argv( 3 ) );
memset( cg.scores, 0, sizeof( cg.scores ) );
for ( i = 0 ; i < cg.numScores ; i++ ) {
cg.scores[i].client = atoi( CG_Argv( i * 11+ 4 ) );
cg.scores[i].score = atoi( CG_Argv( i * 11+ 5 ) );
cg.scores[i].ping = atoi( CG_Argv( i * 11+ 6 ) );
cg.scores[i].time = atoi( CG_Argv( i * 11+ 7 ) );
cg.scores[i].scoreFlags = atoi( CG_Argv( i * 11+ 8 ) );
powerups = atoi( CG_Argv( i * 11+ 9 ) );
// cg.scores[i].faveTarget = atoi( CG_Argv( i * 12+ 10) );
// cg.scores[i].faveTargetKills = atoi( CG_Argv( i * 12+ 11) );
cg.scores[i].worstEnemy = atoi( CG_Argv( i * 11+ 10) );
cg.scores[i].worstEnemyKills= atoi( CG_Argv( i * 11+ 11) );
cg.scores[i].faveWeapon = atoi( CG_Argv( i * 11+ 12) );
cg.scores[i].killedCnt = atoi( CG_Argv( i * 11+ 13) );
eliminated = atoi( CG_Argv( i * 11+ 14) );
if ( cg.scores[i].client < 0 || cg.scores[i].client >= MAX_CLIENTS ) {
cg.scores[i].client = 0;
}
cgs.clientinfo[ cg.scores[i].client ].score = cg.scores[i].score;
cgs.clientinfo[ cg.scores[i].client ].powerups = powerups;
cgs.clientinfo[ cg.scores[i].client ].eliminated = eliminated;
}
}
/*
=================
CG_ParseTeamInfo
=================
*/
static void CG_ParseTeamInfo( void ) {
int i;
int client;
numSortedTeamPlayers = atoi( CG_Argv( 1 ) );
for ( i = 0 ; i < numSortedTeamPlayers ; i++ ) {
client = atoi( CG_Argv( i * 2 + 2 ) ); //6
sortedTeamPlayers[i] = client;
cgs.clientinfo[ client ].location = atoi( CG_Argv( i * 2 + 3 ) ); //6 +
/*cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 6 + 4 ) );
cgs.clientinfo[ client ].armor = atoi( CG_Argv( i * 6 + 5 ) );
cgs.clientinfo[ client ].curWeapon = atoi( CG_Argv( i * 6 + 6 ) );
cgs.clientinfo[ client ].powerups = atoi( CG_Argv( i * 6 + 7 ) );*/
}
}
/*
=================
CG_ParseHealthInfo
=================
*/
static void CG_ParseHealthInfo( void ) {
int i;
int client;
int numHealthInfoClients = 0;
numHealthInfoClients = atoi( CG_Argv( 1 ) );
for ( i = 0 ; i < numHealthInfoClients ; i++ ) {
client = atoi( CG_Argv( i * 2 + 2 ) );
cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 2 + 3 ) );
}
}
/*
================
CG_ParseServerinfo
This is called explicitly when the gamestate is first received,
and whenever the server updates any serverinfo flagged cvars
================
*/
void CG_ParseServerinfo( void ) {
const char *info;
char *mapname;
info = CG_ConfigString( CS_SERVERINFO );
cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
cgs.pModAssimilation = atoi( Info_ValueForKey( info, "g_pModAssimilation" ) );
cgs.pModDisintegration = atoi( Info_ValueForKey( info, "g_pModDisintegration" ) );
cgs.pModActionHero = atoi( Info_ValueForKey( info, "g_pModActionHero" ) );
cgs.pModSpecialties = atoi( Info_ValueForKey( info, "g_pModSpecialties" ) );
cgs.pModElimination = atoi( Info_ValueForKey( info, "g_pModElimination" ) );
cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) );
cgs.fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) );
cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );
cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) );
cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
cgs.ForceClassColor = atoi( Info_ValueForKey( info, "rpg_forceClassColor" ) );
mapname = Info_ValueForKey( info, "mapname" );
Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
//RPG-X: TiM - new Rankset
Q_strncpyz( cgs.rankSet, Info_ValueForKey( info, "rpg_rankSet"), sizeof(cgs.rankSet) );
//RPG-X: TiM - new Class set
Q_strncpyz( cgs.classSet, Info_ValueForKey( info, "rpg_classSet" ), sizeof( cgs.classSet ) );
//scannable panels
cgs.scannablePanels = atoi( Info_ValueForKey( info, "rpg_scannablePanels" ) );
}
/*
==================
CG_ParseWarmup
==================
*/
static void CG_ParseWarmup( void ) {
const char *info;
int warmup;
info = CG_ConfigString( CS_WARMUP );
warmup = atoi( info );
cg.warmupCount = -1;
if ( warmup == 0 && cg.warmup ) {
} else if ( warmup > 0 && cg.warmup <= 0 ) {
trap_S_StartLocalSound( cgs.media.countPrepareSound, CHAN_ANNOUNCER );
}
cg.warmup = warmup;
}
/*
================
CG_SetConfigValues
Called on load to set the initial values from configure strings
================
*/
void CG_SetConfigValues( void ) {
const char *s;
cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) );
cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) );
cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) );
s = CG_ConfigString( CS_FLAGSTATUS );
cgs.redflag = s[0] - '0';
cgs.blueflag = s[1] - '0';
cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) );
}
/*
=====================
CG_ClientShakeCamera
TiM: Parses the cam shake
config string, and inputs the useful
data.
=====================
*/
void CG_ClientShakeCamera ( void ) {
float intensity;
int duration;
char *str;
str = (char *)CG_ConfigString( CS_CAMERA_SHAKE );
intensity = (float)atoi( COM_Parse( &str ) )/10.0f;
duration = atoi( COM_Parse( &str ) ); //This is an offset so if a player somehow received
//the string halfway thru the cycle (ie just connected etc)
//This way, it'll only do it as much as is left for the rest of the players
cg.shake_serverIndex = duration; //Back up the index for later
duration -= ( cg.time - cgs.levelStartTime ); //This is the actual duration, based off of length, and the time the command was received
CG_CameraShake( intensity, duration, qtrue );
}
/*
==================
CG_ParseClassData
==================
*/
/*void CG_ParseClassData( void )
{
char *str;
int i;
char *val;
char *lineChar;
char *lineCharEnd;
int colorBits;
int classBits;
str = (char *)CG_ConfigString( CS_CLASS_DATA );
if ( !str[0] )
return;
memset( &cgs.classData, 0, sizeof( cgs.classData ) );
for ( i = 0; i < MAX_CLASSES; i++ ) {
val = Info_ValueForKey( str, va( "c%i", i ) );
if (!val[0])
break;
//First slash = consoleName, so skip that
lineChar = strstr( val, "|");
lineChar++;
//next line should be formal name
lineCharEnd = strstr( lineChar, "|" );
lineCharEnd--;
val = lineChar;
val[ strlen(lineChar) - strlen(lineCharEnd) + 1] = '\0';
Q_strncpyz( cgs.classData[i].formalName, val, sizeof( cgs.classData[i].formalName ) );
//CG_Printf( S_COLOR_RED "%s\n", cgs.classData[i].formalName );
//--Next is color
lineChar = lineChar + (strlen(lineChar) - strlen(lineCharEnd))+2;
lineCharEnd = strstr( lineChar, "|" );
lineCharEnd--;
val = lineChar;
val[ strlen(lineChar) - strlen(lineCharEnd)+1] = '\0';
colorBits=atoi( val );
cgs.classData[i].radarColor[0] = colorBits & 255;
cgs.classData[i].radarColor[1] = (colorBits >> 8) & 255;
cgs.classData[i].radarColor[2] = (colorBits >> 16) & 255;
//CG_Printf( S_COLOR_RED "%i\n", colorBits );
//cgs.classData[i].showRanks = (colorBits >> 25) & 1;
//--Next is Rank Icon Color
lineChar = lineCharEnd+2;
classBits = atoi( lineChar );
cgs.classData[i].isMedic = ( classBits >> 1 ) & 1;
cgs.classData[i].showRanks = ( classBits >> 2 ) & 1;
cgs.classData[i].iconColor = ( classBits >> 4 ) & 15;
//CG_Printf( S_COLOR_RED "%i\n", classBits );
}
}*/
/*
================
CG_ConfigStringModified
================
*/
static void CG_ConfigStringModified( void ) {
const char *str;
int num;
num = atoi( CG_Argv( 1 ) );
// get the gamestate from the client system, which will have the
// new configstring already integrated
trap_GetGameState( &cgs.gameState );
// look up the individual string that was modified
str = CG_ConfigString( num );
// do something with it if necessary
if ( num == CS_MUSIC ) {
CG_StartMusic();
} else if ( num == CS_CAMERA_SHAKE ) { //RPG-X : TiM - Camera Shake
CG_ClientShakeCamera();
} else if ( num == CS_SERVERINFO ) {
CG_ParseServerinfo();
} else if ( num == CS_WARMUP ) {
CG_ParseWarmup();
} else if ( num == CS_SCORES1 ) {
cgs.scores1 = atoi( str );
} else if ( num == CS_SCORES2 ) {
cgs.scores2 = atoi( str );
} else if ( num == CS_WARMUP ) {
CG_ParseWarmup();
} else if ( num == CS_LEVEL_START_TIME ) {
cgs.levelStartTime = atoi( str );
} else if ( num == CS_VOTE_TIME ) {
cgs.voteTime = atoi( str );
cgs.voteModified = qtrue;
} else if ( num == CS_VOTE_YES ) {
cgs.voteYes = atoi( str );
cgs.voteModified = qtrue;
} else if ( num == CS_VOTE_NO ) {
cgs.voteNo = atoi( str );
cgs.voteModified = qtrue;
} else if ( num == CS_VOTE_STRING ) {
Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
} else if ( num == CS_INTERMISSION ) {
cg.intermissionStarted = atoi( str );
} else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
cgs.gameModels[ num-CS_MODELS ] = trap_R_RegisterModel( str );
} else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS ) {
if ( str[0] != '*' ) { // player specific sounds don't register here
cgs.gameSounds[ num-CS_SOUNDS] = trap_S_RegisterSound( str );
}
} else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
CG_NewClientInfo( num - CS_PLAYERS );
} else if ( num >= CS_DECOYS && num < CS_DECOYS+MAX_DECOYS ) {
CG_NewDecoyInfo( num - CS_DECOYS );
} else if ( num == CS_FLAGSTATUS ) {
// format is rb where its red/blue, 0 is at base, 1 is taken, 2 is dropped
cgs.redflag = str[0] - '0';
cgs.blueflag = str[1] - '0';
}
#ifdef XTRA
else if(num == CS_SHADERSTATE) {
CG_ShaderStateChanged();
}
#endif
}
/*
=======================
CG_AddToTeamChat
=======================
*/
static void CG_AddToTeamChat( const char *str ) {
int len;
char *p, *ls;
int lastcolor;
int chatHeight;
if (cg_teamChatHeight.integer < TEAMCHAT_HEIGHT) {
chatHeight = cg_teamChatHeight.integer;
} else {
chatHeight = TEAMCHAT_HEIGHT;
}
if (chatHeight <= 0 || cg_teamChatTime.integer <= 0) {
// team chat disabled, dump into normal chat
cgs.teamChatPos = cgs.teamLastChatPos = 0;
return;
}
len = 0;
p = cgs.teamChatMsgs[cgs.teamChatPos % chatHeight];
*p = 0;
lastcolor = '7';
ls = NULL;
while (*str) {
if (len > TEAMCHAT_WIDTH - 1) {
if (ls) {
str -= (p - ls);
str++;
p -= (p - ls);
}
*p = 0;
cgs.teamChatMsgTimes[cgs.teamChatPos % chatHeight] = cg.time;
cgs.teamChatPos++;
p = cgs.teamChatMsgs[cgs.teamChatPos % chatHeight];
*p = 0;
*p++ = Q_COLOR_ESCAPE;
*p++ = lastcolor;
len = 0;
ls = NULL;
}
if ( Q_IsColorString( str ) ) {
*p++ = *str++;
lastcolor = *str;
*p++ = *str++;
continue;
}
if (*str == ' ') {
ls = p;
}
*p++ = *str++;
len++;
}
*p = 0;
cgs.teamChatMsgTimes[cgs.teamChatPos % chatHeight] = cg.time;
cgs.teamChatPos++;
if (cgs.teamChatPos - cgs.teamLastChatPos > chatHeight)
cgs.teamLastChatPos = cgs.teamChatPos - chatHeight;
}
/*
===============
CG_MapRestart
The server has issued a map_restart, so the next snapshot
is completely new and should not be interpolated to.
A tournement restart will clear everything, but doesn't
require a reload of all the media
===============
*/
static void CG_MapRestart( void ) {
if ( cg_showmiss.integer ) {
CG_Printf( "CG_MapRestart\n" );
}
CG_InitLocalEntities();
CG_InitMarkPolys();
// make sure the "3 frags left" warnings play again
cg.fraglimitWarnings = 0;
cg.timelimitWarnings = 0;
cg.intermissionStarted = qfalse;
cgs.voteTime = 0;
CG_StartMusic();
// we really should clear more parts of cg here and stop sounds
// play the "fight" sound if this is a restart without warmup
if ( cg.warmup == 0 /* && cgs.gametype == GT_TOURNAMENT */)
{
trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER );
}
}
/***********************
CG_EncodeIDFile
The server detected that
we have a pure copy of
the ID, so it's sent us
the IP it received so we
can byte encrypt it into
an ID and save it to file
***********************/
static void CG_EncodeIDFile( void )
{
unsigned int playerID;
char *IP;
char strSubnet[3];
int intSubnet[4];
int i, j;
IP = (char *)CG_Argv( 1 );
//IP = "143.163.12.2";
//TiM - Scooter's IP List
//Double-check we're not spawning an ID off of these
if( Q_stricmp( IP, "localhost" ) //localhost
&& Q_strncmp( IP, "10.", 3 ) //class A
&& Q_strncmp( IP, "172.16.", 7 ) //class B
&& Q_strncmp( IP, "192.168.", 8 ) //class C
&& Q_strncmp( IP, "127.", 4 ) //loopback
&& Q_strncmp( IP, "169.254.", 8 ) //link-local
)
{
return;
}
//check we don't already have an ID
if ( (unsigned)atoul( sv_securityCode.string ) != SECURITY_PID )
return;
i = 0;
j = 0;
while ( *IP )
{
if( *IP != '.' )
{
if ( i < 3 )
strSubnet[i++] = *IP;
}
else
{
if ( j < 4 )
intSubnet[j++] = atoi( strSubnet );
i=0;
memset( strSubnet, 0, 3 );
}
IP++;
}
//the final cell
intSubnet[j++] = atoi( strSubnet );
//calculate the key
playerID = ( intSubnet[3] << 24 ) | ( intSubnet[2] << 16 ) | ( intSubnet[1] << 8 ) | intSubnet[0];
//CG_Printf( "%i %i %i %i - %u\n", intSubnet[0], intSubnet[1], intSubnet[2], intSubnet[3], playerID );
//encode the information into the id key file
{
fileHandle_t f;
//unsigned char buffer[SECURITY_SIZE];
int fileLen;
rpgxSecurityFile_t sF;
fileLen = trap_FS_FOpenFile( SECURITY_FILE, &f, FS_READ );
if ( !f || fileLen != SECURITY_SIZE )
{
CG_Error( "ERROR: Could not validate %s file.\n", SECURITY_FILE );
return;
}
trap_FS_Read( &sF, SECURITY_SIZE, f );
trap_FS_FCloseFile( f );
if ( !sF.ID || sF.ID != SECURITY_ID )
{
CG_Error( "ERROR: %s was loaded, but it wasn't valid.\n", SECURITY_FILE );
return;
}
//ensure the hash is valid
if ( sF.hash != atoul( sv_securityHash.string ) )
{
CG_Error( "ERROR: %s was loaded, but the hash wasn't valid.\n", SECURITY_FILE );
return;
}
//okay, reopen the file for writing, and input the new ID
f = 0;
fileLen = trap_FS_FOpenFile( SECURITY_FILE, &f, FS_WRITE );
if ( !f )
{
CG_Error( "ERROR: Could not validate %s file for writing.\n", SECURITY_FILE );
return;
}
//copy over the new key
sF.playerID = playerID;
trap_FS_Write( &sF, SECURITY_SIZE, f );
trap_FS_FCloseFile( f );
}
trap_Cvar_Set( "sv_SecurityCode", va( "%u", playerID ) );
}
/*
==================
ConcatArgs
==================
*/
char *ConcatArgs2( int start ) {
int i, c, tlen;
static char line[MAX_STRING_CHARS];
int len;
char arg[MAX_STRING_CHARS];
len = 0;
c = trap_Argc();
for ( i = start ; i < c ; i++ ) {
trap_Argv( i, arg, sizeof( arg ) );
tlen = strlen( arg );
if ( len + tlen >= MAX_STRING_CHARS - 1 ) {
break;
}
memcpy( line + len, arg, tlen );
len += tlen;
if ( i != c - 1 ) {
line[len] = ' ';
len++;
}
}
line[len] = 0;
return line;
}
#ifdef XTRA
/*
=====================
CG_ShaderStateChanged
=====================
*/
void CG_ShaderStateChanged(void) {
char originalShader[MAX_QPATH];
char newShader[MAX_QPATH];
char timeOffset[16];
const char *o;
char *n,*t;
o = CG_ConfigString( CS_SHADERSTATE );
while (o && *o) {
n = strstr(o, "=");
if (n && *n) {
strncpy(originalShader, o, n-o);
originalShader[n-o] = 0;
n++;
t = strstr(n, ":");
if (t && *t) {
strncpy(newShader, n, t-n);
newShader[t-n] = 0;
} else {
break;
}
t++;
o = strstr(t, "@");
if (o) {
strncpy(timeOffset, t, o-t);
timeOffset[o-t] = 0;
o++;
trap_R_RemapShader( originalShader, newShader, timeOffset );
}
} else {
break;
}
}
}
#endif
/*
=================
CG_ServerCommand
The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
static void CG_ServerCommand( void ) {
const char *cmd;
cmd = CG_Argv(0);
if ( !cmd[0] ) {
// server claimed the command
return;
}
//RPG-X | Phenix | 13/02/2005
// Play a insult to the n00b when moved into n00b class
if ( !strcmp( cmd, "playN00bInsult") ) {
trap_S_StartLocalSound( cgs.media.N00bSound[(rand()%N00bSoundCount)], CHAN_LOCAL_SOUND );
CG_CenterPrint( "Welcome to the n00b Class", SCREEN_HEIGHT * 0.25, BIGCHAR_WIDTH );
return;
}
// RPG-X | Phenix | 08/06/05
if ( !strcmp( cmd, "servermsg") ) {
trap_S_StartLocalSound( cgs.media.AdminMsgSound, CHAN_LOCAL_SOUND );
cg.adminMsgTime = cg.time + 10000;
Q_strncpyz( cg.adminMsgMsg, ConcatArgs2(1), sizeof( cg.adminMsgMsg ) );
//CG_CenterPrint( cg.adminMsgMsg, SCREEN_HEIGHT * 0.25, BIGCHAR_WIDTH );
return;
}
if( !strcmp( cmd, "servercprint") ) {
trap_S_StartLocalSound( cgs.media.AdminMsgSound, CHAN_LOCAL_SOUND );
//cg.adminMsgTime = cg.time + 10000;
Q_strncpyz( cg.adminMsgMsg, ConcatArgs2(1), sizeof( cg.adminMsgMsg ) );
CG_CenterPrint( cg.adminMsgMsg, SCREEN_HEIGHT * 0.25, BIGCHAR_WIDTH );
return;
}
if ( !strcmp( cmd, "cp" ) ) {
CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.25, BIGCHAR_WIDTH );
return;
}
if ( !strcmp( cmd, "cs" ) ) {
CG_ConfigStringModified();
return;
}
if ( !strcmp( cmd, "print" ) ) {
CG_Printf( "%s", CG_Argv(1) );
return;
}
if ( !strcmp( cmd, "chat" ) ) {
trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
CG_Printf( "%s\n", CG_Argv(1) );
return;
}
if ( !strcmp( cmd, "pc" ) ) {
trap_Cvar_Set("ui_playerClass", CG_Argv(1));
return;
}
if ( !strcmp( cmd, "prank" ) ) {
trap_Cvar_Set("ui_playerRank", CG_Argv(1));
return;
}
/*if ( !strcmp( cmd, "cr" ) ) {
trap_Cvar_VariableStringBuffer( "ui_playerclass", pClass, sizeof(pClass) );
trap_Cvar_VariableStringBuffer( "ui_playerrank", pRank, sizeof(pRank) );
if ( !strcmp( pClass, "maker" ) || !strcmp( pClass, "alphaomega22" ) ) {
trap_SendClientCommand( "class command" );
trap_SendClientCommand( va( "rank %s", pRank) );
}
trap_SendClientCommand( va( "class %s", pClass) );
trap_SendClientCommand( va( "rank %s", pRank) );
return;
}*/
if ( !strcmp( cmd, "tchat" ) ) {
trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
CG_AddToTeamChat( CG_Argv(1) );
CG_Printf( "%s\n", CG_Argv(1) );
return;
}
if ( !strcmp( cmd, "scores" ) ) {
CG_ParseScores();
return;
}
if ( !strcmp( cmd, "awards" ) ) {
AW_SPPostgameMenu_f();
return;
}
if ( !strcmp( cmd, "tinfo" ) ) {
CG_ParseTeamInfo();
return;
}
if ( !strcmp( cmd, "hinfo" ) ) {
CG_ParseHealthInfo();
return;
}
if ( !strcmp( cmd, "map_restart" ) ) {
CG_MapRestart();
return;
}
//TiM: Purge all active effects
if ( !strcmp( cmd, "cg_flushFX" ) ) {
int i;
for ( i = 0; i < MAX_LOCAL_ENTITIES; i ++ ) {
cg_localEntities[i].endTime = cg.time;
}
return;
}
/*if ( !strcmp( cmd, "cg_flushAngles" ) ) {
//CG_ResetPlayerEntity( &cg.predictedPlayerEntity ); //&cg_entities[ cg.predictedPlayerState.clientNum ]
cg_entities[cg.predictedPlayerState.clientNum].pe.torso.yawAngle = cg_entities[cg.predictedPlayerState.clientNum].lerpAngles[YAW];
cg_entities[cg.predictedPlayerState.clientNum].pe.legs.yawAngle = cg_entities[cg.predictedPlayerState.clientNum].lerpAngles[YAW];
return;
}*/
// loaddeferred can be both a servercmd and a consolecmd
if ( !strcmp( cmd, "loaddeferred" ) ) { // FIXME: spelled wrong, but not changing for demo
CG_LoadDeferredPlayers();
return;
}
// clientLevelShot is sent before taking a special screenshot for
// the menu system during development
if ( !strcmp( cmd, "clientLevelShot" ) ) {
cg.levelShot = qtrue;
return;
}
//TiM - client received a command from a turbolift ent
//Show the decks UI
if ( !strcmp( cmd, "lift" ) ) {
trap_SendConsoleCommand( va( "ui_turbolift %i", CG_Argv( 1 ) ) );
return;
}
//The server motd thingzor
//RPG-X | Marcin | 15/12/2008
if ( !strcmp( cmd, "motd" ) ) {
trap_SendConsoleCommand( "ui_motd_reset\n" );
trap_SendConsoleCommand( "ui_motd\n" );
return;
}
//RPG-X | Marcin | 15/12/2008
if ( !strcmp( cmd, "motd_line" ) ) {
trap_SendConsoleCommand( va( "ui_motd_line \"%s\"\n", CG_Argv( 1 ) ) );
return;
}
if ( !strcmp( cmd, "configID" ) )
{
CG_EncodeIDFile();
return;
}
if ( !strcmp( cmd, "changeClientInfo" ) )
{
//create local copy of the args
//due to the way CG_Argv works
char arg1[64];
char arg2[64];
Q_strncpyz( arg1, CG_Argv(1), sizeof(arg1) );
Q_strncpyz( arg2, CG_Argv(2), sizeof(arg2) );
trap_Cvar_Set( arg1, arg2 );
return;
}
if ( !strcmp( cmd, "playSnd" ) )
{
trap_SendConsoleCommand( va( "play %s", CG_Argv(1) ) );
return;
}
if ( !strcmp( cmd, "cg_connect" ) ) {
trap_SendConsoleCommand( va( "connect %s", CG_Argv(1) ) );
return;
}
#ifdef XTRA
if ( Q_stricmp (cmd, "remapShader") == 0 )
{
if (trap_Argc() == 4)
{
char shader1[MAX_QPATH];
char shader2[MAX_QPATH];
char shader3[MAX_QPATH];
Q_strncpyz(shader1, CG_Argv(1), sizeof(shader1));
Q_strncpyz(shader2, CG_Argv(2), sizeof(shader2));
Q_strncpyz(shader3, CG_Argv(3), sizeof(shader3));
trap_R_RemapShader(shader1, shader2, shader3);
}
return;
}
#endif
if(!strcmp(cmd, "ui_transporter")) {
trap_SendConsoleCommand(va("ui_transporter %s", CG_Argv(1)));
return;
}
if(!strcmp(cmd, "ui_trdata")) {
trap_SendConsoleCommand(va("ui_trdata \"%s\"", CG_Argv(1)));
return;
}
if(!strcmp(cmd, "holo_data")) {
trap_SendConsoleCommand(va("holo_data \"%s\"", CG_Argv(1)));
return;
}
if(!strcmp(cmd, "ui_holodeck")) {
trap_SendClientCommand(va("ui_holodeck %i", CG_Argv(1)));
return;
}
#ifdef XTRA
if(!strcmp(cmd, "sqlkey")) {
trap_SendClientCommand(va("sqlkey %i", CG_Argv(1)));
return;
}
#endif
CG_Printf( "Unknown client game command: %s\n", cmd );
}
/*
====================
CG_ExecuteNewServerCommands
Execute all of the server commands that were received along
with this this snapshot.
====================
*/
void CG_ExecuteNewServerCommands( int latestSequence ) {
while ( cgs.serverCommandSequence < latestSequence ) {
if ( trap_GetServerCommand( ++cgs.serverCommandSequence ) ) {
CG_ServerCommand();
}
}
}

397
cgame/cg_snapshot.c Normal file
View file

@ -0,0 +1,397 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_snapshot.c -- things that happen on snapshot transition,
// not necessarily every single rendered frame
#include "cg_local.h"
/*
==================
CG_ResetEntity
==================
*/
static void CG_ResetEntity( centity_t *cent ) {
// if an event is set, assume it is new enough to use
// if the event had timed out, it would have been cleared
cent->previousEvent = 0;
cent->trailTime = cg.snap->serverTime;
cent->thinkFlag = 0;
VectorCopy (cent->currentState.origin, cent->lerpOrigin);
VectorCopy (cent->currentState.angles, cent->lerpAngles);
if ( cent->currentState.eType == ET_PLAYER ) {
CG_ResetPlayerEntity( cent );
}
}
/*
===============
CG_TransitionEntity
cent->nextState is moved to cent->currentState and events are fired
===============
*/
static void CG_TransitionEntity( centity_t *cent )
{
/* qboolean bNoDrawFlag = (cent->currentState.eFlags & EF_CLIENT_NODRAW);
if (cent->nextState.eFlags & EF_NODRAW)
{
// kef -- remove our special client-only flag because the game now believes we should have EF_NODRAW
bNoDrawFlag = qfalse;
}
*/
// kef -- this will automatically remove EF_CLIENT_NODRAW because the game never sets it
cent->currentState = cent->nextState;
/* if (bNoDrawFlag)
{
cent->currentState.eFlags |= EF_NODRAW;
cent->currentState.eFlags |= EF_CLIENT_NODRAW;
}
*/
cent->currentValid = qtrue;
// reset if the entity wasn't in the last frame or was teleported
if ( !cent->interpolate ) {
CG_ResetEntity( cent );
}
// clear the next state. if will be set by the next CG_SetNextSnap
cent->interpolate = qfalse;
// check for events
CG_CheckEvents( cent );
}
/*
==================
CG_SetInitialSnapshot
This will only happen on the very first snapshot, or
on tourney restarts. All other times will use
CG_TransitionSnapshot instead.
FIXME: Also called by map_restart?
==================
*/
void CG_SetInitialSnapshot( snapshot_t *snap ) {
int i;
centity_t *cent;
entityState_t *state;
cg.snap = snap;
BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse );
// sort out solid entities
CG_BuildSolidList();
CG_ExecuteNewServerCommands( snap->serverCommandSequence );
// set our local weapon selection pointer to
// what the server has indicated the current weapon is
CG_Respawn();
for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
state = &cg.snap->entities[ i ];
cent = &cg_entities[ state->number ];
cent->currentState = *state;
cent->interpolate = qfalse;
cent->currentValid = qtrue;
CG_ResetEntity( cent );
// check for events
CG_CheckEvents( cent );
}
}
/*
===================
CG_TransitionSnapshot
The transition point from snap to nextSnap has passed
===================
*/
static void CG_TransitionSnapshot( void ) {
centity_t *cent;
snapshot_t *oldFrame;
int i;
if ( !cg.snap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg.snap" );
return;
}
if ( !cg.nextSnap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" );
return;
}
// execute any server string commands before transitioning entities
CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence );
// if we had a map_restart, set everthing with initial
if ( !cg.snap ) {
}
// clear the currentValid flag for all entities in the existing snapshot
for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
cent = &cg_entities[ cg.snap->entities[ i ].number ];
cent->currentValid = qfalse;
}
// move nextSnap to snap and do the transitions
oldFrame = cg.snap;
cg.snap = cg.nextSnap;
BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse );
cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse;
for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
cent = &cg_entities[ cg.snap->entities[ i ].number ];
CG_TransitionEntity( cent );
}
cg.nextSnap = NULL;
// check for playerstate transition events
if ( oldFrame ) {
playerState_t *ops, *ps;
ops = &oldFrame->ps;
ps = &cg.snap->ps;
// teleporting checks are irrespective of prediction
if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) {
cg.thisFrameTeleport = qtrue; // will be cleared by prediction code
//TiM - since the cg_view.c file seems to be out of scope here,
//manually reset the 3rd view
CG_ResetThirdPersonViewDamp();
cg.thirdPersonNoLerp = qtrue;
}
// if we are not doing client side movement prediction for any
// reason, then the client events and view changes will be issued now
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)
|| cg_nopredict.integer || cg_synchronousClients.integer ) {
CG_TransitionPlayerState( ps, ops );
}
}
}
/*
===================
CG_SetNextSnap
A new snapshot has just been read in from the client system.
===================
*/
static void CG_SetNextSnap( snapshot_t *snap ) {
int num;
entityState_t *es;
centity_t *cent;
cg.nextSnap = snap;
BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].nextState, qfalse );
cg_entities[ cg.snap->ps.clientNum ].interpolate = qtrue;
// check for extrapolation errors
for ( num = 0 ; num < snap->numEntities ; num++ ) {
es = &snap->entities[num];
cent = &cg_entities[ es->number ];
cent->nextState = *es;
// if this frame is a teleport, or the entity wasn't in the
// previous frame, don't interpolate
if ( !cent->currentValid || ( ( cent->currentState.eFlags ^ es->eFlags ) & EF_TELEPORT_BIT ) ) {
cent->interpolate = qfalse;
} else {
cent->interpolate = qtrue;
}
}
// if the next frame is a teleport for the playerstate, we
// can't interpolate during demos
if ( cg.snap && ( ( snap->ps.eFlags ^ cg.snap->ps.eFlags ) & EF_TELEPORT_BIT ) ) {
cg.nextFrameTeleport = qtrue;
} else {
cg.nextFrameTeleport = qfalse;
}
// if changing follow mode, don't interpolate
if ( cg.nextSnap->ps.clientNum != cg.snap->ps.clientNum ) {
cg.nextFrameTeleport = qtrue;
}
// if changing server restarts, don't interpolate
if ( ( cg.nextSnap->snapFlags ^ cg.snap->snapFlags ) & SNAPFLAG_SERVERCOUNT ) {
cg.nextFrameTeleport = qtrue;
}
// sort out solid entities
CG_BuildSolidList();
}
/*
========================
CG_ReadNextSnapshot
This is the only place new snapshots are requested
This may increment cgs.processedSnapshotNum multiple
times if the client system fails to return a
valid snapshot.
========================
*/
static snapshot_t *CG_ReadNextSnapshot( void ) {
qboolean r;
snapshot_t *dest;
if ( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
cg.latestSnapshotNum, cgs.processedSnapshotNum );
}
while ( cgs.processedSnapshotNum < cg.latestSnapshotNum ) {
// decide which of the two slots to load it into
if ( cg.snap == &cg.activeSnapshots[0] ) {
dest = &cg.activeSnapshots[1];
} else {
dest = &cg.activeSnapshots[0];
}
// try to read the snapshot from the client system
cgs.processedSnapshotNum++;
r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
// if it succeeded, return
if ( r ) {
CG_AddLagometerSnapshotInfo( dest );
return dest;
}
// a GetSnapshot will return failure if the snapshot
// never arrived, or is so old that its entities
// have been shoved off the end of the circular
// buffer in the client system.
// record as a dropped packet
CG_AddLagometerSnapshotInfo( NULL );
// If there are additional snapshots, continue trying to
// read them.
}
// nothing left to read
return NULL;
}
/*
============
CG_ProcessSnapshots
We are trying to set up a renderable view, so determine
what the simulated time is, and try to get snapshots
both before and after that time if available.
If we don't have a valid cg.snap after exiting this function,
then a 3D game view cannot be rendered. This should only happen
right after the initial connection. After cg.snap has been valid
once, it will never turn invalid.
Even if cg.snap is valid, cg.nextSnap may not be, if the snapshot
hasn't arrived yet (it becomes an extrapolating situation instead
of an interpolating one)
============
*/
void CG_ProcessSnapshots( void ) {
snapshot_t *snap;
int n;
// see what the latest snapshot the client system has is
trap_GetCurrentSnapshotNumber( &n, &cg.latestSnapshotTime );
if ( n != cg.latestSnapshotNum ) {
if ( n < cg.latestSnapshotNum ) {
// this should never happen
CG_Error( "CG_ProcessSnapshots: n < cg.latestSnapshotNum" );
}
cg.latestSnapshotNum = n;
}
// If we have yet to receive a snapshot, check for it.
// Once we have gotten the first snapshot, cg.snap will
// always have valid data for the rest of the game
while ( !cg.snap ) {
snap = CG_ReadNextSnapshot();
if ( !snap ) {
// we can't continue until we get a snapshot
return;
}
// set our weapon selection to what
// the playerstate is currently using
if ( !( snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) {
CG_SetInitialSnapshot( snap );
}
}
// loop until we either have a valid nextSnap with a serverTime
// greater than cg.time to interpolate towards, or we run
// out of available snapshots
do {
// if we don't have a nextframe, try and read a new one in
if ( !cg.nextSnap ) {
snap = CG_ReadNextSnapshot();
// if we still don't have a nextframe, we will just have to
// extrapolate
if ( !snap ) {
break;
}
CG_SetNextSnap( snap );
// if time went backwards, we have a level restart
if ( cg.nextSnap->serverTime < cg.snap->serverTime ) {
CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
return;
}
}
// if our time is < nextFrame's, we have a nice interpolating state
if ( cg.time >= cg.snap->serverTime && cg.time < cg.nextSnap->serverTime ) {
break;
}
// we have passed the transition from nextFrame to frame
CG_TransitionSnapshot();
} while ( 1 );
// assert our valid conditions upon exiting
if ( cg.snap == NULL ) {
CG_Error( "CG_ProcessSnapshots: cg.snap == NULL" );
return;
}
if ( cg.time < cg.snap->serverTime ) {
// this can happen right after a vid_restart
cg.time = cg.snap->serverTime;
}
if ( cg.nextSnap != NULL && cg.nextSnap->serverTime <= cg.time ) {
CG_Error( "CG_ProcessSnapshots: cg.nextSnap->serverTime <= cg.time" );
}
}

78
cgame/cg_syscalls.asm Normal file
View file

@ -0,0 +1,78 @@
code
equ trap_Print -1
equ trap_Error -2
equ trap_Milliseconds -3
equ trap_Cvar_Register -4
equ trap_Cvar_Update -5
equ trap_Cvar_Set -6
equ trap_Cvar_VariableStringBuffer -7
equ trap_Argc -8
equ trap_Argv -9
equ trap_Args -10
equ trap_FS_FOpenFile -11
equ trap_FS_Read -12
equ trap_FS_Write -13
equ trap_FS_FCloseFile -14
equ trap_SendConsoleCommand -15
equ trap_AddCommand -16
equ trap_SendClientCommand -17
equ trap_UpdateScreen -18
equ trap_CM_LoadMap -19
equ trap_CM_NumInlineModels -20
equ trap_CM_InlineModel -21
equ trap_CM_LoadModel -22
equ trap_CM_TempBoxModel -23
equ trap_CM_PointContents -24
equ trap_CM_TransformedPointContents -25
equ trap_CM_BoxTrace -26
equ trap_CM_TransformedBoxTrace -27
equ trap_CM_MarkFragments -28
equ trap_S_StartSound -29
equ trap_S_StartLocalSound -30
equ trap_S_ClearLoopingSounds -31
equ trap_S_AddLoopingSound -32
equ trap_S_UpdateEntityPosition -33
equ trap_S_Respatialize -34
equ trap_S_RegisterSound -35
equ trap_S_StartBackgroundTrack -36
equ trap_R_LoadWorldMap -37
equ trap_R_RegisterModel -38
equ trap_R_RegisterSkin -39
equ trap_R_RegisterShader -40
equ trap_R_ClearScene -41
equ trap_R_AddRefEntityToScene -42
equ trap_R_AddPolyToScene -43
equ trap_R_AddLightToScene -44
equ trap_R_RenderScene -45
equ trap_R_SetColor -46
equ trap_R_DrawStretchPic -47
equ trap_R_ModelBounds -48
equ trap_R_LerpTag -49
equ trap_GetGlconfig -50
equ trap_GetGameState -51
equ trap_GetCurrentSnapshotNumber -52
equ trap_GetSnapshot -53
equ trap_GetServerCommand -54
equ trap_GetCurrentCmdNumber -55
equ trap_GetUserCmd -56
equ trap_SetUserCmdValue -57
equ trap_R_RegisterShaderNoMip -58
equ trap_MemoryRemaining -59
equ trap_R_RegisterShader3D -60
equ trap_Cvar_Set_No_Modify -61
equ memset -101
equ memcpy -102
equ strncpy -103
equ sin -104
equ cos -105
equ atan2 -106
equ sqrt -107
equ floor -108
equ ceil -109
equ testPrintInt -110
equ testPrintFloat -111
equ trap_R_RemapShader -201
equ trap_R_AddPolysToScene -202

293
cgame/cg_syscalls.c Normal file
View file

@ -0,0 +1,293 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_syscalls.c -- this file is only included when building a dll
// cg_syscalls.asm is included instead when building a qvm
#include "cg_local.h"
//TiM | Hack coz VC 6 can't understand Thilo's defnitions :S
//typedef int intptr_t;
static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
syscall = syscallptr;
}
/*static int (QDECL *syscall)( int arg, ... ) = (int (QDECL *)( int, ...))-1;
void dllEntry( int (QDECL *syscallptr)( int arg,... ) ) {
syscall = syscallptr;
}*/
int PASSFLOAT( float x ) {
float floatTemp;
floatTemp = x;
return *(int *)&floatTemp;
}
void trap_Print( const char *fmt ) {
syscall( CG_PRINT, fmt );
}
void trap_Error( const char *fmt ) {
syscall( CG_ERROR, fmt );
}
int trap_Milliseconds( void ) {
return syscall( CG_MILLISECONDS );
}
void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) {
syscall( CG_CVAR_REGISTER, vmCvar, varName, defaultValue, flags );
}
void trap_Cvar_Update( vmCvar_t *vmCvar ) {
syscall( CG_CVAR_UPDATE, vmCvar );
}
void trap_Cvar_Set( const char *var_name, const char *value ) {
syscall( CG_CVAR_SET, var_name, value );
}
void trap_Cvar_Set_No_Modify( const char *var_name, const char *value ) {
syscall( CG_CVAR_SET_NO_MODIFY, var_name, value );
}
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) {
syscall( CG_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize );
}
int trap_Argc( void ) {
return syscall( CG_ARGC );
}
void trap_Argv( int n, char *buffer, int bufferLength ) {
syscall( CG_ARGV, n, buffer, bufferLength );
}
void trap_Args( char *buffer, int bufferLength ) {
syscall( CG_ARGS, buffer, bufferLength );
}
int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
return syscall( CG_FS_FOPENFILE, qpath, f, mode );
}
void trap_FS_Read( void *buffer, int len, fileHandle_t f ) {
syscall( CG_FS_READ, buffer, len, f );
}
void trap_FS_Write( const void *buffer, int len, fileHandle_t f ) {
syscall( CG_FS_WRITE, buffer, len, f );
}
void trap_FS_FCloseFile( fileHandle_t f ) {
syscall( CG_FS_FCLOSEFILE, f );
}
void trap_SendConsoleCommand( const char *text ) {
syscall( CG_SENDCONSOLECOMMAND, text );
}
void trap_AddCommand( const char *cmdName ) {
syscall( CG_ADDCOMMAND, cmdName );
}
void trap_SendClientCommand( const char *s ) {
syscall( CG_SENDCLIENTCOMMAND, s );
}
void trap_UpdateScreen( void ) {
syscall( CG_UPDATESCREEN );
}
void trap_CM_LoadMap( const char *mapname ) {
syscall( CG_CM_LOADMAP, mapname );
}
int trap_CM_NumInlineModels( void ) {
return syscall( CG_CM_NUMINLINEMODELS );
}
clipHandle_t trap_CM_InlineModel( int index ) {
return syscall( CG_CM_INLINEMODEL, index );
}
clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs ) {
return syscall( CG_CM_TEMPBOXMODEL, mins, maxs );
}
int trap_CM_PointContents( const vec3_t p, clipHandle_t model ) {
return syscall( CG_CM_POINTCONTENTS, p, model );
}
int trap_CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles ) {
return syscall( CG_CM_TRANSFORMEDPOINTCONTENTS, p, model, origin, angles );
}
void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask ) {
syscall( CG_CM_BOXTRACE, results, start, end, mins, maxs, model, brushmask );
}
void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask,
const vec3_t origin, const vec3_t angles ) {
syscall( CG_CM_TRANSFORMEDBOXTRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
}
int trap_CM_MarkFragments( int numPoints, const vec3_t *points,
const vec3_t projection,
int maxPoints, vec3_t pointBuffer,
int maxFragments, markFragment_t *fragmentBuffer ) {
return syscall( CG_CM_MARKFRAGMENTS, numPoints, points, projection, maxPoints, pointBuffer, maxFragments, fragmentBuffer );
}
void trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx ) {
syscall( CG_S_STARTSOUND, origin, entityNum, entchannel, sfx );
}
void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ) {
syscall( CG_S_STARTLOCALSOUND, sfx, channelNum );
}
void trap_S_ClearLoopingSounds( void ) {
syscall( CG_S_CLEARLOOPINGSOUNDS );
}
void trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) {
syscall( CG_S_ADDLOOPINGSOUND, entityNum, origin, velocity, sfx );
}
void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ) {
syscall( CG_S_UPDATEENTITYPOSITION, entityNum, origin );
}
void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ) {
syscall( CG_S_RESPATIALIZE, entityNum, origin, axis, inwater );
}
sfxHandle_t trap_S_RegisterSound( const char *sample ) {
return syscall( CG_S_REGISTERSOUND, sample );
}
void trap_S_StartBackgroundTrack( const char *intro, const char *loop ) {
syscall( CG_S_STARTBACKGROUNDTRACK, intro, loop );
}
void trap_R_LoadWorldMap( const char *mapname ) {
syscall( CG_R_LOADWORLDMAP, mapname );
}
qhandle_t trap_R_RegisterModel( const char *name ) {
return syscall( CG_R_REGISTERMODEL, name );
}
qhandle_t trap_R_RegisterSkin( const char *name ) {
return syscall( CG_R_REGISTERSKIN, name );
}
qhandle_t trap_R_RegisterShader( const char *name ) {
return syscall( CG_R_REGISTERSHADER, name );
}
qhandle_t trap_R_RegisterShader3D( const char *name ) {
return syscall( CG_R_REGISTERSHADER3D, name );
}
qhandle_t trap_R_RegisterShaderNoMip( const char *name ) {
return syscall( CG_R_REGISTERSHADERNOMIP, name );
}
void trap_R_ClearScene( void ) {
syscall( CG_R_CLEARSCENE );
}
void trap_R_AddRefEntityToScene( const refEntity_t *re ) {
syscall( CG_R_ADDREFENTITYTOSCENE, re );
}
void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) {
syscall( CG_R_ADDPOLYTOSCENE, hShader, numVerts, verts );
}
void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
syscall( CG_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
}
void trap_R_RenderScene( const refdef_t *fd ) {
syscall( CG_R_RENDERSCENE, fd );
}
void trap_R_SetColor( const float *rgba ) {
syscall( CG_R_SETCOLOR, rgba );
}
void trap_R_DrawStretchPic( float x, float y, float w, float h,
float s1, float t1, float s2, float t2, qhandle_t hShader ) {
syscall( CG_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h), PASSFLOAT(s1), PASSFLOAT(t1), PASSFLOAT(s2), PASSFLOAT(t2), hShader );
}
void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) {
syscall( CG_R_MODELBOUNDS, model, mins, maxs );
}
void trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame,
float frac, const char *tagName ) {
syscall( CG_R_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName );
}
void trap_GetGlconfig( glconfig_t *glconfig ) {
syscall( CG_GETGLCONFIG, glconfig );
}
void trap_GetGameState( gameState_t *gamestate ) {
syscall( CG_GETGAMESTATE, gamestate );
}
void trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime ) {
syscall( CG_GETCURRENTSNAPSHOTNUMBER, snapshotNumber, serverTime );
}
qboolean trap_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
return syscall( CG_GETSNAPSHOT, snapshotNumber, snapshot );
}
qboolean trap_GetServerCommand( int serverCommandNumber ) {
return syscall( CG_GETSERVERCOMMAND, serverCommandNumber );
}
int trap_GetCurrentCmdNumber( void ) {
return syscall( CG_GETCURRENTCMDNUMBER );
}
qboolean trap_GetUserCmd( int cmdNumber, usercmd_t *ucmd ) {
return syscall( CG_GETUSERCMD, cmdNumber, ucmd );
}
void trap_SetUserCmdValue( int stateValue, float sensitivityScale ) {
syscall( CG_SETUSERCMDVALUE, stateValue, PASSFLOAT(sensitivityScale) );
}
void testPrintInt( char *string, int i ) {
syscall( CG_TESTPRINTINT, string, i );
}
void testPrintFloat( char *string, float f ) {
syscall( CG_TESTPRINTFLOAT, string, PASSFLOAT(f) );
}
int trap_MemoryRemaining( void ) {
return syscall( CG_MEMORY_REMAINING );
}
#ifdef XTRA
void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) {
syscall( CG_R_REMAP_SHADER, oldShader, newShader, timeOffset );
}
#endif

246
cgame/cg_text.h Normal file
View file

@ -0,0 +1,246 @@
#ifndef __CG_TEXT_H__
#define __CG_TEXT_H__
// Ingame Text enum
typedef enum
{
IGT_NONE,
IGT_OUTOFAMMO,
IGT_LOWAMMO,
// Scoreboard
IGT_FRAGGEDBY,
IGT_ASSIMILATEDBY,
IGT_PLACEDWITH,
IGT_SPECTATOR,
IGT_WAITINGTOPLAY,
IGT_USETEAMMENU,
IGT_FOLLOWING,
IGT_LOADING,
IGT_AWAITINGSNAPSHOT,
IGT_PURESERVER,
IGT_CHEATSAREENABLED,
IGT_TIMELIMIT,
IGT_FRAGLIMIT,
IGT_CAPTURELIMIT,
IGT_READY,
IGT_SB_SCORE,
IGT_SB_LOC,
IGT_SB_PING,
IGT_SB_TIME,
IGT_SB_NAME,
IGT_REDTEAM,
IGT_BLUETEAM,
IGT_SAY,
IGT_SAY_TEAM,
IGT_SAY_CLASS,
IGT_POINT_LIMIT,
IGT_TIME_LIMIT,
IGT_CAPTURE_LIMIT,
IGT_GAME_FREEFORALL,
IGT_GAME_SINGLEPLAYER,
IGT_GAME_TOURNAMENT,
IGT_GAME_TEAMHOLOMATCH,
IGT_GAME_CAPTUREFLAG,
IGT_GAME_UNKNOWN,
IGT_YOUELIMINATED,
IGT_YOUASSIMILATED,
IGT_PLACEWITH,
IGT_SUICIDES,
IGT_CRATERED,
IGT_WASSQUISHED,
IGT_SANK,
IGT_MELTED,
IGT_INTOLAVA,
IGT_SAWLIGHT,
IGT_WRONGPLACE,
IGT_TRIPPEDHERGRENADE,
IGT_TRIPPEDITSGRENADE,
IGT_TRIPPEDHISGRENADE,
IGT_BLEWHERSELFUP,
IGT_BLEWITSELFUP,
IGT_BLEWHIMSELFUP,
IGT_MELTEDHERSELF,
IGT_MELTEDITSELF,
IGT_MELTEDHIMSELF,
IGT_SMALLERGUN,
IGT_DESTROYEDHERSELF,
IGT_DESTROYEDITSELF,
IGT_DESTROYEDHIMSELF,
IGT_TIEDFOR,
IGT_REDTEAMLEADS,
IGT_BLUETEAMLEADS,
IGT_TO ,
IGT_TEAMSARETIED,
IGT_ATE,
IGT_GRENADE,
IGT_WITHINBLASTRADIUS,
IGT_ALMOSTEVADED,
IGT_PHOTONBURST,
IGT_DISPATCHEDBY,
IGT_SCAVENGERWEAPON,
IGT_NEARLYAVOIDED,
IGT_RAILEDBY,
IGT_ELECTROCUTEDBY,
IGT_DESTROYEDBY,
IGT_TETRYONPULSE,
IGT_BLASTEDBY,
IGT_STASISWEAPON,
IGT_WASWITHIN,
IGT_TRANSPORTERBEAM,
IGT_WASELIMINATEDBY,
IGT_WASELIMINATED,
IGT_SNAPSHOT,
IGT_REPLICATION_MATRIX,
IGT_HOLOGRAPHIC_PROJECTORS,
IGT_SIMULATION_DATA_BASE,
IGT_SAFETY_LOCKS,
IGT_HOLODECKSIMULATION,
IGT_USEDTEAMMENU,
IGT_CONNECTIONINTERRUPTED,
IGT_VOTE,
IGT_YES,
IGT_NO,
IGT_WAITINGFORPLAYERS,
IGT_STARTSIN,
IGT_NONETEXT,
IGT_EFFICIENCY,
IGT_SHARPSHOOTER,
IGT_UNTOUCHABLE,
IGT_LOGISTICS,
IGT_TACTICIAN,
IGT_DEMOLITIONIST,
IGT_STREAK,
IGT_ROLE,
IGT_SECTION31,
IGT_ACE,
IGT_EXPERT,
IGT_MASTER,
IGT_CHAMPION,
IGT_MVP,
IGT_DEFENDER,
IGT_WARRIOR,
IGT_CARRIER,
IGT_INTERCEPTOR,
IGT_BRAVERY,
IGT_TIED_FOR,
IGT_YOUR_RANK,
IGT_YOUR_TEAM,
IGT_WON,
IGT_LOST,
IGT_TEAMS_TIED,
IGT_1ST,
IGT_2ND,
IGT_3RD,
IGT_WINNER,
IGT_CAPTURES,
IGT_POINTS,
IGT_OVERALL,
IGT_CLICK_PLAY_AGAIN,
IGT_TITLEELIMINATED,
IGT_WORSTENEMY,
IGT_FAVORITEWEAPON,
IGT_CONNECTING,
IGT_SPECTABBREV,
IGT_VICTOR,
IGT_DEFEATED,
IGT_DROWNING,
IGT_CORROSION,
IGT_BOILING,
IGT_COMPRESSION,
IGT_TRANSPORTERACCIDENT,
IGT_IMPACT,
IGT_SUICIDE,
IGT_LASERBURNS,
IGT_MISADVENTURE,
IGT_PHASERBURNS,
IGT_ENERGYSCARS,
IGT_SNIPED,
IGT_INFINITEMODULATION,
IGT_GUNNEDDOWN,
IGT_SCAVENGED,
IGT_PERMANENTSTASIS,
IGT_BLASTED,
IGT_MINED,
IGT_PERFORATED,
IGT_DISRUPTED,
IGT_WELDED,
IGT_DEGAUSSED,
IGT_DESTROYED,
IGT_ANNIHILATED,
IGT_VAPORIZED,
IGT_AUTOGUNNED,
IGT_KNOCKOUT,
IGT_ASSIMILATED,
IGT_ZAPPED,
IGT_UNKNOWN,
IGT_CASUALTY,
IGT_METHOD,
IGT_OBITELIMINATED,
IGT_CREDIT,
IGT_PLEASE,
IGT_11TH,
IGT_12TH,
IGT_13TH,
IGT_NUM_ST,
IGT_NUM_ND,
IGT_NUM_RD,
IGT_NUM_TH,
IGT_PLAYERS,
IGT_OBJECTIVES,
IGT_GAME_ELIMINATION,
IGT_GAME_ASSIMILATION,
IGT_GAME_ACTIONHERO,
IGT_GAME_SPECIALTIES,
IGT_GAME_DISINTEGRATION,
//RPG-X: RedTechie Added new text definitions
IGT_SB_RANK,
IGT_SB_RPGCLASS,
IGT_SB_HEALTHBARLCARS,
IGT_SB_HEALTHSTATUS1,
IGT_SB_HEALTHSTATUS2,
IGT_SB_HEALTHSTATUS3,
IGT_SB_HEALTHSTATUS4,
IGT_SB_HEALTHSTATUS5,
IGT_SB_HEALTHSTATUS6,
IGT_SB_FLIGHTSTATUS,
IGT_SB_CLOAKSTATUS,
IGT_SB_EVOSUITSTATUS,
IGT_PINGEDOUT,
IGT_FORCEFIELDDEATH,
IGT_FORCEDSUICIDE,
IGT_MAX
} ingameTextType_t;
extern char *ingame_text[IGT_MAX];
#endif //__CG_TEXT_H__

1707
cgame/cg_view.c Normal file

File diff suppressed because it is too large Load diff

2503
cgame/cg_weapons.c Normal file

File diff suppressed because it is too large Load diff

3
cgame/cgame.def Normal file
View file

@ -0,0 +1,3 @@
EXPORTS
vmMain
dllEntry

337
cgame/cgame.dsp Normal file
View file

@ -0,0 +1,337 @@
# Microsoft Developer Studio Project File - Name="cgame" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=cgame - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "cgame.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "cgame.mak" CFG="cgame - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "cgame - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cgame - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/StarTrek/Code-DM/cgame", VFJBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "cgame - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /out:"../Release/cgamex86.dll"
# SUBTRACT LINK32 /incremental:yes /debug
!ELSEIF "$(CFG)" == "cgame - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G5 /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /out:"../debug/cgamex86.dll"
# SUBTRACT LINK32 /profile /incremental:no /nodefaultlib
!ENDIF
# Begin Target
# Name "cgame - Win32 Release"
# Name "cgame - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "c"
# Begin Source File
SOURCE=..\game\bg_lib.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\game\bg_misc.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_oums.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_pmove.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_slidemove.c
# End Source File
# Begin Source File
SOURCE=.\cg_consolecmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_draw.c
# End Source File
# Begin Source File
SOURCE=.\cg_drawtools.c
# End Source File
# Begin Source File
SOURCE=.\cg_effects.c
# End Source File
# Begin Source File
SOURCE=.\cg_ents.c
# End Source File
# Begin Source File
SOURCE=.\cg_env.c
# End Source File
# Begin Source File
SOURCE=.\cg_event.c
# End Source File
# Begin Source File
SOURCE=.\cg_info.c
# End Source File
# Begin Source File
SOURCE=.\cg_localents.c
# End Source File
# Begin Source File
SOURCE=.\cg_main.c
# End Source File
# Begin Source File
SOURCE=.\cg_marks.c
# End Source File
# Begin Source File
SOURCE=.\cg_players.c
# End Source File
# Begin Source File
SOURCE=.\cg_playerstate.c
# End Source File
# Begin Source File
SOURCE=.\cg_predict.c
# End Source File
# Begin Source File
SOURCE=.\cg_scoreboard.c
# End Source File
# Begin Source File
SOURCE=.\cg_screenfx.c
# End Source File
# Begin Source File
SOURCE=.\cg_servercmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_snapshot.c
# End Source File
# Begin Source File
SOURCE=.\cg_syscalls.c
# End Source File
# Begin Source File
SOURCE=.\cg_view.c
# End Source File
# Begin Source File
SOURCE=.\cg_weapons.c
# End Source File
# Begin Source File
SOURCE=.\fx_borg.c
# End Source File
# Begin Source File
SOURCE=.\fx_compression.c
# End Source File
# Begin Source File
SOURCE=.\fx_dreadnought.c
# End Source File
# Begin Source File
SOURCE=.\fx_grenade.c
# End Source File
# Begin Source File
SOURCE=.\fx_imod.c
# End Source File
# Begin Source File
SOURCE=.\fx_item.c
# End Source File
# Begin Source File
SOURCE=.\fx_lib.c
# End Source File
# Begin Source File
SOURCE=.\fx_misc.c
# End Source File
# Begin Source File
SOURCE=.\fx_phaser.c
# End Source File
# Begin Source File
SOURCE=.\fx_quantum.c
# End Source File
# Begin Source File
SOURCE=.\fx_scavenger.c
# End Source File
# Begin Source File
SOURCE=.\fx_stasis.c
# End Source File
# Begin Source File
SOURCE=.\fx_tetrion.c
# End Source File
# Begin Source File
SOURCE=.\fx_transporter.c
# End Source File
# Begin Source File
SOURCE=..\game\q_math.c
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=..\game\bg_local.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_oums.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_public.h
# End Source File
# Begin Source File
SOURCE=.\cg_anims.h
# End Source File
# Begin Source File
SOURCE=.\cg_local.h
# End Source File
# Begin Source File
SOURCE=.\cg_public.h
# End Source File
# Begin Source File
SOURCE=.\cg_screenfx.h
# End Source File
# Begin Source File
SOURCE=.\cg_text.h
# End Source File
# Begin Source File
SOURCE=.\cgame.def
# End Source File
# Begin Source File
SOURCE=.\fx_local.h
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.h
# End Source File
# Begin Source File
SOURCE=..\game\surfaceflags.h
# End Source File
# Begin Source File
SOURCE=.\tr_types.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\cg_syscalls.asm
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\cgame.bat
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\cgame.q3asm
# PROP Exclude_From_Build 1
# End Source File
# End Target
# End Project

29
cgame/cgame.dsw Normal file
View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "cgame"=".\cgame.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
cgame/cgame.opt Normal file

Binary file not shown.

147
cgame/cgame.plg Normal file
View file

@ -0,0 +1,147 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: cgame - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP194.tmp" with contents
[
/nologo /G5 /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"Release/" /Fp"Release/cgame.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
"C:\stvoy\code-dm\game\bg_misc.c"
"C:\stvoy\code-dm\game\bg_pmove.c"
"C:\stvoy\code-dm\game\bg_slidemove.c"
"C:\stvoy\code-dm\cgame\cg_consolecmds.c"
"C:\stvoy\code-dm\cgame\cg_draw.c"
"C:\stvoy\code-dm\cgame\cg_drawtools.c"
"C:\stvoy\code-dm\cgame\cg_effects.c"
"C:\stvoy\code-dm\cgame\cg_ents.c"
"C:\stvoy\code-dm\cgame\cg_env.c"
"C:\stvoy\code-dm\cgame\cg_event.c"
"C:\stvoy\code-dm\cgame\cg_info.c"
"C:\stvoy\code-dm\cgame\cg_localents.c"
"C:\stvoy\code-dm\cgame\cg_main.c"
"C:\stvoy\code-dm\cgame\cg_marks.c"
"C:\stvoy\code-dm\cgame\cg_players.c"
"C:\stvoy\code-dm\cgame\cg_playerstate.c"
"C:\stvoy\code-dm\cgame\cg_predict.c"
"C:\stvoy\code-dm\cgame\cg_scoreboard.c"
"C:\stvoy\code-dm\cgame\cg_screenfx.c"
"C:\stvoy\code-dm\cgame\cg_servercmds.c"
"C:\stvoy\code-dm\cgame\cg_snapshot.c"
"C:\stvoy\code-dm\cgame\cg_syscalls.c"
"C:\stvoy\code-dm\cgame\cg_view.c"
"C:\stvoy\code-dm\cgame\cg_weapons.c"
"C:\stvoy\code-dm\cgame\fx_borg.c"
"C:\stvoy\code-dm\cgame\fx_compression.c"
"C:\stvoy\code-dm\cgame\fx_dreadnought.c"
"C:\stvoy\code-dm\cgame\fx_grenade.c"
"C:\stvoy\code-dm\cgame\fx_imod.c"
"C:\stvoy\code-dm\cgame\fx_item.c"
"C:\stvoy\code-dm\cgame\fx_lib.c"
"C:\stvoy\code-dm\cgame\fx_misc.c"
"C:\stvoy\code-dm\cgame\fx_phaser.c"
"C:\stvoy\code-dm\cgame\fx_quantum.c"
"C:\stvoy\code-dm\cgame\fx_scavenger.c"
"C:\stvoy\code-dm\cgame\fx_stasis.c"
"C:\stvoy\code-dm\cgame\fx_tetrion.c"
"C:\stvoy\code-dm\cgame\fx_transporter.c"
]
Creating command line "cl.exe @C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP194.tmp"
Creating temporary file "C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP195.tmp" with contents
[
/nologo /base:"0x30000000" /subsystem:windows /dll /incremental:yes /pdb:"Release/cgamex86.pdb" /map:"Release/cgamex86.map" /debug /machine:I386 /def:".\cgame.def" /out:"../debug/cgamex86.dll" /implib:"Release/cgamex86.lib"
".\Release\bg_misc.obj"
".\Release\bg_oums.obj"
".\Release\bg_pmove.obj"
".\Release\bg_slidemove.obj"
".\Release\cg_consolecmds.obj"
".\Release\cg_draw.obj"
".\Release\cg_drawtools.obj"
".\Release\cg_effects.obj"
".\Release\cg_ents.obj"
".\Release\cg_env.obj"
".\Release\cg_event.obj"
".\Release\cg_info.obj"
".\Release\cg_localents.obj"
".\Release\cg_main.obj"
".\Release\cg_marks.obj"
".\Release\cg_players.obj"
".\Release\cg_playerstate.obj"
".\Release\cg_predict.obj"
".\Release\cg_scoreboard.obj"
".\Release\cg_screenfx.obj"
".\Release\cg_servercmds.obj"
".\Release\cg_snapshot.obj"
".\Release\cg_syscalls.obj"
".\Release\cg_view.obj"
".\Release\cg_weapons.obj"
".\Release\fx_borg.obj"
".\Release\fx_compression.obj"
".\Release\fx_dreadnought.obj"
".\Release\fx_grenade.obj"
".\Release\fx_imod.obj"
".\Release\fx_item.obj"
".\Release\fx_lib.obj"
".\Release\fx_misc.obj"
".\Release\fx_phaser.obj"
".\Release\fx_quantum.obj"
".\Release\fx_scavenger.obj"
".\Release\fx_stasis.obj"
".\Release\fx_tetrion.obj"
".\Release\fx_transporter.obj"
".\Release\q_math.obj"
".\Release\q_shared.obj"
]
Creating command line "link.exe @C:\DOCUME~1\marcin\LOCALS~1\Temp\RSP195.tmp"
<h3>Output Window</h3>
Compiling...
bg_misc.c
bg_pmove.c
bg_slidemove.c
cg_consolecmds.c
cg_draw.c
cg_drawtools.c
cg_effects.c
cg_ents.c
cg_env.c
cg_event.c
cg_info.c
cg_localents.c
cg_main.c
cg_marks.c
cg_players.c
cg_playerstate.c
cg_predict.c
cg_scoreboard.c
cg_screenfx.c
cg_servercmds.c
cg_snapshot.c
cg_syscalls.c
cg_view.c
cg_weapons.c
fx_borg.c
fx_compression.c
fx_dreadnought.c
fx_grenade.c
fx_imod.c
fx_item.c
fx_lib.c
fx_misc.c
fx_phaser.c
fx_quantum.c
fx_scavenger.c
fx_stasis.c
fx_tetrion.c
fx_transporter.c
Linking...
Creating library Release/cgamex86.lib and object Release/cgamex86.exp
<h3>Results</h3>
cgamex86.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

42
cgame/cgame.q3asm Normal file
View file

@ -0,0 +1,42 @@
-o "C:\stvoy\code-DM\vm\cgame"
cg_main
..\cg_syscalls
cg_consolecmds
cg_draw
cg_drawtools
cg_effects
cg_ents
cg_env
cg_event
cg_info
cg_localents
cg_marks
cg_players
cg_playerstate
cg_predict
cg_scoreboard
cg_screenfx
cg_servercmds
cg_snapshot
cg_view
cg_weapons
bg_slidemove
bg_pmove
bg_lib
bg_misc
q_math
q_shared
fx_compression
fx_imod
fx_misc
fx_lib
fx_phaser
fx_scavenger
fx_tetrion
fx_transporter
fx_grenade
fx_quantum
fx_stasis
fx_item
fx_dreadnought
fx_borg

1354
cgame/cgame.vcproj Normal file

File diff suppressed because it is too large Load diff

531
cgame/cgame.vcxproj Normal file
View file

@ -0,0 +1,531 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EBB0D9E9-00FC-4DBA-AF4A-4052FE9B17B1}</ProjectGuid>
<RootNamespace>cgame</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/cgame.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>lua\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;XTRA;G_LUA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/cgame.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;lua52.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>C:\Program Files\Raven\Star Trek Voyager Elite Force\RPG-X2\cgamex86.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\cgame.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Release/cgamex86.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release/cgamex86.map</MapFileName>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<BaseAddress>0x30000000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/cgamex86.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/cgame.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<AdditionalOptions>/analyze %(AdditionalOptions)</AdditionalOptions>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/cgame.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<BrowseInformation>
</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../Release/cgamex86.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\cgame.def</ModuleDefinitionFile>
<ProgramDatabaseFile>.\Release/cgamex86.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release/cgamex86.map</MapFileName>
<SubSystem>Windows</SubSystem>
<BaseAddress>0x30000000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/cgamex86.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\game\bg_lib.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_misc.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_oums.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_pmove.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\bg_slidemove.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_consolecmds.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_draw.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_drawtools.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_effects.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_ents.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_env.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_event.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_info.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_localents.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_main.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_marks.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_players.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_playerstate.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_predict.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_scoreboard.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_screenfx.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_servercmds.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_snapshot.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_syscalls.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_view.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="cg_weapons.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_borg.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_compression.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_dreadnought.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_grenade.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_imod.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_item.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_lib.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_misc.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_phaser.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_quantum.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_scavenger.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_stasis.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_tetrion.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="fx_transporter.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\q_math.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
<ClCompile Include="..\game\q_shared.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\game\bg_local.h" />
<ClInclude Include="..\game\bg_public.h" />
<ClInclude Include="cg_anims.h" />
<ClInclude Include="cg_local.h" />
<ClInclude Include="cg_public.h" />
<ClInclude Include="cg_screenfx.h" />
<ClInclude Include="cg_text.h" />
<ClInclude Include="fx_local.h" />
<ClInclude Include="..\game\q_shared.h" />
<ClInclude Include="..\game\surfaceflags.h" />
<ClInclude Include="tr_types.h" />
</ItemGroup>
<ItemGroup>
<None Include="cgame.def" />
<CustomBuildStep Include="cg_syscalls.asm">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="cgame.bat">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="cgame.q3asm">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

186
cgame/cgame.vcxproj.filters Normal file
View file

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{90a720d9-41f5-4abf-91d4-5c109cd2d702}</UniqueIdentifier>
<Extensions>c</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{76164a83-7a3a-4473-b6db-f151d30a82d7}</UniqueIdentifier>
<Extensions>h</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\game\bg_lib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_oums.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_pmove.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\bg_slidemove.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_consolecmds.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_draw.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_drawtools.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_effects.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_ents.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_env.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_event.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_info.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_localents.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_marks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_players.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_playerstate.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_predict.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_scoreboard.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_screenfx.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_servercmds.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_snapshot.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_syscalls.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_view.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cg_weapons.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_borg.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_compression.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_dreadnought.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_grenade.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_imod.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_item.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_lib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_phaser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_quantum.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_scavenger.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_stasis.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_tetrion.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fx_transporter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\q_math.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\game\q_shared.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\game\bg_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\bg_public.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_anims.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_public.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_screenfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cg_text.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fx_local.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\q_shared.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\game\surfaceflags.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tr_types.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="cgame.def">
<Filter>Header Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="cg_syscalls.asm" />
<CustomBuildStep Include="cgame.bat" />
<CustomBuildStep Include="cgame.q3asm" />
</ItemGroup>
</Project>

3
cgame/cgame.vcxproj.user Normal file
View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

214
cgame/fx_borg.c Normal file
View file

@ -0,0 +1,214 @@
#include "cg_local.h"
#include "fx_local.h"
#define BORG_SPIN 0.6f
//------------------------------------------------------------------------------
/*void FX_BorgProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
float len;
vec3_t dir, end;
FX_AddSprite( cent->lerpOrigin, NULL, qfalse,
8.0f + ( random() * 24.0f ), 0.0f,
1.0f, 1.0f,
random() * 360, 0.0f,
1,
cgs.media.borgFlareShader);
// Energy glow
FX_AddSprite( cent->lerpOrigin, NULL, qfalse,
18.0f + ( random() * 24.0f ), 0.0f,
0.2f, 0.1f,
random() * 360, 0.0f,
1,
cgs.media.borgFlareShader);
VectorSet( dir, crandom(), crandom(), crandom() );
VectorNormalize( dir );
len = random() * 12.0f + 18.0f;
VectorMA( cent->lerpOrigin, len, dir, end );
FX_AddElectricity( cent->lerpOrigin, end, 0.2f, 0.6f, 0.0f, 0.3f, 0.0f, 5, cgs.media.borgLightningShaders[2], 1.0f );
}*/
/*
-------------------------
FX_BorgWeaponHitWall
-------------------------
*/ /*
void FX_BorgWeaponHitWall( vec3_t origin, vec3_t normal )
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_MEDKIT];
// Expanding shock ring
FX_AddQuad( origin, normal,
0.5f, 6.4f,
0.8, 0.0,
random() * 360.0f,
200,
cgs.media.borgLightningShaders[0] );
// Impact core
FX_AddQuad( origin, normal,
16.0f + ( random() * 8.0f ), 3.2f,
0.6f, 0.0f,
cg.time * BORG_SPIN,
100,
cgs.media.borgLightningShaders[0] );
//Sound
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
CG_ImpactMark( cgs.media.scavMarkShader, origin, normal, random()*360, 1,1,1,0.2, qfalse, random() + 5.5f, qfalse );
} */
/*
-------------------------
FX_BorgTaser
-------------------------
*/
/*
void FX_BorgTaser( vec3_t end, vec3_t start )
{
float len;
vec3_t dis;
FX_AddSprite( end, NULL, qfalse, 9.0f, 0.0f, 1.0f, 0.0f, 30.0f, 0.0f, 250, cgs.media.borgLightningShaders[0] );
FX_AddSprite( end, NULL, qfalse, 18.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 150, cgs.media.borgLightningShaders[0] );
FX_AddSprite( start, NULL, qfalse, 12.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 100, cgs.media.borgLightningShaders[0] );
FX_AddSprite( start, NULL, qfalse, 6.0f, 0.0f, 1.0f, 0.0f, 60.0f, 0.0f, 150, cgs.media.borgLightningShaders[0] );
VectorSubtract( start, end, dis );
len = VectorNormalize( dis );
if ( len < 96 )
len = 0.6f;
else if ( len < 256 )
len = 0.4f;
else if ( len > 512 )
len = 0.1f;
else
len = 0.2f;
FX_AddLine( start, end, 1.0f, 5.0f, 0.0f, 1.0f, 0.0f, 150, cgs.media.borgLightningShaders[1] );
FX_AddElectricity( start, end, 0.2f, 3.0f, 0.0f, 1.0f, 0.0f, 150, cgs.media.borgLightningShaders[2], len );
FX_AddElectricity( start, end, 0.5f, 2.0f, 0.0f, 1.0f, 0.0f, 150, cgs.media.borgLightningShaders[3], len );
}*/
//------------------------------------------------
// unused!
/*void FX_BorgEyeBeam( vec3_t start, vec3_t end, vec3_t normal, qboolean large )
{
float width, alpha;
vec3_t rgb = {1.0f,0.0f,0.0f};
width = 0.5f + ( crandom() * 0.1 );
if ( large )
width *= 3.5;
alpha = 0.4f + ( random() * 0.25 );
FX_AddLine2( start, end, 1.0f,
width, 0.0f, width, 0.0f,
alpha, alpha,
rgb, rgb,
1.0f,
cgs.media.whiteLaserShader );
FX_AddSprite( start, NULL, qfalse,
1.0f + (random() * 2.0f), 0.0f,
0.6f, 0.6f,
0.0f, 0.0f, 1.0f,
cgs.media.borgEyeFlareShader );
FX_AddQuad( end, normal,
2.0f + (crandom() * 1.0f), 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
cgs.media.borgEyeFlareShader );
}*/
#define BORG_PARTICLE_RADIUS 32
//------------------------------------------------------------------------------------
void FX_BorgTeleportParticles( vec3_t origin, vec3_t dir )
{
int i;
vec3_t neworg, vel;
for ( i = 0; i < 26; i++ )
{
VectorSet( neworg,
origin[0] + ( crandom() * ( BORG_PARTICLE_RADIUS * 0.5 ) ),
origin[1] + ( crandom() * ( BORG_PARTICLE_RADIUS * 0.5 ) ),
origin[2] + ( crandom() * 4.0f ) );
VectorScale( dir, 32 + ( random() * 96 ), vel );
FX_AddSprite( neworg, vel, qfalse, 1.0f + ( crandom() * 2.0f ), 0.0f, 1.0f, 0.0f, random() * 360, 0.0f, 1700, cgs.media.borgFlareShader );
}
}
//-------------------------------------
// unused
/*
void FX_BorgTeleport( vec3_t origin )
{
vec3_t org, org2, angles, dir;
localEntity_t *le;
VectorSet( angles, 0, 0, 1 );
VectorSet( org, origin[0], origin[1], origin[2] - 32 );
FX_BorgTeleportParticles( origin, angles );
VectorSet( angles, 0, 0, -1 );
VectorSet( org2, origin[0], origin[1], origin[2] + 32 );
FX_BorgTeleportParticles( origin, angles );
VectorSubtract( org2, org, dir );
VectorNormalize( dir );
le = FX_AddCylinder( org, dir, 96.0f, 0.0f, 1.0f, 48.0f, 1.0f, 48.0f, 1.0f, 0.0f, 1500, cgs.media.borgFlareShader, 0.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 24;
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.borgBeamInSound );
}*/
//-------------------------------------
//unused
/*
void FX_BorgTeleportTrails( vec3_t origin )
{
int i;
float scale;
vec3_t org, ang, angvect;
for ( i = 0; i < 2; i++ )
{
// position on the sphere
if ( i == 0 )
{
ang[ROLL] = 0;
ang[PITCH] = sin( cg.time * 0.002f ) * 360;
ang[YAW] = cg.time * 0.04f;
}
else
{
ang[ROLL] = 0;
ang[PITCH] = sin( cg.time * 0.002f + 3.14159f ) * 360;
ang[YAW] = cg.time * 0.04f + 180.0f;
}
AngleVectors( ang, angvect, NULL, NULL);
// Set the particle position
org[0] = 12 * angvect[0] + origin[0];
org[1] = 12 * angvect[1] + origin[1];
org[2] = 32 * angvect[2] + origin[2];
scale = random() * 4.0f + 4.0f;
FX_AddSprite( org, NULL, qtrue, scale, -scale, 1.0f, 1.0f, 0.0f, 0.0f, 200.0f + random() * 200.0f, cgs.media.borgFlareShader );
}
}*/

434
cgame/fx_compression.c Normal file
View file

@ -0,0 +1,434 @@
//Compression rifle weapon effects
#include "cg_local.h"
#include "fx_local.h"
qboolean AltCompressionAftereffect(localEntity_t *le)
{
localEntity_t *cyl = NULL;
qhandle_t shader = cgs.media.compressionAltBlastShader;
float percentLife = 1.0 - (le->endTime - cg.time)*le->lifeRate;
float alpha = 0.6 - (0.6*percentLife);
float length = 20;
vec3_t vec2, dir2;
cyl = FX_AddCylinder( le->refEntity.origin,
le->data.spawner.dir,
length,// height,
0,// dheight,
10,//10+(30*(1-percentLife)),// scale,
210,// dscale,
10+(30*percentLife),// scale2,
210,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
VectorMA(le->refEntity.origin, length*2.0, le->data.spawner.dir, vec2);
VectorScale(le->data.spawner.dir, -1.0, dir2);
cyl = FX_AddCylinder( vec2,
dir2,
length,// height,
0,// dheight,
10,//10+(30*(1-percentLife)),// scale,
210,// dscale,
10+(30*percentLife),// scale2,
210,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
return qtrue;
}
/*
-------------------------
FX_CompressionShot
-------------------------
*/
#define MAXRANGE_CRIFLE 8192
void FX_CompressionShot( vec3_t start, vec3_t dir )
{
localEntity_t *le;
vec3_t end;
trace_t trace;
qboolean render_impact = qtrue;
centity_t *traceEnt = NULL;
int clientNum = -1;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, 0, MASK_SHOT );
// draw the beam
le = FX_AddLine(start, trace.endpos, 1.0, 2.0, 0.0, 1.0, 1.0, 100.0, cgs.media.prifleBolt);
le->leFlags |= LEF_ONE_FRAME;
// draw an impact at the endpoint of the trace
// If the beam hits a skybox, etc. it would look foolish to add in an explosion
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
traceEnt = &cg_entities[trace.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (trace.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
FX_CompressionHit(trace.endpos);
}
else
{
FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qfalse);
}
}
}
/*
-------------------------
FX_CompressionShot
-------------------------
*/
void FX_CompressionAltShot( vec3_t start, vec3_t dir )
{
vec3_t end, vel = {0,0,0};
trace_t trace;
qboolean render_impact = qtrue;
centity_t *traceEnt = NULL;
int clientNum = -1;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, cg_entities[cg.predictedPlayerState.clientNum].currentState.number, MASK_SHOT );
// draw the beam
FX_AddLine( start, trace.endpos, 1.0f, 3.0f, 0.0f, 1.0f, 0.0f, 350/*125.0f*/, cgs.media.sparkShader );
FX_AddLine( start, trace.endpos, 1.0f, 6.0f, 20.0f, 0.6f, 0.0f, 800/*175.0f*/, cgs.media.phaserShader);//compressionAltBeamShader );
FX_AddSpawner( start, dir, vel, NULL, qfalse, 0,
0, 500, AltCompressionAftereffect, 10 );
// draw an impact at the endpoint of the trace
// If the beam hits a skybox, etc. it would look foolish to add in an explosion
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
traceEnt = &cg_entities[trace.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (trace.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
FX_CompressionHit(trace.endpos);
}
else
{
FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qtrue);
}
}
}
/*
-------------------------
FX_CompressionExplosion
-------------------------
*/
void FX_CompressionExplosion( vec3_t start, vec3_t origin, vec3_t normal, qboolean altfire )
{
localEntity_t *le;
vec3_t dir;
vec3_t velocity; //, shot_dir;
vec3_t hitpos;
float scale, dscale;
int i, j, numSparks;
weaponInfo_t *weaponInfo = &cg_weapons[WP_COMPRESSION_RIFLE];
float distance;
vec3_t color = {0.7, 0.43, 0.44};
int size = 2;
//FX_CompressionHit( origin ); //TiM: let's test if the rifle doesn't make stuff explode when its shot :)
//return;
//Sparks
//TiM: Calc spark count off proximity to effect
VectorSubtract ( cg.refdef.vieworg, origin, dir );
distance = VectorNormalize( dir );
distance = 50 * ( 1.0f - (distance / 128) ) ;
distance = Com_Clamp( 25, 50, distance );
numSparks = distance + (random() * 4.0f); //4
if (altfire)
{
numSparks *= 1.5f;
}
for ( i = 0; i < numSparks; i++ )
{
scale = 10.0f + (random() * 1.0f); //.25
dscale = -scale;
//Randomize the direction
for (j = 0; j < 3; j ++ )
{
//if ( j !=5 )
//dir[j] = normal[j] + (0.75 * crandom());
//else
dir[j] = normal[j] + (-1 * crandom()); //0.75
}
VectorNormalize(dir);
//set the speed
VectorScale( dir, 200 + (50 * crandom()), velocity); //200
le = FX_AddTrail( origin,
velocity,
qtrue, //qtrue
12.0f,//4
-12.0f,//4
scale,
-scale,
1.0f,
1.0f,
0.5f,
1000.0f, //1000
cgs.media.orangeStarShader);
// FXE_Spray( normal, 200, 50, 0.4f, le);
}
VectorMA( origin, 8, normal, dir );
VectorSet(velocity, 0, 0, 8);
/*
FX_AddSprite( dir,
velocity,
qfalse,
(altfire?50.0f:32.0f),
16.0f,
1.0f,
0.0f,
random()*45.0f,
0.0f,
(altfire?1300.0f:1000.0f),
cgs.media.steamShader );
*/
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
if (!altfire)
{
CG_InitLensFlare( origin,
350, 350,
color, 1.2, 2.0, 1600, 200,
color, 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 210);
VectorMA(origin, size, normal, hitpos);
FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.liteRedParticleShader );
FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f,
1.0f, 0.0f, 0.0f, 0, 400, cgs.media.liteRedParticleStreakShader );
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader,
475, qfalse, 1.2f + ( crandom() * 0.3f), LEF_NONE);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 12, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 1, 200 );
}
else
{
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader,
500, qfalse, 2.2f + ( crandom() * 0.4f), LEF_NONE);
le->light = 200;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 28, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 2, 240 );
}
// nice explosion sound at the point of impact
trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
}
/*
-------------------------
FX_CompressionHit
-------------------------
*/
void FX_CompressionHit( vec3_t origin )
{
FX_AddSprite( origin,
NULL,
qfalse,
32.0f,
-32.0f,
1.0f,
1.0f,
random()*360,
0.0f,
250.0f,
cgs.media.prifleImpactShader );
//FIXME: Play an impact sound with a body
// trap_S_StartSound (origin, NULL, 0, cgi_S_RegisterSound ("sound/weapons/prifle/fire.wav") );
}
void FX_PrifleBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.prifleBeam;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 2.5f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = rand() & 1 + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}

310
cgame/fx_dreadnought.c Normal file
View file

@ -0,0 +1,310 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_DreadnoughtHitWall
-------------------------
*/
/*void FX_DreadnoughtHitWall( vec3_t origin, vec3_t normal, qboolean spark )
{
float scale = 1.0f + ( random() * 1.0f );
int num, i;
localEntity_t *le = NULL;
vec3_t vel;
// weaponInfo_t *weaponInfo = &cg_weapons[WP_DERMAL_REGEN];
// trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound);
le = FX_AddQuad( origin, normal, 32.0 + random() * 48, 0, 0.5, 0.5, 0, 100, cgs.media.purpleParticleShader );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
le = FX_AddQuad( origin, normal, 24.0 + random() * 32, 0, 0.6, 0.6, 0, 100, cgs.media.ltblueParticleShader );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
CG_ImpactMark( cgs.media.scavMarkShader, origin, normal, random()*360, 1,1,1,0.2, qfalse,
random() * 4 + 8, qfalse );
if ( spark )
{
trap_R_AddLightToScene( origin, 75 + (rand()&31), 1.0, 0.8, 1.0 );
// Drop some sparks
num = (int)(random() * 2) + 2;
for ( i = 0; i < num; i++ )
{
scale = 0.6f + random();
if ( rand() & 1 )
FXE_Spray( normal, 70, 80, 0.9f, vel);
else
FXE_Spray( normal, 80, 200, 0.5f, vel);
FX_AddTrail( origin, vel, qfalse, 8.0f + random() * 8, -48.0f,
scale, -scale, 1.0f, 0.8f, 0.4f, 600.0f, cgs.media.spark2Shader );
}
}
}*/
/*
-------------------------
FX_DreadnoughtFire
-------------------------
*/
/*void FX_DreadnoughtFire( vec3_t origin, vec3_t end, vec3_t normal, qboolean spark, qboolean impact )
{
// localEntity_t *le = NULL;
float scale = 1.0f + ( random() * 1.0f );
refEntity_t beam;
// Draw beams first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( origin, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE;
beam.customShader = cgs.media.dnBoltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*0.2;
beam.shaderRGBA[1] = 0xff*0.2;
beam.shaderRGBA[2] = 0xff*0.2;
beam.shaderRGBA[3] = 0xff;
beam.data.line.stscale = 2.0;
beam.data.line.width = scale*6;
trap_R_AddRefEntityToScene( &beam );
// Add second core beam
memset( &beam, 0, sizeof( beam ) );
VectorCopy( origin, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE;
beam.customShader = cgs.media.dnBoltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*0.8;
beam.shaderRGBA[1] = 0xff*0.8;
beam.shaderRGBA[2] = 0xff*0.8;
beam.shaderRGBA[3] = 0xff;
beam.data.line.stscale = 1.0;
beam.data.line.width = scale*4.5;
trap_R_AddRefEntityToScene( &beam );
if (spark)
{
// Add first electrical bolt
memset( &beam, 0, sizeof( beam ) );
VectorCopy( origin, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_ELECTRICITY;
beam.customShader = cgs.media.dnBoltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*0.8;
beam.shaderRGBA[1] = 0xff*0.8;
beam.shaderRGBA[2] = 0xff*0.8;
beam.shaderRGBA[3] = 0xff;
beam.data.electricity.stscale = 1.0;
beam.data.electricity.width = scale*0.5;
beam.data.electricity.deviation = 0.2;
trap_R_AddRefEntityToScene( &beam );
}
// Add next electrical bolt
memset( &beam, 0, sizeof( beam ) );
VectorCopy( origin, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_ELECTRICITY;
beam.customShader = cgs.media.dnBoltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*0.8;
beam.shaderRGBA[1] = 0xff*0.8;
beam.shaderRGBA[2] = 0xff*0.8;
beam.shaderRGBA[3] = 0xff;
beam.data.electricity.stscale = 1.0;
beam.data.electricity.width = scale*0.75;
beam.data.electricity.deviation = 0.12;
trap_R_AddRefEntityToScene( &beam );
/*
le = FX_AddLine( origin, end, 2.0f, scale * 6, 0.0f, 0.2f, 0.2f, 100, cgs.media.dnBoltShader );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
le = FX_AddLine( origin, end, 1.0f, scale * 4.5, 0.0f, 0.8f, 0.8f, 100, cgs.media.dnBoltShader );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
if ( spark )
{
le = FX_AddElectricity( origin, end, 1.0f, scale * 0.5, 0, 0.8, 0.8, 100, cgs.media.dnBoltShader, 0.2 );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
}
le = FX_AddElectricity( origin, end, 1.0f, scale * 0.75, 0, 0.8, 0.8, 100, cgs.media.dnBoltShader, 0.12 );
if (le)
{
le->leFlags |= LEF_ONE_FRAME;
}
// Add a subtle screen shake
CG_ExplosionEffects( origin, 1.0f, 15 );
if (impact)
{
FX_DreadnoughtHitWall( end, normal, spark );
}
}*/
/*
-------------------------
FX_DreadnoughtProjectileThink
Freaky random lightning burst
-------------------------
*/
/*#define FX_DN_ALT_THINK_TIME 100
void FX_DreadnoughtProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
// refEntity_t beam;
float scale;
scale = flrandom(10.0, 15.0);
// If this is a new thinking time, draw some starting stuff...
if (cent->miscTime < cg.time)
{
trace_t trace;
vec3_t fwd, right, boltdir, boltend, mins={-2,-2,-2}, maxs={2,2,2};
float len;
localEntity_t *le;
int playSound = 1;//(irandom(0,1) == 0)?1:0;
cent->miscTime = cg.time + FX_DN_ALT_THINK_TIME;
VectorSubtract(cent->currentState.origin, cent->currentState.origin2, fwd);
// Throw a sprite from the start to the end over the next
VectorScale(fwd, 1000.0*(1.0/FX_DN_ALT_THINK_TIME), boltdir);
le = FX_AddSprite(cent->currentState.origin2, boltdir, qfalse, scale*8, -scale*2, 1.0, 1.0, 0, 0, FX_DN_ALT_THINK_TIME, cgs.media.blueParticleShader);
le->light = 200;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.5f, 0.8f, 1.0f );
len = VectorNormalize(fwd);
// Illegal if org and org2 are the same.
if (len<=0)
return;
// Draw a bolt from the old position to the new.
FX_AddLine( cent->currentState.origin2, cent->currentState.origin, 1.0, scale*4, -scale*4, 0.75, 0.0, FX_DN_ALT_THINK_TIME*2, cgs.media.dnBoltShader);
// ALSO draw an electricity bolt from the old position to the new.
FX_AddElectricity( cent->currentState.origin2, cent->currentState.origin, 0.2f, scale, -scale, 1.0, 0.5, FX_DN_ALT_THINK_TIME*2, cgs.media.dnBoltShader, 0.5 );
// And a bright new sprite at the current locale.
FX_AddSprite(cent->currentState.origin, NULL, qfalse, scale*2, scale*4, 1.0, 1.0, 0, 0, FX_DN_ALT_THINK_TIME, cgs.media.blueParticleShader);
// Put a sprite in the old position, fading away.
FX_AddSprite(cent->currentState.origin2, NULL, qfalse, scale*5, -scale*5, 1.0, 1.0, 0, 0, FX_DN_ALT_THINK_TIME*2, cgs.media.blueParticleShader);
// Shoot rays out (roughly) to the sides to connect with walls or whatever...
// PerpendicularVector(right, fwd);
right[0] = fwd[1];
right[1] = -fwd[0];
right[2] = -fwd[2];
// Right vector
// The boltdir uses a random offset to the perp vector.
boltdir[0] = right[0] + flrandom(-0.25, 0.25);
boltdir[1] = right[1] + flrandom(-0.25, 0.25);
boltdir[2] = right[2] + flrandom(-1.0, 1.0);
// Shoot a vector off to the side and trace till we hit a wall.
VectorMA(cent->currentState.origin, 256, boltdir, boltend);
CG_Trace( &trace, cent->currentState.origin, mins, maxs, boltend, cent->currentState.number, MASK_SOLID );
if (trace.fraction < 1.0)
{
VectorCopy(trace.endpos, boltend);
FX_AddElectricity( cent->currentState.origin, boltend, 0.2f, scale, -scale, 1.0, 0.5, FX_DN_ALT_THINK_TIME*2, cgs.media.dnBoltShader, 0.5 );
// Put a sprite at the endpoint that stays.
FX_AddQuad(trace.endpos, trace.plane.normal, scale, -scale*0.5, 1.0, 0.5, 0.0, FX_DN_ALT_THINK_TIME*2, cgs.media.blueParticleShader);
if (playSound)
{
if (irandom(0,1))
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_DERMAL_REGEN];
trap_S_StartSound(trace.endpos, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->alt_missileSound);
playSound = 0;
}
}
}
// Left vector
// The boltdir uses a random offset to the perp vector.
boltdir[0] = -right[0] + flrandom(-0.25, 0.25);
boltdir[1] = -right[1] + flrandom(-0.25, 0.25);
boltdir[2] = -right[2] + flrandom(-1.0, 1.0);
// Shoot a vector off to the side and trace till we hit a wall.
VectorMA(cent->currentState.origin, 256, boltdir, boltend);
CG_Trace( &trace, cent->currentState.origin, mins, maxs, boltend, cent->currentState.number, MASK_SOLID );
if (trace.fraction < 1.0)
{
VectorCopy(trace.endpos, boltend);
FX_AddElectricity( cent->currentState.origin, boltend, 0.2f, scale, -scale, 1.0, 0.5, FX_DN_ALT_THINK_TIME*2, cgs.media.dnBoltShader, 0.5 );
// Put a sprite at the endpoint that stays.
FX_AddQuad(trace.endpos, trace.plane.normal, scale, -scale*0.5, 1.0, 0.5, 0.0, FX_DN_ALT_THINK_TIME*2, cgs.media.blueParticleShader);
if (playSound)
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_DERMAL_REGEN];
trap_S_StartSound(trace.endpos, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->alt_missileSound);
playSound = 0;
}
}
}
}*/
/*
-------------------------
FX_DreadnoughtShotMiss
Alt-fire, miss effect
-------------------------
*/
/*void FX_DreadnoughtShotMiss( vec3_t end, vec3_t dir )
{
vec3_t org;
weaponInfo_t *weaponInfo = &cg_weapons[WP_DERMAL_REGEN];
trap_S_StartSound(end, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound);
// Move me away from the wall a bit so that I don't z-buffer into it
VectorMA( end, 0.5, dir, org );
// Expanding rings
// FX_AddQuad( org, dir, 1, 24, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
// FX_AddQuad( org, dir, 1, 60, 0.8, 0.2, random() * 360, 300, cgs.media.stasisRingShader );
// Impact effect
FX_AddQuad( org, dir, 7, 35, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
FX_AddQuad( org, dir, 5, 25, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
CG_ImpactMark( cgs.media.scavMarkShader, org, dir, random()*360, 1,1,1,0.6, qfalse,
8 + random() * 2, qfalse );
FX_AddSprite( end, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
}*/

350
cgame/fx_grenade.c Normal file
View file

@ -0,0 +1,350 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_GrenadeThink
-------------------------
*/
void FX_GrenadeThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 8.0f + random() * 32.0f, 0.0f, 0.75f, 0.75f, 0, 0.0f, 1, cgs.media.dkorangeParticleShader );
if ( rand() & 1 )
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 16.0f + random() * 32.0f, 0.0f, 0.6f, 0.6f, 0, 0.0f, 1, cgs.media.yellowParticleShader );
}
/*
-------------------------
FX_GrenadeHitWall
-------------------------
*/
void FX_GrenadeHitWall( vec3_t origin, vec3_t normal )
{
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
CG_SurfaceExplosion( origin, normal, 8, 1, qfalse );
}
/*
-------------------------
FX_GrenadeHitPlayer
-------------------------
*/
void FX_GrenadeHitPlayer( vec3_t origin, vec3_t normal )
{
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
CG_SurfaceExplosion( origin, normal, 8, 1, qfalse );
}
/*
-------------------------
FX_GrenadeExplode
-------------------------
*/
void FX_GrenadeExplode( vec3_t origin, vec3_t normal )
{
localEntity_t *le;
qhandle_t null;
vec3_t direction, org, vel;
int i;
VectorSet( direction, 0,0,1 );
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, null, 250, qfalse, 25.0f, LEF_FADE_RGB);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
FX_AddQuad( origin, normal, 5, 100, 1.0, 0.0, random() * 360, 300, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( normal, 470, 325, 0.5f, vel);
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );
// Smoke and impact
// FX_AddSpawner( origin, normal, NULL, NULL, 100, 25.0f, 2000.0f, (void *) CG_SmokeSpawn, NULL, 1024 );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
}
/*void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
localEntity_t *le;
vec3_t direction, org, vel;
int i;
VectorCopy( norm, direction);
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, (qhandle_t)NULL, 250, qfalse, 25.0f, LEF_FADE_RGB);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
FX_AddQuad( origin, norm, 5, 100, 1.0, 0.0, random() * 360, 300, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( norm, 470, 325, 0.5f, vel);
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExnull
// Smoke and impact
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
}*/
//-----------------------------------
//By: RedTechie - Imported/Modifyed from SP
//-----------------------------------
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
localEntity_t *le;
//FXTrail *fx;
vec3_t direction, org, vel;
int i;
CG_InitLensFlare( origin,
350, 350,
colorTable[CT_DKRED1], 1.2, 2.0, 1600, 200,
colorTable[CT_DKRED1], 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 90, 0, 300);
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
VectorMA( origin, 12, direction, org );
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 6, cgs.media.surfaceExplosionShader, 700, qfalse, 1.2f + (random()*0.5f),LEF_FADE_RGB ); //RPG-X: RedTechie - Scale use to be 1.2f + (random()*0.3f)
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );
VectorMA( org, 8, norm, direction );
VectorSet(vel, 0, 0, 8);
//Some smoke
FX_AddSprite( direction,
vel,
qfalse,
20.0f + random()*50.0f,//1.2f + (random()*0.5f),//60.0f - random()*60.0f
16.0f,
100.0f,//1.0f
100.0f,//0.0f
random()*45.0f,
-12.0f,
8000.0f,
cgs.media.steamShader );
for ( i = 0; i < 6; i++)
{
float width, length;
FXE_Spray( norm, 500, 175, 0.8f, vel);//, (FXPrimitive *) fx
length = 24.0 + random() * 12;
width = 0.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 2500.0f, cgs.media.orangeTrailShader);//RPG-X: RedTechie - Killtime use to be 1000.0f
/*FX_AddTrail( origin, NULL, NULL, 16.0f, -15.0f,
1.5, -1.5, 1.0f, 1.0f, 0.2f, 1000.0f, cgs.media.orangeTrailShader, rand() & FXF_BOUNCE );
*/
/*if ( fx == NULL )
return;*/
}
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 2.0, 350 );
}
qboolean GrenadeBeep(localEntity_t *le)
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_GRENADE_LAUNCHER];
trap_S_StartSound(le->refEntity.origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound);
return qtrue;
}
/*
-------------------------
FX_GrenadeShrapnelBits
By: RedTechie - From SP
-------------------------
*/
/*void FX_BlowBits( vec3_t start, vec3_t end, vec3_t dir, vec3_t user )
{
vec3_t diff, org;
float len;
// FXLine *fx;
VectorSubtract( end, start, diff );
len = VectorNormalize( diff ) * ( 0.2 + random() * 0.3 );
VectorMA( start, len, diff, org );
//fx =
FX_AddLine( end, start, (int)(random() * 3.2f), 2.0f + random() * 2, 0, 0.5f, 0.1f, 150 + random() * 150, cgs.media.orangeTrailShader );
//if ( fx == NULL )
// return;
//fx->SetFlags( FXF_SHRINK );
FX_AddQuad( end, dir, NULL, NULL, 1.0f, 64.0f, 1.0, 0.0, random() * 360.0f, 0.0f, 0.0, 200, cgs.media.orangeRingShader );
// FX_AddQuad( end, dir, NULL, NULL, 20.0, -15.0, 0.6, 0.4, 0.0,0.0,0.0,450, cgs.media.borgEyeFlareShader );
}
*/
#define FX_GRENADE_ALT_STICK_TIME 2500
void FX_GrenadeShrapnelBits( vec3_t start )
{
vec3_t zero = {0, 0, 0};
// check G_MissileStick() to make sure this killtime coincides with that nextthink
FX_AddSpawner( start, zero, NULL, NULL, qfalse, 300,
0, FX_GRENADE_ALT_STICK_TIME, GrenadeBeep, 10 );
}
/*
-------------------------
FX_fxfunc_Explosion
-------------------------
*/
void FX_fxfunc_Explosion( vec3_t start, vec3_t origin, vec3_t normal )
{
localEntity_t *le;
vec3_t dir;
vec3_t velocity;
// vec3_t end;
// trace_t trace;
float scale, dscale;
int i, j, numSparks;
//weaponInfo_t *weaponInfo = &cg_weapons[WP_COMPRESSION_RIFLE];
//float scale, dscale;
// int s;
// vec3_t new_org;
//Sparks
numSparks = 20 + (random() * 4.0f);//4
for ( i = 0; i < numSparks; i++ )
{
scale = 0.25f + (random() * 1.0f);
dscale = -scale;
//Randomize the direction
for (j = 0; j < 3; j ++ )
{
dir[j] = normal[j] + (0.75 * crandom());
}
VectorNormalize(dir);
//set the speed
VectorScale( dir, 200 + (50 * crandom()), velocity);
le = FX_AddTrail( origin,
velocity,
qtrue,
4.0f,
-4.0f,
scale,
-scale,
1.0f,
1.0f,
0.5f,
1000.0f,
cgs.media.sparkShader);
}
VectorMA( origin, 8, normal, dir );
VectorSet(velocity, 0, 0, 8);
// Smoke puffs
FX_AddSprite( dir,
velocity,
qfalse,
20.0f + random()*60.0f,//2.2f + ( crandom() * 0.9f),//60.0f - random()*60.0f
16.0f,
100.0f,//1.0f
100.0f,//0.0f
random()*45.0f,
-12.0f,
8000.0f,
cgs.media.steamShader );
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader, 475, qfalse, 2.2f + ( crandom() * 0.9f), LEF_NONE);//RPG-X: RedTechie - Scale use to be - 1.2f + ( crandom() * 0.3f)
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
//CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 12, qfalse );
//Shake the camera
CG_ExplosionEffects( origin, 2, 400 );
// nice explosion sound at the point of impact
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );
//trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
}
/*
-------------------------
FX_fxfunc_Shot
-------------------------
*/
#define MAXRANGE_CRIFLE 8192
void FX_fxfunc_Shot( vec3_t start, vec3_t dir )
{
vec3_t end;
trace_t trace;
VectorMA(start, MAXRANGE_CRIFLE, dir, end);
CG_Trace( &trace, start, NULL, NULL, end, 0, MASK_SHOT );
//FX_CompressionExplosion(start, trace.endpos, trace.plane.normal, qfalse );
FX_fxfunc_Explosion(start, trace.endpos, trace.plane.normal);
}

315
cgame/fx_imod.c Normal file
View file

@ -0,0 +1,315 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_AltIMODBolt
-------------------------
*/
/*void FX_AltIMODBolt( vec3_t start, vec3_t end, vec3_t dir )
{
vec3_t control1, control2, control1_vel, control2_vel,
control1_acceleration, control2_acceleration;
vec3_t direction, vr, vu;
float len;
localEntity_t *le;
MakeNormalVectors( dir, vr, vu );
VectorSubtract( end, start, direction );
len = VectorNormalize( direction );
VectorMA(start, len*0.5f, direction, control1 );
VectorMA(start, len*0.25f, direction, control2 );
vectoangles( direction, control1_vel );
control1_vel[ROLL] += crandom() * 360;
AngleVectors( control1_vel, NULL, NULL, control1_vel );
vectoangles( direction, control2_vel );
control2_vel[ROLL] += crandom() * 360;
AngleVectors( control2_vel, NULL, NULL, control2_vel );
VectorScale(control1_vel, 12.0f + (140.0f * random()), control1_vel);
VectorScale(control2_vel, -12.0f + (-140.0f * random()), control2_vel);
VectorClear(control1_acceleration);
VectorClear(control2_acceleration);
le = FX_AddBezier( start, end,
control1, control2, control1_vel, control2_vel, control1_acceleration, control2_acceleration,
4.0f, //scale
1000.0f, //killtime
cgs.media.IMOD2Shader );
le->alpha = 0.8;
le->dalpha = -0.8;
}*/
/*
-------------------------
FX_IMODBolt2
-------------------------
*/
/*void FX_IMODBolt2( vec3_t start, vec3_t end, vec3_t dir )
{
vec3_t control1, control2, control1_velocity, control2_velocity,
control1_acceleration, control2_acceleration;
float length = 0;
vec3_t vTemp;
localEntity_t *le;
// initial position of control points
VectorSubtract(end, start, vTemp);
length = VectorNormalize(vTemp);
VectorMA(start, 0.5 * length, vTemp, control1);
VectorMA(start, 0.25 * length, vTemp, control2);
// initial velocity of control points
vectoangles(vTemp, control1_velocity);
control1_velocity[ROLL] += crandom() * 360;
AngleVectors(control1_velocity, NULL, NULL, control1_velocity);
vectoangles(vTemp, control2_velocity);
control2_velocity[ROLL] += crandom() * 360;
AngleVectors(control2_velocity, NULL, NULL, control2_velocity);
VectorScale(control1_velocity, 12.0f + (140.0f * random()), control1_velocity);
VectorScale(control2_velocity, -12.0f + (-140.0f * random()), control2_velocity);
// constant acceleration of control points
/*
VectorScale(control1_velocity, -1.2, control1_acceleration);
for (i = 0; i < 3; i++)
{
control1_acceleration[i] += flrandom (-10, 10);
}
VectorScale(control2_velocity, -1.2, control2_acceleration);
for (i = 0; i < 3; i++)
{
control2_acceleration[i] += flrandom (-10, 10);
}
*/
// VectorClear(control1_acceleration);
// VectorClear(control2_acceleration);
//
// le = FX_AddBezier(start, end, control1, control2, control1_velocity, control2_velocity, control1_acceleration,
// control2_acceleration, 4, 600, cgs.media.altIMOD2Shader);
// le->alpha = 0.6;
// le->dalpha = -0.6;
//}*/
/*
-------------------------
FX_IMODShot
-------------------------
*/
//#define MAXRANGE_IMOD 8192
/*void FX_IMODShot( vec3_t end, vec3_t start, vec3_t dir)
{
vec3_t ofs, end2;
trace_t trace;
qboolean render_impact = qtrue;
VectorMA( end, 1, dir, ofs );
FX_AddLine(start, end, 1.0, 8.0, -8.0, 1.0, 0.0, 350, cgs.media.altIMODShader);
FX_IMODBolt2( start, end, dir);
// cover up the start point of the beam
FX_AddSprite( start, NULL, qfalse, irandom(8,12), -8, 1.0, 0.6, random()*360, 0.0, 400, cgs.media.purpleParticleShader);
// where do we put an explosion?
VectorMA(start, MAXRANGE_IMOD, cg.refdef.viewaxis[0], end2);
CG_Trace( &trace, start, NULL, NULL, end2, 0, MASK_SHOT );
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
FX_IMODExplosion(end, trace.plane.normal);
}
}*/
/*
-------------------------
FX_AltIMODShot
-------------------------
*/
//unused
/*#define FX_ALT_IMOD_HOLD 200
#define FX_ALT_IMOD_FLASHSIZE 16
qboolean IMODAltAftereffect(localEntity_t *le)
{
localEntity_t *spr = NULL;
qhandle_t shader = cgs.media.blueParticleShader;
//only want an initial sprite
le->endTime = cg.time;
spr = FX_AddSprite( le->refEntity.origin,// origin
NULL, // velocity
qfalse, // gravity
FX_ALT_IMOD_FLASHSIZE, // scale
-10, // dscale
0.8, // startalpha
0.0, // endalpha
0.0, // roll
0.0, // elasticity
700, // killTime
shader); // shader
return qtrue;
}*/
/*void FX_AltIMODShot( vec3_t end, vec3_t start, vec3_t dir)
{
vec3_t ofs, end2;
int i = 0;
trace_t trace;
qboolean render_impact = qtrue;
VectorMA( end, 1, dir, ofs );
FX_AddLine( start, end, 1.0f, 32.0f, -32.0f, 1.0f, 1.0f, 500.0f, cgs.media.IMODShader);
for ( i = 0; i < 2; i++ )
FX_AltIMODBolt( start, end, dir );
// cover up the start point of the beam
FX_AddSprite( start, NULL, qfalse, FX_ALT_IMOD_FLASHSIZE, 0, 1.0, 0.6, 0.0, 0.0, FX_ALT_IMOD_HOLD, cgs.media.blueParticleShader);
FX_AddSpawner( start, dir, NULL, NULL, qfalse, FX_ALT_IMOD_HOLD,
0, FX_ALT_IMOD_HOLD+100, IMODAltAftereffect, 10 );
// where do we put an explosion?
VectorMA(start, MAXRANGE_IMOD, cg.refdef.viewaxis[0], end2);
CG_Trace( &trace, start, NULL, NULL, end2, 0, MASK_SHOT );
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if ( render_impact )
{
FX_AltIMODExplosion(end, trace.plane.normal);
}
}*/
/*
-------------------------
FX_IMODExplosion
-------------------------
*/
/*void FX_IMODExplosion( vec3_t origin, vec3_t normal )
{
localEntity_t *le;
vec3_t direction, vel;
float scale, dscale;
int i, numSparks;
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
//Tag the last one with a light
le = CG_MakeExplosion( origin, direction, cgs.media.explosionModel, cgs.media.imodExplosionShader, 400, qfalse);
le->light = 75;
VectorSet( le->lightColor, 1.0f, 0.8f, 0.5f );
//Sparks
numSparks = 3 + (rand() & 7);
// kef -- fixme. what does vel do?
VectorClear(vel);
for ( i = 0; i < numSparks; i++ )
{
scale = 1.0f + (random() * 0.5f);
dscale = -scale*0.5;
FX_AddTrail( origin,
NULL,
qfalse,
32.0f + (random() * 64.0f),
-256.0f,
scale,
0.0f,
1.0f,
0.0f,
0.25f,
750.0f,
cgs.media.purpleParticleShader );
//FXE_Spray( normal, 500, 250, 0.75f, /*256,*///vel );
//}
//CG_ImpactMark( cgs.media.IMODMarkShader, origin, normal, random()*360, 1,1,1,0.75, qfalse, 5, qfalse );
// CG_ImpactMark( cgs.media.scavMarkShader, origin, normal, random()*360, 1,1,1,0.2, qfalse, random() + 1, qfalse );
// CG_ExplosionEffects( origin, 1.0f, 150 );
//}*/
/*
-------------------------
FX_AltIMODExplosion
-------------------------
*/
/*void FX_AltIMODExplosion( vec3_t origin, vec3_t normal )
{
localEntity_t *le;
vec3_t direction, org, vel;
float scale, dscale;
int i, numSparks;
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
//Tag the last one with a light
le = CG_MakeExplosion( origin, direction, cgs.media.explosionModel, cgs.media.electricalExplosionSlowShader, 475, qfalse);
le->light = 150;
VectorSet( le->lightColor, 1.0f, 0.8f, 0.5f );
for ( i = 0; i < 2; i ++)
{
VectorSet( org, origin[0] + 16 * random(), origin[1] + 16 * random(), origin[2] + 16 * random() );
CG_MakeExplosion( org, direction, cgs.media.explosionModel, cgs.media.electricalExplosionFastShader,
250, qfalse);
}
//Sparks
numSparks = 8 + (rand() & 7);
// kef -- fixme. what does this vector do!?! waaaaaah!
VectorClear(vel);
for ( i = 0; i < numSparks; i++ )
{
scale = 1.5f + (random() * 0.5f);
dscale = -scale*0.5;
FX_AddTrail( origin,
NULL,
qfalse,
32.0f + (random() * 64.0f),
-256.0f,
scale,
0.0f,
1.0f,
0.0f,
0.25f,
750.0f,
cgs.media.spark2Shader );
FXE_Spray( normal, 500, 250, 0.75f, /*256,*/ //vel );
//}
//CG_ImpactMark( cgs.media.IMODMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 8, qfalse );
//CG_ExplosionEffects( origin, 2.0f, 250 );
//}*/

306
cgame/fx_item.c Normal file
View file

@ -0,0 +1,306 @@
#include "cg_local.h"
#include "fx_local.h"
//
// detpack
//
#define NUM_RING_SHADERS 6
qboolean DetpackAftereffect(localEntity_t *le)
{
localEntity_t *cyl = NULL;
qhandle_t shader = cgs.media.phaserShader;
qhandle_t slowRingShaders[NUM_RING_SHADERS];
float percentLife = 1.0 - (le->endTime - cg.time)*le->lifeRate;
float alpha = 0.6 - (0.6*percentLife*percentLife);
// data for shell
float shellLife = percentLife + .2;
float height1 = 20 + (percentLife * 150);
float height2 =(50*percentLife);
float scale1 = 40 + (percentLife * 1500);
float scale2 = 20 + (percentLife * 1200);
// data for flat energy rings
float ringLife = percentLife + .5;
float scale3 = 200 + (percentLife * 3400);
float scale4 = 100 + (percentLife * 3000);
float scale5 = 20 + (percentLife * 1000);
float scale6 = 10 + (percentLife * 200);
float ringAlpha = 0.6 - (0.6*ringLife*ringLife);
vec3_t up = {0,0,1},origin1;
slowRingShaders[0] = cgs.media.testDetpackRingShader1;
slowRingShaders[1] = cgs.media.testDetpackRingShader2;
slowRingShaders[2] = cgs.media.testDetpackRingShader3;
slowRingShaders[3] = cgs.media.testDetpackRingShader4;
slowRingShaders[4] = cgs.media.testDetpackRingShader5;
slowRingShaders[5] = cgs.media.testDetpackRingShader6;
// slower, inner ring
VectorCopy(le->refEntity.origin, origin1);
if (NUM_RING_SHADERS == le->data.spawner.data1)
{
le->data.spawner.data1 = 0;
}
else if (le->data.spawner.data1 < 0)
{
le->data.spawner.data1 = 0;
}
shader = slowRingShaders[le->data.spawner.data1++];
// fast, outer ring
cyl = FX_AddCylinder( origin1,
up,
0.1,// height,
0,// dheight,
scale5,// scale,
0,// dscale,
scale6,// scale2,
0,// dscale2,
ringAlpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
if (shellLife <= 1.0f)
{
origin1[2] += height2;
shader = cgs.media.phaserShader;
cyl = FX_AddCylinder( origin1,
up,
height1,// height,
0,// dheight,
scale1,// scale,
0,// dscale,
scale2,// scale2,
0,// dscale2,
alpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
cyl = FX_AddCylinder( le->refEntity.origin,
up,
height2, // height,
0, // dheight,
scale1, // scale,
0, // dscale,
scale1, // scale2,
0, // dscale2,
alpha, // startalpha,
0.0, // endalpha,
500, // killTime,
shader,
15); // bias );
cyl->leFlags |= LEF_ONE_FRAME;
}
// flat energy wave thingy
if (ringLife <= 1.0f)
{
shader = cgs.media.testDetpackShader3;
VectorCopy(le->refEntity.origin, origin1);
// fast, outer ring
cyl = FX_AddCylinder( origin1,
up,
0.1,// height,
0,// dheight,
scale3,// scale,
0,// dscale,
scale4,// scale2,
0,// dscale2,
ringAlpha,// startalpha,
0.0,// endalpha,
500,// killTime,
shader,
15);// bias );
cyl->leFlags |= LEF_ONE_FRAME;
}
return qtrue;
}
void FX_Detpack(vec3_t origin)
{
localEntity_t *le;
qhandle_t null;
vec3_t direction, org, vel, norm = {0,0,1};
int i;
VectorCopy( norm, direction);
// Add an explosion and tag a light to it
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, null, 250, qfalse, 100.0f, LEF_FADE_RGB);
le->light = 300;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
// Ground ring
// FX_AddQuad( origin, norm, 5, 150, 1.0, 0.0, random() * 360, 600, cgs.media.bigShockShader );
// Flare
VectorMA( origin, 12, direction, org );
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 500, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
for (i = 0; i < 12; i++)
{
float width, length;
FXE_Spray( norm, 470, 325, 0.5f, vel);
length = 50.0 + random() * 12;
width = 1.5 + random() * 2;
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
// trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.detpackExplodeSound );
// Smoke and impact
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
// mondo explosion shock wave cloud thing
le = FX_AddSpawner( origin, norm, NULL, NULL, qfalse, 0,
0, 1500, DetpackAftereffect, 10 );
le->data.spawner.data1 = 0;
// shake absolutely _everyone_
CG_ExplosionEffects(origin, 5.0f, 8092);
}
//
// portable shield
//
//RPG-X ToDo: Modify force field Code Here
void FX_DrawPortableShield(centity_t *cent)
{
int xaxis, height, posWidth, negWidth, team; // light;
vec3_t start, end, normal;
//vec4_t RGBA;
float halfHeight;
localEntity_t *le;
qhandle_t shader;
if (cent->currentState.eFlags & EF_NODRAW)
{
return;
}
// decode the data stored in time2
//pos = ((cent->currentState.time2 >> 32) & 1);
//vert = ((cent->currentState.time2 >> 31) & 1);
xaxis = ((cent->currentState.time2 >> 30) & 1); //24
height = ((cent->currentState.time2 >> 20) & 1023); //16
posWidth = ((cent->currentState.time2 >> 10) & 1023); //8
negWidth = (cent->currentState.time2 & 1023);
team = (cent->currentState.otherEntityNum2);
halfHeight = (float)height * .5;
/*if ( !vert )
{*/
VectorCopy(cent->lerpOrigin, start);
VectorCopy(cent->lerpOrigin, end);
start[2] += halfHeight;
end[2] += halfHeight;
VectorClear(normal);
if (xaxis) // drawing along x-axis
{
start[0] -= negWidth;
end[0] += posWidth;
normal[1] = 1;
}
else
{
start[1] -= negWidth;
end[1] += posWidth;
normal[0] = 1;
}
//}
//else
//{
// VectorCopy(cent->lerpOrigin, start);
// VectorCopy(cent->lerpOrigin, end);
// if ( xaxis ) {
// start[1] += halfHeight;
// end[1] += halfHeight;
// }
// else
// {
// start[0] += halfHeight;
// end[0] += halfHeight;
// }
// VectorClear(normal);
// if (xaxis) // drawing along x-axis
// {
// start[0] -= negWidth;
// end[0] += posWidth;
// normal[2] = 1;
// }
// else
// {
// start[1] -= negWidth;
// end[1] += posWidth;
// normal[2] = 1;
// }
//}
// draw a rectangle o' shieldness
/*
if (team == TEAM_RED)
{
if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
{ // Damaged.
shader = cgs.media.shieldDamageShaderRed;
}
else
{
shader = cgs.media.shieldActivateShaderRed;
}
}
else
{*/
//TiM - Show the forcefield when the place flag is active only
//This way, we canhave it flare on events, and invisible the rest of the time
//tho make sure admins can see it
if((int)cent->currentState.origin2[0] == 1) {
shader = cgs.media.shieldActivateShaderBorg;
}
else if((int)cent->currentState.origin2[0] == 2) {
shader = cgs.media.shieldActivateShaderYellow;
}
else if((int)cent->currentState.origin2[0] == 3) {
shader = cgs.media.shieldActivateShaderRed;
}
else {
shader = cgs.media.shieldActivateShaderBlue;
}
if ( cent->currentState.eFlags & EF_ITEMPLACEHOLDER || cgs.clientinfo[cg.snap->ps.clientNum].isAdmin/*cg.snap->ps.persistant[PERS_CLASS] == PC_ADMIN*/ )
le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
//TiM
//if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
//{ // Damaged.
// shader = cgs.media.shieldDamageShaderBlue;
//}
//else
//{
// shader = cgs.media.shieldActivateShaderBlue;
//}
//-
// }
//le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
// le->leFlags |= LEF_ONE_FRAME;
}

970
cgame/fx_lib.c Normal file
View file

@ -0,0 +1,970 @@
// FX Library
#include "cg_local.h"
void FXE_Spray (vec3_t direction, float speed, float variation, float cone, vec3_t velocity)
{
vec3_t dir;
int i;
//Randomize the direction
for (i = 0; i < 3; i ++ )
{
dir[i] = direction[i] + (cone * crandom());
}
VectorNormalize(dir);
//set the speed
VectorScale( dir, speed + (variation * crandom()), velocity);
}
localEntity_t *FX_AddLine(vec3_t start, vec3_t end, float stScale, float scale, float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddLine: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_LINE;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.line.width = scale;
le->data.line.dwidth = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
le->refEntity.data.line.stscale = stScale;
le->refEntity.data.line.width = scale;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( start, le->refEntity.origin);
VectorCopy ( end, le->refEntity.oldorigin );
AxisClear(le->refEntity.axis);
le->refEntity.shaderRGBA[0] = 0xff;
le->refEntity.shaderRGBA[1] = 0xff;
le->refEntity.shaderRGBA[2] = 0xff;
le->refEntity.shaderRGBA[3] = 0xff;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
localEntity_t *FX_AddLine2(vec3_t start, vec3_t end, float stScale, float width1, float dwidth1, float width2, float dwidth2,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddLine2: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_LINE2;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.line2.width = width1;
le->data.line2.dwidth = dwidth1;
le->data.line2.width2 = width2;
le->data.line2.dwidth2 = dwidth2;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorCopy(startRGB, le->data.line2.startRGB);
VectorSubtract(endRGB, startRGB, le->data.line2.dRGB);
le->refEntity.data.line.stscale = stScale;
le->refEntity.data.line.width = width1;
le->refEntity.data.line.width2 = width2;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( start, le->refEntity.origin);
VectorCopy ( end, le->refEntity.oldorigin );
AxisClear(le->refEntity.axis);
le->refEntity.shaderRGBA[0] = 0xff;
le->refEntity.shaderRGBA[1] = 0xff;
le->refEntity.shaderRGBA[2] = 0xff;
le->refEntity.shaderRGBA[3] = 0xff;
le->color[0] = startRGB[0];
le->color[1] = startRGB[1];
le->color[2] = startRGB[2];
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
localEntity_t *FX_AddOrientedLine(vec3_t start, vec3_t end, vec3_t normal, float stScale, float scale,
float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddLine: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_OLINE;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.line.width = scale;
le->data.line.dwidth = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
le->refEntity.data.line.stscale = stScale;
le->refEntity.data.line.width = scale;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( start, le->refEntity.origin);
VectorCopy ( end, le->refEntity.oldorigin );
AxisClear(le->refEntity.axis);
VectorCopy( normal, le->refEntity.axis[0] );
RotateAroundDirection( le->refEntity.axis, 0); // le->refEntity.data.sprite.rotation ); This is roll in quad land
le->refEntity.shaderRGBA[0] = 0xff;
le->refEntity.shaderRGBA[1] = 0xff;
le->refEntity.shaderRGBA[2] = 0xff;
le->refEntity.shaderRGBA[3] = 0xff;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
localEntity_t *FX_AddTrail( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha,
float elasticity, float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddTrail: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_TRAIL;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.trail.width = scale;
le->data.trail.dwidth = dscale;
le->data.trail.length = length;
le->data.trail.dlength = dlength;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorSet(le->data.trail.startRGB, 1, 1, 1);
VectorSet(le->data.trail.dRGB, 0, 0, 0);
le->refEntity.data.line.stscale = 1.0;
le->refEntity.data.line.width = scale;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
// kef -- extrapolate oldorigin based on length of trail and origin?
if (velocity)
{
vec3_t vel;
VectorNormalize2(velocity, vel);
VectorMA(origin, -length, vel, le->refEntity.oldorigin);
}
else
{
VectorCopy ( origin, le->refEntity.oldorigin );
}
AxisClear(le->refEntity.axis);
le->refEntity.shaderRGBA[0] = 0xff;
le->refEntity.shaderRGBA[1] = 0xff;
le->refEntity.shaderRGBA[2] = 0xff;
le->refEntity.shaderRGBA[3] = 0xff*startalpha;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
le->pos.trDuration = killTime;
if (elasticity > 0)
{
le->leFlags |= LEF_USE_COLLISION;
le->bounceFactor = elasticity;
}
}
return(le);
}
localEntity_t *FX_AddTrail2( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB,
float elasticity, float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddTrail: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_TRAIL;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.trail.width = scale;
le->data.trail.dwidth = dscale;
le->data.trail.length = length;
le->data.trail.dlength = dlength;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorCopy(startRGB, le->data.trail.startRGB);
VectorSubtract(endRGB, startRGB, le->data.trail.dRGB);
le->refEntity.data.line.stscale = 1.0;
le->refEntity.data.line.width = scale;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
// kef -- extrapolate oldorigin based on length of trail and origin?
if (velocity)
{
vec3_t vel;
VectorNormalize2(velocity, vel);
VectorMA(origin, -length, vel, le->refEntity.oldorigin);
}
else
{
VectorCopy ( origin, le->refEntity.oldorigin );
}
AxisClear(le->refEntity.axis);
le->refEntity.shaderRGBA[0] = 0xff*startRGB[0];
le->refEntity.shaderRGBA[1] = 0xff*startRGB[1];
le->refEntity.shaderRGBA[2] = 0xff*startRGB[2];
le->refEntity.shaderRGBA[3] = 0xff*startalpha;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
le->pos.trDuration = killTime;
if (elasticity > 0)
{
le->leFlags |= LEF_USE_COLLISION;
le->bounceFactor = elasticity;
}
}
return(le);
}
/*
===============
FX_AddSprite
Adds a view oriented sprite to the FX wrapper render list
===============
*/
localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddSprite: NULL shader\n");
}
#endif
// Glow mark
le = CG_AllocLocalEntity();
le->leType = LE_VIEWSPRITE;
le->refEntity.data.sprite.rotation = roll;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.sprite.radius = scale;
le->data.sprite.dradius = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorSet(le->data.sprite.startRGB, 1, 1, 1);
VectorSet(le->data.sprite.dRGB, 0, 0, 0);
// le->refEntity.hModel = 0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
le->pos.trDuration = killTime;
if (elasticity > 0)
{
le->leFlags |= LEF_USE_COLLISION;
le->bounceFactor = elasticity;
}
}
return(le);
}
/*
===============
FX_AddSprite2
Adds a view oriented sprite to the FX wrapper render list
===============
*/
localEntity_t *FX_AddSprite2(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float roll, float elasticity,
float killTime, qhandle_t shader)
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddSprite: NULL shader\n");
}
#endif
// Glow mark
le = CG_AllocLocalEntity();
le->leType = LE_VIEWSPRITE;
le->refEntity.data.sprite.rotation = roll;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.sprite.radius = scale;
le->data.sprite.dradius = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorCopy(startRGB, le->data.sprite.startRGB);
VectorSubtract(endRGB, startRGB, le->data.sprite.dRGB);
// le->refEntity.hModel = 0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
le->color[0] = startRGB[0];
le->color[1] = startRGB[1];
le->color[2] = startRGB[2];
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
le->pos.trDuration = killTime;
if (elasticity > 0)
{
le->leFlags |= LEF_USE_COLLISION;
le->bounceFactor = elasticity;
}
}
return(le);
}
/*
===============
FX_AddBezier
Adds a Bezier curve to the FX wrapper render list
===============
*/
localEntity_t *FX_AddBezier(vec3_t start, vec3_t end, vec3_t cpoint1, vec3_t cpoint2, vec3_t cpointvel1, vec3_t cpointvel2,
vec3_t cpointacc1, vec3_t cpointacc2, float width, float killTime, qhandle_t shader)
{
localEntity_t *le = CG_AllocLocalEntity();
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddBezier: NULL shader\n");
}
#endif
// just testing beziers
le->leType = LE_BEZIER;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.line.width = width;
le->alpha = 1.0;
le->dalpha = -1.0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( start, le->refEntity.origin);
VectorCopy ( end, le->refEntity.oldorigin );
AxisClear(le->refEntity.axis);
le->refEntity.shaderRGBA[0] = 0xff;
le->refEntity.shaderRGBA[1] = 0xff;
le->refEntity.shaderRGBA[2] = 0xff;
le->refEntity.shaderRGBA[3] = 0xff;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
if (cpoint1)
{
VectorCopy(cpoint1, le->data.line.control1);
}
if (cpoint2)
{
VectorCopy(cpoint2, le->data.line.control2);
}
if (cpointvel1)
{
VectorCopy(cpointvel1, le->data.line.control1_velocity);
}
if (cpointvel2)
{
VectorCopy(cpointvel2, le->data.line.control2_velocity);
}
if (cpointacc1)
{
VectorCopy(cpointacc1, le->data.line.control1_acceleration);
}
if (cpointacc2)
{
VectorCopy(cpointacc2, le->data.line.control2_acceleration);
}
return le;
}
/*
===============
FX_AddQuad
Adds a quad to the FX wrapper render list
===============
*/
localEntity_t *FX_AddQuad( vec3_t origin, vec3_t normal, float scale, float dscale,
float startalpha, float endalpha, float roll, float killTime, qhandle_t shader )
{
localEntity_t *le = CG_AllocLocalEntity();
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddQuad: NULL shader\n");
}
#endif
le->leType = LE_QUAD;
le->refEntity.data.sprite.rotation = roll;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.sprite.radius = scale;
le->data.sprite.dradius = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
VectorSet(le->data.sprite.startRGB, 1, 1, 1);
VectorSet(le->data.sprite.dRGB, 0, 0, 0);
// le->refEntity.hModel = 0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
VectorCopy( normal, le->refEntity.axis[0] );
RotateAroundDirection( le->refEntity.axis, le->refEntity.data.sprite.rotation );
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
/*
===============
FX_AddQuad2
Adds a quad to the FX wrapper render list
===============
*/
localEntity_t *FX_AddQuad2( vec3_t origin, vec3_t normal, float scale, float dscale, float startalpha, float endalpha,
vec3_t startRGB, vec3_t endRGB, float roll, float killTime, qhandle_t shader )
{
localEntity_t *le = CG_AllocLocalEntity();
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddQuad: NULL shader\n");
}
#endif
le->leType = LE_QUAD;
le->refEntity.data.sprite.rotation = roll;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.sprite.radius = scale;
le->data.sprite.dradius = dscale;
VectorCopy(startRGB, le->data.sprite.startRGB);
VectorSubtract(endRGB, startRGB, le->data.sprite.dRGB);
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
// le->refEntity.hModel = 0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
VectorCopy( normal, le->refEntity.axis[0] );
RotateAroundDirection( le->refEntity.axis, le->refEntity.data.sprite.rotation );
le->color[0] = startRGB[0];
le->color[1] = startRGB[1];
le->color[2] = startRGB[2];
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
/*
===============
FX_AddCylinder
Adds a cylinder to the FX wrapper render list
Overloaded for RGB
===============
*/
//NOTENOTE: The reigning king of parameters!
#define DEFAULT_ST_SCALE 1.0f
localEntity_t *FX_AddCylinder( vec3_t start,
vec3_t normal,
float height,
float dheight,
float scale,
float dscale,
float scale2,
float dscale2,
float startalpha,
float endalpha,
float killTime,
qhandle_t shader,
float bias )
{
localEntity_t *le = CG_AllocLocalEntity();
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddCylinder: NULL shader\n");
}
#endif
le->leType = LE_CYLINDER;
le->refEntity.data.cylinder.height = height;
le->refEntity.data.cylinder.width = scale;
le->refEntity.data.cylinder.width2 = scale2;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.cylinder.height = height;
le->data.cylinder.dheight = dheight;
le->data.cylinder.width = scale;
le->data.cylinder.dwidth = dscale;
le->data.cylinder.width2 = scale2;
le->data.cylinder.dwidth2 = dscale2;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
le->refEntity.customShader = shader;
le->refEntity.data.cylinder.bias = bias;
le->refEntity.data.cylinder.stscale = 1.0;
le->refEntity.data.cylinder.wrap = qtrue;
// set origin
VectorCopy ( start, le->refEntity.origin);
VectorCopy ( start, le->refEntity.oldorigin );
VectorCopy( normal, le->refEntity.axis[0] );
RotateAroundDirection( le->refEntity.axis, 0);
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
return(le);
}
/*
===============
FX_AddElectricity
Adds a electricity bolt to the scene
===============
*/
localEntity_t *FX_AddElectricity( vec3_t origin, vec3_t origin2, float stScale, float scale, float dscale,
float startalpha, float endalpha, float killTime, qhandle_t shader, float deviation )
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddElectricity: NULL shader\n");
}
#endif
le = CG_AllocLocalEntity();
le->leType = LE_ELECTRICITY;
// set origin
VectorCopy (origin, le->refEntity.origin);
VectorCopy (origin2, le->refEntity.oldorigin );
le->refEntity.data.electricity.stscale = stScale;
le->refEntity.data.electricity.deviation = deviation;
le->data.electricity.width = scale;
le->data.electricity.dwidth = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->refEntity.customShader = shader;
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = startalpha;
return(le);
}
/*
===============
FX_AddParticle
Adds a particle (basically, a sprite with an optional think function) to the FX wrapper render list
===============
*/
localEntity_t *FX_AddParticle( vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader, qboolean (*thinkFn)(localEntity_t *le) )
{
localEntity_t *le;
#ifdef _DEBUG
if (!shader)
{
Com_Printf("FX_AddParticle: NULL shader\n");
}
#endif
// Glow mark
le = CG_AllocLocalEntity();
le->leType = LE_PARTICLE;
le->refEntity.data.sprite.rotation = roll;
le->startTime = cg.time;
le->endTime = le->startTime + killTime;
le->data.particle.radius = scale;
le->data.particle.dradius = dscale;
le->alpha = startalpha;
le->dalpha = endalpha - startalpha;
// le->refEntity.hModel = 0;
le->refEntity.customShader = shader;
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = startalpha;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
// wacky think function stuff
le->data.particle.thinkFn = thinkFn;
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
le->pos.trDuration = killTime;
if (elasticity > 0)
{
le->leFlags |= LEF_USE_COLLISION;
le->bounceFactor = elasticity;
}
}
return(le);
}
/*
===============
FX_AddSpawner
Adds a spawner -- basically, a local entity with a think function. Spawners don't have any rendered entities
associated with them inherently, but the spawner's think fn probably generates them.
===============
*/
localEntity_t *FX_AddSpawner( vec3_t origin, vec3_t dir, vec3_t velocity, vec3_t user, qboolean gravity, int delay,
float variance, float killTime, qboolean (*thinkFn)(localEntity_t *le), int radius )
{
localEntity_t *le = NULL;
if (NULL == thinkFn)
{
// a spawner with no think fn is silly. and useless.
return NULL;
}
le = CG_AllocLocalEntity();
le->leType = LE_SPAWNER;
le->data.spawner.data1 = radius;
le->data.spawner.delay = delay;
le->data.spawner.nextthink = cg.time + delay;
le->startTime = cg.time;
// if we want the spawner to hang around forever, we use a killtime of 0 and the think fn keeps adjusting it.
//thing is, we still need it to not get culled right here, so give it an arbitrary endTime somewhere in the future.
if (0 == killTime)
{
le->endTime = le->startTime + 10000;
le->data.spawner.dontDie = qtrue;
}
else
{
le->endTime = le->startTime + killTime;
}
le->data.spawner.variance = variance;
if(dir)
VectorCopy(dir, le->data.spawner.dir);
// set origin
VectorCopy ( origin, le->refEntity.origin);
VectorCopy ( origin, le->refEntity.oldorigin );
// maybe employ the user variable here, like in singleplayer? or in the think fn?
le->color[0] = 1.0;
le->color[1] = 1.0;
le->color[2] = 1.0;
le->color[3] = 1.0;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
// wacky think function stuff
le->data.spawner.thinkFn = thinkFn;
if (velocity)
{
le->leFlags |= LEF_MOVE;
VectorCopy (origin, le->pos.trBase);
if(velocity)
VectorCopy (velocity, le->pos.trDelta);
if (gravity)
le->pos.trType = TR_GRAVITY;
else
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
// we better not ever have a spawner with a velocity that we expect to last forever, so just plain
//assigning killTime here _should_ be ok
le->pos.trDuration = killTime;
// if (elasticity > 0)
// {
// le->leFlags |= LEF_USE_COLLISION;
// le->bounceFactor = elasticity;
// }
}
return (le);
}
// provide the center of the circle, a normal out from it (normalized, please), and the radius.
//out will then become a random position on the radius of the circle.
void fxRandCircumferencePos(vec3_t center, vec3_t normal, float radius, vec3_t out)
{
float rnd = flrandom(0, 2*M_PI);
float s = sin(rnd);
float c = cos(rnd);
vec3_t vTemp, radialX, radialY;
vTemp[0]=0.57735;
vTemp[1]=0.57735;
vTemp[2]=0.57735;
CrossProduct(normal, vTemp, radialX);
CrossProduct(normal, radialX, radialY);
VectorScale(radialX, radius, radialX);
VectorScale(radialY, radius, radialY);
VectorMA(center, s, radialX, out);
VectorMA(out, c, radialY, out);
}

197
cgame/fx_local.h Normal file
View file

@ -0,0 +1,197 @@
#define DEFAULT_DEVIATION 0.5
//
// fx_*.c
//
void FXE_Spray (vec3_t direction, float speed, float variation, float cone, vec3_t velocity);
localEntity_t *FX_AddLine(vec3_t start, vec3_t end, float stScale, float scale, float dscale,
float startalpha, float endalpha, float killTime, qhandle_t shader);
localEntity_t *FX_AddLine2(vec3_t start, vec3_t end, float stScale, float width1, float dwidth1, float width2, float dwidth2,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader);
localEntity_t *FX_AddOrientedLine(vec3_t start, vec3_t end, vec3_t normal, float stScale, float scale,
float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader);
localEntity_t *FX_AddTrail( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha,
float elasticity, float killTime, qhandle_t shader);
localEntity_t *FX_AddTrail2( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
float scale, float dscale, float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB,
float elasticity, float killTime, qhandle_t shader);
localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader);
localEntity_t *FX_AddSprite2(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float roll, float elasticity,
float killTime, qhandle_t shader);
localEntity_t *FX_AddBezier(vec3_t start, vec3_t end, vec3_t cpoint1, vec3_t cpoint2, vec3_t cpointvel1,
vec3_t cpointvel2,vec3_t cpointacc1, vec3_t cpointacc2, float width,
float killTime, qhandle_t shader);
localEntity_t *FX_AddQuad( vec3_t origin, vec3_t normal, float scale, float dscale,
float startalpha, float endalpha, float roll, float killTime, qhandle_t shader );
localEntity_t *FX_AddQuad2( vec3_t origin, vec3_t normal, float scale, float dscale, float startalpha, float endalpha,
vec3_t startRGB, vec3_t endRGB, float roll, float killTime, qhandle_t shader );
localEntity_t *FX_AddCylinder( vec3_t start,
vec3_t normal,
float height,
float dheight,
float scale,
float dscale,
float scale2,
float dscale2,
float startalpha,
float endalpha,
float killTime,
qhandle_t shader,
float bias );
localEntity_t *FX_AddElectricity( vec3_t origin, vec3_t origin2, float stScale, float scale, float dscale,
float startalpha, float endalpha, float killTime, qhandle_t shader, float deviation );
localEntity_t *FX_AddParticle( vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
float startalpha, float endalpha, float roll, float elasticity,
float killTime, qhandle_t shader, qboolean (*thinkFn)(localEntity_t *le));
localEntity_t *FX_AddSpawner( vec3_t origin, vec3_t dir, vec3_t velocity, vec3_t user, qboolean gravity, int delay,
float variance, float killTime, qboolean (*thinkFn)(localEntity_t *le), int radius );
//
// phaser
//
void FX_PhaserFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
//
// compression rifle
//
void FX_CompressionShot( vec3_t start, vec3_t end );
void FX_CompressionAltShot( vec3_t start, vec3_t end );
void FX_CompressionExplosion( vec3_t start, vec3_t origin, vec3_t normal, qboolean altfire );
void FX_CompressionHit( vec3_t origin );
//void FX_CompressionHitWall( vec3_t origin, vec3_t dir );
void FX_PrifleBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire );
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire );
//
// imod
//
//void FX_IMODShot( vec3_t end, vec3_t start, vec3_t dir);
//void FX_IMODExplosion( vec3_t origin, vec3_t normal );
//void FX_AltIMODShot( vec3_t end, vec3_t start, vec3_t dir );
//void FX_AltIMODExplosion( vec3_t origin, vec3_t normal );
//
// tetrion disruptor
//
//void FX_TetrionProjectileThink( centity_t *cent, const struct weaponInfo_s *wi );
void FX_TetrionShot( vec3_t start, vec3_t forward );
void FX_TetrionWeaponHitWall( vec3_t origin, vec3_t normal );
//void FX_TetrionRicochet( vec3_t origin, vec3_t normal );
//void FX_TetrionAltHitWall( vec3_t origin, vec3_t normal );
void FX_TetrionAltHitPlayer( vec3_t origin, vec3_t normal );
//
// Scavenger Rifle
//
void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red );
//void FX_ScavengerProjectileThink( centity_t *ent, const weaponInfo_t *wi );
//void FX_ScavengerAltFireThink( centity_t *ent, const weaponInfo_t *wi );
//void FX_ScavengerWeaponHitWall( vec3_t origin, vec3_t normal, qboolean fired_by_NPC );
//void FX_ScavengerWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean fired_by_NPC );
//void FX_ScavengerAltExplode( vec3_t origin, vec3_t dir );
//
// Grenade launcher
//
void FX_GrenadeThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_GrenadeHitWall( vec3_t origin, vec3_t normal );
void FX_GrenadeHitPlayer( vec3_t origin, vec3_t normal );
void FX_GrenadeExplode( vec3_t origin, vec3_t normal );
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm );
void FX_GrenadeShrapnelBits( vec3_t start);
void FX_fxfunc_Explosion( vec3_t start, vec3_t origin, vec3_t normal );
void FX_fxfunc_Shot( vec3_t start, vec3_t dir );
// Borg FX
//void FX_BorgProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
//void FX_BorgWeaponHitWall( vec3_t origin, vec3_t normal );
//void FX_BorgTaser( vec3_t start, vec3_t end );
//void FX_BorgEyeBeam( vec3_t start, vec3_t end, vec3_t normal, qboolean large );
//void FX_BorgTeleport( vec3_t origin );
//void FX_BorgTeleportTrails( vec3_t origin );// effect seen by other borg when you are in a mid-teleport
//
// detpack
//
void FX_Detpack(vec3_t origin);
//
// Stasis Weapon
//
//Disruptor
void FX_DisruptorBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty );
//void FX_StasisProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_StasisWeaponHitWall( vec3_t origin, vec3_t dir, int size );
//void FX_StasisWeaponHitPlayer( vec3_t origin, vec3_t dir, int size );
//void FX_StasisShot( centity_t *cent, vec3_t end, vec3_t start );
//void FX_StasisShotImpact( vec3_t end, vec3_t dir );
//void FX_StasisShotMiss( vec3_t end, vec3_t dir );
//
// Quantum Burst
//
void FX_QuantumThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_QuantumAltThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_QuantumHitWall( vec3_t origin, vec3_t normal );
void FX_QuantumAltHitWall( vec3_t origin, vec3_t normal );
void FX_QuantumColumns( vec3_t origin );
//
// Dreadnought
//
//void FX_DreadnoughtHitWall( vec3_t origin, vec3_t normal, qboolean spark );
//void FX_DreadnoughtFire( vec3_t origin, vec3_t end, vec3_t normal, qboolean spark, qboolean impact );
//void FX_DreadnoughtProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
//void FX_DreadnoughtShotMiss( vec3_t end, vec3_t dir );
//
// transporter
//
void FX_Transporter(vec3_t origin);
void FX_TransporterPad( vec3_t origin );
void FX_SPTransporterLensFlares( centity_t* cent, vec3_t headVector, int startTime );
// Holdable, portable shield item
void FX_DrawPortableShield(centity_t *cent);
// Shield
void FX_PlayerShieldHit( centity_t *cent );
//
// Miscellaneous FX
//
void FX_Disruptor( vec3_t org, float length );
void FX_ExplodeBits( vec3_t org);
void FX_qFlash( centity_t* cent, vec3_t org, int timeIndex );
//
// sin table
//
void fxRandCircumferencePos(vec3_t center, vec3_t normal, float radius, vec3_t out);

286
cgame/fx_misc.c Normal file
View file

@ -0,0 +1,286 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_Disruptor
-------------------------
*/
void DisruptorShards(vec3_t org)
{
vec3_t normal, end;
// Pick a random endpoint
VectorSet( normal, crandom(), crandom(), crandom() );
VectorNormalize( normal );
end[0] = org[0] + ( normal[0] * ( 48 + crandom() * 16 ));
end[1] = org[1] + ( normal[1] * ( 48 + crandom() * 16 ));
end[2] = org[2] + ( normal[2] * ( 64 + crandom() * 24 ));
// Draw a light shard, use a couple of different kinds so it doesn't look too homogeneous
if( rand() & 1 )
{
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.orangeParticleShader );
}
else
{
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.yellowParticleShader );
}
}
qboolean MakeDisruptorShard( localEntity_t *le )
{
DisruptorShards(le->refEntity.origin);
return(qtrue);
}
// Effect used when scav beams in--this wouldn't work well for a scav on the ground if they were to beam out
void FX_Disruptor( vec3_t org, float length )
{//FIXME: make it move with owner?
vec3_t org1, org2, normal={0,0,1};
int t;
VectorMA( org, 48, normal, org1 );
VectorMA( org, -48, normal, org2 );
// This is the core
FX_AddLine( org1, org2, 1.0, 0.1, 48.0, 1.0, 0.0, length, cgs.media.dkorangeParticleShader );
// Spawn a bunch to get the effect going
for (t=0; t < 12; t++ )
{
DisruptorShards( org);
}
// Keep spawning the light shards for a while.
FX_AddSpawner( org, normal, NULL, NULL, qfalse, 20, 10, length*0.75, MakeDisruptorShard, 0);
}
void FX_EnergyGibs(vec3_t origin )
{
localEntity_t *le;
refEntity_t *re;
vec3_t dir;
int i, j, k;
int chunkModel=0;
float baseScale = 0.7f, dist;
int numChunks;
numChunks = irandom( 10, 15 );
VectorSubtract(cg.snap->ps.origin, origin, dir);
dist = VectorLength(dir);
if (dist > 512)
{
numChunks *= 512.0/dist; // 1/2 at 1024, 1/4 at 2048, etc.
}
for ( i = 0; i < numChunks; i++ )
{
chunkModel = cgs.media.chunkModels[MT_METAL][irandom(0,5)];
le = CG_AllocLocalEntity();
re = &le->refEntity;
le->leType = LE_FRAGMENT;
le->endTime = cg.time + 2000;
VectorCopy( origin, re->origin );
for ( j = 0; j < 3; j++ )
{
re->origin[j] += crandom() * 12;
}
VectorCopy( re->origin, le->pos.trBase );
//Velocity
VectorSet( dir, crandom(), crandom(), crandom() );
VectorScale( dir, flrandom( 300, 500 ), le->pos.trDelta );
//Angular Velocity
VectorSet( le->angles.trBase, crandom() * 360, crandom() * 360, crandom() * 360 );
VectorSet( le->angles.trDelta, crandom() * 90, crandom() * 90, crandom() * 90 );
AxisCopy( axisDefault, re->axis );
le->data.fragment.radius = flrandom(baseScale * 0.4f, baseScale * 0.8f );
re->nonNormalizedAxes = qtrue;
re->hModel = chunkModel;
re->renderfx |= RF_CAP_FRAMES;
re->customShader = cgs.media.quantumDisruptorShader;
re->shaderTime = cg.time/1000.0f;
le->pos.trType = TR_GRAVITY;
le->pos.trTime = cg.time;
le->angles.trType = TR_INTERPOLATE;
le->angles.trTime = cg.time;
le->bounceFactor = 0.2f + random() * 0.2f;
le->leFlags |= LEF_TUMBLE;
re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 255;
// Make sure that we have the desired start size set
for( k = 0; k < 3; k++)
{
VectorScale(le->refEntity.axis[k], le->data.fragment.radius, le->refEntity.axis[k]);
}
}
}
void FX_ExplodeBits( vec3_t org)
{
float width, length;
vec3_t vel, pos;
int i;
FX_EnergyGibs(org);
for (i = 0; i < 32; i++)
{
VectorSet(vel, flrandom(-320,320), flrandom(-320,320), flrandom(-100,320));
VectorCopy(org, pos);
pos[2] += flrandom(-8, 8);
length = flrandom(10,20);
width = flrandom(2.0,4.0);
FX_AddTrail( pos, vel, qtrue, length, -length, width, -width,
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
}
}
#define Q_FLASH_SIZE 110
void FX_qFlash( centity_t* cent, vec3_t org, int timeIndex ) {
trace_t tr;
refEntity_t flare;
float frac;
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
if ( tr.fraction != 1 ) {
return;
}
}
memset( &flare, 0, sizeof( flare ) );
flare.reType = RT_SPRITE;
flare.shaderRGBA[0] = 0xff;
flare.shaderRGBA[1] = 0xff;
flare.shaderRGBA[2] = 0xff;
flare.shaderRGBA[3] = 0xff;
flare.data.sprite.rotation = 0;
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
flare.customShader = cgs.media.qFlashSprite;
flare.renderfx |= RF_DEPTHHACK;
VectorCopy( org, flare.origin );
//find the basic ratio
frac = (float)(cg.time - timeIndex) / (float)( Q_FLASH_TIME );
//apply a sine function to it to make it less linear
//calculated using the fine graph prog @ http://math.umn.edu/~garrett/a08/Graph.html
frac = ( 0.65f * sin( 4.5f * frac - 0.6f ) + 0.35f );
frac = Com_Clamp( 0.0f, 1.0f, frac );
//CG_Printf( "%f\n", frac );
flare.data.sprite.radius = (float)Q_FLASH_SIZE * frac;
trap_R_AddRefEntityToScene( &flare );
}
#define PROBE_BEAM_LENGTH 32
//TiM - Beam FX for the Neutrino Probe weapon
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
trace_t tr;
refEntity_t beam;
vec3_t end;
float scale;
memset( &beam, 0, sizeof( beam ) );
if ( alt_fire )
scale = flrandom(7.0f, 12.0f);
else
scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) );
VectorMA( origin, PROBE_BEAM_LENGTH, dir, end );
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f );
VectorCopy( origin, beam.origin);
VectorCopy( tr.endpos, beam.oldorigin );
beam.reType = RT_LINE;
beam.customShader = cgs.media.probeBeam;
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
AxisClear( beam.axis );
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
if ( tr.fraction != 1.0f )
{
float radius;
if ( alt_fire )
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
else
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
if ( !radius )
return;
CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f );
}
}
#define REGEN_BEAM_LENGTH 64
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
trace_t tr;
vec3_t end;
VectorMA( origin, REGEN_BEAM_LENGTH, dir, end );
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
trap_R_AddLightToScene( origin, 30, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
if ( tr.fraction != 1.0f )
{
float radius;
if ( alt_fire )
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
else
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
if ( !radius )
return;
CG_ImpactMark( cgs.media.regenDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
trap_R_AddLightToScene( origin, radius*5, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
}
}

357
cgame/fx_phaser.c Normal file
View file

@ -0,0 +1,357 @@
//Phaser
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_PhaserFire
-------------------------
*/
lensFlare_t phaserFlare = { {0.0,0.0,0.0},
20,
20,
{1.0, 0.7, 0.13},
1.2,
1.5,
20,
300,
{0.0, 0.0, 0.0},
20,
300,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qtrue,
1.0,
1.0,
1.0,
1.0,
1.0,
qtrue };
void FX_PhaserFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 2.0f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = rand() & 1 + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}
/*
-------------------------
FX_PhaserAltFire
-------------------------
*/
#define PHASER_ALT_CONE_LEN 256
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
float scale = flrandom(13.0f, 17.0f), scale2 = flrandom(2.0f, 6.0f);
vec3_t vel, diff, end2;
int i = 0, sparks = 0;
refEntity_t beam;
vec3_t rgb = { 1,0.6,0.5}, rgb2={1,0.3,0};
float len;
int color;
VectorSubtract(end, start, diff);
len = VectorNormalize(diff);
color = 0xff * flrandom(0.75, 1.0);
if (empty)
{ // More faint and shaky line.
scale *= flrandom(0.25,0.75);
}
if (len > PHASER_ALT_CONE_LEN)
{ // Draw beam in two parts...
// Draw main beam first.
VectorMA(start, PHASER_ALT_CONE_LEN, diff, end2);
// Draw starting cone
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end2, beam.oldorigin );
beam.reType = RT_LINE2;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw big thick normal beam for the rest.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.oldorigin);
VectorCopy( end, beam.origin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw beam core, all one bit.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
else
{ // Draw beam in two parts...
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserAltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// just one beam is never enough
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
// Phaser beam
// FX_AddLine( start, end, 1.0f, scale, 0.0f, 0.9f, 0.9f, 2, cgs.media.phaserShader );
// FX_AddLine( start, end, 1.0f, scale * 0.5f, 0.0f, 0.8f, 0.8f, 2, cgs.media.phaserShader );
// Per frame impact mark
FX_AddQuad( end, normal, random() * 1.5 + 1.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.sparkShader );
FX_AddQuad( end, normal, random() * 5 + 2.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.yellowParticleShader );
// Multi frame impacts--never do this when it hits a player because it will just look stupid
if ( impact )
{
FX_AddQuad2( end, normal, random() * 2.0 + 5.0f, 2.5f, 0.6f, 0.0f, rgb, rgb2, 0.0f, 500 + random() * 200,
cgs.media.sunnyFlareShader );
CG_ImpactMark( cgs.media.scavMarkShader, end, normal, random()*360, 1,1,1,0.1, qfalse,
random() + 6.0, qfalse );
}
// "Fun" sparks
if ( spark )
{
// kef -- fixme. dunno what the deal is with this velocity vector
VectorClear(vel);
sparks = rand() & 3 + 1;
// Set random starting pos...
end2[0] = flrandom(-1.0, 1.0) + end[0];
end2[1] = flrandom(-1.0, 1.0) + end[1];
end2[2] = flrandom(-1.0, 1.0) + end[2];
for( i = 0; i < sparks; i++ )
{
scale = 0.5f + (random() * 0.5);
FXE_Spray( normal, 200, 75, 0.8f, /*1024*/vel);
FX_AddTrail2( end2, vel, qfalse,
8.0f, -8.0f,
scale, -scale, 0.5f, 0.0f, rgb, rgb2, 0.4f, 500.0f, cgs.media.sparkShader );
}
VectorMA(end, -8, diff, end2);
// Add a hit sprite over everything...
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.origin);
beam.reType = RT_SPRITE;
beam.customShader = cgs.media.sunnyFlareShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*1.0f;
beam.shaderRGBA[1] = 0xff*0.9f;
beam.shaderRGBA[2] = 0xff*0.8f;
beam.shaderRGBA[3] = 0xff;
beam.data.sprite.radius = random()*2.0 + 9.0;
trap_R_AddRefEntityToScene( &beam );
}
}

415
cgame/fx_quantum.c Normal file
View file

@ -0,0 +1,415 @@
#include "cg_local.h"
#include "fx_local.h"
// think function for the quantum explosion particles
//unused
/*qboolean explosionTailThink(localEntity_t *le)
{
refEntity_t *re = &le->refEntity;
float length = 20;
// leave a cool tail
CG_AddTrail(FX_AddTrail( re->origin,
le->data.particle.dir, qtrue,
length, 0,
le->data.particle.radius*0.8, le->data.particle.dradius,
0.2, 0.0, // alpha, dalpha
0,
1,
cgs.media.yellowParticleShader ));
return qtrue;
}*/
/*
-------------------------
FX_QuantumThink
-------------------------
*/
/*vec3_t worldCoord;
int w1;
int h1;
vec3_t glowColor;
float glowOffset;
float hazeOffset;
int minDist;
int maxDist;
vec3_t streakColor;
int streakDistMin;
int streakDistMax;
int streakW;
int streakH;
qboolean whiteStreaks;
int reflecDistMin;
int reflecDistMax;
qboolean reflecAnamorphic;
qboolean defReflecs;
qboolean clamp;
float maxAlpha;
int startTime;
int upTime;
int holdTime;
int downTime;
qboolean qfull;
static lensFlare_t quantumFlare = { {0.0, 0.0, 0.0}, 100, 100, // worldCoord, w1, h1
{0.0, 1.0, 1.0}, 1.1, 1.3, 1000, 40,//glowColor, glowOffset, hazeOffset, minDist, maxDist
{0.0, 1.0, 1.0}, 1000, 40, 600, 10, qtrue, //streakColor, sDistMin, sDistMax, sW, sH, whitestreaks
0, 1, qfalse, qfalse, qfalse, //rDistMin, rDistMax, rAna, rDef, clamp
1.0, 0, 0, 0, 0, qtrue }; //maxalpha, start, up, hold, down, full */
void FX_QuantumThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t line1end, line2end, axis[3], rgb;
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -24.0f, axis[1], line1end );
VectorMA( cent->lerpOrigin, 24.0f, axis[1], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 6 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, -cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -48.0f, axis[2], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[2], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 5 + 2, 0.0f, 0.1 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorSet( rgb, 1.0f, 0.45f, 0.15f ); // orange
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 60 + 30, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.orangeParticleShader );
FX_AddSprite2(cent->lerpOrigin, NULL,qfalse,random() * 10 + 60, 0.0f, 0.1f, 0.1f, rgb, rgb, 0.0f, 0.0f, 1, cgs.media.whiteRingShader );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 16 + 8, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.yellowParticleShader );
/*
VectorCopy( cent->lerpOrigin, quantumFlare.worldCoord );
VectorCopy( colorTable[CT_CYAN], quantumFlare.glowColor );
VectorCopy( colorTable[CT_CYAN], quantumFlare.streakColor );
CG_DrawLensFlare( quantumFlare );*/
}
/*
-------------------------
FX_QuantumAltThink
-------------------------
*/
void FX_QuantumAltThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t line1end, line2end, axis[3], vel, rgb;
float scale;
AxisClear( axis );
// convert direction of travel into axis
if ( VectorNormalize2( cent->currentState.pos.trDelta, axis[0] ) == 0 ) {
axis[0][2] = 1;
}
// spin as it moves
RotateAroundDirection( axis, cg.time * 0.3f );// * 1.25f );
VectorMA( cent->lerpOrigin, -48.0f, axis[1], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[1], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 6 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorMA( cent->lerpOrigin, -48.0f, axis[2], line1end );
VectorMA( cent->lerpOrigin, 48.0f, axis[2], line2end );
FX_AddLine( line1end, line2end, 1.0f, random() * 5 + 2, 0.0f, 0.2 + random() * 0.2, 0.0f, 1, cgs.media.yellowParticleShader );
VectorSet( rgb, 1.0f, 0.45f, 0.15f ); // orange
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 60 + 30, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.orangeParticleShader );
FX_AddSprite2(cent->lerpOrigin, NULL,qfalse,random() * 10 + 60, 0.0f, 0.1f, 0.1f, rgb, rgb, 0.0f, 0.0f, 1, cgs.media.whiteRingShader );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,random() * 16 + 8, 4, 0.5f, 0.0f, 0, 0.0f, 1.0f, cgs.media.yellowParticleShader );
scale = ( 2.0f + cos( cg.time * ( M_PI * 0.001f * 4 ))) * 0.5f;
// Unlike the main fire, I'm leaving around this center core for a moment as a trail...
VectorScale( cent->currentState.pos.trDelta, 0.25f, vel );
FX_AddSprite( cent->lerpOrigin, NULL,qfalse,scale * 8 + 2, scale * -5.0f, 0.8f, 0.0f, 0, 0, 300.0f, cgs.media.sunnyFlareShader);
// Tack on a sprite trail so we can see the cool tracking at work.
VectorSet( vel, flrandom(-12, 12), flrandom(-12, 12), flrandom(-12, 12));
VectorMA( vel, 0.25f, cent->currentState.pos.trDelta, vel);
if ( rand() & 1 )
FX_AddSprite( cent->lerpOrigin, vel,qfalse,random() * 12.0f + scale * 14, -10, 0.2f + random() * 0.2f, 0.0, random()*360, 0, 800 + random() * 200.0f,
cgs.media.orangeRingShader );
else
FX_AddSprite2(cent->lerpOrigin, vel,qfalse,random() * 12.0f + scale * 14, -10, 0.5, 0.0, rgb, rgb, random()*360, 0, 800 + random() * 200.0f,
cgs.media.whiteRingShader );
}
/*
-------------------------
FX_QuantumHitWall
-------------------------
*/
void FX_QuantumHitWall( vec3_t origin, vec3_t normal )
{
localEntity_t *le = NULL;
vec3_t dir, org;
vec3_t vel;
float scale;
int i;
weaponInfo_t *weaponInfo = &cg_weapons[WP_QUANTUM_BURST];
CG_InitLensFlare( origin,
400, 400,
colorTable[CT_YELLOW], 1.2, 2.0, 1600, 200,
colorTable[CT_YELLOW], 1600, 200, 800, 35, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 200);
for ( i = 0; i < 12; i++ )
{
VectorSet( dir, normal[0] + crandom() * 2, normal[1] + crandom() * 2, normal[2] + crandom() );
VectorNormalize( dir );
scale = random() * 300 + 300;
VectorScale( dir, scale, vel );
vel[2] += 300;
if ( rand() & 1 )
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 300 + random() * 100, cgs.media.yellowParticleShader, explosionTailThink );
scale = random()*14+2;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite(origin, vel, qfalse, scale, -scale, 0.9, 0.5, 0.0, 0.0, 200 + random() * 100, cgs.media.yellowParticleShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, 0.0, 300, cgs.media.orangeTrailShader);
}
else
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 450 + random() * 200, cgs.media.sunnyFlareShader, explosionTailThink );
scale = random()*14+6;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite(origin, vel, qfalse, scale, -scale, 0.9, 0.5, 0.0, 0.0, 350 + random() * 150, cgs.media.sunnyFlareShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, 0.0, 500, cgs.media.orangeTrailShader);
}
}
// Always face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, normal, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
// Create sphere
CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.quantumFlashShader, 150, qfalse, 4.6f + ( crandom() * 0.3f), 0 );
// Make an offset explosion
for ( i = 0; i < 3; i++ ) {
org[i] = origin[i] + crandom() * 4;
}
CG_MakeExplosion( org, dir, 0, cgs.media.quantumExplosionShader, 700, 1, qtrue );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 3.0f, 256 );
// One big bright quick flash
FX_AddSprite( origin, NULL, qfalse, 100, -100, 1.0, 1.0, 0, 0, 300, cgs.media.sunnyFlareShader);
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
}
/*
-------------------------
FX_QuantumAltHitWall
-------------------------
*/
void FX_QuantumAltHitWall( vec3_t origin, vec3_t normal )
{
localEntity_t *le = NULL;
vec3_t dir, org;
vec3_t vel;
float scale;
int i;
vec3_t RGB={1.0, 0.6, 0.3}, RGB2={1.0, 0.3, 0.0};
weaponInfo_t *weaponInfo = &cg_weapons[WP_QUANTUM_BURST];
CG_InitLensFlare( origin,
500, 500,
colorTable[CT_YELLOW], 1.2, 2.0, 1600, 200,
colorTable[CT_YELLOW], 1600, 200, 800, 35, qtrue,
1600, 200, qfalse, qfalse,
qfalse, 1.0, cg.time, 0, 0, 350);
for ( i = 0; i < 12; i++ )
{
VectorSet( dir, normal[0] + crandom() * 2, normal[1] + crandom() * 2, normal[2] + crandom() );
VectorNormalize( dir );
scale = random() * 500 + 500;
VectorScale( dir, scale, vel );
vel[2] += 300;
if ( rand() & 1 )
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 300 + random() * 100, cgs.media.yellowParticleShader, explosionTailThink );
scale = random()*14+2;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite2(origin, vel, qfalse, scale, -scale, 0.9, 0.5, RGB, RGB2, 0.0, 0.0, 200 + random() * 100, cgs.media.yellowParticleShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail2(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, RGB, RGB2, 0.0, 300, cgs.media.orangeTrailShader);
}
else
{
// FX_AddParticle( origin, vel, qfalse, random() * 14 + 2, -2.0, 0.9, 0.1, 0.0, 0.0, 450 + random() * 200, cgs.media.sunnyFlareShader, explosionTailThink );
scale = random()*14+6;
// Instead of the particle code, which seems redundant and doesn't fade real well, try adding the projectile...
le=FX_AddSprite2(origin, vel, qfalse, scale, -scale, 0.9, 0.5, RGB, RGB2, 0.0, 0.0, 350 + random() * 150, cgs.media.sunnyFlareShader);
// ...with a trail that overlaps it exactly.
FX_AddTrail2(origin, vel, qfalse, 80, -40, scale, -scale, 0.8, 0.4, RGB, RGB2, 0.0, 500, cgs.media.orangeTrailShader);
}
}
// Always face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, normal, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
// Create sphere
CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.quantumFlashShader, 150, qfalse, 5.4f + ( crandom() * 0.3f), 0 );
// Make an offset explosion
for ( i = 0; i < 3; i++ ) {
org[i] = origin[i] + crandom() * 4;
}
CG_MakeExplosion( org, dir, 0, cgs.media.quantumExplosionShader, 700, 1, qtrue );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse,
random() * 16 + 48, qfalse );
CG_ExplosionEffects( origin, 3.0f, 256 );
// One big bright quick flash
FX_AddSprite( origin, NULL, qfalse, 200, -200, 1.0, 1.0, 0, 0, 400, cgs.media.sunnyFlareShader);
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound );
}
qboolean FX_QuantumSparkle( localEntity_t *le)
{
int t, i;
vec3_t org, v;
for ( i = 0; i < 4; i ++ )
{
VectorCopy( le->refEntity.origin, org );
for ( t = 0; t < 3; t++ )
{
org[t] = le->refEntity.origin[t] + crandom() * 12;
v[t] = crandom() * 18.0f;
}
FX_AddSprite( org, v, qfalse, random() * 1 + 1, -4, 0.5f, 1.0f, 0.0f, 0.0f, 125 + random() * 100, cgs.media.yellowParticleShader);
}
return qtrue;
}
void FX_QuantumFizzles( vec3_t origin )
{
float v;
vec3_t dir, vel, org;
int i;
for ( i = 0; i < 32; i++ )
{
v = random() * 6.0f + 6.0f;
VectorSet( dir, crandom(), crandom(), crandom() );
VectorNormalize( dir );
VectorScale( dir, v, vel );
org[0] = origin[0] + dir[0] * 48;
org[1] = origin[1] + dir[1] * 48;
org[2] = origin[2] + dir[2] * 64;
FX_AddSpawner( org, dir, vel, NULL, qfalse, 125, 10 + random() * 30, 200 + random() * 400, FX_QuantumSparkle, 1024 );
}
}
void FX_QuantumColumns( vec3_t origin )
{
vec3_t dir, bottom, top;
vec3_t sizeMin = {-4, -4, -1};
vec3_t sizeMax = {-4, -4, 1};
trace_t trace;
localEntity_t *le;
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, dir );
VectorNormalize( dir );
//=== Sound ===
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.quantumBoom );
//=== columns ===
VectorCopy( origin, bottom );
bottom[2] -= 256;
trap_CM_BoxTrace( &trace, origin, bottom, sizeMin, sizeMax, 0, MASK_OPAQUE );
VectorCopy( trace.endpos, bottom );
VectorCopy( origin, top );
top[2] += 256;
trap_CM_BoxTrace( &trace, origin, top, sizeMin, sizeMax, 0, MASK_OPAQUE );
VectorCopy( trace.endpos, top );
//found floor and ceiling, now do columns and ring explosions:
//ceiling
VectorSet( dir, 0, 0, -1 );
le = FX_AddCylinder( top, dir, top[2] - origin[2], (origin[2] - top[2]), 40, 100, 20, 50, 1.0, 0.0, 1000, cgs.media.quantumRingShader, 1.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 6;
//floor
VectorSet( dir, 0, 0, 1 );
le = FX_AddCylinder( bottom, dir, origin[2] - bottom[2], (bottom[2] - origin[2]), 40, 100, 20, 50, 1.0, 0.0, 1000, cgs.media.quantumRingShader, 1.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 6;
FX_QuantumFizzles( origin );
// Main explosion, tag with light
le = CG_MakeExplosion2( origin, dir, (qhandle_t)0, 1, cgs.media.quantumExplosionShader, 600, qtrue, 3 + crandom(), 0 );
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 1.0f, 0.6f );
}

458
cgame/fx_scavenger.c Normal file
View file

@ -0,0 +1,458 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_HypoSpray
Redtechie: RPG-X Added
FIXME! FIXME! FIXME! FIXME! Im not spraying in the direction some one shoots me!
TiM: Fixed! An improperly formatted directional vector was being sent. it's all good now :)
-------------------------
*/
#define NUM_HYPO_PUFFS 20
void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red ) // When not red, it'll be blue
{
vec3_t color, vel, accel, angles, work;
float scale, dscale;
int i;
localEntity_t *le;
vectoangles( dir, angles );
for ( i = 0; i < NUM_HYPO_PUFFS; i++ )
{
if ( red )
{
VectorSet( color, 1.0f, random() * 0.4f, random() * 0.4f ); // mostly red
}
else
{
VectorSet( color, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f ); // mostly blue
}
VectorCopy( angles, work );
work[0] += crandom() * 12.0f;
work[1] += crandom() * 12.0f;
AngleVectors( work, vel, NULL, NULL );
scale = random() * 256.0f + 128.0f;
VectorScale( vel, scale, vel );
VectorScale( vel, random() * -0.3f, accel );
scale = random() * 4.0f + 2.0f;
dscale = random() * 64.0f + 24.0f;
//localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
// float startalpha, float endalpha, float roll, float elasticity,
// float killTime, qhandle_t shader);
le = FX_AddSprite( origin, vel, qfalse, scale, dscale, 0.8f + random() * 0.2f, 0.0f, crandom() * 50, /*crandom() * 5*/0, 1000, cgs.media.steamShader );
VectorSet(le->data.sprite.startRGB, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f );// mostly blue
}
}
/*
void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red ) // When not red, it'll be blue
{
localEntity_t *le;
vec3_t color, vel, accel, angles, work, forward, right;
float scale, dscale;
int i;
//vectoangles( dir, angles );
VectorCopy( dir, angles );
//RPG-X: RedTechie - Debug print
//Com_Printf("dir: %f, %f, %f\nangles: %f, %f, %f\n\n",dir[0],dir[1],dir[2],angles[0],angles[1],angles[2]);
for ( i = 0; i < NUM_HYPO_PUFFS; i++ )
{
if ( red )
{
VectorSet( color, 1.0f, random() * 0.4f, random() * 0.4f ); // mostly red
}
else
{
VectorSet( color, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f ); // mostly blue
}
VectorCopy( angles, work );
work[0] += crandom() * 12.0f;
work[1] += crandom() * 12.0f;
scale = random() * 256.0f + 128.0f;
VectorScale( vel, scale, vel );
VectorScale( vel, random() * -0.3f, accel );
//scale = 30.0f + random() * 100.0f + 2.0f;
//dscale = 30.0f + random() * 400.0f + 24.0f;
scale = random() * 4.0f + 2.0f;
dscale = random() * 64.0f + 24.0f;
le = FX_AddSprite( origin, //vec3_t origin,
vel,//vel, //vec3_t velocity,
qfalse, // qboolean gravity,
scale,//scale, //float scale,
dscale, //float dscale,
0.8f + random() * 0.2f, //float startalpha
0.0f, //float endalpha
crandom() * 120,//crandom() * 120, ///float roll
0.0f, //float elasticity
4000, //float killTime -9999999 -1000
cgs.media.steamShader );//qhandle_t shader
//le->endTime = 99999999;
//le->color = color;
VectorSet(le->data.sprite.startRGB, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f );// mostly blue
//le->data.sprite.startRGB = color;
//le->data.sprite.dRGB = color;
//FX_AddSprite( origin, vel, qfalse, scale, dscale, 0.8f + random() * 0.2f, 0.0f, color, color, crandom() * 120, 0.0f, 1000, cgs.media.steamShader );
}
}
*/
//RPG-X: J2J - Fixed Version (incomplete right now)
/*void FX_HypoSpray( vec3_t origin, vec3_t dir, qboolean red ) // When not red, it'll be blue
{
localEntity_t *le;
vec3_t muzzle, /*mins, maxs, end, color, forward, right;
float scale, dscale;
int i;
// Move out to the end of the nozzle
//VectorMA( muzzle, 20, forward, muzzle );
//VectorMA( muzzle, 4, vright, muzzle );
VectorCopy(dir, muzzle);
AngleVectors( dir, forward, right, NULL );
for ( i = 0; i < NUM_HYPO_PUFFS; i++ )
{
if ( red )
{
VectorSet( color, 1.0f, random() * 0.4f, random() * 0.4f ); // mostly red
}
else
{
VectorSet( color, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f ); // mostly blue
}
VectorMA( muzzle, 24, forward, end );
VectorSet( maxs, 6, 6, 6 );
VectorScale( maxs, -1, mins );
// Create the effect -- thought something was needed here, but apparently not.
VectorMA( muzzle, 20, forward, muzzle );w
VectorMA( muzzle, 4, right, muzzle );
scale = random() + 2.0f;
dscale = random() * 64.0f + 24.0f;
muzzle[0] += (scale * cos(abs(dir[1]) * 0.017453292222222222222222222222222);
muzzle[1] += (scale * sin(abs(dir[1]) * 0.017453292222222222222222222222222);
muzzle[2] += (scale * -tan(dir[0] * 0.017453292222222222222222222222222);
VectorScale( muzzle, scale, muzzle );
le = FX_AddSprite( origin, //vec3_t origin,
muzzle,//vel, //vec3_t velocity,
qfalse, // qboolean gravity,
scale,//scale, //float scale,
dscale, //float dscale,
0.8f + random() * 0.2f, //float startalpha
0.0f, //float endalpha
crandom() * 120,//crandom() * 120, ///float roll
0.0f, //float elasticity
4000, //float killTime -9999999 -1000
cgs.media.steamShader );//qhandle_t shader
VectorSet(le->data.sprite.startRGB, random() * 0.5f, random() * 0.5f + 0.5f, 1.0f );// mostly blue
}
return;
}*/
//#define SCAV_SPIN 0.3
/*void FX_ScavengerProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
qboolean fired_from_NPC = qfalse; // Always
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0 )
forward[2] = 1;
// The effect you'd see from first person looks horrible from third person..or when shot by an NPC,
// so we'll just tone down the effect so it's not so horrible. :)
if ( fired_from_NPC )
{
// Energy glow
/*FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
8.0f + random() * 8.0f, 0.0f,
0.7f, 0.0f,
random()*360, 0.0f,
1.0f,
cgs.media.tetrionFlareShader );
// Spinning projectile core
FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
8.0f + random() * 10.0f, 0.0f,
1.0f, 0.0f,
cg.time * SCAV_SPIN, 0.0f,
1.0f,
cgs.media.redFlareShader );
// leave a cool tail
/*FX_AddTrail( cent->lerpOrigin,
forward, qfalse,
16, 0,
1.0f, 0.0f,
0.8f, 0.0f,
0,
1,
cgs.media.tetrionTrail2Shader );
}
else
{
// Energy glow
/*FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
16.0f + random() * 16.0f, 0.0f,
0.5f, 0.0f,
random()*360, 0.0f,
1.0f,
cgs.media.tetrionFlareShader );
// Spinning projectile
FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
4.0f + random() * 10.0f, 0.0f,
0.6f, 0.0f,
cg.time * SCAV_SPIN, 0.0f,
1.0f,
cgs.media.redFlareShader );
// leave a cool tail
/*FX_AddTrail( cent->lerpOrigin,
forward, qfalse,
64, 0,
1.4f, 0.0f,
0.6f, 0.0f,
0,
1,
cgs.media.tetrionTrail2Shader );
}
}*/
/*
-------------------------
FX_ScavengerAltFireThink
-------------------------
*/
//#define SCAV_TRAIL_SPACING 12
/*void FX_ScavengerAltFireThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t diff;
float len;
// Make a trail that's reasonably consistent and not so much based on frame rate.
if (cent->thinkFlag)
{
VectorSubtract( cent->lerpOrigin, cent->beamEnd, diff );
}
else
{
VectorSubtract( cent->lerpOrigin, cent->currentState.origin2, diff );
}
len = VectorNormalize( diff );
if ( len > SCAV_TRAIL_SPACING )
{
vec3_t origin;
int i;
float scale;
for ( i = 0 ; i < len; i += SCAV_TRAIL_SPACING )
{
// Calc the right spot along the trail
VectorMA( cent->lerpOrigin, -i, diff, origin );
scale = 18.0f + (random()*5.0f);
/*FX_AddSprite( origin,
NULL, qfalse,
scale, -8.75,
0.4f, 0.0f,
random() * 360, 0.0f,
250.0f,
cgs.media.scavengerAltShader );
}
// Stash the current position
VectorCopy( cent->lerpOrigin, cent->beamEnd);
cent->thinkFlag = 1;
}
// Glowing bit
/*FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
24.0f + ( random() * 16.0f ), 0.0f,
1.0f, 0.0f,
0, 0.0f,
1.0f,
cgs.media.tetrionFlareShader );
}*/
/*
-------------------------
FX_ScavengerWeaponHitWall
-------------------------
*/
/*void FX_ScavengerWeaponHitWall( vec3_t origin, vec3_t normal, qboolean fired_by_NPC )
{
weaponInfo_t *weaponInfo = &cg_weapons[WP_COFFEE];
// Tone down when shot by an NPC
// FIXME: is this really a good idea?
if ( fired_by_NPC )
{
// Expanding shock ring
FX_AddQuad( origin, normal,
0.5f, 6.4f,
0.8, 0.0,
random() * 360.0f,
200,
cgs.media.redRingShader );
// Impact core
FX_AddQuad( origin, normal,
12.0f + ( random() * 8.0f ), 3.2f,
0.6f, 0.0f,
cg.time * SCAV_SPIN,
100,
cgs.media.redFlareShader );
}
else
{
// Expanding shock ring
FX_AddQuad( origin, normal,
8.0f, 12.8f,
1.0, 0.0,
random() * 360.0f,
200,
cgs.media.redRingShader );
// Impact core
FX_AddQuad( origin, normal,
24.0f + ( random() * 16.0f ), 6.4f,
0.8f, 0.0f,
cg.time * SCAV_SPIN,
100,
cgs.media.redFlareShader );
}
//Sound
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
CG_ImpactMark( cgs.media.scavMarkShader, origin, normal, random()*360, 1,1,1,0.2, qfalse, random() + 5.5f, qfalse );
}*/
/*
-------------------------
FX_ScavengerWeaponHitPlayer
-------------------------
*/
/*void FX_ScavengerWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean fired_by_NPC )
{
if ( fired_by_NPC )
{
// Smaller expanding shock ring
FX_AddQuad( origin, normal,
0.5f, 32.0f,
0.8, 0.0,
random() * 360.0f,
125,
cgs.media.redRingShader );
}
else
{
// Expanding shock ring
FX_AddQuad( origin, normal,
1.0f, 64.0f,
0.8, 0.0,
random() * 360.0f,
125,
cgs.media.redRingShader );
}
//Sound
// trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cg_weapons[WP_COFFEE].missileHitSound );
}*/
/*
-------------------------
FX_Scavenger_Alt_Explode
-------------------------
*/
/*void FX_ScavengerAltExplode( vec3_t origin, vec3_t dir )
{
// FXCylinder *fx2;
localEntity_t *le;
vec3_t direction, org;
int i;
weaponInfo_t *weaponInfo = &cg_weapons[WP_COFFEE];
//Orient the explosions to face the camera
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
VectorMA( origin, 12, direction, org );
// Add an explosion and tag a light to it
//le = CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 5, cgs.media.scavExplosionSlowShader, 675, qfalse, 1.0f + (random()*0.5f), LEF_NONE);
le->light = 150;
le->refEntity.renderfx |= RF_NOSHADOW;
VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );
VectorSet( org, (org[0] + crandom() * 8), (org[1] + crandom() * 8), (org[2] + crandom() * 8) );
//CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 5, cgs.media.scavExplosionFastShader, 375, qfalse, 0.7f + (random()*0.5f), LEF_NONE);
//Sound
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound );
CG_ImpactMark( cgs.media.compressionMarkShader, origin, dir, random()*360, 1,1,1,0.2, qfalse,
random() * 6 + 20, qfalse );
// Always orient horizontally
VectorSet ( direction, 0,0,1 );
le = FX_AddCylinder( origin, direction, 4, 0, 20, 210, 14, 140, 1.0, 0.0, 600, cgs.media.redRing2Shader, 1.5 );
le->refEntity.data.cylinder.wrap = qtrue;
le->refEntity.data.cylinder.stscale = 6;
for (i = 0; i < 6; i++)
{
vec3_t velocity;
FXE_Spray( dir, 300, 175, 0.8f, velocity);
/*FX_AddTrail( origin, velocity, qtrue, 12.0f, -12.0f,
2, -2, 1.0f, 1.0f, 0.2f, 1000.0f, cgs.media.tetrionTrail2Shader);*/
/*}
}*/

617
cgame/fx_stasis.c Normal file
View file

@ -0,0 +1,617 @@
#include "cg_local.h"
#include "fx_local.h"
void FX_StasisDischarge( vec3_t origin, vec3_t normal, int count, float dist_out, float dist_side );
#define FX_STASIS_ALT_RIGHT_OFS 0.10
#define FX_STASIS_ALT_UP_OFS 0.02
#define FX_STASIS_ALT_MUZZLE_OFS 1
#define FX_MAXRANGE_STASIS 4096
/*
-------------------------
FX_StasisShot
Alt-fire, beam that shrinks to its impact point
-------------------------
*/
/*void FX_SmallStasisBeam(centity_t *cent, vec3_t start, vec3_t dir)
{
vec3_t end, org, vel = { 0,0,-4};
trace_t tr;
float r;
int i, ct, t;
VectorMA(start, FX_MAXRANGE_STASIS, dir, end);
CG_Trace(&tr, start, NULL, NULL, end, cent->currentState.number, MASK_SHOT);
// Beam
// FX_AddLine( start, tr.endpos, 1.0f, 3.0f, 4.0f, 0.8f, 0.0f, 400.0f, cgs.media.stasisAltShader);
// Do a quick LOD for number of decay particles
ct = tr.fraction * (FX_MAXRANGE_STASIS * 0.02);
if ( ct < 12 )
ct = 12;
else if ( ct > 24 )
ct = 24;
for ( i = 0; i < ct; i++ )
{
r = random() * tr.fraction * (FX_MAXRANGE_STASIS * 0.5);
VectorMA( start, r, dir, org );
for ( t = 0; t < 3; t++ )
org[t] += crandom();
if ( rand() & 1 )
FX_AddSprite( org, vel, qfalse, random() + 1.5, -3, 1.0, 1.0, 0.0, 0.0, 500, cgs.media.blueParticleShader);
else
FX_AddSprite( org, vel, qfalse, random() + 1.5, -3, 1.0, 1.0, 0.0, 0.0, 500, cgs.media.purpleParticleShader);
}
// Impact graphic if needed.
if (cg_entities[tr.entityNum].currentState.eType == ET_PLAYER)
{ // Hit an entity.
// Expanding rings
// FX_AddSprite( tr.endpos, NULL, qfalse, 1, 60, 0.8, 0.2, random() * 360, 0, 400, cgs.media.stasisRingShader );
// Impact effect
// FX_AddSprite( tr.endpos, NULL, qfalse, 7, 25, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
FX_AddSprite( tr.endpos, NULL, qfalse, 5, 18, 1.0, 0.0, random() * 360, 0, 420, cgs.media.ltblueParticleShader );
}
else if (!(tr.surfaceFlags & SURF_NOIMPACT) )
{
// Move me away from the wall a bit so that I don't z-buffer into it
VectorMA( tr.endpos, 1.5, tr.plane.normal, end);
// Expanding rings
// FX_AddQuad( end, tr.plane.normal, 1, 12, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
// FX_AddQuad( end, tr.plane.normal, 1, 30, 0.8, 0.2, random() * 360, 300, cgs.media.stasisRingShader );
// Impact effect
FX_AddQuad( end, tr.plane.normal, 4, 16, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
FX_AddQuad( end, tr.plane.normal, 3, 12, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
CG_ImpactMark( cgs.media.scavMarkShader, end, tr.plane.normal, random()*360, 1,1,1,0.6, qfalse,
5 + random() * 2, qfalse );
}
FX_AddSprite( tr.endpos, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
// Pass the end position back to the calling function (yes, I know).
VectorCopy(tr.endpos, dir);
}*/
// kef -- fixme. the altfire stuff really wants to use some endcap stuff and some other flags
/*void FX_StasisShot( centity_t *cent, vec3_t end, vec3_t start )
{
trace_t tr;
vec3_t fwd, newdir, org, vel = { 0,0,-4}, newstart, end2;
int i, t, ct;
float len, r;
vec3_t fwd2, right, up;
int bolt1, bolt2;
vec3_t bolt1vec, bolt2vec;
centity_t *traceEnt = NULL;
int clientNum = -1;
// Choose which bolt will have the electricity accent.
bolt1 = irandom(0,2);
bolt2 = irandom(0,4);
VectorSubtract( end, start, fwd );
len = VectorNormalize( fwd );
// Beam
// FX_AddLine( end, start, 1.0f, 4.0f, 6.0f, 0.8f, 0.0f, 500.0f, cgs.media.stasisAltShader);
// Do a quick LOD for number of decay particles
ct = len * 0.03;
if ( ct < 16 )
ct = 16;
else if ( ct > 32 )
ct = 32;
for ( i = 0; i < ct; i++ )
{
r = random() * len * 0.5;
VectorMA( start, r, fwd, org );
for ( t = 0; t < 3; t++ )
org[t] += crandom();
if ( rand() & 1 )
FX_AddSprite( org, vel, qfalse, random() + 2, -4, 1.0, 1.0, 0.0, 0.0, 600, cgs.media.blueParticleShader);
else
FX_AddSprite( org, vel, qfalse, random() + 2, -4, 1.0, 1.0, 0.0, 0.0, 600, cgs.media.purpleParticleShader);
}
VectorMA(start, FX_MAXRANGE_STASIS, fwd, end2);
CG_Trace(&tr, start, NULL, NULL, end2, cent->currentState.number, MASK_SHOT);
if (!( tr.surfaceFlags & SURF_NOIMPACT ))
{
traceEnt = &cg_entities[tr.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (tr.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
// hit a player
FX_StasisShotImpact(tr.endpos, tr.plane.normal);
}
else
{
// hit the world
FX_StasisShotMiss(tr.endpos, tr.plane.normal);
}
}
// cap the impact end of the main beam to hide the nasty end of the line
FX_AddSprite( tr.endpos, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
if (bolt1==0)
{
VectorCopy(end, bolt1vec);
}
else if (bolt2==0)
{
VectorCopy(end, bolt2vec);
}
AngleVectors(cent->currentState.angles, fwd2, right, up);
// CrossProduct(fwd, up, right);
// VectorNormalize(right); // "right" is scaled by the sin of the angle between fwd & up... Ditch that.
// CrossProduct(right, fwd, up); // Change the "fake up" (0,0,1) to a "real up" (perpendicular to the forward vector).
// VectorNormalize(up); // If I cared about how the vertical variance looked when pointing up or down, I'd normalize this.
// Fire a shot up and to the right.
VectorMA(fwd, FX_STASIS_ALT_RIGHT_OFS, right, newdir);
VectorMA(newdir, FX_STASIS_ALT_UP_OFS, up, newdir);
VectorMA(start, FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
FX_SmallStasisBeam(cent, newstart, newdir);
if (bolt1==1)
{
VectorCopy(newdir, bolt1vec);
}
else if (bolt2==1)
{
VectorCopy(newdir, bolt2vec);
}
// Fire a shot up and to the left.
VectorMA(fwd, -FX_STASIS_ALT_RIGHT_OFS, right, newdir);
VectorMA(newdir, FX_STASIS_ALT_UP_OFS, up, newdir);
VectorMA(start, -FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
FX_SmallStasisBeam(cent, newstart, newdir);
if (bolt1==2)
{
VectorCopy(newdir, bolt1vec);
}
else if (bolt2==2)
{
VectorCopy(newdir, bolt2vec);
}
// Fire a shot a bit down and to the right.
VectorMA(fwd, 2.0*FX_STASIS_ALT_RIGHT_OFS, right, newdir);
VectorMA(newdir, -0.5*FX_STASIS_ALT_UP_OFS, up, newdir);
VectorMA(start, 2.0*FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
FX_SmallStasisBeam(cent, newstart, newdir);
if (bolt1==3)
{
VectorCopy(newdir, bolt1vec);
}
else if (bolt2==3)
{
VectorCopy(newdir, bolt2vec);
}
// Fire a shot up and to the left.
VectorMA(fwd, -2.0*FX_STASIS_ALT_RIGHT_OFS, right, newdir);
VectorMA(newdir, -0.5*FX_STASIS_ALT_UP_OFS, up, newdir);
VectorMA(start, -2.0*FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
FX_SmallStasisBeam(cent, newstart, newdir);
if (bolt1==4)
{
VectorCopy(newdir, bolt1vec);
}
else if (bolt2==4)
{
VectorCopy(newdir, bolt2vec);
}
// Put a big gigant-mo sprite at the muzzle end so people can't see the crappy edges of the line
FX_AddSprite( start, NULL, qfalse, random()*3 + 15, -20, 1.0, 0.5, 0.0, 0.0, 600, cgs.media.blueParticleShader);
// Do an electrical arc to one of the impact points.
FX_AddElectricity( start, bolt1vec, 0.2f, 15.0, -15.0, 1.0, 0.5, 100, cgs.media.dnBoltShader, 0.1 );
if (bolt1!=bolt2)
{
// ALSO do an electrical arc to another point.
FX_AddElectricity( bolt1vec, bolt2vec, 0.2f, 15.0, -15.0, 1.0, 0.5, flrandom(100,200), cgs.media.dnBoltShader, 0.5 );
}
}*/
/*
-------------------------
FX_StasisShotImpact
Alt-fire, impact effect
-------------------------
*/
/*void FX_StasisShotImpact( vec3_t end, vec3_t dir )
{
vec3_t org;
// Move me away from the wall a bit so that I don't z-buffer into it
VectorMA( end, 1.5, dir, org );
// Expanding rings
// FX_AddQuad( org, dir, 1, 80, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
// Impact effect
FX_AddQuad( org, dir, 7, 35, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
FX_AddQuad( org, dir, 5, 25, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
// CG_ImpactMark( cgs.media.scavMarkShader, org, dir, random()*360, 1,1,1,0.6, qfalse,
// 8 + random() * 2, qfalse );
// FX_StasisDischarge( org, dir, irandom( 2,4 ), 24 + random() * 12, 64 + random() * 48 );
}*/
/*
-------------------------
FX_StasisShotMiss
Alt-fire, miss effect
-------------------------
*/
/*void FX_StasisShotMiss( vec3_t end, vec3_t dir )
{
vec3_t org;
// Move me away from the wall a bit so that I don't z-buffer into it
VectorMA( end, 0.5, dir, org );
// Expanding rings
// FX_AddQuad( org, dir, 1, 16, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
// FX_AddQuad( org, dir, 1, 40, 0.8, 0.2, random() * 360, 300, cgs.media.stasisRingShader );
// Impact effect
FX_AddQuad( org, dir, 5, 25, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
FX_AddQuad( org, dir, 4, 17, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
CG_ImpactMark( cgs.media.scavMarkShader, org, dir, random()*360, 1,1,1,0.6, qfalse,
6 + random() * 2, qfalse );
FX_AddSprite( end, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
// FX_StasisDischarge( org, dir, irandom( 2,4 ), 24 + random() * 12, 64 + random() * 48 );
}*/
/*
-------------------------
FX_StasisProjectileThink
Main fire, with crazy bits swirling around main projectile
Hehe used to :D -TiM
-------------------------
*/
//unused
/*void FX_StasisProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
int size = 0;
vec3_t forward;
//vec3_t right, up;
//float radius, temp;
vec3_t org;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0 )
forward[2] = 1;
VectorCopy( cent->lerpOrigin, org );
// org[0] -=32;
//FX_AddTrail(
FX_AddTrail( org, forward, qfalse, 64, 0, 30.4f, 0.0f, 0.6f, 0.0f, 0, 1, cgs.media.disruptorBolt );
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 25.0f, 0.0f, 0.7f, 0.0f, 1.0f, 0.0f, 1.0f, cgs.media.disruptorStreak );
}*/
/*
-------------------------
FX_OrientedBolt
Creates new bolts for a while
-------------------------
*/
void FX_OrientedBolt( vec3_t start, vec3_t end, vec3_t dir )
{
vec3_t mid;
VectorSubtract( end, start, mid );
VectorScale( mid, 0.1f + (random() * 0.8), mid );
VectorAdd( start, mid, mid );
VectorMA(mid, 3.0f + (random() * 10.0f), dir, mid );
//FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
//FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[2], DEFAULT_DEVIATION);
FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[3], DEFAULT_DEVIATION);
}
/*
-------------------------
FX_StasisDischarge
Fun "crawling" electricity ( credit goes to Josh for this one )
-------------------------
*/
void FX_StasisDischarge( vec3_t origin, vec3_t normal, int count, float dist_out, float dist_side )
{
trace_t trace;
vec3_t org, dir, dest;
vec3_t vr;
int i;
int discharge = dist_side;
vectoangles( normal, dir );
dir[ROLL] += random() * 360;
for (i = 0; i < count; i++)
{
//Move out a set distance
VectorMA( origin, dist_out, normal, org );
//Even out the hits
dir[ROLL] += (360 / count) + (rand() & 31);
AngleVectors( dir, NULL, vr, NULL );
//Move to the side in a random direction
discharge += (int)( crandom() * 8.0f );
VectorMA( org, discharge, vr, org );
//Trace back to find a surface
VectorMA( org, -dist_out * 3, normal, dest );
CG_Trace( &trace, org, NULL, NULL, dest, 0, MASK_SHOT );
//No surface found, start over
if (trace.fraction == 1)
continue;
//Connect the two points with bolts
FX_OrientedBolt( origin, trace.endpos, normal );
//TiM : Aww screw it. Add a lens flare. ^_^
CG_InitLensFlare( trace.endpos,
10, 10,
colorTable[CT_GREEN], 1.2, 2.0, 1600, 500,
colorTable[CT_GREEN], 1600, 500, 100, 5, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 300.0f + random() * 300);
}
}
/*
-------------------------
FX_StasisWeaponHitWall
Main fire impact
-------------------------
*/
#define NUM_DISCHARGES 6
#define DISCHARGE_DIST 8
#define DISCHARGE_SIDE_DIST 24
void FX_StasisWeaponHitWall( vec3_t origin, vec3_t dir, int size )
{
vec3_t vel, /*accel,*/ hitpos, direction, org;
//int i, t;
weaponInfo_t *weaponInfo = &cg_weapons[WP_DISRUPTOR];
CG_InitLensFlare( origin,
375, 375,
colorTable[CT_GREEN], 1.2, 2.0, 1600, 200,
colorTable[CT_GREEN], 1600, 200, 800, 20, qtrue,
0, 0, qfalse, qtrue,
qfalse, 1.0, cg.time, 0, 0, 200);
// Generate "crawling" electricity // eh, don't it doesn't look that great.
FX_StasisDischarge( origin, dir, NUM_DISCHARGES, DISCHARGE_DIST, DISCHARGE_SIDE_DIST );
VectorMA(origin, size, dir, hitpos);
// Set an oriented residual glow effect
FX_AddQuad( hitpos, dir, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 0, 300, cgs.media.greenParticleShader );
CG_ImpactMark( cgs.media.scavMarkShader, origin, dir, random()*360, 1,1,1,0.6, qfalse,
size * 12 + 1, qfalse );
FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleShader );
/* FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleStreakShader ); */
FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f,
1.0f, 0.0f, 0.0f, 0, 400, cgs.media.greenParticleStreakShader );
VectorSubtract( cg.refdef.vieworg, origin, direction );
VectorNormalize( direction );
VectorMA( origin, 12, direction, org );
VectorMA( org, 8, dir, direction );
VectorSet(vel, 0, 0, 32 ); //8
FX_AddSprite( origin,
vel, qfalse,
random() * 4 + 2, 12,
0.6 + random() * 0.4, 0.0,
random() * 180,
0.0,
random() * 200 + 1200, //300
cgs.media.steamShader );
//FX_AddSprite(
// Only play the impact sound and throw off the purple particles when it's the main projectile
/* if ( size < 3 )
return;
for ( i = 0; i < 4; i++ )
{
for ( t = 0; t < 3; t++ )
vel[t] = ( dir[t] + crandom() * 0.9 ) * ( random() * 100 + 250 );
VectorScale( vel, -2.2, accel );
FX_AddSprite( hitpos, vel, qfalse, random() * 8 + 8, 0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.purpleParticleShader );
}*/
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
}
void FX_DisruptorBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
refEntity_t beam;
sfxHandle_t sfx;
float size;
vec3_t velocity;
int sparks;
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
sfx = 0;
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( startpos, beam.origin);
VectorCopy( endpos, beam.oldorigin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserEmptyShader;
}
else
{
beam.customShader = cgs.media.disruptorBeam;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff;
beam.shaderRGBA[2] = 0xff;
beam.shaderRGBA[3] = 0xff;
if (empty)
{
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
}
else
{
beam.data.line.width = 1.5f + ( crandom() * 0.6f );
}
beam.data.line.stscale = 5.0;
trap_R_AddRefEntityToScene( &beam );
// Now draw the hit graphic
// no explosion at LG impact, it is added with the beam
if ( sfx )
{
Com_Printf("playing %s\n", "phaser sound");
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
//
// impact mark
//
if (impact)
{
if (!empty)
{ // normal.
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
random() + 1, qfalse );
//VectorCopy( endpos, phaserFlare.worldCoord );
/*CG_InitLensFlare( endpos,
80,
80,
rgb,
1.2,
1.5,
1600,
200,
colorTable[CT_BLACK],
1600,
200,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qfalse,
1.0,
1.0,
200.0,
200.0,
200.0 );*/
//CG_InitLensFlare( endpos,
// 30, 30,
// rgb, 1.2, 2.0, 1600, 200,
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
// 0, 0, qfalse, qtrue,
// qfalse, 1.0, cg.time, 0, 0, 50);
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
//CG_DrawLensFlare( &phaserFlare );
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
//eh... looked bad :P
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
cgs.media.sunnyFlareShader );
}
else
{ // Wuss hit when empty.
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
cgs.media.sunnyFlareShader );
}
}
// "Fun" sparks... Not when empty.
if ( spark && !empty)
{
sparks = rand() & 1 + 1;
for(;sparks>0;sparks--)
{
size = 0.2f + (random() * 0.4);
FXE_Spray( normal, 200, 75, 0.8f, velocity);
if (rand() & LEF_USE_COLLISION)
{ // This spark bounces.
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
}
else
{
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
}
}
}
}

240
cgame/fx_tetrion.c Normal file
View file

@ -0,0 +1,240 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_TetrionProjectileThink
-------------------------
*/
/*void FX_TetrionProjectileThink( centity_t *cent, const struct weaponInfo_s *wi )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0 )
forward[2] = 1;
/*FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
4.0f + random() * 16.0f, 0.0f,
0.4f, 0.0f,
random()*360, 0.0f,
1.0f,
cgs.media.greenBurstShader );
FX_AddSprite( cent->lerpOrigin,
NULL, qfalse,
16.0f + random() * 16.0f, 0.0f,
0.6f, 0.0f,
random()*360, 0.0f,
1.0f,
cgs.media.borgFlareShader );
/*FX_AddTrail( cent->lerpOrigin,
forward, qfalse,
64, 0,
2.0f, 0,
0.5f, 0,
0,
1,
cgs.media.greenTrailShader );
}*/
/*
-------------------------
FX_TetrionShot
-------------------------
*/
#define MAXRANGE_TETRION 5000000 //RPG-X: J2J OLD: 8192
void FX_TetrionShot( vec3_t start, vec3_t forward )
{
trace_t trace;
vec3_t end, dir, new_start, new_end, radial, start2, spreadFwd;
float off, len, i, numBullets = 3;
float firingRadius = 6, minDeviation = 0.95, maxDeviation = 1.1;
qboolean render_impact = qtrue;
centity_t *traceEnt = NULL;
int clientNum = -1;
for (i = 0; i < numBullets; i++)
{
render_impact = qtrue;
// determine new firing position
fxRandCircumferencePos(start, forward, firingRadius, new_start);
VectorSubtract(new_start, start, radial);
VectorMA(start, 10, forward, start2);
VectorMA(start2, flrandom(minDeviation, maxDeviation), radial, start2);
VectorSubtract(start2, new_start, spreadFwd);
VectorNormalize(spreadFwd);
// determine new end position for this bullet. give the endpoint some spread, too.
VectorMA(new_start, MAXRANGE_TETRION, spreadFwd, end);
CG_Trace( &trace, new_start, NULL, NULL, end, cg_entities[cg.predictedPlayerState.clientNum].currentState.number, MASK_SHOT );
// Get the length of the whole shot
VectorSubtract( trace.endpos, new_start, dir );
len = VectorNormalize( dir );
// Don't do tracers when it gets really short
if ( len >= 64 )
{
// Move the end_point in a bit so the tracer doesn't always trace the full line length--this isn't strictly necessary, but it does
// add a bit of variance
off = flrandom(0.7, 1.0);
VectorMA( new_start, len * off, dir, new_end );
// Draw the tracer
FX_AddLine( new_end, new_start, 1.0f, 1.5f + random(), 0.0f, flrandom(0.3,0.6), 0.0,
flrandom(300,500), cgs.media.borgFlareShader );
}
// put the impact effect where this tracer hits
if (len >= 32)
{
// Rendering things like impacts when hitting a sky box would look bad, but you still want to see the tracer
if ( trace.surfaceFlags & SURF_NOIMPACT )
{
render_impact = qfalse;
}
if (render_impact)
{
traceEnt = &cg_entities[trace.entityNum];
clientNum = traceEnt->currentState.clientNum;
if ( (trace.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
{
// hit a player. let the shield/pain effects be the indicator for this
}
else
{
// hit something else
FX_TetrionWeaponHitWall(trace.endpos, trace.plane.normal);
}
}
}
}
}
/*
-------------------------
FX_TetrionWeaponHitWall
-------------------------
*/
void FX_TetrionWeaponHitWall( vec3_t origin, vec3_t normal )
{
/* vec3_t vel, accel, org;
int i = 0, t = 0;
float scale = random() * 2.5 + 1.5;
CG_ImpactMark( cgs.media.bulletmarksShader, origin, normal, random()*360, 1,1,1,0.2, qfalse,
scale, qfalse );
// Move out a hair to avoid z buffer nastiness
VectorMA( origin, 0.5, normal, org );
// Add a bit of variation every now and then
if ( rand() & 1 )
{
FX_AddQuad( org, normal,
scale * 2, -4,
0.5, 0.5,
0,
175,
cgs.media.sunnyFlareShader );
}
FX_AddQuad( org, normal,
scale * 4, -8,
1.0, 1.0,
0,
175,
cgs.media.borgFlareShader );
// Add some smoke puffs
for ( i = 0; i < 2; i ++ )
{
for ( t = 0; t < 3; t++ )
{
vel[t] = normal[t] + crandom();
}
VectorScale( vel, 12 + random() * 12, vel );
vel[2] += 16;
VectorScale( vel, -0.25, accel );
FX_AddSprite( origin,
vel, qfalse,
random() * 4 + 2, 12,
0.6 + random() * 0.4, 0.0,
random() * 180,
0.0,
random() * 200 + 300,
cgs.media.steamShader );
}*/
}
/*
-------------------------
FX_TetrionRicochet
-------------------------
*/ /*
void FX_TetrionRicochet( vec3_t origin, vec3_t normal )
{
vec3_t org;
// Move away from the wall a bit to help avoid z buffer clipping.
VectorMA( origin, 0.5, normal, org );
/*FX_AddQuad( org, normal,
24, -24,
1.0, 0.0,
0,
300,
cgs.media.greenBurstShader );
FX_AddQuad( org, normal,
48, -48,
0.5, 0.0,
0,
300,
cgs.media.borgFlareShader );
}*/
/*
-------------------------
FX_TetrionAltHitWall
-------------------------
*/
/*void FX_TetrionAltHitWall( vec3_t origin, vec3_t normal )
{
vec3_t org;
float scale;
scale = random() * 2.0 + 1.0;
/*CG_ImpactMark( cgs.media.bulletmarksShader, origin, normal, random()*360, 1,1,1,0.2, qfalse,
scale, qfalse );
// Move out a hair to avoid z buffer nastiness
VectorMA( origin, 0.5, normal, org );
/*FX_AddQuad( origin, normal,
64, -96,
1.0, 0.0,
0,
200,
cgs.media.greenBurstShader );
FX_AddQuad( origin, normal,
128, -192,
1.0, 0.0,
0,
200,
cgs.media.borgFlareShader );
// kef -- urp.fixme.
// trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cg_weapons[WP_TR116].altmissileHitSound );
}*/
/*
-------------------------
FX_TetrionAltHitPlayer
-------------------------
*/
void FX_TetrionAltHitPlayer( vec3_t origin, vec3_t normal )
{
}

293
cgame/fx_transporter.c Normal file
View file

@ -0,0 +1,293 @@
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
SPTransporterLensFlares
TiM: Judging from the title,
you just KNOW it's mine ;)
Anyway, the point of this
function is to render 4
sprites and then scale + move
them in a way reminisicant
of ST: Voyager's transporter FX.
I wrote this instead of using the
already made FX spawning functions
because they don't let u track an origin.
To stop the particle
from rendering within the character, I'm going to
use the DEPTHHACK renderflag, the flag
originally used for the weapon models
in first-person mode. :)
Planned timing:
0 - 500 : Flare spawns, and scales up to it's main size (width parameter)
500 - 1500 : Flare moves up the height/2 of model (height parameter)
1500 - 2000 : Flare scales down and disappears ( width * 1.0 - (timeScale) )
-------------------------
*/
void FX_SPTransporterLensFlares( centity_t* cent, vec3_t headVector, int startTime ) {
refEntity_t flare;
trace_t tr;
int i;
int direction = 1;
int timeOffset = 0; //250 - time between first and second flares appearing;
float ratio;
float dlightRatio;
vec3_t origin, tempOrigin;
int width;
int height;
//Hrmm... we have a glitch lol. Since DEPTHHACK is on, the flare will be drawn
//from ANYWHERE IN THE LEVEL! O_o
//So.... uh, we'll do a trace between ourselves and the entity this is attached
//to, and if they can't see each other, screw it. :P
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
if ( tr.fraction != 1 ) {
return;
}
}
/*else {
Com_Printf( "Origin: { %f, %f, %f }\n", cent->lerpOrigin[0], cent->lerpOrigin[1], cent->lerpOrigin[2] );
Com_Printf( "HeadVector: { %f, %f, %f }\n", headVector[0], headVector[1], headVector[2] );
return;
}*/
//calculate the necessary data we need to place the origin in the direct center of the model
memset( &flare, 0, sizeof( flare ) );
//Bah. I thought lerpOrigin was at the base of the feet. Turns out it's at the knees O_o
//This little hack should help that
VectorCopy( cent->lerpOrigin, tempOrigin );
tempOrigin[2] -= 24;
//If the distance means we're not lying down
if ( ( headVector[2] - tempOrigin[2] ) > 8 ) {
//find the average between our lerp origin and headVector to find the center
//VectorAdd( headVector, tempOrigin, origin );
//VectorScale( origin, 0.5, origin );
VectorAverage( headVector, tempOrigin, origin );
width = 30;
height = (headVector[2] - tempOrigin[2]) / 2;
}
else {
width = 30;
height = 4;
VectorCopy( cent->lerpOrigin, origin);
}
flare.reType = RT_SPRITE;
flare.shaderRGBA[0] = 0xff;
flare.shaderRGBA[1] = 0xff;
flare.shaderRGBA[2] = 0xff;
flare.shaderRGBA[3] = 0xff;
flare.data.sprite.rotation = 0;
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
flare.renderfx |= RF_DEPTHHACK; //DEPTHHACK renders the element over everything else. Useful in this lens flare simulation case :)
//loop 4 times = 4 flares. :)
for (i = 0; i < 4; i++ ) {
VectorClear( flare.origin );
VectorCopy( origin, flare.origin);
//the first two flares are the main ones
if ( i < 2 ) {
flare.customShader = cgs.media.transport1Shader; //1
timeOffset = startTime;
}
else { // the second two spawn a little later
flare.customShader = cgs.media.transport2Shader;
timeOffset = startTime + 650; //750
}
//the second flare each round goes down instead of up
if ( i % 2 == 0)
direction = 1;
else
direction = -1;
//===========================
if ( cg.time > timeOffset + 2000 ) {
continue;
}
//Phase 1: flares get bigger
if ( cg.time < timeOffset + 500 ) {
ratio = ((float)(cg.time - timeOffset) * 0.002);
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.data.sprite.radius = (float)width * ratio;
/*if ( i ==0 )
Com_Printf( "Phase 1 Radius: %f\n", flare.data.sprite.radius );*/
}
//Phase 2: flares move up/down character
if ( ( cg.time < timeOffset + 1500 ) && ( cg.time >= timeOffset + 500 ) ) {
ratio = ( (float)(cg.time - (timeOffset + 500) ) * 0.001 );
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.data.sprite.radius = (float)width;
flare.origin[2] += (float)direction * (float)height * ratio;
/*if (i == 0 )
Com_Printf( "Phase 2 Location: %f\n", flare.origin[2] );*/
}
//Phase 3: flares get smaller
if ( ( cg.time < timeOffset + 2000 ) && ( cg.time >= timeOffset + 1500 ) ) {
ratio = 1.0f - ( (float)(cg.time - ( timeOffset + 1500 ) ) * 0,002 );
if (ratio < 0 )
ratio = 0.0f;
else if (ratio > 1 )
ratio = 1.0f;
flare.origin[2] += ((float)height * (float)direction);
flare.data.sprite.radius = (float)width * ratio;
/*if ( i == 0 )
Com_Printf( "Phase 3 Radius: %f\n", flare.data.sprite.radius );*/
}
trap_R_AddRefEntityToScene( &flare );
}
//dynamic light calculation
if ( cg.time < ( startTime + 2000 ) ) {
dlightRatio = (float)( cg.time - startTime ) * 0,0005;
}
else {
dlightRatio = 1.0f - ( (float)( cg.time - ( startTime + 2000 ) ) * 0,0005 );
}
//dynamic light FX
trap_R_AddLightToScene( origin, 80.0f * dlightRatio, 0.345, 0.624, 0.835 );
}
/*
-------------------------
TransporterParticle
-------------------------
*/
qboolean TransporterParticle( localEntity_t *le)
{
vec3_t org, velocity = { 0, 0, 68 };
vec3_t accel = { 0, 0, -12 };
float scale, dscale;
qhandle_t shader;
VectorCopy( le->refEntity.origin, org );
org[2] += 0;//38;
shader = ( le->data.spawner.dir[0] == 0 ) ? cgs.media.trans1Shader : cgs.media.trans2Shader;
scale = ( le->data.spawner.dir[0] == 0 ) ? 2.0 : 4.0;
dscale = ( le->data.spawner.dir[0] == 0 ) ? 4.0 : 24.0;
le->data.spawner.dir[0]++;
FX_AddSprite( org,
velocity,
qfalse,
scale,
dscale,
1.0f,
0.0f,
0,
0.0f,
450.0f,
shader );
VectorScale( velocity, -1, velocity );
VectorScale( accel, -1, accel );
FX_AddSprite( org,
velocity,
qfalse,
scale,
dscale,
1.0f,
0.0f,
0,
0.0f,
450.0f,
shader );
return qtrue;
}
/*
-------------------------
TransporterPad
-------------------------
*/
qboolean TransporterPad( localEntity_t *le)
{
vec3_t org;
vec3_t up = {0,0,1};
float scale, dscale;
qhandle_t shader;
VectorCopy( le->refEntity.origin, org );
org[2] -= 3;
shader = cgs.media.trans1Shader;
scale = 20.0;
dscale = 2.0;
FX_AddQuad( org,
up,
scale,
dscale,
1.0f,
0.0f,
0,
950.0f,
shader );
return qtrue;
}
/*
-------------------------
FX_Transporter
-------------------------
*/
void FX_Transporter( vec3_t origin )
{
vec3_t up = {0,0,1};
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 0, 0, 200, TransporterParticle, 0 );
// trap_S_StartSound( origin, NULL, CHAN_AUTO, cgs.media.teleInSound );
}
/*
-------------------------
FX_TransporterPad
-------------------------
*/
void FX_TransporterPad( vec3_t origin )
{
vec3_t up = {0,0,1};
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 1000, 0, 0, TransporterPad, 0 );
}

256
cgame/tr_types.h Normal file
View file

@ -0,0 +1,256 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#ifndef __TR_TYPES_H
#define __TR_TYPES_H
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
#define MAX_ENTITIES 1023 // can't be increased without changing drawsurf bit packing
// renderfx flags
#define RF_LOWLIGHT 0x0001 // subtract ambient to keep it in the dark
#define RF_THIRD_PERSON 0x0002 // don't draw through eyes, only mirrors (player bodies, chat sprites)
#define RF_FIRST_PERSON 0x0004 // only draw through eyes (view weapon, damage blood blob)
#define RF_DEPTHHACK 0x0008 // for view weapon Z crunching
#define RF_FULLBRIGHT 0x0010 // Render with a bright ambient light.
#define RF_NOSHADOW 0x0040 // don't add stencil shadows
#define RF_LIGHTING_ORIGIN 0x0080 // use refEntity->lightingOrigin instead of refEntity->origin
// for lighting. This allows entities to sink into the floor
// with their origin going solid, and allows all parts of a
// player to get the same lighting
#define RF_SHADOW_PLANE 0x0100 // use refEntity->shadowPlane
#define RF_WRAP_FRAMES 0x0200 // mod the model frames by the maxframes to allow continuous
// animation without needing to know the frame count
#define RF_CAP_FRAMES 0x0400 // cap the model frames by the maxframes for one shot anims
#define RF_FORCE_ENT_ALPHA 0x0800 // Models should use ent alpha regardless of what the shader says.
// refdef flags
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
#define RDF_HYPERSPACE 4 // teleportation effect
#ifdef XTRA
#define RDF_MOTIONBLUR 8
#endif
typedef struct {
vec3_t xyz;
float st[2];
byte modulate[4];
} polyVert_t;
typedef struct poly_s {
qhandle_t hShader;
int numVerts;
polyVert_t *verts;
} poly_t;
typedef enum {
RT_MODEL,
RT_SPRITE,
RT_ORIENTEDSPRITE, // Replaces RT_POLY, which wasn't used. --Pat
RT_ALPHAVERTPOLY, // Individual alpha levels on each vertex
RT_BEAM,
RT_RAIL_CORE,
RT_RAIL_RINGS,
RT_LIGHTNING,
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
RT_LINE, // New type for Trek MP --Pat
RT_ORIENTEDLINE,
RT_LINE2, // New line type for Trek MP, with taper support --Pat
RT_BEZIER, // what he said --keith
RT_CYLINDER, // Yet another Trek primitive!
RT_ELECTRICITY, // Yet another Trek primitive!
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
typedef struct {
refEntityType_t reType;
int renderfx;
qhandle_t hModel; // opaque type outside refresh
// most recent data
vec3_t lightingOrigin; // so multi-part models can be lit identically (RF_LIGHTING_ORIGIN)
float shadowPlane; // projection shadows go here, stencils go slightly lower
vec3_t axis[3]; // rotation vectors
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
float origin[3]; // also used as MODEL_BEAM's "from"
int frame; // also used as MODEL_BEAM's diameter
// previous data for frame interpolation
float oldorigin[3]; // also used as MODEL_BEAM's "to"
int oldframe;
float backlerp; // 0.0 = current, 1.0 = old
// texturing
int skinNum; // inline skin index
qhandle_t customSkin; // NULL for default skin
qhandle_t customShader; // use one image for the entire thing
// misc
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
float shaderTexCoord[2]; // texture coordinates used by tcMod entity modifiers
float shaderTime; // subtracted from refdef time to control effect start times
// extra sprite information
union {
struct
{
float rotation;
float radius;
byte vertRGBA[4][4];
} sprite;
struct
{
float width;
float width2;
float stscale;
} line;
struct // that whole put-the-opening-brace-on-the-same-line-as-the-beginning-of-the-definition coding style is fecal
// TiM: You're a fecal. I prefer that style :D
// TiM: (c)2008 You're a you're a fecal. ;P I've grown to like the other one now.... it's way easier to read XD
{
float width;
vec3_t control1;
vec3_t control2;
} bezier;
struct
{
float width;
float width2;
float stscale;
float height;
float bias;
qboolean wrap;
} cylinder;
struct
{
float width;
float deviation;
float stscale;
qboolean wrap;
qboolean taper;
} electricity;
} data;
} refEntity_t;
#define MAX_RENDER_STRINGS 8
#define MAX_RENDER_STRING_LENGTH 32
typedef struct {
int x, y, width, height;
float fov_x, fov_y;
vec3_t vieworg;
vec3_t viewaxis[3]; // transformation matrix
// time in milliseconds for shader effects and other time dependent rendering issues
int time;
int rdflags; // RDF_NOWORLDMODEL, etc
// 1 bits will prevent the associated area from rendering at all
byte areamask[MAX_MAP_AREA_BYTES];
// text messages for deform text shaders
// char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
} refdef_t;
typedef enum {
STEREO_CENTER,
STEREO_LEFT,
STEREO_RIGHT
} stereoFrame_t;
/*
** glconfig_t
**
** Contains variables specific to the OpenGL configuration
** being run right now. These are constant once the OpenGL
** subsystem is initialized.
*/
typedef enum {
TC_NONE,
TC_S3TC,
TC_S3TC_DXT
} textureCompression_t;
typedef enum {
GLDRV_ICD, // driver is integrated with window system
// WARNING: there are tests that check for
// > GLDRV_ICD for minidriverness, so this
// should always be the lowest value in this
// enum set
GLDRV_STANDALONE, // driver is a non-3Dfx standalone driver
GLDRV_VOODOO // driver is a 3Dfx standalone driver
} glDriverType_t;
typedef enum {
GLHW_GENERIC, // where everthing works the way it should
GLHW_3DFX_2D3D, // Voodoo Banshee or Voodoo3, relevant since if this is
// the hardware type then there can NOT exist a secondary
// display adapter
GLHW_RIVA128, // where you can't interpolate alpha
GLHW_RAGEPRO, // where you can't modulate alpha on alpha textures
GLHW_PERMEDIA2 // where you don't have src*dst
} glHardwareType_t;
typedef struct {
char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS];
char version_string[MAX_STRING_CHARS];
char extensions_string[2*MAX_STRING_CHARS];
int maxTextureSize; // queried from GL
int maxActiveTextures; // multitexture ability
int colorBits, depthBits, stencilBits;
glDriverType_t driverType;
glHardwareType_t hardwareType;
qboolean deviceSupportsGamma;
textureCompression_t textureCompression;
qboolean textureEnvAddAvailable;
qboolean textureFilterAnisotropicAvailable;
int vidWidth, vidHeight;
// aspect is the screen's physical width / height, which may be different
// than scrWidth / scrHeight if the pixels are non-square
// normal screens should be 4/3, but wide aspect monitors may be 16/9
float windowAspect;
int displayFrequency;
// synonymous with "does rendering consume the entire screen?", therefore
// a Voodoo or Voodoo2 will have this set to TRUE, as will a Win32 ICD that
// used CDS.
qboolean isFullscreen;
qboolean stereoEnabled;
qboolean smpActive; // dual processor
} glconfig_t;
#if !defined _WIN32
#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"
#define OPENGL_DRIVER_NAME "libGL.so"
#else
#define _3DFX_DRIVER_NAME "3dfxvgl"
#define OPENGL_DRIVER_NAME "opengl32"
#endif // !defined _WIN32
#endif // __TR_TYPES_H

98
codetidbits.txt Normal file
View file

@ -0,0 +1,98 @@
/* Old Code bits
hcolor[0] = 0.0;
hcolor[1] = 1.0;
hcolor[2] = 0.0;
hcolor[3] = 1.0;
x = 250;
y2 = 200;
w = 100;
h = 100;
glowOffset = 60;
streakW = 500;
streakH = 10;*/
//reflecAnamorphic lenses make their flares really stretched
//Actually, just make this control the reflections.
//The user can define the w + h themselves. :P
/*if ( reflecAnamorphic ) {
w = w * 2;
//widthDouble = 2;
}*/
//else
/*CG_DrawPic(
( ( xCart/lensReflec[i].offset )+HALF_SCREEN_WIDTH ) - ( reflecAnamorphic ? lensReflec[i].width : lensReflec[i].width/2 ), //X
( ( yCart/lensReflec[i].offset )+HALF_SCREEN_HEIGHT ) - ( lensReflec[i].height/2 ), //Y
reflecAnamorphic ? lensReflec[i].width * 2 : lensReflec[i].width, //W
lensReflec[i].height, //H
lensReflec[i].graphic //pic
);*/
/* float yMid = ymin + ( (ymax - ymin) /2 );
//if the flare's origin moves to out of range, fade out the alpha on the reflections
//this is how it works O_o each side of the screen is a different quadrant controlled
//by a dif equation, excluding the corners where they'd overlap. The corners have their own
//equations applied later on, hopefully forming a complte circle for the flares to fade out easily. :S
//left bar
if ( x > xmin && x < xmax && y < ymin && y > -ymin )
reflecAlpha = (float)(( xmax - (float)x ) / xDif);
//right bar
if ( x < -xmin && x > -xmax && y < ymin && y > -ymin )
reflecAlpha = (float)(( xmax + (float)x ) / xDif);
//upper bar
if ( y > ymin && y < ymax && x < xmin && x > -xmin )
reflecAlpha = (float)(( ymax - (float)y ) / yDif);
//lower bar
if ( y < -ymin && y > -ymax && x < xmin && x > -xmin )
reflecAlpha = (float)(( ymax + (float)y ) / yDif);
//lower right quadrant
/* if ( x > xmin && x < xmax && y > ymin && y < ymax ) {
if ( (x*0.75) > yMid )*/
/*
CG_DrawPic( , y - ((h * hazeOffset) * 0.5), (w * hazeOffset), h * hazeOffset, cgs.media.flareHaze ); //Surrounding ambient haze
trap_R_SetColor( strkColor );
CG_DrawPic( streakX , streakY , streakW, streakH, cgs.media.flareStreak ); //Colored portion of the anamorphic streaks
trap_R_SetColor( color );
CG_DrawPic( x - ((w * glowOffset) * 0.5), y - ((h * glowOffset) * 0.5), (w * glowOffset), h * glowOffset, cgs.media.flareCore ); //Main colored glow bit of the main flare
if ( whiteStreaks ) { //if player wanted white streaks in their streaks
strkColor[0] = strkColor[1] = strkColor[2] = 1.0;
trap_R_SetColor( strkColor ); //White
CG_DrawPic( streakX + (streakW*0.2), streakY + (streakH*0.2), streakW*0.6, streakH*0.6, cgs.media.flareStreak ); //White Core of streak is ALWAYS 20% smaller.
}
trap_R_SetColor( NULL );
CG_DrawPic( x, y, w, h, cgs.media.flareCore ); //Draw teh main fl4r3 :)*/
//w = (0.0001 * -(length*length)) + w;
//h = (0.0001 * -(length*length)) + h;
/*if ( !clamp ) {
w = w + (int)(-0.1 * length );
h = h + (int)(-0.1 * length );
//clamp it at 10% then fade it out
if ( ((float)w/(float)w1) <= 0.2 && ((float)h/(float)h1) <= 0.2 ) {
w = w1*0.2f;
h = h1*0.2f;
}
//then fade it back in
//if ( ((float)w/(float)w1) >= .05 && ((float)h/(float)h1) >= .05 && fadeAlpha == 0.0 )
if ( ((float)w/(float)w1) <= 0.15 && ((float)h/(float)h1) <= 0.15 ) {
w = w1 * 0.15;
h = h1 * 0.15;
}
//CG_Printf( "Distance = %f, w = %i, h = %i\n", length, w, h);
}*/
//------------------------------------------------------

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