as released 2002-05-24
This commit is contained in:
commit
930d214707
270 changed files with 117620 additions and 0 deletions
BIN
MP_sdk_header4.jpg
Normal file
BIN
MP_sdk_header4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
169
UK-PC-EULA Level Editor.rtf
Normal file
169
UK-PC-EULA Level Editor.rtf
Normal file
|
@ -0,0 +1,169 @@
|
|||
{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial{\*\falt Helvetica};}
|
||||
{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f86\fnil\fcharset77\fprq0{\*\panose 00000000000000000000}Font8721{\*\falt Times New Roman};}{\f87\froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}
|
||||
{\f88\froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};}{\f90\froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\f91\froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};}
|
||||
{\f92\froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\f93\froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};}{\f94\froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}
|
||||
{\f95\fswiss\fcharset238\fprq2 Arial CE{\*\falt Helvetica};}{\f96\fswiss\fcharset204\fprq2 Arial Cyr{\*\falt Helvetica};}{\f98\fswiss\fcharset161\fprq2 Arial Greek{\*\falt Helvetica};}{\f99\fswiss\fcharset162\fprq2 Arial Tur{\*\falt Helvetica};}
|
||||
{\f100\fswiss\fcharset177\fprq2 Arial (Hebrew){\*\falt Helvetica};}{\f101\fswiss\fcharset178\fprq2 Arial (Arabic){\*\falt Helvetica};}{\f102\fswiss\fcharset186\fprq2 Arial Baltic{\*\falt Helvetica};}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;
|
||||
\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;
|
||||
\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive
|
||||
Default Paragraph Font;}{\s15\ql \li0\ri0\sb72\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon0 \snext15 Body;}{
|
||||
\s16\ql \fi-170\li170\ri0\sb72\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin170\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon0 \snext16 Bullet;}{\s17\ql \fi-360\li360\ri0\widctlpar\jclisttab\tx360{\*\pn
|
||||
\pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\aspalpha\aspnum\faauto\ls4\adjustright\rin0\lin360\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 \sautoupd List Bullet;}{\s18\ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0
|
||||
\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext18 Body Text;}}{\*\listtable{\list\listtemplateid-682570846\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \s17\fi-360\li360\jclisttab\tx360 }{\listname ;}\listid-119}{\list\listtemplateid0{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0
|
||||
\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0
|
||||
\levelindent0{\leveltext\'02\'01);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li720\jclisttab\tx720 }{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'02);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'03(\'03);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li1440\jclisttab\tx1440 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'03(\'04);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li1800\jclisttab\tx1800 }{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'03(\'05);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li2160\jclisttab\tx2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'06.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li2520\jclisttab\tx2520 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'07.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li2880\jclisttab\tx2880 }{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'08.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li3240\jclisttab\tx3240 }{\listname ;}\listid1422678978}}{\*\listoverridetable{\listoverride\listid1422678978\listoverridecount9{\lfolevel\listoverrideformat
|
||||
{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4
|
||||
\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'01);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc2\levelnfcn2\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0
|
||||
\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'03);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1
|
||||
\levelspace0\levelindent0{\leveltext\'03(\'04);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'03(\'05);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'06.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers
|
||||
\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\chbrdr
|
||||
\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}\ls1}{\listoverride\listid1422678978\listoverridecount9{\lfolevel\listoverrideformat{\listlevel\levelnfc1\levelnfcn1\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'02\'00.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers
|
||||
\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\chbrdr
|
||||
\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03);}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'04);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'05);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'06);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'07);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'08);}{\levelnumbers\'02;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}\ls2}{\listoverride\listid1422678978\listoverridecount9{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers
|
||||
\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'04\'00.\'01.;}{\levelnumbers\'01\'03;}\chbrdr
|
||||
\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'06\'00.\'01.\'02.;}{\levelnumbers\'01\'03\'05;}\chbrdr
|
||||
\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'08\'00.\'01.\'02.\'03.;}{\levelnumbers\'01\'03\'05\'07;}
|
||||
\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers
|
||||
\'01\'03\'05\'07\'09;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
|
||||
\'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0
|
||||
\levelindent0{\leveltext\'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0
|
||||
\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 }}{\lfolevel\listoverrideformat{\listlevel
|
||||
\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\chbrdr\brdrnone\brdrcf1
|
||||
\chshdng0\chcfpat1\chcbpat1 }}\ls3}{\listoverride\listid-119\listoverridecount0\ls4}}{\info{\title SOFTWARE LICENSE AGREEMENT}{\author Mike Rivera}{\operator Rick Johnson}{\creatim\yr2002\mo5\dy9\hr15\min1}{\revtim\yr2002\mo5\dy9\hr15\min1}{\version2}
|
||||
{\edmins0}{\nofpages3}{\nofwords1802}{\nofchars10272}{\nofcharsws12614}{\vern8247}}\margl2160\margr2160 \widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin2160
|
||||
\dgvorigin1440\dghshow1\dgvshow1\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1
|
||||
\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
|
||||
\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
|
||||
{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\ql \li0\ri0\sb72\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
|
||||
\f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20 SOFTWARE LICENSE AGREEMENT
|
||||
\par }\pard \s15\ql \li0\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\f1\fs20
|
||||
IMPORTANT - READ CAREFULLY: USE OF THIS PROGRAM IS SUBJECT TO THE SOFTWARE LICENSE TERMS SET FORTH BELOW. "PROGRAM" INCLUDES ALL SOFTWARE INCLUDED WITH THIS AGREEMENT, THE ASSOCIATED MEDIA, ANY PRINTED MATERIALS, AND ANY ONLINE O
|
||||
R ELECTRONIC DOCUMENTATION, AND ANY AND ALL COPIES OF SUCH SOFTWARE AND MATERIALS. BY OPENING THIS PACKAGE, INSTALLING, AND/OR USING THE PROGRAM AND ANY SOFTWARE PROGRAMS INCLUDED WITHIN, YOU ACCEPT THE TERMS OF THIS LICENSE WITH ACTIVISION, INC. ("ACTIVI
|
||||
SION").
|
||||
\par LIMITED USE LICENSE. Subject to the conditions described below, Activision grants you the non-exclusive, non-transferable, limited right and license to install and use one copy of this Program solely and exclusively for your personal use. All right
|
||||
s not specifically granted under this Agreement are reserved by Activision and, as applicable, Activision\rquote
|
||||
s licensors. This Program is licensed, not sold, for your use. Your license confers no title or ownership in this Program and should not be construed as a sale of any rights in this Program.
|
||||
\par
|
||||
\par LICENSE CONDITIONS.
|
||||
\par You shall not:
|
||||
\par }\pard\plain \s16\ql \fi-170\li170\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin170\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20 \bullet \tab }{\f1\fs20
|
||||
Exploit this Program or any of its parts commercially, including but not limited to use at a cyber cafe, computer gaming center or any other location-based site. Activision may
|
||||
offer a separate Site License Agreement to permit you to make this Program available for commercial use; see the contact information below.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Use this Program, or permit use of this Program, on more than one computer, computer terminal, or workstation at the same time.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Make copies of this Program or any part thereof, or make copies of the materials accompanying this Program.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Copy this Program onto a hard drive or other storage device; you must run this Program from the included CD-ROM (although this Pr
|
||||
ogram itself may automatically copy a portion of this Program onto your hard drive during installation in order to run more efficiently).
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Use the program, or permit use of this Program, in a network, multi-user arrangement or remote access arrangement, including any online use, except as otherwise explicitly provided by this Program.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Sell, rent, lease, license, distribute or otherwise transfer this Program, or any copies of this Program, without the express prior written consent of Activision.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Reverse engineer, derive source code, modify, decompile, disassemble, or create derivative works of this Program, in whole or in part.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Remove, disable or circumvent any proprietary notices or labels contained on or within the Program.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 Export or re-export this Program or any copy or adaptation in violation of any applicable laws or regulations of the United Sates government.
|
||||
\par
|
||||
\par }\pard\plain \s15\ql \li0\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20
|
||||
OWNERSHIP. All title, ownership rights and intellectual property rights in and to this Program and any and all copies thereof (including
|
||||
but not limited to any titles, computer code, themes, objects, characters, character names, stories, dialog, catch phrases, locations, concepts, artwork, animation, sounds, musical compositions, audio-visual effects, methods of operation, moral rights, a
|
||||
ny related documentation, and "applets" incorporated into this Program) are owned by Activision, affiliates of Activision or Activision\rquote
|
||||
s licensors. This Program is protected by the copyright laws of the United States, international copyright treaties and conventions and other laws. This Program contains certain licensed materials and Activision\rquote
|
||||
s licensors may protect their rights in the event of any violation of this Agreement.
|
||||
\par PROGRAM UTILITIES. This Program contains certain design, programming and proces
|
||||
sing utilities, tools, assets and other resources ("Program Utilities") for use with this Program that allow you to create customized new game levels and other related game materials for personal use in connection with the Program ("New Game Materials").
|
||||
The use of the Program Utilities is subject to the following additional license restrictions:
|
||||
\par }\pard\plain \s16\ql \fi-170\li170\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin170\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20 \bullet \tab }{\f1\fs20
|
||||
You agree that, as a condition to your using the Program Utilities, you will not use or allow third parties to use the Program Utilities and the New Game Materia
|
||||
ls created by you for any commercial purposes, including but not limited to selling, renting, leasing, licensing, distributing, or otherwise transferring the ownership of such New Game Materials, whether on a stand alone basis or packaged in combination w
|
||||
i
|
||||
th the New Game Materials created by others, through any and all distribution channels, including, without limitation, retail sales and on-line electronic distribution. You agree not to solicit, initiate or encourage any proposal or offer from any person
|
||||
or entity to create any New Game Materials for commercial distribution. You agree to promptly inform Activision in writing of any instances of your receipt of any such proposal or offer.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 If you decide to make available the use of the New Game Materials created by you to other gamers, you agree to do so solely without charge.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 New Game Materials shall not contain modifications to any COM, EXE or DLL files or to any other executable Product files.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 New Game Materials may be created only if such New Game Materials can be used exclusively in combination with the retail version of the Program. New Game Materials may not be designed to be used as a stand-alone product.
|
||||
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 New Game Materials must not contain any illegal, obscene or defamatory materials, material
|
||||
s that infringe rights of privacy and publicity of third parties or (without appropriate irrevocable licenses granted specifically for that purpose) any trademarks, copyright-protected works or other properties of third parties.
|
||||
\par }{\f1\fs20 \bullet \tab }{\f1\fs20 All New Game Materials must contain prominent identification at least in any on-line description and with reasonable duration on the opening screen: (a) the name and E-mail address of the New Game Materials\rquote
|
||||
creator(s) and (b) the words "THIS MATERIAL IS NOT MADE OR SUPPORTED BY ACTIVISION."
|
||||
\par
|
||||
\par }\pard\plain \s15\ql \li0\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20
|
||||
LIMITED WARRANTY: Activision warrants to the original consumer purchaser of this Program that the recording medium on which the Program is recorded will be free from defects in material and workmanship for 90 days from the date of purchase. If
|
||||
the recording medium is found defective within 90 days of original purchase, Activision agrees to replace, free of charge, any product discovered to be defective within such period upon its receipt of the Product, postage paid, with proof of the date of
|
||||
p
|
||||
urchase, as long as the Program is still being manufactured by Activision. In the event that the Program is no longer available, Activision retains the right to substitute a similar program of equal or greater value. This warranty is limited to the record
|
||||
i
|
||||
ng medium containing the Program as originally provided by Activision and is not applicable to normal wear and tear. This warranty shall not be applicable and shall be void if the defect has arisen through abuse, mistreatment, or neglect. Any implied warr
|
||||
anties prescribed by statute are expressly limited to the 90-day period described above.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20
|
||||
EXCEPT AS SET FORTH ABOVE, THIS WARRANTY IS IN LIEU OF ALL OTHER WARRANTIES, WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FIT
|
||||
NESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, AND NO OTHER REPRESENTATIONS OR CLAIMS OF ANY KIND SHALL BE BINDING ON OR OBLIGATE ACTIVISION. }{\f1\fs20
|
||||
WILL ACTIVISION BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGE RESULTING FROM POSSESSION, USE OR M
|
||||
ALFUNCTION OF THIS PRODUCT, INCLUDING DAMAGE TO PROPERTY AND, TO THE EXTENT PERMITTED BY LAW, DAMAGES FOR PERSONAL INJURY, EVEN IF ACTIVISION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED
|
||||
W
|
||||
ARRANTY LASTS AND/OR THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATIONS AND/OR EXCLUSION OR LIMITATION OF LIABILITY MAY NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS, AND YOU MAY HAVE OTHER RIGHT
|
||||
S WHICH VARY FROM STATE TO STATE.
|
||||
\par }\pard\plain \s15\ql \li0\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20
|
||||
When returning the Program for warranty replacement please send the original product disks only in protective packaging and include: (1) a photocopy of your dated sales receipt; (2) your name and return address typed or cle
|
||||
arly printed; (3) a brief note describing the defect, the problem(s) you are encountered and the system on which you are running the Program; (4) if you are returning the Program after the 90-day warranty period, but within one year after the date of purc
|
||||
hase, please include cheque or money order payable to Activision for $10\~U.S. ($19 AUD for Australia, or }{\f1\fs20 \'a310.00}{\f1\fs20 for Europe) currency per CD. Note: Certified mail recommended.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 In Europe send to:
|
||||
\par
|
||||
\par }\pard \ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 {\f1\fs20 WARRANTY REPLACEMENTS}{\f1\fs20\lang2057\langfe1033\langnp2057
|
||||
\par }\pard\plain \s18\ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 \fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f1\fs20\lang1033\langfe1033\langnp1033 ACTIVISION (UK) Ltd., Parliament House,
|
||||
St Laurence Way, Slough, Berkshire, SL1 2BW, United Kingdom.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 Disc Replacement: +44 (0)}{\f1\fs20\cf6 }{\f1\fs20 8705 143 525}{\f1\fs20\lang2057\langfe1033\langnp2057
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\f1\fs20
|
||||
\par
|
||||
\par In Australia send to:
|
||||
\par
|
||||
\par Warranty Replacements
|
||||
\par Activision
|
||||
\par }\pard \ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 {\f1\fs20 Century Plaza}{\f1\fs20
|
||||
\par }{\f1\fs20 41 Rawson Street}{\f1\fs20
|
||||
\par }{\f1\fs20 Epping, NSW 2121}{\f1\fs20
|
||||
\par }{\f1\fs20 Australia}{\f1\fs20
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\f1\fs20
|
||||
\par }\pard\plain \s15\ql \li0\ri0\sb7\keep\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f86\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\f1\fs20 LIMITATION ON DAMAGES: IN NO EVENT WILL
|
||||
ACTIVISION BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES RESULTING FROM POSSESSION, USE OR MALFUNCTION OF THE PROGRAM, INCLUDING DAMAGES TO PROPERTY, LOSS OF GOODWILL, COMPUTER FAILURE OR MALFUNCTION AND, TO THE EXTENT PERMITTED BY LAW, DAMA
|
||||
GES FOR PERSONAL INJURIES, EVEN IF ACTIVISION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ACTIVISION\rquote
|
||||
S LIABILITY SHALL NOT EXCEED THE ACTUAL PRICE PAID FOR THE LICENSE TO USE THIS PROGRAM. SOME STATES/COUNTRIES DO NOT ALLOW LIMITATIONS ON HOW LONG
|
||||
AN IMPLIED WARRANTY LASTS AND/OR THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATIONS AND/OR EXCLUSION OR LIMITATION OF LIABILITY MAY NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS, AND YOU MAY HAVE
|
||||
OTHER RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION.
|
||||
\par
|
||||
\par TERMINATION: Without prejudice to any other rights of Activision, this Agreement will terminate automatically if you fail to comply with its terms and conditions. In such event, you must destroy all copies of this Program and all of its component parts.
|
||||
|
||||
\par U.S. GOVERNMENT RESTRICTED RIGHTS: The Program and documentation have been developed entirely at private expense and are provided as "Commercial Computer Software" or "restricted computer software."
|
||||
Use, duplication or disclosure by the U.S. Government or a U.S. Government subcontractor is subject to the restrictions set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clauses in DFARS 252.227-7013 or as set for
|
||||
th in subparagraph (c)(1) and (2) of the Commercial Computer Software Restricted Rights clauses at FAR 52.227-19, as applicable. The Contractor/Manufacturer is Activision, Inc., 3100 Ocean Park Boulevard, Santa Monica, California 90405.
|
||||
\par INJUNCTION: Because
|
||||
Activision would be irreparably damaged if the terms of this Agreement were not specifically enforced, you agree that Activision shall be entitled, without bond, other security or proof of damages, to appropriate equitable remedies with respect to breache
|
||||
s of this Agreement, in addition to such other remedies as Activision may otherwise have under applicable laws.
|
||||
\par
|
||||
\par INDEMNITY: You agree to indemnify, defend and hold Activision, its partners, affiliates, licensors, contractors, officers, directors, employees
|
||||
and agents harmless from all damages, losses and expenses arising directly or indirectly from your acts and omissions to act in using the Product pursuant to the terms of this Agreement.
|
||||
\par
|
||||
\par MISCELLANEOUS: This Agreement represents the complete agreement conc
|
||||
erning this license between the parties and supersedes all prior agreements and representations between them. It may be amended only by a writing executed by both parties. If any provision of this Agreement is held to be unenforceable for any reason, such
|
||||
|
||||
provision shall be reformed only to the extent necessary to make it enforceable and the remaining provisions of this Agreement shall not be affected. This Agreement shall be construed under California law as such law is applied to agreements between Calif
|
||||
ornia residents entered into and to be performed within California, except as governed by federal law and you consent to the exclusive jurisdiction of the state and federal courts in Los Angeles, California.
|
||||
\par
|
||||
\par If you have any questions concerning this license, you may contact Activision at 3100 Ocean Park Boulevard, Santa Monica, California 90405,}{\f1\fs20 USA,}{\f1\fs20 (310) 255-2000, Attn. Business and Legal Affairs, legal@activision.com}{\f1\fs20 .}{
|
||||
\f1\fs20
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20
|
||||
\par }}
|
140
US-PC-EULA Level-Editor.rtf
Normal file
140
US-PC-EULA Level-Editor.rtf
Normal file
|
@ -0,0 +1,140 @@
|
|||
{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial{\*\falt Helvetica};}
|
||||
{\f12\froman\fcharset0\fprq2{\*\panose 00000000000000000000}New York{\*\falt Times New Roman};}{\f27\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f38\fswiss\fcharset0\fprq2{\*\panose 020b0603020202020204}Trebuchet MS;}
|
||||
{\f85\fnil\fcharset77\fprq0{\*\panose 00000000000000000000}Font14579{\*\falt Times New Roman};}{\f86\froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\f87\froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};}
|
||||
{\f89\froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\f90\froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};}{\f91\froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}
|
||||
{\f92\froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};}{\f93\froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\f94\fswiss\fcharset238\fprq2 Arial CE{\*\falt Helvetica};}
|
||||
{\f95\fswiss\fcharset204\fprq2 Arial Cyr{\*\falt Helvetica};}{\f97\fswiss\fcharset161\fprq2 Arial Greek{\*\falt Helvetica};}{\f98\fswiss\fcharset162\fprq2 Arial Tur{\*\falt Helvetica};}{\f99\fswiss\fcharset177\fprq2 Arial (Hebrew){\*\falt Helvetica};}
|
||||
{\f100\fswiss\fcharset178\fprq2 Arial (Arabic){\*\falt Helvetica};}{\f101\fswiss\fcharset186\fprq2 Arial Baltic{\*\falt Helvetica};}{\f302\fswiss\fcharset238\fprq2 Tahoma CE;}{\f303\fswiss\fcharset204\fprq2 Tahoma Cyr;}
|
||||
{\f305\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f306\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f307\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f308\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f309\fswiss\fcharset186\fprq2 Tahoma Baltic;}
|
||||
{\f390\fswiss\fcharset238\fprq2 Trebuchet MS CE;}{\f394\fswiss\fcharset162\fprq2 Trebuchet MS Tur;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;
|
||||
\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{
|
||||
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f27\fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
|
||||
\f38\fs48\lang1033\langfe1033\kerning32\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 heading 1;}{\s2\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f38\fs36\lang1033\langfe1033\cgrid\langnp1033\langfenp1033
|
||||
\sbasedon0 \snext0 heading 2;}{\s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f38\fs28\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 heading 3;}{
|
||||
\s4\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f38\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 heading 4;}{
|
||||
\s5\ql \li0\ri0\sb240\sa60\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f38\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 heading 5;}{
|
||||
\s6\ql \li0\ri0\sb240\sa60\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f38\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 heading 6;}{\*\cs10 \additive Default Paragraph Font;}{\*\cs15 \additive \ul\cf0
|
||||
\sbasedon10 Hyperlink;}{\*\cs16 \additive \ul\cf0 \sbasedon10 FollowedHyperlink;}{\s17\ql \li0\ri0\sb60\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 Body;}
|
||||
{\s18\ql \li0\ri0\sl480\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \caps\f85\fs54\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext18 Heading;}{
|
||||
\s19\ql \fi-145\li288\ri0\sb60\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin288\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 Bullet;}{\s20\ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0
|
||||
\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext20 Body Text;}}{\info{\title SOFTWARE LICENSE AGREEMENT}{\author Belinda M. Van Sickle}{\operator Rick Johnson}{\creatim\yr2002\mo5\dy9\hr14\min50}{\revtim\yr2002\mo5\dy9\hr14\min50}
|
||||
{\printim\yr1999\mo8\dy13\hr8\min44}{\version2}{\edmins0}{\nofpages1}{\nofwords1706}{\nofchars9725}{\*\company Ignited Minds, LLC}{\nofcharsws11942}{\vern8247}}{\*\userprops {\propname Microsoft Theme}\proptype30{\staticval klingon-industrial 111}}
|
||||
\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0\jexpand\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot\htmautsp\nolnhtadjtbl\lnbrkrule
|
||||
\fet0{\*\background {\shp{\*\shpinst\shpleft0\shptop0\shpright0\shpbottom0\shpfhdr0\shpbxmargin\shpbxignore\shpbymargin\shpbyignore\shpwr0\shpwrk0\shpfblwtxt1\shpz0\shplid1025{\sp{\sn shapeType}{\sv 1}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}
|
||||
{\sp{\sn fillType}{\sv 3}}{\sp{\sn fillBlipName}{\sv indtextb}}{\sp{\sn fFilled}{\sv 1}}{\sp{\sn lineWidth}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn bWMode}{\sv 9}}{\sp{\sn fBackground}{\sv 1}}{\sp{\sn fLayoutInCell}{\sv 1}}}}}\sectd
|
||||
\linex0\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4
|
||||
\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}
|
||||
{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s18\ql \li0\ri0\sl-480\slmult0
|
||||
\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \caps\f85\fs54\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f1\fs20 SOFTWARE LICENSE AGREEMENT
|
||||
\par }\pard\plain \s17\ql \li0\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 IMPORTANT - READ CAREFULLY: YOUR USE OF THIS SOFTWARE (THE \'93PROGRAM\'94
|
||||
) IS SUBJECT TO THE SOFTWARE LICENSE TERMS SET FORTH BELOW. THE \'93PROGRAM\'94 INCLUDES ALL SOFTWARE INCLUDED WITH THIS AGREEMENT, THE ASSOCIATED MEDIA, ANY PRINTED M
|
||||
ATERIALS, AND ANY ON-LINE OR ELECTRONIC DOCUMENTATION, AND ANY AND ALL COPIES OF SUCH SOFTWARE AND MATERIALS. BY OPENING THIS PACKAGE, INSTALLING, AND/OR USING THE PROGRAM AND ANY SOFTWARE PROGRAMS INCLUDED WITHIN THE PROGRAM, YOU ACCEPT THE TERMS OF THIS
|
||||
LICENSE WITH ACTIVISION, INC. (\'93ACTIVISION\'94).
|
||||
\par
|
||||
\par LIMITED USE LICENSE: Subject to the conditions described below, Activision grants you the non-exclusive, non-transferable, limited right and license to install and use one copy of the Program solely and exclu
|
||||
sively for your personal use. All rights not specifically granted under this Agreement are reserved by Activision and, as applicable, Activision\rquote
|
||||
s licensors. The Program is licensed, not sold, for your use. Your license confers no title or ownership in the
|
||||
Program and should not be construed as a sale of any rights in the Program. All rights not specifically granted under this Agreement are reserved by Activision and, as applicable, its licensors.
|
||||
\par
|
||||
\par LICENSE CONDITIONS
|
||||
\par You agree not to:
|
||||
\par }\pard\plain \s19\ql \fi-113\li119\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin119\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 \bullet \tab Exploit the Program
|
||||
or any of its parts commercially, including but not limited to use at a cyber cafe, computer gaming center or any other location-based site. Activision may offer a separate Site License Agreement to permit you to make the Program available for commercial
|
||||
use; see the contact information below.
|
||||
\par \bullet \tab Sell, rent, lease, license, distribute or otherwise transfer this Program, or any copies of this Program, without the express prior written consent of Activision.
|
||||
\par \bullet \tab Use the Program, or permit use of the Program, in a network, multi-user arrangement or remote access arrangement, including any on-line use, except as otherwise specifically provided by the Program.
|
||||
\par \bullet \tab Use the Program, or permit use of the Program, on more than one computer, computer terminal, or workstation at the same time.
|
||||
\par \bullet \tab Make copies of the Program or any part thereof, except for back up or archival purposes, or make copies of the materials accompanying the Program.
|
||||
\par \bullet \tab Copy the Program onto a hard drive or other storage device; you must run the Program
|
||||
from the included CD-ROM (although the Program itself may automatically copy a portion of the Program onto your hard drive during installation in order to run more efficiently).
|
||||
\par \bullet \tab Reverse engineer, derive source code, modify, decompile, or disassemble the Program, in whole or in part.
|
||||
\par \bullet \tab Remove, disable or circumvent any proprietary notices or labels contained on or within the Program.
|
||||
\par \bullet \tab Export or re-export the Program or any copy or adaptation thereof in violation of any applicable laws or regulations.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f27\fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {
|
||||
\par }\pard\plain \s17\ql \li0\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 OW
|
||||
NERSHIP: All title, ownership rights and intellectual property rights in and to the Program and any and all copies thereof are owned by Activision or its licensors. The Program is protected by the copyright laws of the United States, international copyrig
|
||||
ht treaties and conventions and other laws. The Program contains certain licensed materials and Activision\rquote
|
||||
s licensors may protect their rights in the event of any violation of this Agreement. You agree not to remove, disable or circumvent any proprietary notices or labels contained on or within the Program.
|
||||
\par
|
||||
\par THE PROGRAM UTILITIES: The Program contains certain design, programming and processing utilities, tools, assets and other resources (\'93the Program Utilities\'94) for use with the Program that allow you to c
|
||||
reate customized new game levels and other related game materials for personal use in connection with the Program (\'93New Game Materials\'94). The use of the Program Utilities is subject to the following additional license restrictions:
|
||||
\par }\pard\plain \s19\ql \fi-108\li119\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin119\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 \bullet \tab You agree that, as a c
|
||||
ondition to your using the Program Utilities, you will not use or allow third parties to use the Program Utilities and the New Game Materials created by you for any commercial purposes, including but not limited to selling, renting, leasing, licensing, di
|
||||
s
|
||||
tributing, or otherwise transferring the ownership of such New Game Materials, whether on a stand alone basis or packaged in combination with the New Game Materials created by others, through any and all distribution channels, including, without limitatio
|
||||
n
|
||||
, retail sales and on-line electronic distribution. You agree not to solicit, initiate or encourage any proposal or offer from any person or entity to create any New Game Materials for commercial distribution. You agree to promptly inform Activision in wr
|
||||
iting of any instances of your receipt of any such proposal or offer.
|
||||
\par \bullet \tab If you decide to make available the use of the New Game Materials created by you to other gamers, you agree to do so solely without charge.
|
||||
\par \bullet \tab New Game Materials shall not contain modifications to any COM, EXE or DLL files or to any other executable Product files.
|
||||
\par \bullet \tab New Game Materials may be created only if such New Game Materials can be used exclusively in combination with the retail version of the Program. New Game Materials may not be designed to be used as a stand-alone product.
|
||||
\par \bullet \tab New Game Materials must not contain any illegal, obscene or defamatory materials, materials that infringe rights of privacy and publicity of third parties or (without appropriate irrevocable licenses granted
|
||||
specifically for that purpose) any trademarks, copyright-protected works or other properties of third parties.
|
||||
\par \bullet \tab All New Game Materials must contain prominent identification at least in any on-line description and with reasonable duration on the opening screen: (a) the name and E-mail address of the New Game Materials\rquote
|
||||
creator(s) and (b) the words \'93THIS MATERIAL IS NOT MADE OR SUPPORTED BY ACTIVISION.\'94
|
||||
\par }\pard\plain \s17\ql \li0\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20
|
||||
\par LIMITED WARRANTY: Activision warrants to the original consumer purchaser of the Program that the record
|
||||
ing medium on which the Program is recorded will be free from defects in material and workmanship for 90 days from the date of purchase. If the recording medium is found defective within 90 days of original purchase, Activision agrees to replace, free of
|
||||
c
|
||||
harge, any product discovered to be defective within such period upon its receipt of the Product, postage paid, with proof of the date of purchase, as long as the Program is still being manufactured by Activision. In the event that the Program is no longe
|
||||
r
|
||||
available, Activision retains the right to substitute a similar program of equal or greater value. This warranty is limited to the recording medium containing the Program as originally provided by Activision and is not applicable to normal wear and tear.
|
||||
This warranty shall not be applicable and shall be void if the defect has arisen through abuse, mistreatment, or neglect. Any implied warranties prescribed by statute are expressly limited to the 90-day period described above.}{\f1\fs20
|
||||
\par }{\f1\fs20 EXCEPT AS SET FORTH ABOVE, TH
|
||||
IS WARRANTY IS IN LIEU OF ALL OTHER WARRANTIES, WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, AND NO OTHER REPRESENTATIONS OR CLAIMS OF ANY KIND SHALL BE BINDI
|
||||
NG ON OR OBLIGATE ACTIVISION.
|
||||
\par When returning the Program for warranty replacement please send the original product disks only in protective packaging and include: (1) a photocopy of your dated sales receipt; (2) your name and return address typed or clearl
|
||||
y printed; (3) a brief note describing the defect, the problem(s) you are encountered and the system on which you are running the Program; (4) if you are returning the Program after the 90-day warranty period, but within one year after the date of purchas
|
||||
e, please include check or money order for $10 U.S. (A$19 for Australia, or \'a310.00 for Europe) currency per CD or floppy disk replacement. Note: Certified mail recommended.
|
||||
\par In the U.S. send to:
|
||||
\par
|
||||
\par Warranty Replacements
|
||||
\par Activision, Inc.
|
||||
\par P.O. Box 67713
|
||||
\par Los Angeles, California 90067
|
||||
\par
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f27\fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f1\fs20 In Europe send to:
|
||||
\par }{\f1\fs20
|
||||
\par WARRANTY REPLACEMENTS
|
||||
\par }\pard\plain \s20\ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 \fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f1\fs20\lang1033\langfe1033\langnp1033
|
||||
ACTIVISION (UK) Ltd., Parliament House, St Laurence Way, Slough, Berkshire, SL1 2BW, United Kingdom.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f27\fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20 Disc Replacement: +44 (0)}{\f1\fs20\cf6 }{\f1\fs20 8705 143 525
|
||||
\par
|
||||
\par }{\b\f1\fs20 In Australia send to:
|
||||
\par }{\f1\fs20
|
||||
\par Warranty Replacements
|
||||
\par Activision
|
||||
\par }\pard \ql \li0\ri0\widctlpar\nooverflow\faauto\rin0\lin0\itap0 {\f1\fs20 Century Plaza}{\f1\fs20\cf0
|
||||
\par }{\f1\fs20 41 Rawson Street}{\f1\fs20
|
||||
\par }{\f1\fs20 Epping, NSW 2121}{\f1\fs20
|
||||
\par }{\f1\fs20 Australia
|
||||
\par }\pard\plain \s17\ql \li0\ri0\sb29\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f12\fs18\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20
|
||||
\par LIMITATION ON DAMAGES: IN NO EVENT WILL ACTIVISION BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES RESULTING FROM POSSESSION, USE OR MALFUNCTION OF THE PROGRAM, INCLUDING DAMAGES T
|
||||
O PROPERTY, LOSS OF GOODWILL, COMPUTER FAILURE OR MALFUNCTION AND, TO THE EXTENT PERMITTED BY LAW, DAMAGES FOR PERSONAL INJURIES, EVEN IF ACTIVISION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ACTIVISION\rquote
|
||||
S LIABILITY SHALL NOT EXCEED THE ACTUAL PRI
|
||||
CE PAID FOR THE LICENSE TO USE THIS PROGRAM. SOME STATES/COUNTRIES DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY LASTS AND/OR THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATIONS AND/OR EXCLUSION OR LIMIT
|
||||
ATION OF LIABILITY MAY NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS, AND YOU MAY HAVE OTHER RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION.
|
||||
\par TERMINATION: Without prejudice to any other rights of Activision, this Agreement will terminate automatically if you fail to comply with its terms and conditions. In such event, you must destroy all copies of the Program and all of its component parts.
|
||||
|
||||
\par
|
||||
\par U.S. GOVERNMENT RESTRICTED RIGHTS: the Program and documentation have been developed entirely at private expense and are provided as \'93Commercial Computer Software\'94 or \'93restricted computer software.\'94
|
||||
Use, duplication or disclosure by the U.S. Government or a U.S. Government subcontractor is subject to the restrictions set forth in subparagraph (c)(1)
|
||||
(ii) of the Rights in Technical Data and Computer Software clauses in DFARS 252.227-7013 or as set forth in subparagraph (c)(1) and (2) of the Commercial Computer Software Restricted Rights clauses at FAR 52.227-19, as applicable. The Contractor/Manufactu
|
||||
rer is Activision, Inc., 3100 Ocean Park Boulevard, Santa Monica, California 90405.
|
||||
\par
|
||||
\par INJUNCTION: Because Activision would be irreparably damaged if the terms of this Agreement were not specifically enforced, you agree that Activision shall be entitled, with
|
||||
out bond, other security or proof of damages, to appropriate equitable remedies with respect to breaches of this Agreement, in addition to such other remedies as Activision may otherwise have under applicable laws.
|
||||
\par
|
||||
\par INDEMNITY: You agree to indemnify, defen
|
||||
d and hold Activision, its partners, licensors, affiliates, contractors, officers, directors, employees and agents harmless from all damages, losses and expenses arising directly or indirectly from your acts and omissions to act in using the Product pursu
|
||||
ant to the terms of this Agreement
|
||||
\par
|
||||
\par MISCELLANEOUS: This Agreement represents the complete agreement concerning this license between the parties and supersedes all prior agreements and representations between them. It may be amended only by a writing execut
|
||||
ed by both parties. If any provision of this Agreement is held to be unenforceable for any reason, such provision shall be reformed only to the extent necessary to make it enforceable and the remaining provisions of this Agreement shall not be affected. T
|
||||
h
|
||||
is Agreement shall be construed under California law as such law is applied to agreements between California residents entered into and to be performed within California, except as governed by federal law and you consent to the exclusive jurisdiction of t
|
||||
he state and federal courts in Los Angeles, California.
|
||||
\par
|
||||
\par If you have any questions concerning this license, you may contact Activision at 3100 Ocean Park Boulevard, Santa Monica, California 90405, USA, (310) 255-2000, Attn. Business and Legal Affairs, legal@activision.com.
|
||||
\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f27\fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f1\fs20
|
||||
\par }}
|
1496
base/maps/examples.map
Normal file
1496
base/maps/examples.map
Normal file
File diff suppressed because it is too large
Load diff
BIN
bin/EffectsEd.exe
Normal file
BIN
bin/EffectsEd.exe
Normal file
Binary file not shown.
BIN
bin/ModView.exe
Normal file
BIN
bin/ModView.exe
Normal file
Binary file not shown.
BIN
bin/Radiant.exe
Normal file
BIN
bin/Radiant.exe
Normal file
Binary file not shown.
1
bin/RadiantMP.bat
Normal file
1
bin/RadiantMP.bat
Normal file
|
@ -0,0 +1 @@
|
|||
start radiant -noNPC -noConfusEd .\sof2mp.qe4
|
BIN
bin/ShaderEd2.exe
Normal file
BIN
bin/ShaderEd2.exe
Normal file
Binary file not shown.
BIN
bin/SoF2Asm.exe
Normal file
BIN
bin/SoF2Asm.exe
Normal file
Binary file not shown.
BIN
bin/SoF2lcc.exe
Normal file
BIN
bin/SoF2lcc.exe
Normal file
Binary file not shown.
BIN
bin/brick.jpg
Normal file
BIN
bin/brick.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
bin/carcass.exe
Normal file
BIN
bin/carcass.exe
Normal file
Binary file not shown.
BIN
bin/clamp.jpg
Normal file
BIN
bin/clamp.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
bin/cpp.exe
Normal file
BIN
bin/cpp.exe
Normal file
Binary file not shown.
BIN
bin/dirt.jpg
Normal file
BIN
bin/dirt.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
540
bin/entities.def
Normal file
540
bin/entities.def
Normal file
|
@ -0,0 +1,540 @@
|
|||
/*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended
|
||||
DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION.
|
||||
The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface.
|
||||
|
||||
If an item is the target of another entity, it will not spawn in until fired.
|
||||
|
||||
An item fires all of its targets when it is picked up. If the toucher can't carry it, the targets won't be fired.
|
||||
|
||||
"notfree" if set to 1, don't spawn in free for all games
|
||||
"notteam" if set to 1, don't spawn in team games
|
||||
"notsingle" if set to 1, don't spawn in single player games
|
||||
"wait" override the default wait before respawning. -1 = never respawn automatically, which can be used with targeted spawning.
|
||||
"random" random number of plus or minus seconds varied from the respawn time
|
||||
"count" override quantity or duration on most items.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_armor_big (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_armor_medium (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_armor_small (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_health_big (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_health_small (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_US_SOCOM (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Pistol, uses 45 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M19 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Pistol, uses 45 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_microuzi (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Sub-Machinegun, uses 9mm rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M3A1 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Sub-Machinegun, uses 45 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_USAS_12 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Shotgun, uses 12-gauge rounds
|
||||
ammo ---------- amount of ammo (defaults to 10)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M590 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Shotgun, uses 12-gauge rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_MSG90A1 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Sniper Rifle, uses 7.62 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M4 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Assault Rifle, uses 5.56 rounds and 40mm grenades
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_AK_74 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Assault Rifle, uses 5.56 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M60 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Machinegun, uses 7.62 rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_RPG_7 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
RPG, uses 40mm rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_MM_1 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade Launcher, uses 40mm rounds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M67 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M84 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_F1 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_L2A2 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_MDN11 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_SMOHG92 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_AN_M14 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
Incendiary Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_weapon_M15 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
White Phosphorus Grenade
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_45 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_9mm (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_12gauge (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_762 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_556 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_40mm (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_ammo_rpg7 (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED pickup_backpack (0 .6 .6) (-15 -15 -15) (15 15 15)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -46) (16 16 48) initial
|
||||
potential spawning position for deathmatch games.
|
||||
The first time a player enters the game, they will be at an 'initial' spot.
|
||||
Targets will be fired when someone spawns in on them.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED info_player_intermission (1 0 1) (-16 -16 -46) (16 16 48)
|
||||
The intermission will be viewed from this point. Target an info_notnull for the view direction.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED gametype_player (0 1 0) (-16 -16 -46) (16 16 48) REDTEAM BLUETEAM
|
||||
Potential spawning position for red or blue team in custom gametype games.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED gametype_trigger (0 0 .8) ?
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED gametype_item (0 0 1) (-16 -16 -16) (16 16 16)
|
||||
"name" name of the item to spawn (defined in gametype script)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_group (0 0 0) ?
|
||||
Used to group brushes together just for editor convenience. They are turned into normal brushes by the utilities.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
Used as a positional target for in-game calculation, like jumppad targets.
|
||||
target_position does the same thing
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16)
|
||||
Point teleporters at these.
|
||||
Now that we don't have teleport destination pads, this is just
|
||||
an info_notnull
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_model (1 0 0) (-16 -16 -16) (16 16 16) RMG
|
||||
this model is inserted into the bsp file
|
||||
"model" arbitrary .md3 file to display
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_G2model (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
"model" arbitrary .glm file to display
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_portal_surface (0 0 1) (-8 -8 -8) (8 8 8)
|
||||
The portal surface nearest this entity will show a view from the targeted misc_portal_camera, or a mirror view if untargeted.
|
||||
This must be within 64 world units of the surface!
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate noswing
|
||||
The target for a misc_portal_director. You can set either angles or target another entity to determine the direction of view.
|
||||
"roll" an angle modifier to orient the camera around the target vector;
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED misc_bsp (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
"bspmodel" arbitrary .bsp file to display
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED terrain (1.0 1.0 1.0) ?
|
||||
Terrain entity
|
||||
It will stretch to the full height of the brush
|
||||
|
||||
numPatches - integer number of patches to split the terrain brush into (default 200)
|
||||
terxels - integer number of terxels on a patch side (default 4) (2 <= count <= 8)
|
||||
seed - integer seed for random terrain generation (default 0)
|
||||
textureScale - float scale of texture (default 0.005)
|
||||
heightMap - name of heightmap data image to use
|
||||
terrainDef - defines how the game textures the terrain (file is base/ext_data/*.terrain - default is grassyhills)
|
||||
instanceDef - defines which bsp instances appear
|
||||
miscentDef - defines which client models spawn on the terrain (file is base/ext_data/*.miscents)
|
||||
densityMap - how dense the client models are packed
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED fx_play_effect (.2 .5 .8) (-8 -8 -8) (8 8 8) START_OFF
|
||||
Plays specified effect file
|
||||
|
||||
"effect" name of .efx file
|
||||
"wait" seconds between triggerings, default 0.3
|
||||
"random" wait variance in seconds, default 0
|
||||
"target" direction of effect, default up
|
||||
"count" plays effect this many times then deletes itself, default -1 = infinite
|
||||
|
||||
|
||||
START_OFF fx starts off
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER
|
||||
TOGGLE wait in both the start and end states for a trigger event.
|
||||
START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
|
||||
NOMONSTER monsters will not trigger this door
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"angle" determines the opening direction
|
||||
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
|
||||
"speed" movement speed (100 default)
|
||||
"wait" wait before returning (3 default, -1 = never return)
|
||||
"lip" lip remaining at end of move (8 default)
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
"health" if set, the door must be shot open
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_plat (0 .5 .8) ?
|
||||
Plats are always drawn in the extended position so they will light correctly.
|
||||
|
||||
"lip" default 8, protrusion above rest position
|
||||
"height" total height of movement, defaults to model height
|
||||
"speed" overrides default 200.
|
||||
"dmg" overrides default 2
|
||||
"model2" .md3 model to also draw
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_button (0 .5 .8) ?
|
||||
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"angle" determines the opening direction
|
||||
"target" all entities with a matching targetname will be used
|
||||
"speed" override the default 40 speed
|
||||
"wait" override the default 1 second wait (-1 = never return)
|
||||
"lip" override the default 4 pixel lip remaining at end of move
|
||||
"health" if set, the button must be killed instead of touched
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8)
|
||||
Train path corners.
|
||||
Target: next path corner and other targets to fire
|
||||
"speed" speed to move to the next corner
|
||||
"wait" seconds to wait before behining move to next corner
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS
|
||||
A train is a mover that moves between path_corner target points.
|
||||
Trains MUST HAVE AN ORIGIN BRUSH.
|
||||
The train spawns at the first target it is pointing at.
|
||||
"model2" .md3 model to also draw
|
||||
"speed" default 100
|
||||
"dmg" default 2
|
||||
"noise" looping sound to play when the train is in motion
|
||||
"target" next path corner
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_static (0 .5 .8) ?
|
||||
A bmodel that just sits there, doing nothing. Can be used for conditional walls and models.
|
||||
"model2" .md3 model to also draw
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_rotating (0 .5 .8) ? START_ON - X_AXIS Y_AXIS
|
||||
You need to have an origin brush as part of this entity. The center of that brush will be
|
||||
the point around which it is rotated. It will rotate around the Z axis by default. You can
|
||||
check either the X_AXIS or Y_AXIS box to change that.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"speed" determines how fast it moves; default value is 100.
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
|
||||
Normally bobs on the Z axis
|
||||
"model2" .md3 model to also draw
|
||||
"height" amplitude of bob (32 default)
|
||||
"speed" seconds to complete a bob cycle (4 default)
|
||||
"phase" the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_pendulum (0 .5 .8) ?
|
||||
You need to have an origin brush as part of this entity.
|
||||
Pendulums always swing north / south on unrotated models. Add an angles field to the model to allow rotation in other directions.
|
||||
Pendulum frequency is a physical constant based on the length of the beam and gravity.
|
||||
"model2" .md3 model to also draw
|
||||
"speed" the number of degrees each way the pendulum swings, (30 default)
|
||||
"phase" the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_glass (0 .5 .8) ?
|
||||
Breakable glass
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED worldspawn (0 0 0) ?
|
||||
|
||||
Every map should have exactly one worldspawn.
|
||||
"music" music wav file
|
||||
"soundSet" soundset name to use (do not combine with 'noise', ignores all other flags)
|
||||
"gravity" 800 is default gravity
|
||||
"message" Text to print during connection process
|
||||
"mission" Indicates which mission script file should be used to find the scripts for mission mode
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED model_static (1 0 0) (-16 -16 -16) (16 16 16) NO_MP
|
||||
"model" arbitrary .md3 file to display
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_give (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Gives the activator all the items pointed to.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_delay (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
"wait" seconds to pause before firing targets.
|
||||
"random" delay variance, total delay = delay +/- random seconds
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_score (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
"count" number of points to add, default 1
|
||||
|
||||
The activator is given this many points.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_print (1 0 0) (-8 -8 -8) (8 8 8) redteam blueteam private
|
||||
"message" text to print
|
||||
If "private", only the activator gets the message. If no checks, all clients get the message.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off global activator
|
||||
"noise" wav file to play
|
||||
"soundSet" soundset name to use (do not combine with 'noise', ignores all other flags)
|
||||
|
||||
A global sound will play full volume throughout the level.
|
||||
Activator sounds will play on the player that activated the target.
|
||||
Global and activator sounds can't be combined with looping.
|
||||
Normal sounds play each time the target is used.
|
||||
Looped sounds will be toggled by use functions.
|
||||
Multiple identical looping sounds will just increase volume without any speed cost.
|
||||
"wait" : Seconds between auto triggerings, 0 = don't auto trigger
|
||||
"random" wait variance, default is 0
|
||||
"radius" radius of attenuation
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON
|
||||
When triggered, fires a laser. You can either set a target or a direction.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_teleporter (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
The activator will be teleported away.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) RED_ONLY BLUE_ONLY RANDOM
|
||||
This doesn't perform any actions except fire its targets.
|
||||
The activator can be forced to be from a certain team.
|
||||
if RANDOM is checked, only one of the targets will be fired, not all of them
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_kill (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
Kills the activator.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_position (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
Used as a positional target for in-game calculation, like jumppad targets.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_location (0 0.5 0) (-8 -8 -8) (8 8 8)
|
||||
Set "message" to the name of this location.
|
||||
|
||||
Closest target_location in sight used for the location, if none
|
||||
in site, closest in distance
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_multiple (.5 .5 .5) ?
|
||||
"wait" : Seconds between triggerings, 0.5 default, -1 = one time only.
|
||||
"random" wait variance, default is 0
|
||||
Variable sized repeatable trigger. Must be targeted at one or more entities.
|
||||
so, the basic time between firing is a random time between
|
||||
(wait - random) and (wait + random)
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
This trigger will always fire. It is activated by the world.
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_push (.5 .5 .5) ?
|
||||
Must point at a target_position, which will be the apex of the leap.
|
||||
This will be client side predicted, unlike target_push
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) bouncepad
|
||||
Pushes the activator in the direction.of angle, or towards a target apex.
|
||||
"speed" defaults to 1000
|
||||
if "bouncepad", play bounce noise instead of windfly
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR
|
||||
Allows client side prediction of teleportation events.
|
||||
Must point at a target_position, which will be the teleport destination.
|
||||
|
||||
If spectator is set, only spectators can use this teleport
|
||||
Spectator teleporters are not normally placed in the editor, but are created
|
||||
automatically near doors to allow spectators to move through them
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF - SILENT NO_PROTECTION SLOW
|
||||
Any entity that touches this will be hurt.
|
||||
It does dmg points of damage each server frame
|
||||
Targeting the trigger will toggle its on / off state.
|
||||
|
||||
SILENT supresses playing the sound
|
||||
SLOW changes the damage rate to once per second
|
||||
NO_PROTECTION *nothing* stops the damage
|
||||
|
||||
"dmg" default 5 (whole numbers only)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED trigger_ladder (.5 .5 .5) ?
|
||||
Indicates a ladder and its normal
|
||||
|
||||
"angles" angle ladder faces
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON
|
||||
This should be renamed trigger_timer...
|
||||
Repeatedly fires its targets.
|
||||
Can be turned on or off by using.
|
||||
|
||||
"wait" base time between triggering all targets, default is 1
|
||||
"random" wait variance, default is 0
|
||||
so, the basic time between firing is a random time between
|
||||
(wait - random) and (wait + random)
|
||||
|
||||
*/
|
||||
|
||||
|
BIN
bin/none.jpg
Normal file
BIN
bin/none.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 631 B |
BIN
bin/plugins/curry.dll
Normal file
BIN
bin/plugins/curry.dll
Normal file
Binary file not shown.
BIN
bin/plugins/gensurf.dll
Normal file
BIN
bin/plugins/gensurf.dll
Normal file
Binary file not shown.
108
bin/plugins/gensurf.ini
Normal file
108
bin/plugins/gensurf.ini
Normal file
|
@ -0,0 +1,108 @@
|
|||
[Options]
|
||||
Game=0
|
||||
Amplitude=128
|
||||
Roughness=16
|
||||
WaveLength=1024
|
||||
Extents=-512,-512,512,512
|
||||
CornerValues=0,0,0,0
|
||||
TextureOffset=0,0
|
||||
TextureScale=1,1
|
||||
NH=0x0008
|
||||
NV=0x0008
|
||||
AddHints=0x0000
|
||||
ArghRad2=0x0000
|
||||
AutoOverwrite=0x0000
|
||||
FixBorders=0x0001
|
||||
HideBackFaces=0x0000
|
||||
Plane=0x0000
|
||||
Preview=0x0000
|
||||
RandomSeed=0x0001
|
||||
Skybox=0x0000
|
||||
UseDetail=0x0000
|
||||
UseLadder=0x0000
|
||||
WaveType=0x0003
|
||||
vid_x=0x01c7
|
||||
vid_y=0x011c
|
||||
view_x=0x0500
|
||||
view_y=0x0000
|
||||
view_cx=0x0867
|
||||
view_cy=0x0400
|
||||
UsePatches=0x0000
|
||||
SlantAngle=0x003c
|
||||
[Quake2]
|
||||
OutputDir=
|
||||
Texture=e1u1/grass1_4
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=c:\quake2\baseq2\textures\
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Half-Life]
|
||||
OutputDir=
|
||||
Texture=OUT_GRND1
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[SiN]
|
||||
OutputDir=
|
||||
Texture=generic/floor_organic/fl_grass
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Heretic2]
|
||||
OutputDir=
|
||||
Texture=canyon/canyon05
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Kingpin]
|
||||
OutputDir=
|
||||
Texture=bricks/s_sr_m3
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=c:\kingpin\main\textures\
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Genesis3D]
|
||||
OutputDir=
|
||||
Texture=rock13
|
||||
Texture2=
|
||||
Texture3=
|
||||
TextureDir=
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Quake3]
|
||||
OutputDir=
|
||||
Texture=organics/grass3
|
||||
Texture2=common/caulk
|
||||
Texture3=
|
||||
TextureDir=
|
||||
UsePak=0x0000
|
||||
PakFile=
|
||||
LastPakFile=
|
||||
GameDir=
|
||||
[Bitmap]
|
||||
Filename=S:\design\gensurf_images\col2.bmp
|
||||
DefaultPath=S:\design\gensurf_images\
|
||||
BlackValue=0
|
||||
WhiteValue=256
|
||||
[Formula]
|
||||
Formula=256-radius/4+128*sin(radius/512)
|
BIN
bin/plugins/max4/XSIImporter.dli
Normal file
BIN
bin/plugins/max4/XSIImporter.dli
Normal file
Binary file not shown.
BIN
bin/plugins/max4/vmdexp.dle
Normal file
BIN
bin/plugins/max4/vmdexp.dle
Normal file
Binary file not shown.
BIN
bin/plugins/purgeevil.dll
Normal file
BIN
bin/plugins/purgeevil.dll
Normal file
Binary file not shown.
BIN
bin/plugins/shapes.dll
Normal file
BIN
bin/plugins/shapes.dll
Normal file
Binary file not shown.
BIN
bin/rcc.exe
Normal file
BIN
bin/rcc.exe
Normal file
Binary file not shown.
BIN
bin/sof2data.exe
Normal file
BIN
bin/sof2data.exe
Normal file
Binary file not shown.
BIN
bin/sof2map.exe
Normal file
BIN
bin/sof2map.exe
Normal file
Binary file not shown.
23
bin/sof2mp.qe4
Normal file
23
bin/sof2mp.qe4
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"basepath" "..\base"
|
||||
"rshcmd" ""
|
||||
"remotebasepath" "..\base"
|
||||
"entitypath" "__QERPATH*.def"
|
||||
"texturepath" "..\base\textures"
|
||||
"autosave" "..\base\maps\autosave.map"
|
||||
|
||||
"bsp FullVis (1/2 LMs)" "__QERPATHsof2map -bsp -rename -samplesize 32 $ -class 4 && __QERPATHsof2map -vis $ -class 2 && __QERPATHsof2map -light -extra -samplesize 32 $"
|
||||
"bsp FullVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light $"
|
||||
"bsp FullVis (extra)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light -extra $"
|
||||
"bsp FullVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $"
|
||||
"bsp FastVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $"
|
||||
"bsp FastVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $ && __QERPATHsof2map -light $"
|
||||
"bsp NoVis" "__QERPATHlocalbatch\novis.bat $"
|
||||
"bsp OnlyEnts" "__QERPATHsof2map -bsp -rename -onlyents $"
|
||||
"bsp Info" "__QERPATHsof2map -info $"
|
||||
"bsp Relight (extra)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra $"
|
||||
"bsp Relight (1/2 LM)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra -samplesize 32 $"
|
||||
"brush_primit" "0"
|
||||
|
||||
}
|
||||
|
23
bin/sof2mp.qe4.duplicate1
Normal file
23
bin/sof2mp.qe4.duplicate1
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"basepath" "..\base"
|
||||
"rshcmd" ""
|
||||
"remotebasepath" "..\base"
|
||||
"entitypath" "__QERPATH*.def"
|
||||
"texturepath" "..\base\textures"
|
||||
"autosave" "..\base\maps\autosave.map"
|
||||
|
||||
"bsp FullVis (1/2 LMs)" "__QERPATHsof2map -bsp -rename -samplesize 32 $ -class 4 && __QERPATHsof2map -vis $ -class 2 && __QERPATHsof2map -light -extra -samplesize 32 $"
|
||||
"bsp FullVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light $"
|
||||
"bsp FullVis (extra)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $ && __QERPATHsof2map -light -extra $"
|
||||
"bsp FullVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis $"
|
||||
"bsp FastVis (nolight)" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $"
|
||||
"bsp FastVis" "__QERPATHsof2map -bsp -rename $ && __QERPATHsof2map -vis -fast $ && __QERPATHsof2map -light $"
|
||||
"bsp NoVis" "__QERPATHlocalbatch\novis.bat $"
|
||||
"bsp OnlyEnts" "__QERPATHsof2map -bsp -rename -onlyents $"
|
||||
"bsp Info" "__QERPATHsof2map -info $"
|
||||
"bsp Relight (extra)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra $"
|
||||
"bsp Relight (1/2 LM)" "__QERPATHsof2map -bsp -rename -onlyents $ && __QERPATHsof2map -light -extra -samplesize 32 $"
|
||||
"brush_primit" "0"
|
||||
|
||||
}
|
||||
|
BIN
bin/stucco.jpg
Normal file
BIN
bin/stucco.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
61
code/Sof2MP.dsp
Normal file
61
code/Sof2MP.dsp
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Microsoft Developer Studio Project File - Name="Sof2MP" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Generic Project" 0x010a
|
||||
|
||||
CFG=Sof2MP - 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 "Sof2MP.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 "Sof2MP.mak" CFG="Sof2MP - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Sof2MP - Win32 Release" (based on "Win32 (x86) Generic Project")
|
||||
!MESSAGE "Sof2MP - Win32 Debug" (based on "Win32 (x86) Generic Project")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
MTL=midl.exe
|
||||
|
||||
!IF "$(CFG)" == "Sof2MP - 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 Target_Dir ""
|
||||
|
||||
!ELSEIF "$(CFG)" == "Sof2MP - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Sof2MP - Win32 Release"
|
||||
# Name "Sof2MP - Win32 Debug"
|
||||
# End Target
|
||||
# End Project
|
149
code/Sof2MP.dsw
Normal file
149
code/Sof2MP.dsw
Normal file
|
@ -0,0 +1,149 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SoF2cgame"=.\cgame\sof2_cgame.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SoF2game"=.\game\sof2_game.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SoF2ui"=.\ui\sof2_ui.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Sof2MP"=.\Sof2MP.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name SoF2cgame
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name SoF2game
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name SoF2ui
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gt_ctf
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gt_dm
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gt_elim
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gt_inf
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gt_tdm
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gt_ctf"=.\gametype\gt_ctf\gt_ctf.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gt_dm"=.\gametype\gt_dm\gt_dm.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gt_elim"=.\gametype\gt_elim\gt_elim.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gt_inf"=.\gametype\gt_inf\gt_inf.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gt_tdm"=.\gametype\gt_tdm\gt_tdm.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
89
code/all.bat
Normal file
89
code/all.bat
Normal file
|
@ -0,0 +1,89 @@
|
|||
@set include=
|
||||
@del /q ..\base\vm
|
||||
@cd game
|
||||
call game.bat
|
||||
@cd ..\cgame
|
||||
call cgame.bat
|
||||
@cd ..\ui
|
||||
call ui.bat
|
||||
@cd ..\gametype\gt_ctf
|
||||
call gt_ctf.bat
|
||||
@cd ..\gt_inf
|
||||
call gt_inf.bat
|
||||
@cd ..\gt_elim
|
||||
call gt_elim.bat
|
||||
@cd ..\gt_dm
|
||||
call gt_dm.bat
|
||||
@cd ..\gt_tdm
|
||||
call gt_tdm.bat
|
||||
@cd ..\..
|
||||
|
||||
@echo off
|
||||
echo .
|
||||
echo .
|
||||
|
||||
set bad = 0
|
||||
if not exist "game\vm\sof2mp_game.qvm" goto badGame
|
||||
:testcgame
|
||||
if not exist "cgame\vm\sof2mp_cgame.qvm" goto badCGame
|
||||
:testui
|
||||
if not exist "ui\vm\sof2mp_ui.qvm" goto badUI
|
||||
:testdm
|
||||
if not exist "gametype\gt_dm\vm\gt_dm.qvm" goto badDM
|
||||
:testtdm
|
||||
if not exist "gametype\gt_tdm\vm\gt_tdm.qvm" goto badTDM
|
||||
:testctf
|
||||
if not exist "gametype\gt_ctf\vm\gt_ctf.qvm" goto badCTF
|
||||
:testinf
|
||||
if not exist "gametype\gt_inf\vm\gt_inf.qvm" goto badINF
|
||||
:testelim
|
||||
if not exist "gametype\gt_elim\vm\gt_elim.qvm" goto badELIM
|
||||
if %bad == "0" goto goodBuild
|
||||
goto end
|
||||
|
||||
:badGame
|
||||
echo ***** SoF2MP_game.qvm did not build!
|
||||
set bad = 1
|
||||
goto testcgame
|
||||
|
||||
:badCGame
|
||||
echo ***** SoF2MP_cgame.qvm did not build!
|
||||
set bad = 1
|
||||
goto testui
|
||||
|
||||
:badUI
|
||||
echo ***** SoF2MP_ui.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:badDM
|
||||
echo ***** gt_dm.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:badTDM
|
||||
echo ***** gt_tdm.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:badCTF
|
||||
echo ***** gt_ctf.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:badINF
|
||||
echo ***** gt_inf.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:badELIM
|
||||
echo ***** gt_elim.qvm did not build!
|
||||
set bad = 1
|
||||
goto end
|
||||
|
||||
:goodBuild
|
||||
echo VMs were built successfully!
|
||||
|
||||
:end
|
||||
echo .
|
||||
echo .
|
119
code/cgame/animtable.h
Normal file
119
code/cgame/animtable.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
stringID_table_t bg_animTable [MAX_ANIMATIONS+1] =
|
||||
{
|
||||
ENUM2STRING(BOTH_DEATH_NORMAL),
|
||||
ENUM2STRING(BOTH_DEATH_NECK),
|
||||
ENUM2STRING(BOTH_DEATH_CHEST_1),
|
||||
ENUM2STRING(BOTH_DEATH_CHEST_2),
|
||||
ENUM2STRING(BOTH_DEATH_GROIN_1),
|
||||
ENUM2STRING(BOTH_DEATH_GROIN_2),
|
||||
ENUM2STRING(BOTH_DEATH_GUT_1),
|
||||
ENUM2STRING(BOTH_DEATH_GUT_2),
|
||||
ENUM2STRING(BOTH_DEATH_HEAD_1),
|
||||
ENUM2STRING(BOTH_DEATH_HEAD_2),
|
||||
ENUM2STRING(BOTH_DEATH_SHOULDER_LEFT_1),
|
||||
ENUM2STRING(BOTH_DEATH_SHOULDER_LEFT_2),
|
||||
ENUM2STRING(BOTH_DEATH_ARMS_LEFT_1),
|
||||
ENUM2STRING(BOTH_DEATH_ARMS_LEFT_2),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_LEFT_1),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_LEFT_2),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_LEFT_3),
|
||||
ENUM2STRING(BOTH_DEATH_THIGH_LEFT_1),
|
||||
ENUM2STRING(BOTH_DEATH_THIGH_LEFT_2),
|
||||
ENUM2STRING(BOTH_DEATH_ARMS_RIGHT_1),
|
||||
ENUM2STRING(BOTH_DEATH_ARMS_RIGHT_2),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_RIGHT_1),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_RIGHT_2),
|
||||
ENUM2STRING(BOTH_DEATH_LEGS_RIGHT_3),
|
||||
ENUM2STRING(BOTH_DEATH_SHOULDER_RIGHT_1),
|
||||
ENUM2STRING(BOTH_DEATH_SHOULDER_RIGHT_2),
|
||||
ENUM2STRING(BOTH_DEATH_THIGH_RIGHT_1),
|
||||
ENUM2STRING(BOTH_DEATH_THIGH_RIGHT_2),
|
||||
|
||||
ENUM2STRING(TORSO_DROP),
|
||||
ENUM2STRING(TORSO_DROP_ONEHANDED),
|
||||
ENUM2STRING(TORSO_DROP_KNIFE),
|
||||
ENUM2STRING(TORSO_RAISE),
|
||||
ENUM2STRING(TORSO_RAISE_ONEHANDED),
|
||||
ENUM2STRING(TORSO_RAISE_KNIFE),
|
||||
|
||||
ENUM2STRING(LEGS_IDLE),
|
||||
ENUM2STRING(LEGS_IDLE_CROUCH),
|
||||
ENUM2STRING(LEGS_WALK),
|
||||
ENUM2STRING(LEGS_WALK_BACK),
|
||||
ENUM2STRING(LEGS_WALK_CROUCH),
|
||||
ENUM2STRING(LEGS_WALK_CROUCH_BACK),
|
||||
|
||||
ENUM2STRING(LEGS_RUN),
|
||||
ENUM2STRING(LEGS_RUN_BACK),
|
||||
|
||||
ENUM2STRING(LEGS_SWIM),
|
||||
|
||||
ENUM2STRING(LEGS_JUMP),
|
||||
ENUM2STRING(LEGS_JUMP_BACK),
|
||||
|
||||
ENUM2STRING(LEGS_TURN),
|
||||
|
||||
ENUM2STRING(LEGS_LEAN_LEFT),
|
||||
ENUM2STRING(LEGS_LEAN_RIGHT),
|
||||
ENUM2STRING(LEGS_LEAN_CROUCH_LEFT),
|
||||
ENUM2STRING(LEGS_LEAN_CROUCH_RIGHT),
|
||||
|
||||
ENUM2STRING(LEGS_LEANLEFT_WALKLEFT),
|
||||
ENUM2STRING(LEGS_LEANLEFT_WALKRIGHT),
|
||||
ENUM2STRING(LEGS_LEANRIGHT_WALKLEFT),
|
||||
ENUM2STRING(LEGS_LEANRIGHT_WALKRIGHT),
|
||||
|
||||
ENUM2STRING(LEGS_LEANLEFT_CROUCH_WALKLEFT),
|
||||
ENUM2STRING(LEGS_LEANLEFT_CROUCH_WALKRIGHT),
|
||||
ENUM2STRING(LEGS_LEANRIGHT_CROUCH_WALKLEFT),
|
||||
ENUM2STRING(LEGS_LEANRIGHT_CROUCH_WALKRIGHT),
|
||||
|
||||
ENUM2STRING(TORSO_IDLE_KNIFE ),
|
||||
ENUM2STRING(TORSO_IDLE_PISTOL ),
|
||||
ENUM2STRING(TORSO_IDLE_RIFLE ),
|
||||
ENUM2STRING(TORSO_IDLE_MSG90A1_ZOOMED ),
|
||||
ENUM2STRING(TORSO_IDLE_M4 ),
|
||||
ENUM2STRING(TORSO_IDLE_M590 ),
|
||||
ENUM2STRING(TORSO_IDLE_USAS12 ),
|
||||
ENUM2STRING(TORSO_IDLE_RPG),
|
||||
ENUM2STRING(TORSO_IDLE_M60),
|
||||
ENUM2STRING(TORSO_IDLE_MM1),
|
||||
ENUM2STRING(TORSO_IDLE_GRENADE),
|
||||
|
||||
ENUM2STRING(TORSO_ATTACK_KNIFE ),
|
||||
ENUM2STRING(TORSO_ATTACK_KNIFE_THROW ),
|
||||
ENUM2STRING(TORSO_ATTACK_PISTOL ),
|
||||
ENUM2STRING(TORSO_ATTACK_RIFLE ),
|
||||
ENUM2STRING(TORSO_ATTACK_MSG90A1_ZOOMED ),
|
||||
ENUM2STRING(TORSO_ATTACK_M4 ),
|
||||
ENUM2STRING(TORSO_ATTACK_M590 ),
|
||||
ENUM2STRING(TORSO_ATTACK_USAS12 ),
|
||||
ENUM2STRING(TORSO_ATTACK_RIFLEBUTT ),
|
||||
ENUM2STRING(TORSO_ATTACK_RPG),
|
||||
ENUM2STRING(TORSO_ATTACK_M60),
|
||||
ENUM2STRING(TORSO_ATTACK_MM1),
|
||||
ENUM2STRING(TORSO_ATTACK_GRENADE_START ),
|
||||
ENUM2STRING(TORSO_ATTACK_GRENADE_END ),
|
||||
ENUM2STRING(TORSO_ATTACK_BAYONET ),
|
||||
ENUM2STRING(TORSO_ATTACK_PISTOLWHIP ),
|
||||
|
||||
ENUM2STRING(TORSO_RELOAD_M60),
|
||||
ENUM2STRING(TORSO_RELOAD_PISTOL),
|
||||
ENUM2STRING(TORSO_RELOAD_RIFLE),
|
||||
ENUM2STRING(TORSO_RELOAD_MSG90A1),
|
||||
ENUM2STRING(TORSO_RELOAD_RPG),
|
||||
ENUM2STRING(TORSO_RELOAD_USAS12),
|
||||
|
||||
ENUM2STRING(TORSO_RELOAD_M590_START),
|
||||
ENUM2STRING(TORSO_RELOAD_M590_SHELL),
|
||||
ENUM2STRING(TORSO_RELOAD_M590_END),
|
||||
|
||||
ENUM2STRING(TORSO_RELOAD_MM1_START),
|
||||
ENUM2STRING(TORSO_RELOAD_MM1_SHELL),
|
||||
ENUM2STRING(TORSO_RELOAD_MM1_END),
|
||||
|
||||
//must be terminated
|
||||
NULL,-1
|
||||
};
|
||||
|
||||
|
576
code/cgame/cg_consolecmds.c
Normal file
576
code/cgame/cg_consolecmds.c
Normal file
|
@ -0,0 +1,576 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_consolecmds.c -- text commands typed in at the local console, or
|
||||
// executed by a key binding
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../ui/ui_shared.h"
|
||||
#include "../ui/ui_public.h"
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Viewpos_f
|
||||
|
||||
Debugging command to print the current position
|
||||
=============
|
||||
*/
|
||||
static void CG_Viewpos_f (void)
|
||||
{
|
||||
Com_Printf ("(%i %i %i) : %i\n", (int)cg.refdef.vieworg[0],
|
||||
(int)cg.refdef.vieworg[1], (int)cg.refdef.vieworg[2],
|
||||
(int)cg.refdef.viewangles[YAW]);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_ScoresDown_f
|
||||
=============
|
||||
*/
|
||||
static void CG_ScoresDown_f( void )
|
||||
{
|
||||
if ( cg.scoresRequestTime + 2000 < cg.time )
|
||||
{
|
||||
// the scores are more than two seconds out of data,
|
||||
// so request new ones
|
||||
cg.scoresRequestTime = cg.time;
|
||||
trap_SendClientCommand( "score" );
|
||||
|
||||
// leave the current scores up if they were already
|
||||
// displayed, but if this is the first hit, clear them out
|
||||
if ( !cg.showScores )
|
||||
{
|
||||
cg.showScores = qtrue;
|
||||
cg.numScores = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// show the cached contents even if they just pressed if it
|
||||
// is within two seconds
|
||||
cg.showScores = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_ScoresUp_f
|
||||
=============
|
||||
*/
|
||||
static void CG_ScoresUp_f( void )
|
||||
{
|
||||
if ( cg.showScores )
|
||||
{
|
||||
cg.showScores = qfalse;
|
||||
cg.scoreFadeTime = cg.time;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_AutomapDown_f
|
||||
=============
|
||||
*/
|
||||
static void CG_AutomapDown_f( void )
|
||||
{
|
||||
cg.showAutomap = qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_AutomapUp_f
|
||||
=============
|
||||
*/
|
||||
static void CG_AutomapUp_f( void )
|
||||
{
|
||||
cg.showAutomap = qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_ReloadHud_f
|
||||
=============
|
||||
*/
|
||||
static void CG_ReloadHud_f ( void )
|
||||
{
|
||||
// Reset the string table used for menus
|
||||
String_Init();
|
||||
|
||||
// Clear all menus
|
||||
Menu_Reset();
|
||||
|
||||
// Reload the menus
|
||||
CG_LoadMenus ( "ui/hud.txt" );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Radio_f
|
||||
|
||||
Bring up the radio menu if all the conditions are met
|
||||
=============
|
||||
*/
|
||||
static void CG_Radio_f ( void )
|
||||
{
|
||||
// Only in team games
|
||||
if ( !cgs.gametypeData->teams )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Not when ghosting or following
|
||||
if ( cg.snap->ps.pm_flags & (PMF_FOLLOW|PMF_GHOST) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Not when a spectator
|
||||
if ( cg.snap->ps.pm_type == PM_SPECTATOR )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
trap_UI_SetActiveMenu ( UIMENU_RADIO );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Objectives_f
|
||||
|
||||
Bring up the objectives menu if all the conditions are met
|
||||
=============
|
||||
*/
|
||||
static void CG_Objectives_f ( void )
|
||||
{
|
||||
// Dont bother popping up the objectives dialog if there is
|
||||
// no objective text
|
||||
if ( !cgs.gametypeData->description )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
trap_UI_SetActiveMenu ( UIMENU_OBJECTIVES );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Outfitting_f
|
||||
|
||||
Bring up the outfitting menu if all the conditions are met
|
||||
=============
|
||||
*/
|
||||
static void CG_Outfitting_f ( void )
|
||||
{
|
||||
// Only allow outfitting when pickups are disabled
|
||||
if ( !cgs.pickupsDisabled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
trap_UI_SetActiveMenu ( UIMENU_OUTFITTING );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Team_f
|
||||
|
||||
bring up the team selection user interface
|
||||
=============
|
||||
*/
|
||||
static void CG_Team_f ( void )
|
||||
{
|
||||
// No team menu in non-team games
|
||||
if ( !cgs.gametypeData->teams )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case which only brings up the team menu if its the clients first
|
||||
// time to the objectives dialog
|
||||
if ( atoi ( CG_Argv(1) ) )
|
||||
{
|
||||
if ( ui_info_seenobjectives.integer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CG_UpdateTeamCountCvars ( );
|
||||
|
||||
trap_Cvar_Set ( "ui_info_seenobjectives", "1" );
|
||||
trap_UI_SetActiveMenu ( UIMENU_TEAM );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_Drop_f
|
||||
|
||||
Drops the selected weapon
|
||||
=============
|
||||
*/
|
||||
void CG_Drop_f ( void )
|
||||
{
|
||||
char cmd[128];
|
||||
int exclude;
|
||||
|
||||
// Cant drop when following or a ghost
|
||||
if ( cg.snap->ps.pm_flags & (PMF_FOLLOW|PMF_GHOST) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Either dead or spectating if not normal
|
||||
if ( cg.predictedPlayerState.pm_type != PM_NORMAL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Can only drop a weapon when in ready state
|
||||
if ( cg.predictedPlayerState.weaponstate != WEAPON_READY )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Cant drop the knife
|
||||
if( cg.weaponSelect == WP_KNIFE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the menu since a weapon is being dropped
|
||||
cg.weaponMenuUp = qfalse;
|
||||
|
||||
// Build the server command
|
||||
Com_sprintf( cmd, 128, "drop %i", cg.weaponSelect );
|
||||
|
||||
// Go to next weapon before the current drops
|
||||
exclude = cg.weaponSelect;
|
||||
cg.weaponSelect = WP_M67_GRENADE;
|
||||
CG_PrevWeapon ( qfalse, exclude );
|
||||
|
||||
// Send server comand
|
||||
trap_SendClientCommand( cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_GetOutfittingGroupFromString
|
||||
|
||||
Converts the given string into an outfitting group id
|
||||
=============
|
||||
*/
|
||||
static int CG_GetOutfittingGroupFromString ( const char* str )
|
||||
{
|
||||
if ( Q_stricmp ( str, "primary" ) == 0 )
|
||||
{
|
||||
return OUTFITTING_GROUP_PRIMARY;
|
||||
}
|
||||
else if ( Q_stricmp ( str, "secondary" ) == 0 )
|
||||
{
|
||||
return OUTFITTING_GROUP_SECONDARY;
|
||||
}
|
||||
else if ( Q_stricmp ( str, "pistol" ) == 0 )
|
||||
{
|
||||
return OUTFITTING_GROUP_PISTOL;
|
||||
}
|
||||
else if ( Q_stricmp ( str, "grenade" ) == 0 )
|
||||
{
|
||||
return OUTFITTING_GROUP_GRENADE;
|
||||
}
|
||||
else if ( Q_stricmp ( str, "knife" ) == 0 )
|
||||
{
|
||||
return OUTFITTING_GROUP_KNIFE;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_WeaponToggle_f
|
||||
|
||||
toggles between multiple weapons
|
||||
=============
|
||||
*/
|
||||
static void CG_WeaponToggle_f ( void )
|
||||
{
|
||||
int group1;
|
||||
int group2;
|
||||
int weapon1;
|
||||
int weapon2;
|
||||
gitem_t* item;
|
||||
int i;
|
||||
|
||||
// Get the toggle groups
|
||||
group1 = CG_GetOutfittingGroupFromString ( CG_Argv(1) );
|
||||
group2 = CG_GetOutfittingGroupFromString ( CG_Argv(2) );
|
||||
|
||||
// Invalid toggle if either is -1
|
||||
if ( group1 == -1 ) // || group2 == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure they have something from both of the groups
|
||||
weapon1 = WP_NONE;
|
||||
weapon2 = WP_NONE;
|
||||
for ( i = WP_KNIFE; i < WP_NUM_WEAPONS; i ++ )
|
||||
{
|
||||
// Make sure this weapon is selectable.
|
||||
if ( !CG_WeaponSelectable ( i, qtrue ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
item = BG_FindWeaponItem ( i );
|
||||
if ( item->outfittingGroup == group1 )
|
||||
{
|
||||
weapon1 = i;
|
||||
}
|
||||
else if ( item->outfittingGroup == group2 )
|
||||
{
|
||||
weapon2 = i;
|
||||
}
|
||||
}
|
||||
|
||||
// IF only one of the two weapons is available then go to it
|
||||
if ( weapon1 == WP_NONE && weapon2 == WP_NONE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( weapon1 == WP_NONE )
|
||||
{
|
||||
cg.weaponSelect = weapon2;
|
||||
return;
|
||||
}
|
||||
else if ( weapon2 == WP_NONE )
|
||||
{
|
||||
cg.weaponSelect = weapon1;
|
||||
return;
|
||||
}
|
||||
|
||||
// They have both weapons, so figure out which to go to
|
||||
item = BG_FindWeaponItem ( cg.weaponSelect );
|
||||
|
||||
if ( item->outfittingGroup == group1 )
|
||||
{
|
||||
cg.weaponSelect = weapon2;
|
||||
}
|
||||
else
|
||||
{
|
||||
cg.weaponSelect = weapon1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_NextWeapon_f
|
||||
|
||||
selects next weapon in inventory and allows empty weapons to
|
||||
be selected
|
||||
=============
|
||||
*/
|
||||
static void CG_NextWeapon_f ( void )
|
||||
{
|
||||
CG_NextWeapon ( qtrue, -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_PrevWeapon_f
|
||||
|
||||
selects previous weapon in inventory and allows empty weapons
|
||||
to be selectd
|
||||
=============
|
||||
*/
|
||||
static void CG_PrevWeapon_f ( void )
|
||||
{
|
||||
CG_PrevWeapon ( qtrue, -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_LastWeapon_f
|
||||
|
||||
Selects the last weapon that was selected
|
||||
=============
|
||||
*/
|
||||
static void CG_LastWeapon_f ( void )
|
||||
{
|
||||
if ( CG_WeaponSelectable ( cg.weaponLastSelect, qtrue ) )
|
||||
{
|
||||
int swap = cg.weaponSelect;
|
||||
cg.weaponSelect = cg.weaponLastSelect;
|
||||
cg.weaponLastSelect = swap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void CG_TellTarget_f( void ) {
|
||||
int clientNum;
|
||||
char command[128];
|
||||
char message[128];
|
||||
|
||||
clientNum = CG_CrosshairPlayer();
|
||||
if ( clientNum == -1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
trap_Args( message, 128 );
|
||||
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
|
||||
trap_SendClientCommand( command );
|
||||
}
|
||||
|
||||
static void CG_TellAttacker_f( void ) {
|
||||
int clientNum;
|
||||
char command[128];
|
||||
char message[128];
|
||||
|
||||
clientNum = CG_LastAttacker();
|
||||
if ( clientNum == -1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
trap_Args( message, 128 );
|
||||
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
|
||||
trap_SendClientCommand( command );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_StartOrbit_f
|
||||
==================
|
||||
*/
|
||||
|
||||
static void CG_StartOrbit_f( void ) {
|
||||
char var[MAX_TOKEN_CHARS];
|
||||
|
||||
trap_Cvar_VariableStringBuffer( "developer", var, sizeof( var ) );
|
||||
if ( !atoi(var) ) {
|
||||
return;
|
||||
}
|
||||
if (cg_cameraOrbit.value != 0) {
|
||||
trap_Cvar_Set ("cg_cameraOrbit", "0");
|
||||
trap_Cvar_Set("cg_thirdPerson", "0");
|
||||
} else {
|
||||
trap_Cvar_Set("cg_cameraOrbit", "5");
|
||||
trap_Cvar_Set("cg_thirdPerson", "1");
|
||||
trap_Cvar_Set("cg_thirdPersonAngle", "0");
|
||||
trap_Cvar_Set("cg_thirdPersonRange", "100");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *cmd;
|
||||
void (*function)(void);
|
||||
|
||||
} consoleCommand_t;
|
||||
|
||||
static consoleCommand_t commands[] =
|
||||
{
|
||||
{ "testmodel", CG_TestModel_f },
|
||||
{ "nextframe", CG_TestModelNextFrame_f },
|
||||
{ "prevframe", CG_TestModelPrevFrame_f },
|
||||
{ "nextskin", CG_TestModelNextSkin_f },
|
||||
{ "prevskin", CG_TestModelPrevSkin_f },
|
||||
{ "viewpos", CG_Viewpos_f },
|
||||
{ "+scores", CG_ScoresDown_f },
|
||||
{ "-scores", CG_ScoresUp_f },
|
||||
{ "+automap", CG_AutomapDown_f },
|
||||
{ "-automap", CG_AutomapUp_f },
|
||||
{ "weapnext", CG_NextWeapon_f },
|
||||
{ "weapprev", CG_PrevWeapon_f },
|
||||
{ "weaplast", CG_LastWeapon_f },
|
||||
{ "weapon", CG_Weapon_f },
|
||||
{ "tell_target", CG_TellTarget_f },
|
||||
{ "tell_attacker", CG_TellAttacker_f },
|
||||
{ "reloadhud", CG_ReloadHud_f },
|
||||
{ "startOrbit", CG_StartOrbit_f },
|
||||
{ "loaddeferred", CG_LoadDeferredPlayers },
|
||||
{ "drop", CG_Drop_f },
|
||||
|
||||
{ "weaptoggle", CG_WeaponToggle_f },
|
||||
|
||||
{ "ui_radio", CG_Radio_f },
|
||||
{ "ui_objectives", CG_Objectives_f },
|
||||
{ "ui_outfitting", CG_Outfitting_f },
|
||||
{ "ui_team", CG_Team_f },
|
||||
};
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_ConsoleCommand
|
||||
|
||||
The string has been tokenized and can be retrieved with
|
||||
Cmd_Argc() / Cmd_Argv()
|
||||
=================
|
||||
*/
|
||||
qboolean CG_ConsoleCommand( void )
|
||||
{
|
||||
const char *cmd;
|
||||
int i;
|
||||
|
||||
// No console commands when a map is changing
|
||||
if ( cg.mMapChange )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
cmd = CG_Argv(0);
|
||||
|
||||
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ )
|
||||
{
|
||||
if ( !Q_stricmp( cmd, commands[i].cmd ) )
|
||||
{
|
||||
commands[i].function();
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_InitConsoleCommands
|
||||
|
||||
Let the client system know about all of our commands
|
||||
so it can perform tab completion
|
||||
=================
|
||||
*/
|
||||
void CG_InitConsoleCommands( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ )
|
||||
{
|
||||
trap_AddCommand( commands[i].cmd );
|
||||
}
|
||||
|
||||
//
|
||||
// the game server will interpret these commands, which will be automatically
|
||||
// forwarded to the server after they are not recognized locally
|
||||
//
|
||||
trap_AddCommand ("kill");
|
||||
trap_AddCommand ("say");
|
||||
trap_AddCommand ("say_team");
|
||||
trap_AddCommand ("tell");
|
||||
trap_AddCommand ("vsay_team");
|
||||
trap_AddCommand ("give");
|
||||
trap_AddCommand ("god");
|
||||
trap_AddCommand ("notarget");
|
||||
trap_AddCommand ("noclip");
|
||||
trap_AddCommand ("team");
|
||||
trap_AddCommand ("follow");
|
||||
trap_AddCommand ("levelshot");
|
||||
#ifdef _SOF2_BOTS
|
||||
trap_AddCommand ("addbot");
|
||||
#endif
|
||||
trap_AddCommand ("setviewpos");
|
||||
trap_AddCommand ("callvote");
|
||||
trap_AddCommand ("vote");
|
||||
trap_AddCommand ("stats");
|
||||
trap_AddCommand ("teamtask");
|
||||
trap_AddCommand ("loaddeferred");
|
||||
trap_AddCommand ("gametype_restart");
|
||||
}
|
1842
code/cgame/cg_draw.c
Normal file
1842
code/cgame/cg_draw.c
Normal file
File diff suppressed because it is too large
Load diff
421
code/cgame/cg_drawtools.c
Normal file
421
code/cgame/cg_drawtools.c
Normal file
|
@ -0,0 +1,421 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc
|
||||
#include "cg_local.h"
|
||||
|
||||
/*
|
||||
================
|
||||
CG_AdjustFrom640
|
||||
|
||||
Adjusted for resolution and screen aspect ratio
|
||||
================
|
||||
*/
|
||||
void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) {
|
||||
#if 0
|
||||
// adjust for wide screens
|
||||
if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) {
|
||||
*x += 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * 640 / 480 ) );
|
||||
}
|
||||
#endif
|
||||
// scale for screen sizes
|
||||
*x *= cgs.screenXScale;
|
||||
*y *= cgs.screenYScale;
|
||||
*w *= cgs.screenXScale;
|
||||
*h *= cgs.screenYScale;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_FillRect
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
=================
|
||||
*/
|
||||
void CG_FillRect( float x, float y, float width, float height, const float *color ) {
|
||||
trap_R_SetColor( color );
|
||||
|
||||
CG_AdjustFrom640( &x, &y, &width, &height );
|
||||
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, NULL, cgs.media.whiteShader );
|
||||
|
||||
trap_R_SetColor( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_DrawSides
|
||||
|
||||
Coords are virtual 640x480
|
||||
================
|
||||
*/
|
||||
void CG_DrawSides(float x, float y, float w, float h, float size) {
|
||||
CG_AdjustFrom640( &x, &y, &w, &h );
|
||||
size *= cgs.screenXScale;
|
||||
trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, NULL, cgs.media.whiteShader );
|
||||
trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, NULL, cgs.media.whiteShader );
|
||||
}
|
||||
|
||||
void CG_DrawTopBottom(float x, float y, float w, float h, float size) {
|
||||
CG_AdjustFrom640( &x, &y, &w, &h );
|
||||
size *= cgs.screenYScale;
|
||||
trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, NULL, cgs.media.whiteShader );
|
||||
trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, NULL, cgs.media.whiteShader );
|
||||
}
|
||||
/*
|
||||
================
|
||||
UI_DrawRect
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
=================
|
||||
*/
|
||||
void CG_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
|
||||
trap_R_SetColor( color );
|
||||
|
||||
CG_DrawTopBottom(x, y, width, height, size);
|
||||
CG_DrawSides(x, y, width, height, size);
|
||||
|
||||
trap_R_SetColor( NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_DrawPic
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
=================
|
||||
*/
|
||||
void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ) {
|
||||
CG_AdjustFrom640( &x, &y, &width, &height );
|
||||
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, NULL, hShader );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_DrawStretchPic
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
=================
|
||||
*/
|
||||
void CG_DrawStretchPic(
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height,
|
||||
float sx,
|
||||
float sy,
|
||||
float sw,
|
||||
float sh,
|
||||
const float* color,
|
||||
qhandle_t hShader
|
||||
)
|
||||
{
|
||||
CG_AdjustFrom640( &x, &y, &width, &height );
|
||||
trap_R_DrawStretchPic( x, y, width, height, sx, sy, sw, sh, NULL, hShader );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_DrawRotatePic
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
A width of 0 will draw with the original image width
|
||||
rotates around the upper right corner of the passed in point
|
||||
=================
|
||||
*/
|
||||
void CG_DrawRotatePic( float x, float y, float width, float height,float angle, qhandle_t hShader ) {
|
||||
CG_AdjustFrom640( &x, &y, &width, &height );
|
||||
trap_R_DrawRotatePic( x, y, width, height, 0, 0, 1, 1, angle, hShader );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_DrawRotatePic2
|
||||
|
||||
Coordinates are 640*480 virtual values
|
||||
A width of 0 will draw with the original image width
|
||||
Actually rotates around the center point of the passed in coordinates
|
||||
=================
|
||||
*/
|
||||
void CG_DrawRotatePic2( float x, float y, float width, float height,float angle, qhandle_t hShader ) {
|
||||
CG_AdjustFrom640( &x, &y, &width, &height );
|
||||
trap_R_DrawRotatePic2( x, y, width, height, 0, 0, 1, 1, angle, hShader );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawStrlen
|
||||
|
||||
Returns character count, skiping color escape codes
|
||||
=================
|
||||
*/
|
||||
int CG_DrawStrlen( const char *str ) {
|
||||
const char *s = str;
|
||||
int count = 0;
|
||||
|
||||
while ( *s ) {
|
||||
if ( Q_IsColorString( s ) ) {
|
||||
s += 2;
|
||||
} else {
|
||||
count++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CG_TileClearBox
|
||||
|
||||
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
||||
refresh window.
|
||||
=============
|
||||
*/
|
||||
static void CG_TileClearBox( int x, int y, int w, int h, qhandle_t hShader ) {
|
||||
float s1, t1, s2, t2;
|
||||
|
||||
s1 = x/64.0;
|
||||
t1 = y/64.0;
|
||||
s2 = (x+w)/64.0;
|
||||
t2 = (y+h)/64.0;
|
||||
trap_R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, NULL, hShader );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
CG_TileClear
|
||||
|
||||
Clear around a sized down screen
|
||||
==============
|
||||
*/
|
||||
void CG_TileClear( void )
|
||||
{
|
||||
int top, bottom, left, right;
|
||||
int w, h;
|
||||
|
||||
w = cgs.glconfig.vidWidth;
|
||||
h = cgs.glconfig.vidHeight;
|
||||
|
||||
if ( cg.refdef.x == 0 && cg.refdef.y == 0 &&
|
||||
cg.refdef.width == w && cg.refdef.height == h ) {
|
||||
return; // full screen rendering
|
||||
}
|
||||
|
||||
top = cg.refdef.y;
|
||||
bottom = top + cg.refdef.height-1;
|
||||
left = cg.refdef.x;
|
||||
right = left + cg.refdef.width-1;
|
||||
|
||||
// clear above view screen
|
||||
CG_TileClearBox( 0, 0, w, top, cgs.media.backTileShader );
|
||||
|
||||
// clear below view screen
|
||||
CG_TileClearBox( 0, bottom, w, h - bottom, cgs.media.backTileShader );
|
||||
|
||||
// clear left of view screen
|
||||
CG_TileClearBox( 0, top, left, bottom - top + 1, cgs.media.backTileShader );
|
||||
|
||||
// clear right of view screen
|
||||
CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_FadeColor
|
||||
================
|
||||
*/
|
||||
float *CG_FadeColor( int startMsec, int totalMsec ) {
|
||||
static vec4_t color;
|
||||
int t;
|
||||
|
||||
if ( startMsec == 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = cg.time - startMsec;
|
||||
|
||||
if ( t >= totalMsec ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// fade out
|
||||
if ( totalMsec - t < FADE_TIME ) {
|
||||
color[3] = ( totalMsec - t ) * 1.0/FADE_TIME;
|
||||
} else {
|
||||
color[3] = 1.0;
|
||||
}
|
||||
color[0] = color[1] = color[2] = 1;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_TeamColor
|
||||
================
|
||||
*/
|
||||
float *CG_TeamColor( int team ) {
|
||||
static vec4_t red = {1, 0.2f, 0.2f, 1};
|
||||
static vec4_t blue = {0.2f, 0.2f, 1, 1};
|
||||
static vec4_t other = {1, 1, 1, 1};
|
||||
static vec4_t spectator = {0.7f, 0.7f, 0.7f, 1};
|
||||
|
||||
switch ( team ) {
|
||||
case TEAM_RED:
|
||||
return red;
|
||||
case TEAM_BLUE:
|
||||
return blue;
|
||||
case TEAM_SPECTATOR:
|
||||
return spectator;
|
||||
default:
|
||||
return other;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_GetColorForHealth
|
||||
=================
|
||||
*/
|
||||
void CG_GetColorForHealth( vec4_t color, int health, int armor )
|
||||
{
|
||||
int count;
|
||||
int max;
|
||||
|
||||
VectorCopy ( colorWhite, color );
|
||||
|
||||
color[3] = 1.0f;
|
||||
|
||||
// calculate the total points of damage that can
|
||||
// be sustained at the current health / armor level
|
||||
if ( health <= 0 )
|
||||
{
|
||||
VectorCopy ( colorBlack, color );
|
||||
return;
|
||||
}
|
||||
|
||||
count = armor;
|
||||
max = health * ARMOR_PROTECTION / ( 1.0 - ARMOR_PROTECTION );
|
||||
|
||||
if ( max < count )
|
||||
{
|
||||
count = max;
|
||||
}
|
||||
|
||||
health += count;
|
||||
|
||||
// set the color based on health
|
||||
color[0] = 1.0f;
|
||||
if ( health >= 100 )
|
||||
{
|
||||
color[2] = 1.0f;
|
||||
}
|
||||
else if ( health < 66 )
|
||||
{
|
||||
color[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[2] = ( health - 66 ) / 33.0;
|
||||
}
|
||||
|
||||
if ( health > 60 )
|
||||
{
|
||||
color[1] = 1.0f;
|
||||
}
|
||||
else if ( health < 30 )
|
||||
{
|
||||
color[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[1] = ( health - 30 ) / 30.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CG_DrawText
|
||||
|
||||
Renders text on the screen
|
||||
=====================
|
||||
*/
|
||||
void CG_DrawText ( float x, float y, qhandle_t font, float scale, vec4_t color, const char* text, int limit, int flags )
|
||||
{
|
||||
x *= cgs.screenXScale;
|
||||
y *= cgs.screenYScale;
|
||||
scale *= (cgs.screenXScale);
|
||||
|
||||
trap_R_DrawText ( (int)x, (int)y, font, scale, color, text, limit, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CG_DrawTimer
|
||||
|
||||
Draws a timer on the screen with the given parameters
|
||||
=====================
|
||||
*/
|
||||
void CG_DrawTimer ( float x, float y, qhandle_t font, float scale, vec4_t color, int flags, int msec )
|
||||
{
|
||||
const char* s;
|
||||
|
||||
if ( msec )
|
||||
{
|
||||
int mins;
|
||||
int seconds;
|
||||
int tens;
|
||||
qboolean neg;
|
||||
|
||||
// Remember the milliseconds were negative
|
||||
// before making them positive again
|
||||
if ( msec < 0 )
|
||||
{
|
||||
msec *= -1;
|
||||
neg = qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
neg = qfalse;
|
||||
}
|
||||
|
||||
seconds = msec / 1000;
|
||||
mins = seconds / 60;
|
||||
seconds -= mins * 60;
|
||||
tens = seconds / 10;
|
||||
seconds -= tens * 10;
|
||||
|
||||
s = va( "%s%i:%i%i", neg?"-":"",mins, tens, seconds );
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "------";
|
||||
}
|
||||
|
||||
CG_DrawText ( x, y, font, scale, color, s, 0, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CG_DrawTextWithCursor
|
||||
|
||||
Renders text on the screen with a blinking cursor
|
||||
=====================
|
||||
*/
|
||||
void CG_DrawTextWithCursor ( float x, float y, qhandle_t font, float scale, vec4_t color, const char* text, int limit, int flags, int cursorPos, char cursor )
|
||||
{
|
||||
x *= cgs.screenXScale;
|
||||
y *= cgs.screenYScale;
|
||||
scale *= (cgs.screenXScale);
|
||||
|
||||
trap_R_DrawTextWithCursor ( (int)x, (int)y, font, scale, color, text, limit, flags, cursorPos, cursor );
|
||||
}
|
275
code/cgame/cg_effects.c
Normal file
275
code/cgame/cg_effects.c
Normal file
|
@ -0,0 +1,275 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_effects.c -- these functions generate localentities, usually as a result
|
||||
// of event processing
|
||||
|
||||
#include "cg_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;
|
||||
|
||||
if ( cg_noProjectileTrail.integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
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->reType = RT_SPRITE;
|
||||
re->rotation = 0;
|
||||
re->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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CG_TestLine( vec3_t start, vec3_t end, int time, unsigned int color, int radius)
|
||||
{
|
||||
localEntity_t *le;
|
||||
refEntity_t *re;
|
||||
|
||||
le = CG_AllocLocalEntity();
|
||||
le->leType = LE_LINE;
|
||||
le->startTime = cg.time;
|
||||
le->endTime = cg.time + time;
|
||||
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
||||
|
||||
re = &le->refEntity;
|
||||
VectorCopy( start, re->origin );
|
||||
VectorCopy( end, re->oldorigin);
|
||||
re->shaderTime = cg.time / 1000.0f;
|
||||
|
||||
re->reType = RT_LINE;
|
||||
re->radius = 0.5*radius;
|
||||
re->customShader = cgs.media.whiteShader; //trap_R_RegisterShaderNoMip("textures/colombia/canvas_doublesided");
|
||||
|
||||
re->shaderTexCoord[0] = re->shaderTexCoord[1] = 1.0f;
|
||||
|
||||
if (color==0)
|
||||
{
|
||||
re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
re->shaderRGBA[0] = color & 0xff;
|
||||
color >>= 8;
|
||||
re->shaderRGBA[1] = color & 0xff;
|
||||
color >>= 8;
|
||||
re->shaderRGBA[2] = color & 0xff;
|
||||
re->shaderRGBA[3] = 0xff;
|
||||
}
|
||||
|
||||
le->color[3] = 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_ThrowShard
|
||||
==================
|
||||
*/
|
||||
void CG_ThrowShard( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
|
||||
localEntity_t *le;
|
||||
refEntity_t *re;
|
||||
|
||||
le = CG_AllocLocalEntity();
|
||||
re = &le->refEntity;
|
||||
|
||||
le->leType = LE_FRAGMENT;
|
||||
le->startTime = cg.time;
|
||||
le->endTime = le->startTime + 5000 + random() * 3000;
|
||||
|
||||
VectorCopy( origin, re->origin );
|
||||
AxisCopy( axisDefault, re->axis );
|
||||
re->hModel = hModel;
|
||||
|
||||
le->pos.trType = TR_GRAVITY;
|
||||
le->angles.trType = TR_GRAVITY;
|
||||
VectorCopy( origin, le->pos.trBase );
|
||||
VectorCopy( velocity, le->pos.trDelta );
|
||||
VectorSet(le->angles.trBase, 20, 20, 20);
|
||||
VectorCopy( velocity, le->angles.trDelta );
|
||||
le->pos.trTime = cg.time;
|
||||
le->angles.trTime = cg.time;
|
||||
|
||||
le->leFlags = LEF_TUMBLE;
|
||||
|
||||
le->angles.trBase[YAW] = 180;
|
||||
|
||||
le->bounceFactor = 0.3f;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_GlassShatter
|
||||
Throws glass shards from within a given bounding box in the world
|
||||
==================
|
||||
*/
|
||||
void CG_GlassShatter(int entnum, vec3_t org, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
vec3_t velocity, a, shardorg, dif, difx;
|
||||
float windowmass;
|
||||
float shardsthrow = 0;
|
||||
|
||||
trap_S_StartSound(org, entnum, CHAN_BODY, cgs.media.glassBreakSound, -1, -1 );
|
||||
|
||||
VectorSubtract(maxs, mins, a);
|
||||
|
||||
windowmass = VectorLength(a); //should give us some idea of how big the chunk of glass is
|
||||
|
||||
while (shardsthrow < windowmass)
|
||||
{
|
||||
velocity[0] = crandom()*150;
|
||||
velocity[1] = crandom()*150;
|
||||
velocity[2] = 150 + crandom()*75;
|
||||
|
||||
VectorCopy(org, shardorg);
|
||||
|
||||
dif[0] = (maxs[0]-mins[0])/2;
|
||||
dif[1] = (maxs[1]-mins[1])/2;
|
||||
dif[2] = (maxs[2]-mins[2])/2;
|
||||
|
||||
if (dif[0] < 2)
|
||||
{
|
||||
dif[0] = 2;
|
||||
}
|
||||
if (dif[1] < 2)
|
||||
{
|
||||
dif[1] = 2;
|
||||
}
|
||||
if (dif[2] < 2)
|
||||
{
|
||||
dif[2] = 2;
|
||||
}
|
||||
|
||||
difx[0] = (float) Q_irand(1, (int)((dif[0]*0.9)*2));
|
||||
difx[1] = (float) Q_irand(1, (int)((dif[1]*0.9)*2));
|
||||
difx[2] = (float) Q_irand(1, (int)((dif[2]*0.9)*2));
|
||||
|
||||
if (difx[0] > dif[0])
|
||||
{
|
||||
shardorg[0] += difx[0]-(dif[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
shardorg[0] -= difx[0];
|
||||
}
|
||||
if (difx[1] > dif[1])
|
||||
{
|
||||
shardorg[1] += difx[1]-(dif[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
shardorg[1] -= difx[1];
|
||||
}
|
||||
if (difx[2] > dif[2])
|
||||
{
|
||||
shardorg[2] += difx[2]-(dif[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
shardorg[2] -= difx[2];
|
||||
}
|
||||
|
||||
trap_FX_PlayEffectID( cgs.media.glassChunkEffect, shardorg, velocity, -1, -1 );
|
||||
|
||||
shardsthrow += 20;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CG_PointLineIntersect ( vec3_t start, vec3_t end, vec3_t point, float rad, vec3_t intersection )
|
||||
{
|
||||
vec3_t dir;
|
||||
vec3_t distance;
|
||||
float len;
|
||||
float lineSize;
|
||||
|
||||
VectorSubtract ( end, start, dir );
|
||||
lineSize = VectorNormalize ( dir );
|
||||
|
||||
// Calculate the distnace from the shooter to the target
|
||||
VectorSubtract ( point, start, distance );
|
||||
|
||||
// Use that distnace to determine the point of tangent in relation to
|
||||
// the center of the player entity
|
||||
VectorMA ( start, DotProduct ( dir, distance ), dir, intersection );
|
||||
|
||||
VectorSubtract ( intersection, point, distance );
|
||||
len = VectorLengthSquared ( distance );
|
||||
|
||||
// Is the intersection point within the given radius requirements?
|
||||
if ( len < rad * rad )
|
||||
{
|
||||
// Make sure its not past the end of the given line
|
||||
VectorSubtract ( intersection, start, distance );
|
||||
len = VectorLengthSquared ( distance );
|
||||
|
||||
// If the len
|
||||
if ( len < lineSize * lineSize )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void CG_BulletFlyBySound ( vec3_t start, vec3_t end )
|
||||
{
|
||||
// make the incidental sounds - all of these should already be precached on the server
|
||||
vec3_t soundPoint;
|
||||
if( CG_PointLineIntersect(start, end, cg.refdef.vieworg, 100, soundPoint ) )
|
||||
{
|
||||
if (irand(1, 10) < 5)
|
||||
{
|
||||
int which = irand(0, NUMFLYBYS - 1);
|
||||
|
||||
trap_S_StartSound (soundPoint, cg.predictedPlayerState.clientNum, CHAN_AUTO, cgs.media.flybySounds[which], -1, -1 );
|
||||
}
|
||||
}
|
||||
}
|
1049
code/cgame/cg_ents.c
Normal file
1049
code/cgame/cg_ents.c
Normal file
File diff suppressed because it is too large
Load diff
1195
code/cgame/cg_event.c
Normal file
1195
code/cgame/cg_event.c
Normal file
File diff suppressed because it is too large
Load diff
97
code/cgame/cg_gametype.c
Normal file
97
code/cgame/cg_gametype.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
// cg_gametype.c -- dynamic gametype handling
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_ParseGametypeItems
|
||||
===============
|
||||
*/
|
||||
qboolean CG_ParseGametypeItems ( TGPGroup itemsGroup )
|
||||
{
|
||||
TGPGroup itemGroup;
|
||||
int itemCount;
|
||||
char temp[MAX_QPATH];
|
||||
|
||||
// Handle NULL for convienience
|
||||
if ( !itemsGroup )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Loop over all the items and add each
|
||||
itemGroup = trap_GPG_GetSubGroups ( itemsGroup );
|
||||
itemCount = 0;
|
||||
|
||||
while ( itemGroup )
|
||||
{
|
||||
// Parse icon file
|
||||
trap_GPG_FindPairValue ( itemGroup, "icon", "", temp );
|
||||
bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ].icon = (char *)trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
// Parse display name file
|
||||
trap_GPG_FindPairValue ( itemGroup, "displayname", "", temp );
|
||||
bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ].pickup_name = (char *)trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
// Parse world model file
|
||||
trap_GPG_FindPairValue ( itemGroup, "model", "", temp );
|
||||
bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ].world_model[0] = (char *)trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
// Parse bolt model file
|
||||
trap_GPG_FindPairValue ( itemGroup, "boltmodel", "", temp );
|
||||
trap_G2API_InitGhoul2Model(&cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].boltModel, temp, 0 , 0, 0, 0, 0);
|
||||
cg_items[MODELINDEX_GAMETYPE_ITEM+itemCount].radius[0] = 60;
|
||||
|
||||
CG_RegisterItemVisuals ( MODELINDEX_GAMETYPE_ITEM+itemCount );
|
||||
|
||||
itemCount++;
|
||||
|
||||
// Next sub group
|
||||
itemGroup = trap_GPG_GetNext(itemGroup);
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_ParseGametypeFile
|
||||
===============
|
||||
*/
|
||||
qboolean CG_ParseGametypeFile ( void )
|
||||
{
|
||||
TGenericParser2 GP2;
|
||||
TGPGroup topGroup;
|
||||
TGPGroup gametypeGroup;
|
||||
|
||||
// Open the given gametype file
|
||||
GP2 = trap_GP_ParseFile ( (char*)cgs.gametypeData->script, qtrue, qfalse );
|
||||
if (!GP2)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Grab the top group and the list of sub groups
|
||||
topGroup = trap_GP_GetBaseParseGroup(GP2);
|
||||
gametypeGroup = trap_GPG_FindSubGroup(topGroup, "gametype" );
|
||||
if ( !gametypeGroup )
|
||||
{
|
||||
trap_GP_Delete(&GP2);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Mainly interested in the items within the file
|
||||
CG_ParseGametypeItems ( trap_GPG_FindSubGroup ( gametypeGroup, "items" ) );
|
||||
|
||||
// Free up the parser
|
||||
trap_GP_Delete(&GP2);
|
||||
|
||||
// Defaults
|
||||
trap_Cvar_Set ( "ui_blueteamname", "Blue Team" );
|
||||
trap_Cvar_Set ( "ui_redteamname", "Red Team" );
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
1454
code/cgame/cg_gore.c
Normal file
1454
code/cgame/cg_gore.c
Normal file
File diff suppressed because it is too large
Load diff
318
code/cgame/cg_info.c
Normal file
318
code/cgame/cg_info.c
Normal file
|
@ -0,0 +1,318 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_info.c -- display information while data is being loading
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#define MAX_LOADING_PLAYER_ICONS 16
|
||||
#define MAX_LOADING_ITEM_ICONS 26
|
||||
|
||||
static int loadingPlayerIconCount;
|
||||
static int loadingItemIconCount;
|
||||
static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
|
||||
static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS];
|
||||
|
||||
void CG_LoadBar(void);
|
||||
|
||||
/*
|
||||
======================
|
||||
CG_LoadingStage
|
||||
======================
|
||||
*/
|
||||
void CG_LoadingStage ( int stage )
|
||||
{
|
||||
if ( !cg.loading )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cg.loadStage = stage;
|
||||
|
||||
if ( cg.loadStage )
|
||||
{
|
||||
trap_UpdateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
CG_LoadingString
|
||||
======================
|
||||
*/
|
||||
void CG_LoadingString( const char *s )
|
||||
{
|
||||
if ( !cg.loading )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) );
|
||||
|
||||
trap_UpdateScreen();
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_LoadingItem
|
||||
===================
|
||||
*/
|
||||
void CG_LoadingItem( int itemNum )
|
||||
{
|
||||
gitem_t *item;
|
||||
|
||||
if ( !cg.loading )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
item = &bg_itemlist[itemNum];
|
||||
|
||||
if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) {
|
||||
loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon );
|
||||
}
|
||||
|
||||
CG_LoadingString( item->pickup_name );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_LoadingClient
|
||||
===================
|
||||
*/
|
||||
void CG_LoadingClient( int clientNum )
|
||||
{
|
||||
const char *info;
|
||||
char personality[MAX_QPATH];
|
||||
|
||||
if ( !cg.loading )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
info = CG_ConfigString( CS_PLAYERS + clientNum );
|
||||
|
||||
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
|
||||
Q_CleanStr( personality );
|
||||
|
||||
CG_LoadingString( personality );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_DrawInformation
|
||||
|
||||
Draw all the status / pacifier stuff during level loading
|
||||
====================
|
||||
*/
|
||||
void CG_DrawInformation( void )
|
||||
{
|
||||
static qhandle_t levelshot = 0;
|
||||
static char levelshotShader[MAX_QPATH] = "";
|
||||
|
||||
const char *s;
|
||||
const char *info;
|
||||
const char *sysInfo;
|
||||
char shader[MAX_QPATH];
|
||||
int y;
|
||||
int value;
|
||||
qhandle_t overlay;
|
||||
char buf[1024];
|
||||
|
||||
// As long as the map change flag is set we draw the map change screen
|
||||
if ( cg.mMapChange )
|
||||
{
|
||||
CG_DrawMapChange ( );
|
||||
return;
|
||||
}
|
||||
|
||||
info = CG_ConfigString( CS_SERVERINFO );
|
||||
sysInfo = CG_ConfigString( CS_SYSTEMINFO );
|
||||
|
||||
if ( cg.mInRMG )
|
||||
{
|
||||
const char* terrainInfo;
|
||||
|
||||
terrainInfo = CG_ConfigString( CS_TERRAINS + 1 );
|
||||
if ( terrainInfo )
|
||||
{
|
||||
s = Info_ValueForKey ( terrainInfo, "terraindef" );
|
||||
Com_sprintf ( shader, sizeof(shader), "gfx/menus/levelshots/mp_rmg_%s", s );
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf ( shader, sizeof(shader), "gfx/menus/levelshots/unknownmap_mp" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s = Info_ValueForKey( info, "mapname" );
|
||||
Com_sprintf ( shader, sizeof(shader), "gfx/menus/levelshots/%s", s );
|
||||
}
|
||||
|
||||
if ( Q_stricmp ( levelshotShader, shader ) )
|
||||
{
|
||||
levelshot = trap_R_RegisterShaderNoMip( shader );
|
||||
Com_sprintf ( levelshotShader, sizeof(levelshotShader), shader );
|
||||
}
|
||||
|
||||
overlay = trap_R_RegisterShaderNoMip( "gfx/menus/levelshots/unknownmap_mp" );
|
||||
|
||||
// Draw the level shot
|
||||
trap_R_SetColor( NULL );
|
||||
|
||||
if ( levelshot )
|
||||
{
|
||||
vec4_t fade;
|
||||
|
||||
fade[0] = 1.0f;
|
||||
fade[1] = 1.0f;
|
||||
fade[2] = 1.0f;
|
||||
fade[3] = 1.0f - ((float)cg.loadStage / 15.0f);
|
||||
|
||||
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
|
||||
|
||||
trap_R_SetColor ( fade );
|
||||
|
||||
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, overlay );
|
||||
|
||||
trap_R_SetColor ( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, overlay );
|
||||
}
|
||||
|
||||
// Draw the progress bar
|
||||
CG_LoadBar();
|
||||
|
||||
// Determine the string to print
|
||||
if ( cg.infoScreenText[0] )
|
||||
{
|
||||
s = va("Loading... %s", cg.infoScreenText);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "Awaiting snapshot...";
|
||||
}
|
||||
|
||||
// Render the string
|
||||
CG_DrawText( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, 198 - 32,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
|
||||
// draw info string information
|
||||
|
||||
y = 250-32;
|
||||
|
||||
// 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);
|
||||
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( buf, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, buf, 0, 0 );
|
||||
|
||||
y += PROP_HEIGHT;
|
||||
|
||||
// pure server
|
||||
s = Info_ValueForKey( sysInfo, "sv_pure" );
|
||||
if ( atoi(s) )
|
||||
{
|
||||
s = "Pure Server";
|
||||
CG_DrawText( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
|
||||
y += PROP_HEIGHT;
|
||||
}
|
||||
|
||||
// server-specific message of the day
|
||||
s = CG_ConfigString( CS_MOTD );
|
||||
if ( s[0] )
|
||||
{
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
|
||||
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] )
|
||||
{
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
|
||||
y += PROP_HEIGHT;
|
||||
}
|
||||
|
||||
// cheats warning
|
||||
s = Info_ValueForKey( sysInfo, "sv_cheats" );
|
||||
if ( s[0] == '1' )
|
||||
{
|
||||
s = "CHEATS ARE ENABLED";
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
|
||||
y += PROP_HEIGHT;
|
||||
|
||||
cg.cheats = qtrue;
|
||||
}
|
||||
else
|
||||
cg.cheats = qfalse;
|
||||
|
||||
s = cgs.gametypeData->displayName;
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
y += PROP_HEIGHT;
|
||||
|
||||
value = atoi( Info_ValueForKey( info, "timelimit" ) );
|
||||
if ( value )
|
||||
{
|
||||
s = va( "Timelimit %i", value );
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
y += PROP_HEIGHT;
|
||||
}
|
||||
|
||||
value = atoi( Info_ValueForKey( info, "scorelimit" ) );
|
||||
if ( value )
|
||||
{
|
||||
s = va( "Scorelimit %i", value );
|
||||
CG_DrawText ( 320 - trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.53f, 0 ) / 2, y,
|
||||
cgs.media.hudFont, 0.53f, colorWhite, s, 0, 0 );
|
||||
y += PROP_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_LoadBar
|
||||
===================
|
||||
*/
|
||||
|
||||
#define LOADBAR_CLIP_WIDTH 256
|
||||
#define LOADBAR_CLIP_HEIGHT 64
|
||||
#define LOADBAR_BULLET_WIDTH 16
|
||||
#define LOADBAR_BULLET_HEIGHT 64
|
||||
|
||||
void CG_LoadBar(void)
|
||||
{
|
||||
int x,y,i;
|
||||
|
||||
y = 50;
|
||||
x = (640 - LOADBAR_CLIP_WIDTH) / 2;
|
||||
|
||||
for (i=0;i < cg.loadStage; i++ )
|
||||
{
|
||||
CG_DrawPic(x + (i*LOADBAR_BULLET_WIDTH), y, LOADBAR_BULLET_WIDTH, LOADBAR_BULLET_HEIGHT, cgs.media.loadBulletShader );
|
||||
}
|
||||
|
||||
CG_DrawPic ( x, y, LOADBAR_CLIP_WIDTH, LOADBAR_CLIP_HEIGHT, cgs.media.loadClipShader );
|
||||
}
|
89
code/cgame/cg_light.c
Normal file
89
code/cgame/cg_light.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_light.c
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#if !defined(CG_LIGHTS_H_INC)
|
||||
#include "cg_lights.h"
|
||||
#endif
|
||||
|
||||
static clightstyle_t cl_lightstyle[MAX_LIGHT_STYLES];
|
||||
static int lastofs;
|
||||
|
||||
/*
|
||||
================
|
||||
FX_ClearLightStyles
|
||||
================
|
||||
*/
|
||||
void CG_ClearLightStyles (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
|
||||
lastofs = -1;
|
||||
|
||||
for(i=0;i<MAX_LIGHT_STYLES*3;i++)
|
||||
{
|
||||
CG_SetLightstyle (i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FX_RunLightStyles
|
||||
================
|
||||
*/
|
||||
void CG_RunLightStyles (void)
|
||||
{
|
||||
int ofs;
|
||||
int i;
|
||||
clightstyle_t *ls;
|
||||
|
||||
ofs = cg.time / 50;
|
||||
// if (ofs == lastofs)
|
||||
// return;
|
||||
lastofs = ofs;
|
||||
|
||||
for (i=0,ls=cl_lightstyle ; i<MAX_LIGHT_STYLES ; i++, ls++)
|
||||
{
|
||||
if (!ls->length)
|
||||
{
|
||||
ls->value[0] = ls->value[1] = ls->value[2] = ls->value[3] = 255;
|
||||
}
|
||||
else if (ls->length == 1)
|
||||
{
|
||||
ls->value[0] = ls->map[0][0];
|
||||
ls->value[1] = ls->map[0][1];
|
||||
ls->value[2] = ls->map[0][2];
|
||||
ls->value[3] = 255; //ls->map[0][3];
|
||||
}
|
||||
else
|
||||
{
|
||||
ls->value[0] = ls->map[ofs%ls->length][0];
|
||||
ls->value[1] = ls->map[ofs%ls->length][1];
|
||||
ls->value[2] = ls->map[ofs%ls->length][2];
|
||||
ls->value[3] = 255; //ls->map[ofs%ls->length][3];
|
||||
}
|
||||
trap_R_SetLightStyle(i, *(int*)ls->value);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_SetLightstyle (int i)
|
||||
{
|
||||
const char *s;
|
||||
int j, k;
|
||||
|
||||
s = CG_ConfigString( i+CS_LIGHT_STYLES );
|
||||
j = strlen (s);
|
||||
if (j >= MAX_QPATH)
|
||||
{
|
||||
Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);
|
||||
}
|
||||
|
||||
cl_lightstyle[(i/3)].length = j;
|
||||
for (k=0 ; k<j ; k++)
|
||||
{
|
||||
cl_lightstyle[(i/3)].map[k][(i%3)] = (float)(s[k]-'a')/(float)('z'-'a') * 255.0;
|
||||
}
|
||||
}
|
20
code/cgame/cg_lights.h
Normal file
20
code/cgame/cg_lights.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_lights.h --
|
||||
|
||||
#pragma once
|
||||
#if !defined(CG_LIGHTS_H_INC)
|
||||
#define CG_LIGHTS_H_INC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int length;
|
||||
color4ub_t value;
|
||||
color4ub_t map[MAX_QPATH];
|
||||
} clightstyle_t;
|
||||
|
||||
void CG_ClearLightStyles (void);
|
||||
void CG_RunLightStyles (void);
|
||||
void CG_SetLightstyle (int i);
|
||||
|
||||
#endif // CG_LIGHTS_H_INC
|
1446
code/cgame/cg_local.h
Normal file
1446
code/cgame/cg_local.h
Normal file
File diff suppressed because it is too large
Load diff
594
code/cgame/cg_localents.c
Normal file
594
code/cgame/cg_localents.c
Normal file
|
@ -0,0 +1,594 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_localents.c -- every frame, generate renderer commands for locally
|
||||
// processed entities, like smoke puffs, shells, etc.
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#define MAX_LOCAL_ENTITIES 512
|
||||
localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES];
|
||||
localEntity_t cg_activeLocalEntities; // double linked list
|
||||
localEntity_t *cg_freeLocalEntities; // single linked list
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_InitLocalEntities
|
||||
|
||||
This is called at startup and for map restarts
|
||||
===================
|
||||
*/
|
||||
void CG_InitLocalEntities( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
memset( cg_localEntities, 0, sizeof( cg_localEntities ) );
|
||||
cg_activeLocalEntities.next = &cg_activeLocalEntities;
|
||||
cg_activeLocalEntities.prev = &cg_activeLocalEntities;
|
||||
cg_freeLocalEntities = cg_localEntities;
|
||||
|
||||
for ( i = 0 ; i < MAX_LOCAL_ENTITIES - 1 ; i++ )
|
||||
{
|
||||
cg_localEntities[i].next = &cg_localEntities[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_FreeLocalEntity
|
||||
==================
|
||||
*/
|
||||
void CG_FreeLocalEntity( localEntity_t *le )
|
||||
{
|
||||
if ( !le->prev )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_FreeLocalEntity: not active" );
|
||||
}
|
||||
|
||||
if (le->refEntity.ghoul2)
|
||||
{
|
||||
trap_G2API_CleanGhoul2Models(&le->refEntity.ghoul2);
|
||||
}
|
||||
|
||||
// remove from the doubly linked active list
|
||||
le->prev->next = le->next;
|
||||
le->next->prev = le->prev;
|
||||
|
||||
// the free list is only singly linked
|
||||
le->next = cg_freeLocalEntities;
|
||||
cg_freeLocalEntities = le;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_AllocLocalEntity
|
||||
|
||||
Will allways succeed, even if it requires freeing an old active entity
|
||||
===================
|
||||
*/
|
||||
localEntity_t *CG_AllocLocalEntity( void ) {
|
||||
localEntity_t *le;
|
||||
|
||||
if ( !cg_freeLocalEntities ) {
|
||||
// no free entities, so free the one at the end of the chain
|
||||
// remove the oldest active entity
|
||||
CG_FreeLocalEntity( cg_activeLocalEntities.prev );
|
||||
}
|
||||
|
||||
le = cg_freeLocalEntities;
|
||||
cg_freeLocalEntities = cg_freeLocalEntities->next;
|
||||
|
||||
memset( le, 0, sizeof( *le ) );
|
||||
|
||||
// link into the active list
|
||||
le->next = cg_activeLocalEntities.next;
|
||||
le->prev = &cg_activeLocalEntities;
|
||||
cg_activeLocalEntities.next->prev = le;
|
||||
cg_activeLocalEntities.next = le;
|
||||
return le;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================================================================================
|
||||
|
||||
FRAGMENT PROCESSING
|
||||
|
||||
A fragment localentity interacts with the environment in some way (hitting walls),
|
||||
or generates more localentities along a trail.
|
||||
|
||||
====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_FragmentBounceMark
|
||||
================
|
||||
*/
|
||||
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
|
||||
int radius;
|
||||
|
||||
if ( le->leMarkType == LEMT_BLOOD )
|
||||
{
|
||||
radius = 16 + (rand()&31);
|
||||
|
||||
trap_R_AddDecalToScene ( cgs.media.bloodMarkShader, trace->endpos,
|
||||
trace->plane.normal, random()*360,
|
||||
1,1,1,1, qtrue, radius, qfalse );
|
||||
|
||||
}
|
||||
else if ( le->leMarkType == LEMT_BURN )
|
||||
{
|
||||
radius = 8 + (rand()&15);
|
||||
|
||||
trap_R_AddDecalToScene ( cgs.media.burnMarkShader, trace->endpos,
|
||||
trace->plane.normal, random()*360,
|
||||
1,1,1,1, qtrue, radius, qfalse );
|
||||
}
|
||||
|
||||
|
||||
// don't allow a fragment to make multiple marks, or they
|
||||
// pile up while settling
|
||||
le->leMarkType = LEMT_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_FragmentBounceSound
|
||||
================
|
||||
*/
|
||||
void CG_FragmentBounceSound( localEntity_t *le, trace_t *trace )
|
||||
{
|
||||
if ( le->leBounceSoundType == LEBS_BRASS )
|
||||
{
|
||||
}
|
||||
|
||||
// don't allow a fragment to make multiple bounce sounds,
|
||||
// or it gets too noisy as they settle
|
||||
le->leBounceSoundType = LEBS_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CG_ReflectVelocity
|
||||
================
|
||||
*/
|
||||
void CG_ReflectVelocity( localEntity_t *le, trace_t *trace ) {
|
||||
vec3_t velocity;
|
||||
float dot;
|
||||
int hitTime;
|
||||
|
||||
// reflect the velocity on the trace plane
|
||||
hitTime = cg.time - cg.frametime + cg.frametime * trace->fraction;
|
||||
BG_EvaluateTrajectoryDelta( &le->pos, hitTime, velocity );
|
||||
dot = DotProduct( velocity, trace->plane.normal );
|
||||
VectorMA( velocity, -2*dot, trace->plane.normal, le->pos.trDelta );
|
||||
|
||||
VectorScale( le->pos.trDelta, le->bounceFactor, le->pos.trDelta );
|
||||
|
||||
VectorCopy( trace->endpos, le->pos.trBase );
|
||||
le->pos.trTime = cg.time;
|
||||
|
||||
|
||||
// check for stop, making sure that even on low FPS systems it doesn't bobble
|
||||
if ( trace->allsolid ||
|
||||
( trace->plane.normal[2] > 0 &&
|
||||
( le->pos.trDelta[2] < 40 || le->pos.trDelta[2] < -cg.frametime * le->pos.trDelta[2] ) ) ) {
|
||||
le->pos.trType = TR_STATIONARY;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_AddFragment
|
||||
================
|
||||
*/
|
||||
void CG_AddFragment( localEntity_t *le ) {
|
||||
vec3_t newOrigin;
|
||||
trace_t trace;
|
||||
|
||||
if ( le->pos.trType == TR_STATIONARY ) {
|
||||
// sink into the ground if near the removal time
|
||||
int t;
|
||||
float oldZ;
|
||||
|
||||
t = le->endTime - cg.time;
|
||||
if ( t < SINK_TIME ) {
|
||||
// we must use an explicit lighting origin, otherwise the
|
||||
// lighting would be lost as soon as the origin went
|
||||
// into the ground
|
||||
VectorCopy( le->refEntity.origin, le->refEntity.lightingOrigin );
|
||||
le->refEntity.renderfx |= RF_LIGHTING_ORIGIN;
|
||||
oldZ = le->refEntity.origin[2];
|
||||
le->refEntity.origin[2] -= 16 * ( 1.0 - (float)t / SINK_TIME );
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
le->refEntity.origin[2] = oldZ;
|
||||
} else {
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate new position
|
||||
BG_EvaluateTrajectory( &le->pos, cg.time, newOrigin );
|
||||
|
||||
// trace a line from previous position to new position
|
||||
CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID );
|
||||
|
||||
if ( trace.fraction == 1.0 ) {
|
||||
// still in free fall
|
||||
VectorCopy( newOrigin, le->refEntity.origin );
|
||||
|
||||
if ( le->leFlags & LEF_TUMBLE ) {
|
||||
vec3_t angles;
|
||||
|
||||
BG_EvaluateTrajectory( &le->angles, cg.time, angles );
|
||||
AnglesToAxis( angles, le->refEntity.axis );
|
||||
}
|
||||
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
return;
|
||||
}
|
||||
|
||||
// if it is in a nodrop zone, remove it
|
||||
// this keeps gibs from waiting at the bottom of pits of death
|
||||
// and floating levels
|
||||
if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP )
|
||||
{
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trace.startsolid)
|
||||
{
|
||||
// leave a mark
|
||||
CG_FragmentBounceMark( le, &trace );
|
||||
|
||||
// do a bouncy sound
|
||||
CG_FragmentBounceSound( le, &trace );
|
||||
|
||||
// reflect the velocity on the trace plane
|
||||
CG_ReflectVelocity( le, &trace );
|
||||
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
TRIVIAL LOCAL ENTITIES
|
||||
|
||||
These only do simple scaling or modulation before passing to the renderer
|
||||
=====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_AddFadeRGB
|
||||
====================
|
||||
*/
|
||||
void CG_AddFadeRGB( localEntity_t *le ) {
|
||||
refEntity_t *re;
|
||||
float c;
|
||||
|
||||
re = &le->refEntity;
|
||||
|
||||
c = ( le->endTime - cg.time ) * le->lifeRate;
|
||||
c *= 0xff;
|
||||
|
||||
re->shaderRGBA[0] = le->color[0] * c;
|
||||
re->shaderRGBA[1] = le->color[1] * c;
|
||||
re->shaderRGBA[2] = le->color[2] * c;
|
||||
re->shaderRGBA[3] = le->color[3] * c;
|
||||
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_AddMoveScaleFade
|
||||
==================
|
||||
*/
|
||||
static void CG_AddMoveScaleFade( localEntity_t *le ) {
|
||||
refEntity_t *re;
|
||||
float c;
|
||||
vec3_t delta;
|
||||
float len;
|
||||
|
||||
re = &le->refEntity;
|
||||
|
||||
if ( le->fadeInTime > le->startTime && cg.time < le->fadeInTime ) {
|
||||
// fade / grow time
|
||||
c = 1.0 - (float) ( le->fadeInTime - cg.time ) / ( le->fadeInTime - le->startTime );
|
||||
}
|
||||
else {
|
||||
// fade / grow time
|
||||
c = ( le->endTime - cg.time ) * le->lifeRate;
|
||||
}
|
||||
|
||||
re->shaderRGBA[3] = 0xff * c * le->color[3];
|
||||
|
||||
if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) {
|
||||
re->radius = le->radius * ( 1.0 - c ) + 8;
|
||||
}
|
||||
|
||||
BG_EvaluateTrajectory( &le->pos, cg.time, re->origin );
|
||||
|
||||
// if the view would be "inside" the sprite, kill the sprite
|
||||
// so it doesn't add too much overdraw
|
||||
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len < le->radius ) {
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_AddScaleFade
|
||||
|
||||
For rocket smokes that hang in place, fade out, and are
|
||||
removed if the view passes through them.
|
||||
There are often many of these, so it needs to be simple.
|
||||
===================
|
||||
*/
|
||||
static void CG_AddScaleFade( localEntity_t *le ) {
|
||||
refEntity_t *re;
|
||||
float c;
|
||||
vec3_t delta;
|
||||
float len;
|
||||
|
||||
re = &le->refEntity;
|
||||
|
||||
// fade / grow time
|
||||
c = ( le->endTime - cg.time ) * le->lifeRate;
|
||||
|
||||
re->shaderRGBA[3] = 0xff * c * le->color[3];
|
||||
re->radius = le->radius * ( 1.0 - c ) + 8;
|
||||
|
||||
// if the view would be "inside" the sprite, kill the sprite
|
||||
// so it doesn't add too much overdraw
|
||||
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len < le->radius ) {
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_AddFallScaleFade
|
||||
|
||||
This is just an optimized CG_AddMoveScaleFade
|
||||
For blood mists that drift down, fade out, and are
|
||||
removed if the view passes through them.
|
||||
There are often 100+ of these, so it needs to be simple.
|
||||
=================
|
||||
*/
|
||||
static void CG_AddFallScaleFade( localEntity_t *le ) {
|
||||
refEntity_t *re;
|
||||
float c;
|
||||
vec3_t delta;
|
||||
float len;
|
||||
|
||||
re = &le->refEntity;
|
||||
|
||||
// fade time
|
||||
c = ( le->endTime - cg.time ) * le->lifeRate;
|
||||
|
||||
re->shaderRGBA[3] = 0xff * c * le->color[3];
|
||||
|
||||
re->origin[2] = le->pos.trBase[2] - ( 1.0 - c ) * le->pos.trDelta[2];
|
||||
|
||||
re->radius = le->radius * ( 1.0 - c ) + 16;
|
||||
|
||||
// if the view would be "inside" the sprite, kill the sprite
|
||||
// so it doesn't add too much overdraw
|
||||
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len < le->radius ) {
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_AddRefEntity
|
||||
===================
|
||||
*/
|
||||
void CG_AddRefEntity( localEntity_t *le )
|
||||
{
|
||||
if (le->endTime < cg.time)
|
||||
{
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_AddLine
|
||||
===================
|
||||
*/
|
||||
void CG_AddLine( localEntity_t *le )
|
||||
{
|
||||
refEntity_t *re;
|
||||
|
||||
re = &le->refEntity;
|
||||
|
||||
re->reType = RT_LINE;
|
||||
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CG_AddGib
|
||||
================
|
||||
*/
|
||||
void CG_AddGib( localEntity_t *le ) {
|
||||
vec3_t newOrigin;
|
||||
trace_t trace;
|
||||
|
||||
if ( le->pos.trType == TR_STATIONARY ) {
|
||||
// sink into the ground if near the removal time
|
||||
int t;
|
||||
float oldZ;
|
||||
|
||||
le->refEntity.origin[2] += le->zOffset;
|
||||
t = le->endTime - cg.time;
|
||||
if ( t < SINK_TIME ) {
|
||||
// we must use an explicit lighting origin, otherwise the
|
||||
// lighting would be lost as soon as the origin went
|
||||
// into the ground
|
||||
VectorCopy( le->refEntity.origin, le->refEntity.lightingOrigin );
|
||||
le->refEntity.renderfx |= RF_LIGHTING_ORIGIN;
|
||||
oldZ = le->refEntity.origin[2];
|
||||
le->refEntity.origin[2] -= 16 * ( 1.0 - (float)t / SINK_TIME );
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
le->refEntity.origin[2] = oldZ;
|
||||
} else {
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
}
|
||||
le->refEntity.origin[2] -= le->zOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate new position
|
||||
BG_EvaluateTrajectory( &le->pos, cg.time, newOrigin );
|
||||
|
||||
// trace a line from previous position to new position
|
||||
CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID );
|
||||
if ( trace.fraction == 1.0 ) {
|
||||
// still in free fall
|
||||
VectorCopy( newOrigin, le->refEntity.origin );
|
||||
|
||||
if ( le->leFlags & LEF_TUMBLE ) {
|
||||
vec3_t angles;
|
||||
|
||||
BG_EvaluateTrajectory( &le->angles, cg.time, angles );
|
||||
AnglesToAxis( angles, le->refEntity.axis );
|
||||
}
|
||||
|
||||
le->refEntity.origin[2] += le->zOffset;
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
le->refEntity.origin[2] -= le->zOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if it is in a nodrop zone, remove it
|
||||
// this keeps gibs from waiting at the bottom of pits of death
|
||||
// and floating levels
|
||||
if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP )
|
||||
{
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trace.startsolid)
|
||||
{
|
||||
// leave a mark
|
||||
// CG_FragmentBounceMark( le, &trace );
|
||||
|
||||
// do a bouncy sound
|
||||
// CG_FragmentBounceSound( le, &trace );
|
||||
|
||||
// reflect the velocity on the trace plane
|
||||
CG_ReflectVelocity( le, &trace );
|
||||
|
||||
le->refEntity.origin[2] += le->zOffset;
|
||||
trap_R_AddRefEntityToScene( &le->refEntity );
|
||||
le->refEntity.origin[2] -= le->zOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_AddLocalEntities
|
||||
===================
|
||||
*/
|
||||
void CG_AddLocalEntities( void )
|
||||
{
|
||||
localEntity_t *le, *next;
|
||||
|
||||
// walk the list backwards, so any new local entities generated
|
||||
// (trails, marks, etc) will be present this frame
|
||||
le = cg_activeLocalEntities.prev;
|
||||
for ( ; le != &cg_activeLocalEntities ; le = next )
|
||||
{
|
||||
// grab next now, so if the local entity is freed we
|
||||
// still have it
|
||||
next = le->prev;
|
||||
|
||||
if ( cg.time >= le->endTime )
|
||||
{
|
||||
CG_FreeLocalEntity( le );
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( le->leType )
|
||||
{
|
||||
default:
|
||||
Com_Error( ERR_FATAL, "Bad leType: %i", le->leType );
|
||||
break;
|
||||
|
||||
case LE_FRAGMENT:
|
||||
CG_AddFragment( le );
|
||||
break;
|
||||
|
||||
case LE_MOVE_SCALE_FADE:
|
||||
CG_AddMoveScaleFade( le );
|
||||
break;
|
||||
|
||||
case LE_FADE_RGB:
|
||||
CG_AddFadeRGB( le );
|
||||
break;
|
||||
|
||||
case LE_FALL_SCALE_FADE:
|
||||
CG_AddFallScaleFade( le );
|
||||
break;
|
||||
|
||||
case LE_SCALE_FADE:
|
||||
CG_AddScaleFade( le );
|
||||
break;
|
||||
|
||||
case LE_SHOWREFENTITY:
|
||||
CG_AddRefEntity( le );
|
||||
break;
|
||||
|
||||
case LE_LINE:
|
||||
CG_AddLine( le );
|
||||
break;
|
||||
|
||||
case LE_GIB:
|
||||
CG_AddGib(le);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
1953
code/cgame/cg_main.c
Normal file
1953
code/cgame/cg_main.c
Normal file
File diff suppressed because it is too large
Load diff
0
code/cgame/cg_media.h
Normal file
0
code/cgame/cg_media.h
Normal file
77
code/cgame/cg_miscents.c
Normal file
77
code/cgame/cg_miscents.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_miscents.h --
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#define MAX_MISC_ENTS 4000
|
||||
|
||||
static refEntity_t *MiscEnts = 0;
|
||||
static float *Radius = 0;
|
||||
static int NumMiscEnts = 0;
|
||||
|
||||
void CG_MiscEnt(void)
|
||||
{
|
||||
int modelIndex;
|
||||
refEntity_t *RefEnt;
|
||||
TCGMiscEnt *data = (TCGMiscEnt *)cg.sharedBuffer;
|
||||
vec3_t mins, maxs;
|
||||
float *radius;
|
||||
|
||||
if (NumMiscEnts >= MAX_MISC_ENTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MiscEnts)
|
||||
{
|
||||
MiscEnts = (refEntity_t *)trap_VM_LocalAlloc(sizeof(refEntity_t)*MAX_MISC_ENTS);
|
||||
Radius = (float *)trap_VM_LocalAlloc(sizeof(float)*MAX_MISC_ENTS);
|
||||
}
|
||||
|
||||
radius = &Radius[NumMiscEnts];
|
||||
RefEnt = &MiscEnts[NumMiscEnts++];
|
||||
|
||||
modelIndex = trap_R_RegisterModel(data->mModel);
|
||||
if (modelIndex == 0)
|
||||
{
|
||||
Com_Error(ERR_DROP, "client_model has invalid model definition");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(RefEnt, 0, sizeof(refEntity_t));
|
||||
RefEnt->reType = RT_MODEL;
|
||||
RefEnt->hModel = modelIndex;
|
||||
RefEnt->frame = 0;
|
||||
trap_R_ModelBounds(modelIndex, mins, maxs);
|
||||
VectorCopy(data->mScale, RefEnt->modelScale);
|
||||
VectorCopy(data->mOrigin, RefEnt->origin);
|
||||
|
||||
VectorScaleVector(mins, data->mScale, mins);
|
||||
VectorScaleVector(maxs, data->mScale, maxs);
|
||||
*radius = Distance(mins, maxs);
|
||||
|
||||
AnglesToAxis( data->mAngles, RefEnt->axis );
|
||||
CG_ScaleModelAxis(RefEnt);
|
||||
}
|
||||
|
||||
void CG_DrawMiscEnts(void)
|
||||
{
|
||||
int i;
|
||||
refEntity_t *RefEnt;
|
||||
float *radius;
|
||||
vec3_t difference;
|
||||
|
||||
RefEnt = MiscEnts;
|
||||
radius = Radius;
|
||||
for(i=0;i<NumMiscEnts;i++)
|
||||
{
|
||||
VectorSubtract(RefEnt->origin, cg.refdef.vieworg, difference);
|
||||
if (VectorLength(difference)-(*radius) <= RMG_distancecull.value)
|
||||
{
|
||||
trap_R_AddRefEntityToScene(RefEnt);
|
||||
}
|
||||
RefEnt++;
|
||||
radius++;
|
||||
}
|
||||
}
|
1119
code/cgame/cg_newDraw.c
Normal file
1119
code/cgame/cg_newDraw.c
Normal file
File diff suppressed because it is too large
Load diff
119
code/cgame/cg_playeranim.c
Normal file
119
code/cgame/cg_playeranim.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "cg_local.h"
|
||||
#include "animtable.h"
|
||||
|
||||
|
||||
/*
|
||||
======================
|
||||
CG_ParseAnimationFile
|
||||
|
||||
Read a configuration file containing animation counts and rates
|
||||
models/players/visor/animation.cfg, etc
|
||||
======================
|
||||
*/
|
||||
qboolean CG_ParseAnimationFile ( const char *filename, clientInfo_t *ci)
|
||||
{
|
||||
const char *text_p;
|
||||
int len;
|
||||
int i;
|
||||
char *token;
|
||||
float fps;
|
||||
int skip;
|
||||
char text[20000];
|
||||
fileHandle_t f;
|
||||
int animNum;
|
||||
animation_t *animations;
|
||||
|
||||
animations = ci->animations;
|
||||
|
||||
// load the file
|
||||
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||||
if ( len <= 0 || len >= sizeof( text ) - 1 )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
trap_FS_Read( text, len, f );
|
||||
text[len] = 0;
|
||||
trap_FS_FCloseFile( f );
|
||||
|
||||
// parse the text
|
||||
text_p = text;
|
||||
skip = 0; // quiet the compiler warning
|
||||
|
||||
//FIXME: have some way of playing anims backwards... negative numFrames?
|
||||
|
||||
//initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
|
||||
for(i = 0; i < MAX_ANIMATIONS; i++)
|
||||
{
|
||||
animations[i].firstFrame = 0;
|
||||
animations[i].numFrames = 0;
|
||||
animations[i].loopFrames = -1;
|
||||
animations[i].frameLerp = 100;
|
||||
animations[i].initialLerp = 100;
|
||||
}
|
||||
|
||||
// read information for each frame
|
||||
while(1)
|
||||
{
|
||||
token = COM_Parse( &text_p );
|
||||
|
||||
if ( !token || !token[0])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
animNum = GetIDForString(animTable, token);
|
||||
if(animNum == -1)
|
||||
{
|
||||
//#ifndef FINAL_BUILD
|
||||
#ifdef _DEBUG
|
||||
Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
animations[animNum].firstFrame = atoi( token );
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
animations[animNum].numFrames = atoi( token );
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
animations[animNum].loopFrames = atoi( token );
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
fps = atof( token );
|
||||
if ( fps == 0 )
|
||||
{
|
||||
fps = 1;//Don't allow divide by zero error
|
||||
}
|
||||
if ( fps < 0 )
|
||||
{//backwards
|
||||
animations[animNum].frameLerp = floor(1000.0f / fps);
|
||||
}
|
||||
else
|
||||
{
|
||||
animations[animNum].frameLerp = ceil(1000.0f / fps);
|
||||
}
|
||||
|
||||
animations[animNum].initialLerp = ceil(1000.0f / fabs(fps));
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
0
code/cgame/cg_playeranimate.c
Normal file
0
code/cgame/cg_playeranimate.c
Normal file
1472
code/cgame/cg_players.c
Normal file
1472
code/cgame/cg_players.c
Normal file
File diff suppressed because it is too large
Load diff
313
code/cgame/cg_playerstate.c
Normal file
313
code/cgame/cg_playerstate.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// 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_DamageFeedback
|
||||
==============
|
||||
*/
|
||||
void CG_DamageFeedback( int yawByte, int pitchByte, int damage )
|
||||
{
|
||||
float kick;
|
||||
int health;
|
||||
float scale;
|
||||
vec3_t dir;
|
||||
vec3_t angles;
|
||||
|
||||
// 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 * 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 = 255;
|
||||
cg.v_dmg_pitch = -kick;
|
||||
}
|
||||
else
|
||||
{
|
||||
float front;
|
||||
float left;
|
||||
|
||||
angles[PITCH] = (float)pitchByte / 255.0f * 360.0f;
|
||||
angles[YAW] = (float)yawByte / 255.0f * 360.0f;
|
||||
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] );
|
||||
|
||||
cg.v_dmg_roll = kick * left;
|
||||
cg.v_dmg_pitch = -kick * front;
|
||||
|
||||
cg.damageY = -AngleNormalize180(angles[PITCH]);
|
||||
cg.damageX = AngleNormalize180(angles[YAW] - cg.predictedPlayerState.viewangles[YAW] + 180);
|
||||
}
|
||||
|
||||
// don't let the screen flashes vary as much
|
||||
if ( kick > 10 )
|
||||
{
|
||||
kick = 10;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// no more camera shake
|
||||
cg.shakeStart = 0;
|
||||
|
||||
// Make sure the weapon selection menu isnt up
|
||||
cg.weaponMenuUp = qfalse;
|
||||
|
||||
// clear any left over flash grenades
|
||||
cg.flashbangTime = 0;
|
||||
|
||||
// Reset the animation
|
||||
CG_SetWeaponAnim( cg.snap->ps.weaponAnimId&(~ANIM_TOGGLEBIT), &cg.snap->ps );
|
||||
|
||||
// Update the view weapon surfaces
|
||||
CG_UpdateViewWeaponSurfaces ( &cg.snap->ps );
|
||||
|
||||
trap_ResetAutorun ( );
|
||||
}
|
||||
|
||||
extern char *eventnames[];
|
||||
|
||||
/*
|
||||
==============
|
||||
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_GetEntity ( ps->clientNum );
|
||||
cent->currentState.event = ps->externalEvent;
|
||||
cent->currentState.eventParm = ps->externalEventParm;
|
||||
CG_EntityEvent( cent, cent->lerpOrigin );
|
||||
}
|
||||
|
||||
cent = &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_CheckChangedPredictableEvents
|
||||
==================
|
||||
*/
|
||||
void CG_CheckChangedPredictableEvents( playerState_t *ps )
|
||||
{
|
||||
int i;
|
||||
int event;
|
||||
centity_t *cent;
|
||||
|
||||
cent = &cg_entities[ps->clientNum];
|
||||
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ )
|
||||
{
|
||||
//
|
||||
if (i >= cg.eventSequence)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// if this event is not further back in than the maximum predictable events we remember
|
||||
if (i > cg.eventSequence - MAX_PREDICTED_EVENTS)
|
||||
{
|
||||
// if the new playerstate event is different from a previously predicted one
|
||||
if ( ps->events[i & (MAX_PS_EVENTS-1)] != cg.predictableEvents[i & (MAX_PREDICTED_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;
|
||||
|
||||
if ( cg_showmiss.integer )
|
||||
{
|
||||
Com_Printf("WARNING: changed predicted event\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_CheckLocalSounds
|
||||
==================
|
||||
*/
|
||||
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
|
||||
{
|
||||
// don't play the sounds if the player just changed teams
|
||||
if ( ps->persistant[PERS_TEAM] != ops->persistant[PERS_TEAM] )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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_entities[ps->clientNum], ps->stats[STAT_HEALTH] );
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a zoom transition that isnt the first zoom in
|
||||
if ( ops->zoomFov && (ps->zoomFov != ops->zoomFov) )
|
||||
{
|
||||
trap_S_StartLocalSound ( cgs.media.zoomSound, CHAN_AUTO );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_TransitionPlayerState
|
||||
===============
|
||||
*/
|
||||
void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops )
|
||||
{
|
||||
// respawning. This is done before the follow mode check because spawn count is
|
||||
// maintained into the following client
|
||||
if ( ps->persistant[PERS_SPAWN_COUNT] != ops->persistant[PERS_SPAWN_COUNT] )
|
||||
{
|
||||
CG_Respawn();
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount );
|
||||
}
|
||||
|
||||
// Make sure we clear the weapon menu when we die
|
||||
if ( ps->stats[STAT_HEALTH] != ops->stats[STAT_HEALTH] )
|
||||
{
|
||||
if ( ps->stats[STAT_HEALTH] <= 0 )
|
||||
{
|
||||
cg.weaponMenuUp = qfalse;
|
||||
cg.deathTime = cg.time;
|
||||
trap_ResetAutorun ( );
|
||||
}
|
||||
}
|
||||
|
||||
if ( cg.mapRestart )
|
||||
{
|
||||
CG_Respawn();
|
||||
cg.mapRestart = qfalse;
|
||||
}
|
||||
|
||||
if ( cg.snap->ps.pm_type != PM_INTERMISSION && ps->persistant[PERS_TEAM] != TEAM_SPECTATOR )
|
||||
{
|
||||
CG_CheckLocalSounds( ps, ops );
|
||||
}
|
||||
|
||||
// Always use the weapon from the player state when following
|
||||
if( (ps->pm_flags & PMF_FOLLOW) || (ps->weapon != ops->weapon) )
|
||||
{
|
||||
cg.weaponSelect = ps->weapon;
|
||||
}
|
||||
|
||||
// Check for weapon animation change.
|
||||
if(ps->weaponAnimId!=ops->weaponAnimId )
|
||||
{
|
||||
CG_SetWeaponAnim(ps->weaponAnimId&(~ANIM_TOGGLEBIT),ps);
|
||||
}
|
||||
|
||||
// run events
|
||||
CG_CheckPlayerstateEvents( ps, ops );
|
||||
|
||||
// smooth the ducking viewheight change and not crouch jumping
|
||||
if ( ps->viewheight != ops->viewheight && !(ps->pm_flags & PMF_CROUCH_JUMP) )
|
||||
{
|
||||
cg.duckChange = ps->viewheight - ops->viewheight;
|
||||
cg.duckTime = cg.time;
|
||||
}
|
||||
|
||||
// Need to update the view weapon surfaces when weapon states change
|
||||
if ( ps->weaponstate != ops->weaponstate )
|
||||
{
|
||||
CG_UpdateViewWeaponSurfaces ( ps );
|
||||
}
|
||||
}
|
||||
|
828
code/cgame/cg_predict.c
Normal file
828
code/cgame/cg_predict.c
Normal file
|
@ -0,0 +1,828 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// 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_GENTITIES];
|
||||
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;
|
||||
vec3_t difference;
|
||||
float dsquared;
|
||||
|
||||
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_GetEntity ( snap->entities[ i ].number );
|
||||
ent = ¢->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;
|
||||
}
|
||||
}
|
||||
|
||||
dsquared = RMG_distancecull.value+500;
|
||||
dsquared *= dsquared;
|
||||
|
||||
for(i=0;i<cg_numpermanents;i++)
|
||||
{
|
||||
cent = cg_permanents[i];
|
||||
VectorSubtract(cent->lerpOrigin, snap->ps.origin, difference);
|
||||
if (cent->currentState.eType == ET_TERRAIN ||
|
||||
((difference[0]*difference[0]) + (difference[1]*difference[1]) + (difference[2]*difference[2])) <= dsquared)
|
||||
{
|
||||
cent->currentValid = qtrue;
|
||||
if ( cent->nextState.solid )
|
||||
{
|
||||
cg_solidEntities[cg_numSolidEntities] = cent;
|
||||
cg_numSolidEntities++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cent->currentValid = qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CG_ClipMoveToEntities
|
||||
|
||||
====================
|
||||
*/
|
||||
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 = ¢->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( ¢->currentState.pos, cg.physicsTime, origin );
|
||||
} else {
|
||||
// encoded bbox
|
||||
x = (ent->solid & 255);
|
||||
zd = ((ent->solid>>8) & 255);
|
||||
zu = ((ent->solid>>16) & 255) - 32;
|
||||
|
||||
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_PlayerTrace
|
||||
|
||||
Trace against all players in the game and return a precise ghoul location where they were hit
|
||||
================
|
||||
*/
|
||||
void CG_PlayerTrace ( trace_t* tr, const vec3_t start, const vec3_t end, int skipNumber )
|
||||
{
|
||||
G2Trace_t G2Trace;
|
||||
int i;
|
||||
float hitlen;
|
||||
int hit;
|
||||
vec3_t hitloc;
|
||||
|
||||
hit = -1;
|
||||
|
||||
VectorSubtract ( end, start, hitloc );
|
||||
hitlen = VectorLengthSquared ( hitloc );
|
||||
|
||||
for ( i = 0 ; i < cgs.maxclients ; i++ )
|
||||
{
|
||||
centity_t *cent;
|
||||
animation_t *anim;
|
||||
|
||||
cent = &cg_entities[i];
|
||||
|
||||
// Look for reasons to not even bother with this client
|
||||
if ( !cent->currentValid || cent->currentState.number == skipNumber || cent->currentState.eType != ET_PLAYER )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cant hit dead people
|
||||
if ( cent->currentState.eFlags & EF_DEAD )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do a quick test to make sure its even close to the guy
|
||||
if ( !Q_TestRaySphere ( cent->lerpOrigin, 50, start, end ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if the shot is even close to the player
|
||||
G2Trace[0].mEntityNum = -1;
|
||||
|
||||
anim = &cg.hitAnimations[ cent->pe.legs.anim &(~ANIM_TOGGLEBIT) ];
|
||||
trap_G2API_SetBoneAnim(cg.hitModel, 0, "model_root", anim->firstFrame, anim->firstFrame + anim->numFrames, BONE_ANIM_OVERRIDE_LOOP, 50.0f / anim->frameLerp, cent->pe.legs.animTime, -1, 0);
|
||||
|
||||
anim = &cg.hitAnimations[ cent->pe.torso.anim &(~ANIM_TOGGLEBIT)];
|
||||
trap_G2API_SetBoneAnim(cg.hitModel, 0, "lower_lumbar", anim->firstFrame, anim->firstFrame + anim->numFrames, BONE_ANIM_OVERRIDE_LOOP, 50.0f / anim->frameLerp, cent->pe.torso.animTime, -1, 0);
|
||||
|
||||
trap_G2API_SetBoneAngles( cg.hitModel, 0, "upper_lumbar", cent->pe.ghoulUpperTorsoAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, cg.time );
|
||||
trap_G2API_SetBoneAngles( cg.hitModel, 0, "lower_lumbar", cent->pe.ghoulLowerTorsoAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, cg.time );
|
||||
trap_G2API_SetBoneAngles( cg.hitModel, 0, "cranium", cent->pe.ghoulHeadAngles, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, 0,0, cg.time );
|
||||
|
||||
trap_G2API_CollisionDetect ( G2Trace, cg.hitModel, cent->pe.ghoulLegsAngles, cent->lerpOrigin, cg.time, cent->currentState.number, start, end, vec3_identity, 0, 2 );
|
||||
|
||||
if ( G2Trace[0].mEntityNum == i )
|
||||
{
|
||||
vec3_t temp;
|
||||
float len;
|
||||
|
||||
VectorSubtract ( G2Trace[0].mCollisionPosition, start, temp );
|
||||
len = VectorLengthSquared ( temp );
|
||||
|
||||
if ( len < hitlen )
|
||||
{
|
||||
hitlen = len;
|
||||
hit = i;
|
||||
VectorCopy ( G2Trace[0].mCollisionPosition, hitloc );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( hit != -1 )
|
||||
{
|
||||
tr->entityNum = hit;
|
||||
VectorCopy ( hitloc, tr->endpos );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
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 = ¢->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 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef _SNAPSHOT_EXTRAPOLATION
|
||||
|
||||
if ( next->serverTime <= prev->serverTime )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
f = (float)( cg.time - prev->serverTime ) / (float)( 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;
|
||||
qboolean autoswitch = qfalse;
|
||||
|
||||
if ( !cg_predictItems.integer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, ¢->currentState, cg.time ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// never pick an item up twice in a prediction
|
||||
if ( cent->miscTime == cg.time )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !BG_CanItemBeGrabbed( cgs.gametype, ¢->currentState, &cg.predictedPlayerState ) )
|
||||
{
|
||||
// can't hold it
|
||||
return;
|
||||
}
|
||||
|
||||
item = &bg_itemlist[ cent->currentState.modelindex ];
|
||||
|
||||
// No item prediction on gametype items
|
||||
if ( item->giType == IT_GAMETYPE || item->giType == IT_BACKPACK )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// See if we should autoswitch
|
||||
if ( bg_itemlist[cent->currentState.modelindex].giType == IT_WEAPON )
|
||||
{
|
||||
// Dont autoswitch if the weapon isnt a safe weapon
|
||||
if ( cg_autoswitch.integer == 1 || weaponData[bg_itemlist[cent->currentState.modelindex].giTag].safe )
|
||||
{
|
||||
if ( !(cg.predictedPlayerState.stats[STAT_WEAPONS] & (1<<bg_itemlist[cent->currentState.modelindex].giTag)) )
|
||||
{
|
||||
autoswitch = qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// grab it
|
||||
BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex|(autoswitch?ITEM_AUTOSWITCHBIT:0) , &cg.predictedPlayerState);
|
||||
|
||||
// remove it from the frame so it won't be drawn
|
||||
cent->currentState.eFlags |= EF_NODRAW;
|
||||
|
||||
// don't touch it again this prediction
|
||||
cent->miscTime = cg.time;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=========================
|
||||
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 = ¢->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
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;
|
||||
int current;
|
||||
playerState_t oldPlayerState;
|
||||
qboolean moved;
|
||||
usercmd_t oldestCmd;
|
||||
usercmd_t latestCmd;
|
||||
|
||||
// will be set if touching a trigger_teleport
|
||||
cg.hyperspace = qfalse;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
#if _Debug
|
||||
cg_pmove.isClient=-1;
|
||||
#endif
|
||||
cg_pmove.ps = &cg.predictedPlayerState;
|
||||
cg_pmove.trace = CG_Trace;
|
||||
cg_pmove.pointcontents = CG_PointContents;
|
||||
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_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
|
||||
}
|
||||
cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 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 )
|
||||
{
|
||||
Com_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;
|
||||
}
|
||||
|
||||
if ( pmove_msec.integer < 8 )
|
||||
{
|
||||
trap_Cvar_Set("pmove_msec", "8");
|
||||
}
|
||||
else if (pmove_msec.integer > 33)
|
||||
{
|
||||
trap_Cvar_Set("pmove_msec", "33");
|
||||
}
|
||||
|
||||
cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
|
||||
cg_pmove.pmove_msec = pmove_msec.integer;
|
||||
|
||||
// run cmds
|
||||
moved = qfalse;
|
||||
for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ )
|
||||
{
|
||||
// get the command
|
||||
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
|
||||
|
||||
if ( cg_pmove.pmove_fixed )
|
||||
{
|
||||
PM_UpdateViewAngles( cg_pmove.ps, &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;
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
Com_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 ))
|
||||
{
|
||||
Com_Printf("prediction error\n");
|
||||
}
|
||||
}
|
||||
|
||||
VectorSubtract( oldPlayerState.origin, adjusted, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > 0.1 )
|
||||
{
|
||||
if ( cg_showmiss.integer )
|
||||
{
|
||||
Com_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 )
|
||||
{
|
||||
Com_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// don't predict gauntlet firing, which is only supposed to happen
|
||||
// when it actually inflicts damage
|
||||
cg_pmove.gauntletHit = qfalse;
|
||||
|
||||
if ( cg_pmove.pmove_fixed )
|
||||
{
|
||||
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
|
||||
}
|
||||
|
||||
cg_pmove.animations = cgs.clientinfo[cg.clientNum].animations;
|
||||
|
||||
Pmove (&cg_pmove);
|
||||
|
||||
moved = qtrue;
|
||||
|
||||
// add push trigger movement effects
|
||||
CG_TouchTriggerPrediction();
|
||||
|
||||
// check for predictable events that changed from previous predictions
|
||||
//CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
|
||||
}
|
||||
|
||||
if ( cg_showmiss.integer > 1 )
|
||||
{
|
||||
Com_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
|
||||
}
|
||||
|
||||
if ( !moved )
|
||||
{
|
||||
if ( cg_showmiss.integer )
|
||||
{
|
||||
Com_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)
|
||||
{
|
||||
Com_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)
|
||||
{
|
||||
Com_Printf("WARNING: double event\n");
|
||||
cg.eventSequence = cg.predictedPlayerState.eventSequence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_InitHitModel
|
||||
===============
|
||||
*/
|
||||
void CG_InitHitModel ( void )
|
||||
{
|
||||
void* ghoul2;
|
||||
char temp[20480];
|
||||
int numPairs;
|
||||
qhandle_t handle;
|
||||
|
||||
ghoul2 = NULL;
|
||||
|
||||
// Initialize the ghoul2 model
|
||||
trap_G2API_InitGhoul2Model ( &ghoul2,
|
||||
"models/characters/average_sleeves/average_sleeves.glm",
|
||||
0, 0, 0, (1<<4), 2 );
|
||||
|
||||
// Verify it
|
||||
if ( !ghoul2 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the skin file that will be used for hit information
|
||||
numPairs = BG_ParseSkin ( "models/characters/skins/col_rebel_h1.g2skin", temp, sizeof(temp) );
|
||||
if ( !numPairs )
|
||||
{
|
||||
trap_G2API_CleanGhoul2Models ( &ghoul2 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Register the skin and attach it to the ghoul model
|
||||
handle = trap_G2API_RegisterSkin( "hitmodel", numPairs, temp );
|
||||
trap_G2API_SetSkin( ghoul2, 0, handle );
|
||||
|
||||
// Read in the animations for this model
|
||||
trap_G2API_GetAnimFileNameIndex( ghoul2, 0, temp );
|
||||
BG_ParseAnimationFile ( va("%s_mp.cfg", temp), cg.hitAnimations );
|
||||
|
||||
// Hand the hit model back
|
||||
cg.hitModel = ghoul2;
|
||||
}
|
439
code/cgame/cg_public.h
Normal file
439
code/cgame/cg_public.h
Normal file
|
@ -0,0 +1,439 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_public.h --
|
||||
|
||||
/*
|
||||
==================================================================
|
||||
|
||||
functions imported from the main executable
|
||||
|
||||
==================================================================
|
||||
*/
|
||||
|
||||
#define CGAME_IMPORT_API_VERSION 4
|
||||
|
||||
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_FS_GETFILELIST,
|
||||
CG_SENDCONSOLECOMMAND,
|
||||
CG_ADDCOMMAND,
|
||||
CG_SENDCLIENTCOMMAND,
|
||||
CG_UPDATESCREEN,
|
||||
CG_RMG_INIT,
|
||||
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_STOPALLSOUNDS,
|
||||
CG_S_STARTLOCALSOUND,
|
||||
CG_S_CLEARLOOPINGSOUNDS,
|
||||
CG_S_ADDLOOPINGSOUND,
|
||||
CG_S_UPDATEENTITYPOSITION,
|
||||
CG_S_RESPATIALIZE,
|
||||
CG_S_REGISTERSOUND,
|
||||
CG_S_STARTBACKGROUNDTRACK,
|
||||
CG_AS_ADDPRECACHEENTRY,
|
||||
CG_AS_PARSESETS,
|
||||
CG_AS_UPDATEAMBIENTSET,
|
||||
CG_AS_ADDLOCALSET,
|
||||
CG_AS_GETBMODELSOUND,
|
||||
CG_R_LOADWORLDMAP,
|
||||
CG_R_REGISTERMODEL,
|
||||
CG_R_REGISTERSKIN,
|
||||
CG_R_REGISTERSHADER,
|
||||
CG_R_CLEARSCENE,
|
||||
CG_R_CLEARDECALS,
|
||||
CG_R_ADDREFENTITYTOSCENE,
|
||||
CG_R_ADDPOLYTOSCENE,
|
||||
CG_R_ADDDECALTOSCENE,
|
||||
CG_R_ADDLIGHTTOSCENE,
|
||||
CG_R_RENDERSCENE,
|
||||
CG_R_DRAWVISUALOVERLAY,
|
||||
CG_R_SETCOLOR,
|
||||
CG_R_DRAWSTRETCHPIC,
|
||||
CG_R_MODELBOUNDS,
|
||||
CG_R_LERPTAG,
|
||||
CG_R_DRAWROTATEPIC,
|
||||
CG_R_DRAWROTATEPIC2,
|
||||
CG_R_DRAWTEXT,
|
||||
CG_R_DRAWTEXTWITHCURSOR,
|
||||
CG_R_GETTEXTWIDTH,
|
||||
CG_R_GETTEXTHEIGHT,
|
||||
CG_GETGLCONFIG,
|
||||
CG_GETGAMESTATE,
|
||||
CG_GETCURRENTSNAPSHOTNUMBER,
|
||||
CG_GETSNAPSHOT,
|
||||
CG_GETDEFAULTSTATE,
|
||||
CG_GETSERVERCOMMAND,
|
||||
CG_GETCURRENTCMDNUMBER,
|
||||
CG_GETUSERCMD,
|
||||
CG_SETUSERCMDVALUE,
|
||||
CG_RW_SETTEAM,
|
||||
CG_RESETAUTORUN,
|
||||
CG_R_REGISTERSHADERNOMIP,
|
||||
CG_MEMORY_REMAINING,
|
||||
CG_R_REGISTERFONT,
|
||||
CG_KEY_ISDOWN,
|
||||
CG_KEY_GETCATCHER,
|
||||
CG_KEY_SETCATCHER,
|
||||
CG_KEY_GETKEY,
|
||||
CG_PC_ADD_GLOBAL_DEFINE,
|
||||
CG_PC_LOAD_SOURCE,
|
||||
CG_PC_FREE_SOURCE,
|
||||
CG_PC_READ_TOKEN,
|
||||
CG_PC_SOURCE_FILE_AND_LINE,
|
||||
CG_PC_LOAD_GLOBAL_DEFINES,
|
||||
CG_PC_REMOVE_ALL_GLOBAL_DEFINES,
|
||||
|
||||
CG_MEMSET = 100,
|
||||
CG_MEMCPY,
|
||||
CG_STRNCPY,
|
||||
CG_SIN,
|
||||
CG_COS,
|
||||
CG_ATAN2,
|
||||
CG_SQRT,
|
||||
CG_ANGLEVECTORS,
|
||||
CG_PERPENDICULARVECTOR,
|
||||
CG_FLOOR,
|
||||
CG_CEIL,
|
||||
CG_TESTPRINTINT,
|
||||
CG_TESTPRINTFLOAT,
|
||||
CG_ACOS,
|
||||
CG_ASIN,
|
||||
CG_MATRIXMULTIPLY,
|
||||
|
||||
|
||||
CG_SP_GETSTRINGTEXTSTRING,
|
||||
|
||||
CG_S_STOPBACKGROUNDTRACK,
|
||||
CG_REAL_TIME,
|
||||
CG_SNAPVECTOR,
|
||||
CG_REMOVECOMMAND,
|
||||
CG_R_LIGHTFORPOINT,
|
||||
CG_CIN_PLAYCINEMATIC,
|
||||
CG_CIN_STOPCINEMATIC,
|
||||
CG_CIN_RUNCINEMATIC,
|
||||
CG_CIN_DRAWCINEMATIC,
|
||||
CG_CIN_SETEXTENTS,
|
||||
CG_R_REMAP_SHADER,
|
||||
CG_R_GET_LIGHT_STYLE,
|
||||
CG_R_SET_LIGHT_STYLE,
|
||||
CG_FX_ADDLINE,
|
||||
CG_S_ADDREALLOOPINGSOUND,
|
||||
CG_S_STOPLOOPINGSOUND,
|
||||
|
||||
CG_CM_TEMPCAPSULEMODEL,
|
||||
CG_CM_CAPSULETRACE,
|
||||
CG_CM_TRANSFORMEDCAPSULETRACE,
|
||||
CG_R_ADDADDITIVELIGHTTOSCENE,
|
||||
CG_GET_ENTITY_TOKEN,
|
||||
CG_R_ADDPOLYSTOSCENE,
|
||||
CG_R_INPVS,
|
||||
|
||||
CG_FX_REGISTER_EFFECT,
|
||||
CG_FX_PLAY_SIMPLE_EFFECT,
|
||||
CG_FX_PLAY_EFFECT,
|
||||
CG_FX_PLAY_ENTITY_EFFECT,
|
||||
CG_FX_PLAY_SIMPLE_EFFECT_ID,
|
||||
CG_FX_PLAY_EFFECT_ID,
|
||||
CG_FX_PLAY_ENTITY_EFFECT_ID,
|
||||
CG_FX_PLAY_BOLTED_EFFECT_ID,
|
||||
CG_FX_ADD_SCHEDULED_EFFECTS,
|
||||
CG_FX_INIT_SYSTEM,
|
||||
CG_FX_FREE_SYSTEM,
|
||||
CG_FX_ADJUST_TIME,
|
||||
CG_FX_DRAW_2D_EFFECTS,
|
||||
CG_FX_RESET,
|
||||
|
||||
CG_G2_LISTBONES,
|
||||
CG_G2_LISTSURFACES,
|
||||
|
||||
CG_G2_ADDBOLT,
|
||||
CG_G2_SETBOLTON,
|
||||
CG_G2_REMOVEBOLT,
|
||||
CG_G2_ATTACHG2MODEL,
|
||||
CG_G2_DETACHG2MODEL,
|
||||
|
||||
CG_G2_HAVEWEGHOULMODELS,
|
||||
CG_G2_SETMODELS,
|
||||
CG_G2_GETBOLT,
|
||||
CG_G2_INITGHOUL2MODEL,
|
||||
CG_G2_CLEANMODELS,
|
||||
CG_G2_ANGLEOVERRIDE,
|
||||
CG_G2_PLAYANIM,
|
||||
CG_G2_GETANIM,
|
||||
CG_G2_SETSURFACEONOFF,
|
||||
CG_G2_SETROOTSURFACE,
|
||||
CG_G2_SETNEWORIGIN,
|
||||
CG_G2_GETGLANAME,
|
||||
CG_G2_COPYGHOUL2INSTANCE,
|
||||
CG_G2_COPYSPECIFICGHOUL2MODEL,
|
||||
CG_G2_DUPLICATEGHOUL2INSTANCE,
|
||||
CG_G2_REMOVEGHOUL2MODEL,
|
||||
CG_G2_ADDSKINGORE,
|
||||
CG_G2_CLEARSKINGORE,
|
||||
CG_G2_SETGHOUL2MODELFLAGS,
|
||||
CG_G2_GETGHOUL2MODELFLAGS,
|
||||
CG_G2_SETGHOUL2MODELFLAGSBYINDEX,
|
||||
CG_G2_GETGHOUL2MODELFLAGSBYINDEX,
|
||||
CG_G2_GETNUMMODELS,
|
||||
CG_G2_GETANIMFILENAMEINDEX,
|
||||
CG_G2_FINDBOLTINDEX,
|
||||
CG_G2_GETBOLTINDEX,
|
||||
|
||||
CG_G2_REGISTERSKIN,
|
||||
CG_G2_SETSKIN,
|
||||
CG_G2_COLLISIONDETECT,
|
||||
|
||||
CG_MAT_RESET,
|
||||
CG_MAT_CACHE,
|
||||
CG_MAT_GET_SOUND,
|
||||
CG_MAT_GET_DECAL,
|
||||
CG_MAT_GET_DECAL_SCALE,
|
||||
CG_MAT_GET_EFFECT,
|
||||
CG_MAT_GET_DEBRIS,
|
||||
CG_MAT_GET_DEBRIS_SCALE,
|
||||
|
||||
CG_CM_TM_CREATE,
|
||||
CG_CM_TM_ADDBUILDING,
|
||||
CG_CM_TM_ADDSPOT,
|
||||
CG_CM_TM_ADDTARGET,
|
||||
CG_CM_TM_UPLOAD,
|
||||
CG_CM_TM_CONVERT_POS,
|
||||
|
||||
// CGenericParser2 (void *) routines
|
||||
GP_PARSE,
|
||||
GP_PARSE_FILE,
|
||||
GP_CLEAN,
|
||||
GP_DELETE,
|
||||
GP_GET_BASE_PARSE_GROUP,
|
||||
|
||||
// CGPGroup (void *) routines
|
||||
GPG_GET_NAME,
|
||||
GPG_GET_NEXT,
|
||||
GPG_GET_INORDER_NEXT,
|
||||
GPG_GET_INORDER_PREVIOUS,
|
||||
GPG_GET_PAIRS,
|
||||
GPG_GET_INORDER_PAIRS,
|
||||
GPG_GET_SUBGROUPS,
|
||||
GPG_GET_INORDER_SUBGROUPS,
|
||||
GPG_FIND_SUBGROUP,
|
||||
GPG_FIND_PAIR,
|
||||
GPG_FIND_PAIRVALUE,
|
||||
|
||||
// CGPValue (void *) routines
|
||||
GPV_GET_NAME,
|
||||
GPV_GET_NEXT,
|
||||
GPV_GET_INORDER_NEXT,
|
||||
GPV_GET_INORDER_PREVIOUS,
|
||||
GPV_IS_LIST,
|
||||
GPV_GET_TOP_VALUE,
|
||||
GPV_GET_LIST,
|
||||
|
||||
CG_CM_REGISTER_TERRAIN,
|
||||
CG_RE_INIT_RENDERER_TERRAIN,
|
||||
|
||||
CG_SET_SHARED_BUFFER,
|
||||
|
||||
CG_VM_LOCALALLOC,
|
||||
CG_VM_LOCALALLOCUNALIGNED,
|
||||
CG_VM_LOCALTEMPALLOC,
|
||||
CG_VM_LOCALTEMPFREE,
|
||||
CG_VM_LOCALSTRINGALLOC,
|
||||
|
||||
CG_UI_SETACTIVEMENU,
|
||||
CG_UI_CLOSEALL,
|
||||
|
||||
} cgameImport_t;
|
||||
|
||||
|
||||
/*
|
||||
==================================================================
|
||||
|
||||
functions exported to the main executable
|
||||
|
||||
==================================================================
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CG_INIT,
|
||||
// void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
|
||||
// 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, map 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 );
|
||||
|
||||
CG_KEY_EVENT,
|
||||
// void (*CG_KeyEvent)( int key, qboolean down );
|
||||
|
||||
CG_MOUSE_EVENT,
|
||||
// void (*CG_MouseEvent)( int dx, int dy );
|
||||
CG_EVENT_HANDLING,
|
||||
// void (*CG_EventHandling)(int type);
|
||||
|
||||
CG_POINT_CONTENTS,
|
||||
|
||||
CG_GET_LERP_ORIGIN,
|
||||
// void CG_LerpOrigin(int num, vec3_t result);
|
||||
|
||||
CG_GET_LERP_ANGLES,
|
||||
CG_GET_MODEL_SCALE,
|
||||
CG_GET_GHOUL2,
|
||||
CG_GET_MODEL_LIST,
|
||||
|
||||
CG_CALC_LERP_POSITIONS,
|
||||
// void CG_CalcEntityLerpPositions(int num);
|
||||
|
||||
CG_TRACE,
|
||||
|
||||
CG_GET_ORIGIN, // int entnum, vec3_t origin
|
||||
CG_GET_ANGLES, // int entnum, vec3_t angle
|
||||
|
||||
CG_GET_ORIGIN_TRAJECTORY, // int entnum
|
||||
CG_GET_ANGLE_TRAJECTORY, // int entnum
|
||||
|
||||
CG_FX_CAMERASHAKE,
|
||||
|
||||
CG_MISC_ENT,
|
||||
|
||||
CG_MAP_CHANGE,
|
||||
|
||||
} cgameExport_t;
|
||||
|
||||
// CG_POINT_CONTENTS
|
||||
typedef struct
|
||||
{
|
||||
vec3_t mPoint; // input
|
||||
int mPassEntityNum; // input
|
||||
} TCGPointContents;
|
||||
|
||||
// CG_GET_LERP_ORIGIN
|
||||
// CG_GET_LERP_ANGLES
|
||||
// CG_GET_MODEL_SCALE
|
||||
typedef struct
|
||||
{
|
||||
int mEntityNum; // input
|
||||
vec3_t mPoint; // output
|
||||
} TCGVectorData;
|
||||
|
||||
// CG_TRACE
|
||||
typedef struct
|
||||
{
|
||||
trace_t mResult; // output
|
||||
vec3_t mStart, mMins, mMaxs, mEnd; // input
|
||||
int mSkipNumber, mMask; // input
|
||||
} TCGTrace;
|
||||
|
||||
// CG_FX_CAMERASHAKE
|
||||
typedef struct
|
||||
{
|
||||
vec3_t mOrigin; // input
|
||||
float mIntensity; // input
|
||||
int mRadius; // input
|
||||
int mTime; // input
|
||||
} TCGCameraShake;
|
||||
|
||||
// CG_MISC_ENT
|
||||
typedef struct
|
||||
{
|
||||
char mModel[MAX_QPATH]; // input
|
||||
vec3_t mOrigin, mAngles, mScale; // input
|
||||
} TCGMiscEnt;
|
||||
|
||||
/// CG_CM_TM_CONVERT_POS
|
||||
typedef struct
|
||||
{
|
||||
vec3_t mOrigin; // input
|
||||
int mWidth, mHeight; // input
|
||||
int mX, mY; // output
|
||||
} TCGConvertPos;
|
||||
|
||||
|
||||
#define MAX_CG_SHARED_BUFFER_SIZE 2048
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
enum {
|
||||
CGAME_EVENT_NONE,
|
||||
CGAME_EVENT_TEAMMENU,
|
||||
CGAME_EVENT_SCOREBOARD,
|
||||
CGAME_EVENT_EDITHUD
|
||||
};
|
||||
|
||||
//----------------------------------------------
|
521
code/cgame/cg_scoreboard.c
Normal file
521
code/cgame/cg_scoreboard.c
Normal file
|
@ -0,0 +1,521 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// cg_scoreboard -- draw the scoreboard on top of the game screen
|
||||
#include "cg_local.h"
|
||||
|
||||
|
||||
#define SB_HEADER 86
|
||||
#define SB_TOP (SB_HEADER+32)
|
||||
|
||||
// Where the status bar starts, so we don't overwrite it
|
||||
#define SB_STATUSBAR 420
|
||||
|
||||
#define SB_MAXCLIENTS_NORMAL 12
|
||||
#define SB_MAXCLIENTS_MORE 26
|
||||
#define SB_MAXCLIENTS_ALOT 32
|
||||
|
||||
// Used when interleaved
|
||||
#define SB_HEADER_WIDTH (580)
|
||||
#define SB_HEADER_HEIGHT 30
|
||||
#define SB_HEADER_X ((640-SB_HEADER_WIDTH)/2)
|
||||
#define SB_HEADER_Y 86
|
||||
#define SB_SCORELINE_X (SB_HEADER_X+30)
|
||||
#define SB_SCORELINE_Y 120
|
||||
#define SB_SCORELINE_WIDTH (SB_HEADER_WIDTH-60)
|
||||
#define SB_NAME_X (SB_SCORELINE_X)
|
||||
#define SB_SCORE_X (SB_SCORELINE_X+287)
|
||||
#define SB_KILLS_X (SB_SCORELINE_X+335)
|
||||
#define SB_DEATHS_X (SB_SCORELINE_X+384)
|
||||
#define SB_PING_X (SB_SCORELINE_X+440)
|
||||
#define SB_TIME_X (SB_SCORELINE_X+489)
|
||||
|
||||
int sb_lineHeight;
|
||||
int sb_maxClients;
|
||||
float sb_nameFontScale;
|
||||
float sb_numberFontScale;
|
||||
float sb_readyFontScale;
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawClientScore
|
||||
=================
|
||||
*/
|
||||
static void CG_DrawClientScore( float x, float y, float w, score_t* score, float* color )
|
||||
{
|
||||
clientInfo_t* ci;
|
||||
vec4_t dataColor;
|
||||
vec4_t nameColor;
|
||||
const char* s;
|
||||
float f;
|
||||
|
||||
nameColor[3] = dataColor[3] = 1.0f;
|
||||
|
||||
// Validate the score
|
||||
if ( score->client < 0 || score->client >= cgs.maxclients )
|
||||
{
|
||||
Com_Printf( "Bad score->client: %i\n", score->client );
|
||||
return;
|
||||
}
|
||||
|
||||
// Convienience
|
||||
ci = &cgs.clientinfo[score->client];
|
||||
|
||||
CG_DrawPic ( x - 5, y, w, sb_lineHeight, cgs.media.scoreboardLine );
|
||||
|
||||
// highlight your position
|
||||
if ( score->client == cg.snap->ps.clientNum )
|
||||
{
|
||||
vec4_t hcolor;
|
||||
|
||||
hcolor[0] = 1.0f;
|
||||
hcolor[1] = 1.0f;
|
||||
hcolor[2] = 1.0f;
|
||||
hcolor[3] = .10f;
|
||||
|
||||
CG_FillRect( x - 5, y, w, sb_lineHeight, hcolor );
|
||||
|
||||
VectorSet ( nameColor, 1.0f, 1.0f, 1.0f );
|
||||
VectorSet ( dataColor, 0.5f, 0.5f, 0.5f );
|
||||
}
|
||||
else if ( (cg.snap->ps.pm_type == PM_DEAD) && score->client == cg.snap->ps.persistant[PERS_ATTACKER] )
|
||||
{
|
||||
vec4_t hcolor;
|
||||
|
||||
hcolor[0] = 1.0f;
|
||||
hcolor[1] = 1.0f;
|
||||
hcolor[2] = 1.0f;
|
||||
hcolor[3] = .10f;
|
||||
|
||||
CG_FillRect( x - 5, y, w, sb_lineHeight, hcolor );
|
||||
|
||||
VectorCopy ( color, nameColor );
|
||||
VectorSet ( dataColor, 0.5f, 0.5f, 0.5f );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy ( color, nameColor );
|
||||
VectorSet ( dataColor, 0.3f, 0.3f, 0.3f );
|
||||
|
||||
if ( ci->ghost )
|
||||
{
|
||||
VectorScale ( nameColor, 0.6f, nameColor );
|
||||
}
|
||||
}
|
||||
|
||||
CG_DrawText( x, y, cgs.media.hudFont, sb_nameFontScale, nameColor, ci->name, 24, DT_OUTLINE );
|
||||
|
||||
s = va("%i", score->score );
|
||||
f = trap_R_GetTextWidth ( s, cgs.media.hudFont, sb_nameFontScale, 0 );
|
||||
CG_DrawText( x + w - 10 - f, y, cgs.media.hudFont, sb_nameFontScale, nameColor, va("%i", score->score), 0, DT_OUTLINE );
|
||||
|
||||
// Draw skull if dead and not in intermission
|
||||
if ( cg.snap->ps.pm_type == PM_INTERMISSION )
|
||||
{
|
||||
if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) )
|
||||
{
|
||||
vec3_t deadColor;
|
||||
deadColor[0] = 0.60f;
|
||||
deadColor[1] = 0.60f;
|
||||
deadColor[2] = 0.60f;
|
||||
deadColor[3] = 1.0f;
|
||||
CG_DrawText( x + w - 70, y + 3, cgs.media.hudFont, sb_readyFontScale, deadColor, "READY", 0, DT_OUTLINE );
|
||||
}
|
||||
}
|
||||
else if ( ci->ghost )
|
||||
{
|
||||
CG_DrawPic ( x + w - 70, y + 1, sb_numberFontScale * 0.8f, sb_numberFontScale * 0.8f, cgs.media.deadShader );
|
||||
}
|
||||
// Draw any gametype items the guy is carrying
|
||||
else
|
||||
{
|
||||
float xx = x + w - 70;
|
||||
int i;
|
||||
for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ )
|
||||
{
|
||||
centity_t* cent;
|
||||
|
||||
cent = CG_GetEntity ( score->client);
|
||||
|
||||
// No have item, no draw it
|
||||
if ( !(ci->gametypeitems & (1<<i) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !cg_items[MODELINDEX_GAMETYPE_ITEM+i].icon )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CG_DrawPic ( xx, y + 1, sb_numberFontScale * 0.8f, sb_numberFontScale * 0.8f, cg_items[MODELINDEX_GAMETYPE_ITEM+i].icon );
|
||||
|
||||
xx += sb_numberFontScale;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s = va("%i/%i", score->kills, score->deaths);
|
||||
f = trap_R_GetTextWidth ( s, cgs.media.hudFont, sb_readyFontScale, 0 );
|
||||
CG_DrawText( x + w - 10 - f, y + sb_numberFontScale, cgs.media.hudFont, sb_readyFontScale, dataColor, s, 0, 0 );
|
||||
|
||||
CG_DrawText( x, y + sb_numberFontScale, cgs.media.hudFont, sb_readyFontScale, dataColor, va("id: %i", score->client ), 0, 0 );
|
||||
CG_DrawText( x + 40, y + sb_numberFontScale, cgs.media.hudFont, sb_readyFontScale, dataColor, va("ping: %i", score->ping ), 0, 0 );
|
||||
CG_DrawText( x + 95, y + sb_numberFontScale, cgs.media.hudFont, sb_readyFontScale, dataColor, va("time: %i", score->time ), 0, 0 );
|
||||
|
||||
if ( score->teamkillDamage )
|
||||
{
|
||||
CG_DrawText( x + 150, y + sb_numberFontScale, cgs.media.hudFont, sb_readyFontScale, dataColor, va("tk: %i%%", score->teamkillDamage ), 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_TeamScoreboard
|
||||
=================
|
||||
*/
|
||||
static int CG_TeamScoreboard( float x, float y, float w, team_t team )
|
||||
{
|
||||
int i;
|
||||
int skipped;
|
||||
float color[4];
|
||||
int count;
|
||||
clientInfo_t *ci;
|
||||
const char* s;
|
||||
int players;
|
||||
qboolean drawnClient;
|
||||
|
||||
// Do we make sure the current client is drawn?
|
||||
drawnClient = qtrue;
|
||||
if ( cg.scores [ cg.snap->ps.clientNum ].team == team )
|
||||
{
|
||||
drawnClient = qfalse;
|
||||
}
|
||||
|
||||
// Determine the color for this team
|
||||
switch ( team )
|
||||
{
|
||||
case TEAM_RED:
|
||||
VectorCopy4 ( g_color_table[ColorIndex(COLOR_RED)], color );
|
||||
break;
|
||||
|
||||
case TEAM_BLUE:
|
||||
VectorCopy4 ( g_color_table[ColorIndex(COLOR_BLUE)], color );
|
||||
break;
|
||||
|
||||
case TEAM_FREE:
|
||||
VectorCopy4 ( g_color_table[ColorIndex(COLOR_GREEN)], color );
|
||||
break;
|
||||
|
||||
case TEAM_SPECTATOR:
|
||||
default:
|
||||
VectorCopy4 ( colorWhite, color );
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw as many clients as we can for this team
|
||||
for ( skipped = -1, count = 0, i = 0 ; i < cg.numScores && count < sb_maxClients ; i++ )
|
||||
{
|
||||
score_t* score;
|
||||
|
||||
score = &cg.scores[i];
|
||||
ci = &cgs.clientinfo[ score->client ];
|
||||
|
||||
if ( team != score->team )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( count == sb_maxClients - 1 && !drawnClient )
|
||||
{
|
||||
if ( score->client != cg.snap->ps.clientNum )
|
||||
{
|
||||
skipped = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
drawnClient = qtrue;
|
||||
}
|
||||
|
||||
CG_DrawClientScore( x, y + SB_HEADER_HEIGHT + sb_lineHeight * count, w, score, color );
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if ( skipped != -1 && count < sb_maxClients )
|
||||
{
|
||||
CG_DrawClientScore( x, y + SB_HEADER_HEIGHT + sb_lineHeight * count, w, &cg.scores[skipped], color );
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
s = "";
|
||||
switch ( team )
|
||||
{
|
||||
case TEAM_RED:
|
||||
s = "RED TEAM";
|
||||
players = ui_info_redcount.integer;
|
||||
break;
|
||||
|
||||
case TEAM_BLUE:
|
||||
s = "BLUE TEAM";
|
||||
players = ui_info_bluecount.integer;
|
||||
break;
|
||||
|
||||
case TEAM_FREE:
|
||||
s = "PLAYERS";
|
||||
players = ui_info_freecount.integer;
|
||||
break;
|
||||
|
||||
default:
|
||||
case TEAM_SPECTATOR:
|
||||
s = "SPECTATORS";
|
||||
players = ui_info_speccount.integer;
|
||||
break;
|
||||
}
|
||||
|
||||
// Use the same team color here, but alpha it a bit.
|
||||
color[3] = 0.6f;
|
||||
|
||||
// Draw the header information for this team
|
||||
CG_DrawPic ( x - 5, y, w, 25, cgs.media.scoreboardHeader );
|
||||
CG_FillRect( x - 5, y, w, 25, color );
|
||||
CG_DrawText ( x, y, cgs.media.hudFont, 0.40f, colorWhite, va("%s", s), 0, 0 );
|
||||
CG_DrawText ( x, y + 13, cgs.media.hudFont, 0.30f, colorWhite, va("players: %d", players), 0, 0 );
|
||||
|
||||
// Draw the totals if this is the red or blue team
|
||||
if ( (team == TEAM_RED || team == TEAM_BLUE))
|
||||
{
|
||||
const char* s;
|
||||
float f;
|
||||
|
||||
s = va("%d",(cg.teamScores[team-TEAM_RED]));
|
||||
f = trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.43f, 0 );
|
||||
CG_DrawText ( x + w - 10 - f, y, cgs.media.hudFont, 0.43f, colorWhite, s, 0, DT_OUTLINE );
|
||||
}
|
||||
|
||||
if ( count )
|
||||
{
|
||||
CG_DrawPic ( x - 5, y + SB_HEADER_HEIGHT + sb_lineHeight * count, w, sb_lineHeight, cgs.media.scoreboardFooter );
|
||||
}
|
||||
|
||||
y = count * sb_lineHeight + y + 10;
|
||||
|
||||
if ( y > cg.scoreBoardBottom )
|
||||
{
|
||||
cg.scoreBoardBottom = y;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawNormalScoreboard
|
||||
|
||||
Draws a scoreboard that has no teams
|
||||
=================
|
||||
*/
|
||||
qboolean CG_DrawNormalScoreboard ( float y )
|
||||
{
|
||||
cg.scoreBoardBottom = 0;
|
||||
|
||||
// DRaw the game timer and the game type
|
||||
CG_DrawText ( 385, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, "Game Time:", 0, DT_OUTLINE );
|
||||
CG_DrawTimer ( 455, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, DT_OUTLINE, cg.time - cgs.levelStartTime );
|
||||
CG_DrawText ( 150, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, cgs.gametypeData->displayName, 0, DT_OUTLINE );
|
||||
|
||||
if ( ui_info_speccount.integer )
|
||||
{
|
||||
CG_FillRect ( 0, 470, 640, 10, colorBlack );
|
||||
CG_DrawText ( 5, 470, cgs.media.hudFont, 0.30f, colorWhite, va("SPECTATORS: %s", cg.scoreBoardSpectators), 0, 0 );
|
||||
}
|
||||
|
||||
if ( ui_info_freecount.integer > 10 )
|
||||
{
|
||||
sb_maxClients = 16;
|
||||
sb_lineHeight = 20;
|
||||
sb_nameFontScale = 0.35f;
|
||||
sb_readyFontScale = 0.30f;
|
||||
sb_numberFontScale = trap_R_GetTextHeight ( "W", cgs.media.hudFont, sb_nameFontScale, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_maxClients = 10;
|
||||
sb_lineHeight = 30;
|
||||
sb_nameFontScale = 0.43f;
|
||||
sb_readyFontScale = 0.30f;
|
||||
sb_numberFontScale = trap_R_GetTextHeight ( "W", cgs.media.hudFont, sb_nameFontScale, 0 ) + 4;
|
||||
}
|
||||
|
||||
CG_TeamScoreboard ( 150, y, 350, TEAM_FREE );
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawTeamScoreboard
|
||||
|
||||
Draw the normal in-game scoreboard
|
||||
=================
|
||||
*/
|
||||
qboolean CG_DrawTeamScoreboard( float y )
|
||||
{
|
||||
qboolean redFirst = qfalse;
|
||||
|
||||
cg.scoreBoardBottom = 0;
|
||||
|
||||
// DRaw the game timer and the game type
|
||||
CG_DrawText ( 470, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, "Game Time:", 0, DT_OUTLINE );
|
||||
CG_DrawTimer ( 540, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, DT_OUTLINE, cg.time - cgs.levelStartTime );
|
||||
CG_DrawText ( 60, y - 14, cgs.media.hudFont, 0.38f, colorLtGrey, cgs.gametypeData->displayName, 0, DT_OUTLINE );
|
||||
|
||||
if ( ui_info_speccount.integer )
|
||||
{
|
||||
CG_FillRect ( 0, 470, 640, 10, colorBlack );
|
||||
CG_DrawText ( 5, 470, cgs.media.hudFont, 0.30f, colorWhite, va("SPECTATORS: %s", cg.scoreBoardSpectators), 0, 0 );
|
||||
}
|
||||
|
||||
if ( ui_info_redcount.integer > 10 || ui_info_bluecount.integer > 10 )
|
||||
{
|
||||
sb_maxClients = 16;
|
||||
sb_lineHeight = 20;
|
||||
sb_nameFontScale = 0.35f;
|
||||
sb_readyFontScale = 0.30f;
|
||||
sb_numberFontScale = trap_R_GetTextHeight ( "W", cgs.media.hudFont, sb_nameFontScale, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_maxClients = 10;
|
||||
sb_lineHeight = 30;
|
||||
sb_nameFontScale = 0.43f;
|
||||
sb_readyFontScale = 0.30f;
|
||||
sb_numberFontScale = trap_R_GetTextHeight ( "W", cgs.media.hudFont, sb_nameFontScale, 0 ) + 4;
|
||||
}
|
||||
|
||||
// If there are more scores than the scoreboard can show then show the
|
||||
// players team first rather than the winning team
|
||||
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR )
|
||||
{
|
||||
if ( cg.teamScores[0] >= cg.teamScores[1] )
|
||||
{
|
||||
redFirst = qtrue;
|
||||
}
|
||||
}
|
||||
else if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED )
|
||||
{
|
||||
redFirst = qtrue;
|
||||
}
|
||||
|
||||
if ( redFirst )
|
||||
{
|
||||
CG_TeamScoreboard( 50, y, 265, TEAM_RED );
|
||||
CG_TeamScoreboard( 330, y, 265, TEAM_BLUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_TeamScoreboard( 330, y, 265, TEAM_RED );
|
||||
CG_TeamScoreboard( 50, y, 265, TEAM_BLUE );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawScoreboard
|
||||
|
||||
Draws either a team or a normal scoreboard
|
||||
=================
|
||||
*/
|
||||
qboolean CG_DrawScoreboard ( void )
|
||||
{
|
||||
float y;
|
||||
float w;
|
||||
|
||||
// don't draw amuthing if the menu or console is up
|
||||
if ( cg_paused.integer )
|
||||
{
|
||||
cg.deferredPlayerLoading = 0;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// don't draw scoreboard during death while warmup up
|
||||
if ( cg.warmup && !cg.showScores )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( !cg.showScores &&
|
||||
cg.predictedPlayerState.pm_type != PM_DEAD &&
|
||||
cg.predictedPlayerState.pm_type != PM_INTERMISSION )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// scoreboard
|
||||
y = 45;
|
||||
|
||||
if ( cgs.gametypeData->teams )
|
||||
{
|
||||
if ( ui_info_redcount.integer < 10 && ui_info_bluecount.integer < 10 )
|
||||
{
|
||||
y += 50;
|
||||
}
|
||||
}
|
||||
else if ( ui_info_freecount.integer < 10 )
|
||||
{
|
||||
y += 50;
|
||||
}
|
||||
|
||||
// Draw any gameover text
|
||||
if ( cgs.gameover[0] )
|
||||
{
|
||||
w = trap_R_GetTextWidth ( cgs.gameover, cgs.media.hudFont, 0.48f, 0 );
|
||||
CG_DrawText ( 320 - w / 2, y - 30, cgs.media.hudFont, 0.48f, colorWhite, cgs.gameover, 0, DT_OUTLINE );
|
||||
}
|
||||
else if ( cgs.gametypeMessageTime > cg.time )
|
||||
{
|
||||
w = trap_R_GetTextWidth ( cgs.gametypeMessage, cgs.media.hudFont, 0.48f, 0 );
|
||||
CG_DrawText ( 320 - w / 2, y - 30, cgs.media.hudFont, 0.48f, colorWhite, cgs.gametypeMessage, 0, DT_OUTLINE );
|
||||
}
|
||||
// Should we draw who killed you?
|
||||
else if ( cg.snap->ps.pm_type == PM_DEAD &&
|
||||
cg.snap->ps.persistant[PERS_ATTACKER] < MAX_CLIENTS &&
|
||||
cg.snap->ps.persistant[PERS_ATTACKER] != cg.snap->ps.clientNum )
|
||||
{
|
||||
const char* s;
|
||||
s = va("Killed by %s", cgs.clientinfo[cg.snap->ps.persistant[PERS_ATTACKER]].name );
|
||||
w = trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.48f, 0 );
|
||||
CG_DrawText ( 320 - w / 2, y - 30, cgs.media.hudFont, 0.48f, colorWhite, s, 0, DT_OUTLINE );
|
||||
}
|
||||
else if ( cgs.gametypeData->teams )
|
||||
{
|
||||
const char* s;
|
||||
if ( cg.teamScores[0] == cg.teamScores[1] )
|
||||
{
|
||||
s = va ( "Game Tied at %d", cg.teamScores[0] );
|
||||
}
|
||||
else if ( cg.teamScores[0] > cg.teamScores[1] )
|
||||
{
|
||||
s = va ( "Red leads Blue by %d", cg.teamScores[0] - cg.teamScores[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
s = va ( "Blue leads Red by %d", cg.teamScores[1] - cg.teamScores[0] );
|
||||
}
|
||||
|
||||
w = trap_R_GetTextWidth ( s, cgs.media.hudFont, 0.48f, 0 );
|
||||
CG_DrawText ( 320 - w / 2, y - 30, cgs.media.hudFont, 0.48f, colorWhite, s, 0, DT_OUTLINE );
|
||||
}
|
||||
|
||||
// load any models that have been deferred
|
||||
cg.deferredPlayerLoading++;
|
||||
|
||||
if ( cgs.gametypeData->teams )
|
||||
{
|
||||
return CG_DrawTeamScoreboard ( y );
|
||||
}
|
||||
|
||||
return CG_DrawNormalScoreboard ( y );
|
||||
}
|
1052
code/cgame/cg_servercmds.c
Normal file
1052
code/cgame/cg_servercmds.c
Normal file
File diff suppressed because it is too large
Load diff
503
code/cgame/cg_snapshot.c
Normal file
503
code/cgame/cg_snapshot.c
Normal file
|
@ -0,0 +1,503 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// 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 the previous snapshot this entity was updated in is at least
|
||||
// an event window back in time then we can reset the previous event
|
||||
if ( cent->snapShotTime < cg.time - EVENT_VALID_MSEC )
|
||||
{
|
||||
cent->previousEvent = 0;
|
||||
}
|
||||
|
||||
cent->trailTime = cg.snap->serverTime;
|
||||
|
||||
VectorCopy (cent->currentState.origin, cent->lerpOrigin);
|
||||
VectorCopy (cent->currentState.angles, cent->lerpAngles);
|
||||
if ( cent->currentState.eType == ET_PLAYER )
|
||||
{
|
||||
CG_ResetPlayerEntity( cent );
|
||||
}
|
||||
|
||||
cent->pe.weapon = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_TransitionEntity
|
||||
|
||||
cent->nextState is moved to cent->currentState and events are fired
|
||||
===============
|
||||
*/
|
||||
static void CG_TransitionEntity( centity_t *cent )
|
||||
{
|
||||
cent->currentState = cent->nextState;
|
||||
cent->currentValid = qtrue;
|
||||
|
||||
// reset if the entity wasn't in the last frame or was teleported
|
||||
if ( !cent->interpolate ) {
|
||||
CG_ResetEntity( cent );
|
||||
}
|
||||
|
||||
// Time is overloaded for players to store the spawn count, so when a player is newly spawned
|
||||
// their gore should be reset
|
||||
if ( cent->pe.spawnCount != cent->currentState.time )
|
||||
{
|
||||
cent->pe.spawnCount = cent->currentState.time;
|
||||
|
||||
// Force all the animations to be restarted
|
||||
cent->pe.torso.anim = -1;
|
||||
cent->pe.legs.anim = -1;
|
||||
|
||||
if ( cent->ghoul2 )
|
||||
{
|
||||
trap_G2API_ClearSkinGore ( cent->ghoul2 );
|
||||
}
|
||||
}
|
||||
|
||||
// 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 map 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;
|
||||
|
||||
cent = CG_GetEntity ( snap->ps.clientNum );
|
||||
|
||||
if (!cgs.clientinfo[snap->ps.clientNum].ghoul2Model)
|
||||
{
|
||||
Com_Error(ERR_DROP, "CG_SetInitialSnapshot invalid g2 pointer for client\n");
|
||||
}
|
||||
|
||||
if ((cent->ghoul2 == NULL) && trap_G2_HaveWeGhoul2Models(cgs.clientinfo[snap->ps.clientNum].ghoul2Model))
|
||||
{
|
||||
trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[snap->ps.clientNum].ghoul2Model, ¢->ghoul2);
|
||||
}
|
||||
|
||||
BG_PlayerStateToEntityState( &snap->ps, ¢->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_GetEntity ( state->number );
|
||||
|
||||
memcpy(¢->currentState, state, sizeof(entityState_t));
|
||||
//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 )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_TransitionSnapshot: NULL cg.snap" );
|
||||
}
|
||||
|
||||
if ( !cg.nextSnap )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_TransitionSnapshot: NULL cg.nextSnap" );
|
||||
}
|
||||
|
||||
// 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_GetEntity ( cg.snap->entities[ i ].number );
|
||||
cent->currentValid = qfalse;
|
||||
}
|
||||
|
||||
// move nextSnap to snap and do the transitions
|
||||
oldFrame = cg.snap;
|
||||
cg.snap = cg.nextSnap;
|
||||
|
||||
cent = CG_GetEntity ( cg.snap->ps.clientNum );
|
||||
BG_PlayerStateToEntityState( &cg.snap->ps, ¢->currentState, qfalse );
|
||||
cent->interpolate = qfalse;
|
||||
cent->currentValid = qtrue;
|
||||
|
||||
for ( i = 0 ; i < cg.snap->numEntities ; i++ )
|
||||
{
|
||||
// Transition the entity
|
||||
cent = CG_GetEntity ( cg.snap->entities[ i ].number );
|
||||
CG_TransitionEntity( cent );
|
||||
|
||||
// remember time of snapshot this entity was last updated in
|
||||
cent->snapShotTime = cg.snap->serverTime;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
cent = CG_GetEntity ( snap->ps.clientNum );
|
||||
|
||||
BG_PlayerStateToEntityState( &snap->ps, ¢->nextState, qfalse );
|
||||
cent->interpolate = qtrue;
|
||||
|
||||
// check for extrapolation errors
|
||||
for ( num = 0 ; num < snap->numEntities ; num++ )
|
||||
{
|
||||
es = &snap->entities[num];
|
||||
cent = CG_GetEntity ( es->number );
|
||||
|
||||
memcpy(¢->nextState, es, sizeof(entityState_t));
|
||||
//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 ) {
|
||||
Com_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];
|
||||
}
|
||||
*/
|
||||
dest = &cg.activeSnapshots[cg.activeSnapshot%3];
|
||||
|
||||
// try to read the snapshot from the client system
|
||||
cgs.processedSnapshotNum++;
|
||||
r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
|
||||
|
||||
// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
|
||||
if ( cg.nextSnap && r && dest->serverTime == cg.nextSnap->serverTime ) {
|
||||
// r = r;
|
||||
// continue;
|
||||
}
|
||||
|
||||
// if it succeeded, return
|
||||
if ( r ) {
|
||||
cg.activeSnapshot++;
|
||||
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
|
||||
Com_Error( ERR_FATAL, "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 || cg.needNextSnap ) // !cg.nextSnap )
|
||||
{
|
||||
snap = CG_ReadNextSnapshot();
|
||||
|
||||
// if we still don't have a nextframe, we will just have to
|
||||
// extrapolate
|
||||
if ( !snap )
|
||||
{
|
||||
if ( cg_drawSnapshot.integer )
|
||||
Com_Printf ( "NOSNAP\n" );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _SNAPSHOT_EXTRAPOLATION
|
||||
|
||||
cg.needNextSnap = qfalse;
|
||||
|
||||
if ( cg.nextSnap)
|
||||
{
|
||||
if ( cg_drawSnapshot.integer )
|
||||
Com_Printf ( "TRANS\n" );
|
||||
|
||||
CG_TransitionSnapshot();
|
||||
}
|
||||
#endif
|
||||
|
||||
CG_SetNextSnap( snap );
|
||||
|
||||
|
||||
// if time went backwards, we have a level restart
|
||||
if ( cg.nextSnap->serverTime < cg.snap->serverTime )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_ProcessSnapshots: Server time went backwards" );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _SNAPSHOT_EXTRAPOLATION
|
||||
|
||||
if ( cg.needNextSnap )
|
||||
{
|
||||
if ( cg_drawSnapshot.integer )
|
||||
Com_Printf ( "NEED\n" );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// if our time is < nextFrame's, we have a nice interpolating state
|
||||
if ( cg.time >= cg.snap->serverTime && cg.time < cg.nextSnap->serverTime )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _SNAPSHOT_EXTRAPOLATION
|
||||
|
||||
cg.needNextSnap = qtrue;
|
||||
|
||||
if ( cg_drawSnapshot.integer )
|
||||
Com_Printf ( "SNAP: time=%i\n", cg.time );
|
||||
|
||||
#else
|
||||
// we have passed the transition from nextFrame to frame
|
||||
CG_TransitionSnapshot();
|
||||
#endif
|
||||
|
||||
} while ( 1 );
|
||||
|
||||
// assert our valid conditions upon exiting
|
||||
if ( cg.snap == NULL )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_ProcessSnapshots: cg.snap == NULL" );
|
||||
}
|
||||
|
||||
if ( cg.time < cg.snap->serverTime )
|
||||
{
|
||||
// this can happen right after a vid_restart
|
||||
cg.time = cg.snap->serverTime;
|
||||
}
|
||||
|
||||
#ifndef _SNAPSHOT_EXTRAPOLATION
|
||||
if ( cg.nextSnap != NULL && cg.nextSnap->serverTime <= cg.time )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_ProcessSnapshots: cg.nextSnap->serverTime <= cg.time" );
|
||||
}
|
||||
#endif
|
||||
}
|
229
code/cgame/cg_syscalls.asm
Normal file
229
code/cgame/cg_syscalls.asm
Normal file
|
@ -0,0 +1,229 @@
|
|||
code
|
||||
|
||||
equ trap_Print -1 ; CG_PRINT
|
||||
equ trap_Error -2 ; CG_ERROR
|
||||
equ trap_Milliseconds -3 ; CG_MILLISECONDS
|
||||
equ trap_Cvar_Register -4 ; CG_CVAR_REGISTER
|
||||
equ trap_Cvar_Update -5 ; CG_CVAR_UPDATE
|
||||
equ trap_Cvar_Set -6 ; CG_CVAR_SET
|
||||
equ trap_Cvar_VariableStringBuffer -7 ; CG_CVAR_VARIABLESTRINGBUFFER
|
||||
equ trap_Argc -8 ; CG_ARGC
|
||||
equ trap_Argv -9 ; CG_ARGV
|
||||
equ trap_Args -10 ; CG_ARGS
|
||||
equ trap_FS_FOpenFile -11 ; CG_FS_FOPENFILE
|
||||
equ trap_FS_Read -12 ; CG_FS_READ
|
||||
equ trap_FS_Write -13 ; CG_FS_WRITE
|
||||
equ trap_FS_FCloseFile -14 ; CG_FS_FCLOSEFILE
|
||||
equ trap_SendConsoleCommand -16 ; CG_SENDCONSOLECOMMAND
|
||||
equ trap_AddCommand -17 ; CG_ADDCOMMAND
|
||||
equ trap_RemoveCommand -121 ; CG_REMOVECOMMAND
|
||||
equ trap_SendClientCommand -18 ; CG_SENDCLIENTCOMMAND
|
||||
equ trap_UpdateScreen -19 ; CG_UPDATESCREEN
|
||||
equ trap_RMG_Init -20 ; CG_RMG_INIT
|
||||
equ trap_CM_LoadMap -21 ; CG_CM_LOADMAP
|
||||
equ trap_CM_NumInlineModels -22 ; CG_CM_NUMINLINEMODELS
|
||||
equ trap_CM_InlineModel -23 ; CG_CM_INLINEMODEL
|
||||
equ trap_CM_TempBoxModel -25 ; CG_CM_TEMPBOXMODEL
|
||||
equ trap_CM_TempCapsuleModel -134 ; CG_CM_TEMPCAPSULEMODEL
|
||||
equ trap_CM_PointContents -26 ; CG_CM_POINTCONTENTS
|
||||
equ trap_CM_TransformedPointContents -27 ; CG_CM_TRANSFORMEDPOINTCONTENTS
|
||||
equ trap_CM_BoxTrace -28 ; CG_CM_BOXTRACE
|
||||
equ trap_CM_CapsuleTrace -135 ; CG_CM_CAPSULETRACE
|
||||
equ trap_CM_TransformedBoxTrace -29 ; CG_CM_TRANSFORMEDBOXTRACE
|
||||
equ trap_CM_TransformedCapsuleTrace -136 ; CG_CM_TRANSFORMEDCAPSULETRACE
|
||||
equ trap_CM_MarkFragments -30 ; CG_CM_MARKFRAGMENTS
|
||||
equ trap_S_StopAllSounds -32 ; CG_S_STOPALLSOUNDS
|
||||
equ trap_S_StartSound -31 ; CG_S_STARTSOUND
|
||||
equ trap_S_StartLocalSound -33 ; CG_S_STARTLOCALSOUND
|
||||
equ trap_S_ClearLoopingSounds -34 ; CG_S_CLEARLOOPINGSOUNDS
|
||||
equ trap_S_AddLoopingSound -35 ; CG_S_ADDLOOPINGSOUND
|
||||
equ trap_S_AddRealLoopingSound -132 ; CG_S_ADDREALLOOPINGSOUND
|
||||
equ trap_S_StopLoopingSound -133 ; CG_S_STOPLOOPINGSOUND
|
||||
equ trap_S_UpdateEntityPosition -36 ; CG_S_UPDATEENTITYPOSITION
|
||||
equ trap_S_Respatialize -37 ; CG_S_RESPATIALIZE
|
||||
equ trap_S_RegisterSound -38 ; CG_S_REGISTERSOUND
|
||||
equ trap_S_StartBackgroundTrack -39 ; CG_S_STARTBACKGROUNDTRACK
|
||||
equ trap_AS_AddPrecacheEntry -40 ; CG_AS_ADDPRECACHEENTRY
|
||||
equ trap_AS_ParseSets -41 ; CG_AS_PARSESETS
|
||||
equ trap_AS_UpdateAmbientSet -42 ; CG_AS_UPDATEAMBIENTSET
|
||||
equ trap_AS_AddLocalSet -43 ; CG_AS_ADDLOCALSET
|
||||
equ trap_AS_GetBModelSound -44 ; CG_AS_GETBMODELSOUND
|
||||
equ trap_R_LoadWorldMap -45 ; CG_R_LOADWORLDMAP
|
||||
equ trap_R_RegisterModel -46 ; CG_R_REGISTERMODEL
|
||||
equ trap_R_RegisterSkin -47 ; CG_R_REGISTERSKIN
|
||||
equ trap_R_RegisterShader -48 ; CG_R_REGISTERSHADER
|
||||
equ trap_R_RegisterShaderNoMip -78 ; CG_R_REGISTERSHADERNOMIP
|
||||
equ trap_R_RegisterFont -80 ; CG_R_REGISTERFONT
|
||||
equ trap_R_ClearScene -49 ; CG_R_CLEARSCENE
|
||||
equ trap_R_ClearDecals -50 ; CG_R_CLEARDECALS
|
||||
equ trap_R_AddRefEntityToScene -51 ; CG_R_ADDREFENTITYTOSCENE
|
||||
equ trap_R_AddPolyToScene -52 ; CG_R_ADDPOLYTOSCENE
|
||||
equ trap_R_AddDecalToScene -53 ; CG_R_ADDDECALTOSCENE
|
||||
equ trap_R_AddPolysToScene -139 ; CG_R_ADDPOLYSTOSCENE
|
||||
equ trap_R_LightForPoint -122 ; CG_R_LIGHTFORPOINT
|
||||
equ trap_R_AddLightToScene -54 ; CG_R_ADDLIGHTTOSCENE
|
||||
equ trap_R_AddAdditiveLightToScene -137 ; CG_R_ADDADDITIVELIGHTTOSCENE
|
||||
equ trap_R_RenderScene -55 ; CG_R_RENDERSCENE
|
||||
equ trap_R_DrawVisualOverlay -56 ; CG_R_DRAWVISUALOVERLAY
|
||||
equ trap_R_SetColor -57 ; CG_R_SETCOLOR
|
||||
equ trap_R_DrawStretchPic -58 ; CG_R_DRAWSTRETCHPIC
|
||||
equ trap_R_ModelBounds -59 ; CG_R_MODELBOUNDS
|
||||
equ trap_R_LerpTag -60 ; CG_R_LERPTAG
|
||||
equ trap_R_DrawRotatePic -61 ; CG_R_DRAWROTATEPIC
|
||||
equ trap_R_DrawRotatePic2 -62 ; CG_R_DRAWROTATEPIC2
|
||||
equ trap_R_RemapShader -128 ; CG_R_REMAP_SHADER
|
||||
equ trap_R_GetLightStyle -129 ; CG_R_GET_LIGHT_STYLE
|
||||
equ trap_R_SetLightStyle -130 ; CG_R_SET_LIGHT_STYLE
|
||||
equ trap_R_GetTextWidth -65 ; CG_R_GETTEXTWIDTH
|
||||
equ trap_R_GetTextHeight -66 ; CG_R_GETTEXTHEIGHT
|
||||
equ trap_R_DrawText -63 ; CG_R_DRAWTEXT
|
||||
equ trap_R_DrawTextWithCursor -64 ; CG_R_DRAWTEXTWITHCURSOR
|
||||
equ trap_FX_AddLine -131 ; CG_FX_ADDLINE
|
||||
equ trap_GetGlconfig -67 ; CG_GETGLCONFIG
|
||||
equ trap_GetGameState -68 ; CG_GETGAMESTATE
|
||||
equ trap_GetCurrentSnapshotNumber -69 ; CG_GETCURRENTSNAPSHOTNUMBER
|
||||
equ trap_GetSnapshot -70 ; CG_GETSNAPSHOT
|
||||
equ trap_GetDefaultState -71 ; CG_GETDEFAULTSTATE
|
||||
equ trap_GetServerCommand -72 ; CG_GETSERVERCOMMAND
|
||||
equ trap_GetCurrentCmdNumber -73 ; CG_GETCURRENTCMDNUMBER
|
||||
equ trap_GetUserCmd -74 ; CG_GETUSERCMD
|
||||
equ trap_SetUserCmdValue -75 ; CG_SETUSERCMDVALUE
|
||||
equ trap_RW_SetTeam -76 ; CG_RW_SETTEAM
|
||||
equ trap_ResetAutorun -77 ; CG_RESETAUTORUN
|
||||
equ trap_MemoryRemaining -79 ; CG_MEMORY_REMAINING
|
||||
equ trap_Key_IsDown -81 ; CG_KEY_ISDOWN
|
||||
equ trap_Key_GetCatcher -82 ; CG_KEY_GETCATCHER
|
||||
equ trap_Key_SetCatcher -83 ; CG_KEY_SETCATCHER
|
||||
equ trap_Key_GetKey -84 ; CG_KEY_GETKEY
|
||||
equ trap_PC_AddGlobalDefine -85 ; CG_PC_ADD_GLOBAL_DEFINE
|
||||
equ trap_PC_LoadSource -86 ; CG_PC_LOAD_SOURCE
|
||||
equ trap_PC_FreeSource -87 ; CG_PC_FREE_SOURCE
|
||||
equ trap_PC_ReadToken -88 ; CG_PC_READ_TOKEN
|
||||
equ trap_PC_SourceFileAndLine -89 ; CG_PC_SOURCE_FILE_AND_LINE
|
||||
equ trap_PC_LoadGlobalDefines -90 ; CG_PC_LOAD_GLOBAL_DEFINES
|
||||
equ trap_PC_RemoveAllGlobalDefines -91 ; CG_PC_REMOVE_ALL_GLOBAL_DEFINES
|
||||
equ trap_S_StopBackgroundTrack -118 ; CG_S_STOPBACKGROUNDTRACK
|
||||
equ trap_RealTime -119 ; CG_REAL_TIME
|
||||
equ trap_SnapVector -120 ; CG_SNAPVECTOR
|
||||
equ trap_CIN_PlayCinematic -123 ; CG_CIN_PLAYCINEMATIC
|
||||
equ trap_CIN_StopCinematic -124 ; CG_CIN_STOPCINEMATIC
|
||||
equ trap_CIN_RunCinematic -125 ; CG_CIN_RUNCINEMATIC
|
||||
equ trap_CIN_DrawCinematic -126 ; CG_CIN_DRAWCINEMATIC
|
||||
equ trap_CIN_SetExtents -127 ; CG_CIN_SETEXTENTS
|
||||
equ trap_GetEntityToken -138 ; CG_GET_ENTITY_TOKEN
|
||||
equ trap_R_inPVS -140 ; CG_R_INPVS
|
||||
equ trap_FX_RegisterEffect -141 ; CG_FX_REGISTER_EFFECT
|
||||
equ trap_FX_PlaySimpleEffect -142 ; CG_FX_PLAY_SIMPLE_EFFECT
|
||||
equ trap_FX_PlayEffect -143 ; CG_FX_PLAY_EFFECT
|
||||
equ trap_FX_PlayEntityEffect -144 ; CG_FX_PLAY_ENTITY_EFFECT
|
||||
equ trap_FX_PlaySimpleEffectID -145 ; CG_FX_PLAY_SIMPLE_EFFECT_ID
|
||||
equ trap_FX_PlayEffectID -146 ; CG_FX_PLAY_EFFECT_ID
|
||||
equ trap_FX_PlayEntityEffectID -147 ; CG_FX_PLAY_ENTITY_EFFECT_ID
|
||||
equ trap_FX_PlayBoltedEffectID -148 ; CG_FX_PLAY_BOLTED_EFFECT_ID
|
||||
equ trap_FX_AddScheduledEffects -149 ; CG_FX_ADD_SCHEDULED_EFFECTS
|
||||
equ trap_FX_Draw2DEffects -153 ; CG_FX_DRAW_2D_EFFECTS
|
||||
equ trap_FX_InitSystem -150 ; CG_FX_INIT_SYSTEM
|
||||
equ trap_FX_FreeSystem -151 ; CG_FX_FREE_SYSTEM
|
||||
equ trap_FX_Reset -154 ; CG_FX_RESET
|
||||
equ trap_FX_AdjustTime -152 ; CG_FX_ADJUST_TIME
|
||||
equ trap_G2_ListModelSurfaces -156 ; CG_G2_LISTSURFACES
|
||||
equ trap_G2_ListModelBones -155 ; CG_G2_LISTBONES
|
||||
equ trap_G2_SetGhoul2ModelIndexes -163 ; CG_G2_SETMODELS
|
||||
equ trap_G2API_CollisionDetect -190 ; CG_G2_COLLISIONDETECT
|
||||
equ trap_G2API_AddBolt -157 ; CG_G2_ADDBOLT
|
||||
equ trap_G2API_SetBoltInfo -158 ; CG_G2_SETBOLTON
|
||||
equ trap_G2API_RemoveBolt -159 ; CG_G2_REMOVEBOLT
|
||||
equ trap_G2API_AttachG2Model -160 ; CG_G2_ATTACHG2MODEL
|
||||
equ trap_G2API_DetachG2Model -161 ; CG_G2_DETACHG2MODEL
|
||||
equ trap_G2_HaveWeGhoul2Models -162 ; CG_G2_HAVEWEGHOULMODELS
|
||||
equ trap_G2API_GetBoltMatrix -164 ; CG_G2_GETBOLT
|
||||
equ trap_G2API_InitGhoul2Model -165 ; CG_G2_INITGHOUL2MODEL
|
||||
equ trap_G2API_GetAnimFileNameIndex -185 ; CG_G2_GETANIMFILENAMEINDEX
|
||||
equ trap_G2API_RegisterSkin -188 ; CG_G2_REGISTERSKIN
|
||||
equ trap_G2API_SetSkin -189 ; CG_G2_SETSKIN
|
||||
equ trap_G2API_CleanGhoul2Models -166 ; CG_G2_CLEANMODELS
|
||||
equ trap_G2API_SetBoneAngles -167 ; CG_G2_ANGLEOVERRIDE
|
||||
equ trap_G2API_SetBoneAnim -168 ; CG_G2_PLAYANIM
|
||||
equ trap_G2API_GetBoneAnim -169 ; CG_G2_GETANIM
|
||||
equ trap_G2API_SetSurfaceOnOff -170 ; CG_G2_SETSURFACEONOFF
|
||||
equ trap_G2API_SetRootSurface -171 ; CG_G2_SETROOTSURFACE
|
||||
equ trap_G2API_SetNewOrigin -172 ; CG_G2_SETNEWORIGIN
|
||||
equ trap_G2API_GetGLAName -173 ; CG_G2_GETGLANAME
|
||||
equ trap_G2API_CopyGhoul2Instance -174 ; CG_G2_COPYGHOUL2INSTANCE
|
||||
equ trap_G2API_CopySpecificGhoul2Model -175 ; CG_G2_COPYSPECIFICGHOUL2MODEL
|
||||
equ trap_G2API_DuplicateGhoul2Instance -176 ; CG_G2_DUPLICATEGHOUL2INSTANCE
|
||||
equ trap_G2API_RemoveGhoul2Model -177 ; CG_G2_REMOVEGHOUL2MODEL
|
||||
equ trap_G2API_AddSkinGore -178 ; CG_G2_ADDSKINGORE
|
||||
equ trap_G2API_ClearSkinGore -179 ; CG_G2_CLEARSKINGORE
|
||||
equ trap_G2API_SetGhoul2ModelFlags -180 ; CG_G2_SETGHOUL2MODELFLAGS
|
||||
equ trap_G2API_GetGhoul2ModelFlags -181 ; CG_G2_GETGHOUL2MODELFLAGS
|
||||
equ trap_G2API_SetGhoul2ModelFlagsByIndex -182 ; CG_G2_SETGHOUL2MODELFLAGSBYINDEX
|
||||
equ trap_G2API_GetGhoul2ModelFlagsByIndex -183 ; CG_G2_GETGHOUL2MODELFLAGSBYINDEX
|
||||
equ trap_G2API_GetNumModels -184 ; CG_G2_GETNUMMODELS
|
||||
equ trap_G2API_FindBoltIndex -186 ; CG_G2_FINDBOLTINDEX
|
||||
equ trap_G2API_GetBoltIndex -187 ; CG_G2_GETBOLTINDEX
|
||||
equ trap_MAT_Init -192 ; CG_MAT_CACHE
|
||||
equ trap_MAT_Reset -191 ; CG_MAT_RESET
|
||||
equ trap_MAT_GetSound -193 ; CG_MAT_GET_SOUND
|
||||
equ trap_MAT_GetDecal -194 ; CG_MAT_GET_DECAL
|
||||
equ trap_MAT_GetDecalScale -195 ; CG_MAT_GET_DECAL_SCALE
|
||||
equ trap_MAT_GetEffect -196 ; CG_MAT_GET_EFFECT
|
||||
equ trap_MAT_GetDebris -197 ; CG_MAT_GET_DEBRIS
|
||||
equ trap_MAT_GetDebrisScale -198 ; CG_MAT_GET_DEBRIS_SCALE
|
||||
equ trap_GP_Parse -205 ; GP_PARSE
|
||||
equ trap_GP_ParseFile -206 ; GP_PARSE_FILE
|
||||
equ trap_GP_Clean -207 ; GP_CLEAN
|
||||
equ trap_GP_Delete -208 ; GP_DELETE
|
||||
equ trap_GP_GetBaseParseGroup -209 ; GP_GET_BASE_PARSE_GROUP
|
||||
equ trap_GPG_GetName -210 ; GPG_GET_NAME
|
||||
equ trap_GPG_GetNext -211 ; GPG_GET_NEXT
|
||||
equ trap_GPG_GetInOrderNext -212 ; GPG_GET_INORDER_NEXT
|
||||
equ trap_GPG_GetInOrderPrevious -213 ; GPG_GET_INORDER_PREVIOUS
|
||||
equ trap_GPG_GetPairs -214 ; GPG_GET_PAIRS
|
||||
equ trap_GPG_GetInOrderPairs -215 ; GPG_GET_INORDER_PAIRS
|
||||
equ trap_GPG_GetSubGroups -216 ; GPG_GET_SUBGROUPS
|
||||
equ trap_GPG_GetInOrderSubGroups -217 ; GPG_GET_INORDER_SUBGROUPS
|
||||
equ trap_GPG_FindSubGroup -218 ; GPG_FIND_SUBGROUP
|
||||
equ trap_GPG_FindPair -219 ; GPG_FIND_PAIR
|
||||
equ trap_GPG_FindPairValue -220 ; GPG_FIND_PAIRVALUE
|
||||
equ trap_GPV_GetName -221 ; GPV_GET_NAME
|
||||
equ trap_GPV_GetNext -222 ; GPV_GET_NEXT
|
||||
equ trap_GPV_GetInOrderNext -223 ; GPV_GET_INORDER_NEXT
|
||||
equ trap_GPV_GetInOrderPrevious -224 ; GPV_GET_INORDER_PREVIOUS
|
||||
equ trap_GPV_IsList -225 ; GPV_IS_LIST
|
||||
equ trap_GPV_GetTopValue -226 ; GPV_GET_TOP_VALUE
|
||||
equ trap_GPV_GetList -227 ; GPV_GET_LIST
|
||||
equ trap_CM_TM_Create -199 ; CG_CM_TM_CREATE
|
||||
equ trap_CM_TM_AddBuilding -200 ; CG_CM_TM_ADDBUILDING
|
||||
equ trap_CM_TM_AddSpot -201 ; CG_CM_TM_ADDSPOT
|
||||
equ trap_CM_TM_AddTarget -202 ; CG_CM_TM_ADDTARGET
|
||||
equ trap_CM_TM_Upload -203 ; CG_CM_TM_UPLOAD
|
||||
equ trap_CM_TM_ConvertPosition -204 ; CG_CM_TM_CONVERT_POS
|
||||
equ trap_CM_RegisterTerrain -228 ; CG_CM_REGISTER_TERRAIN
|
||||
equ trap_RE_InitRendererTerrain -229 ; CG_RE_INIT_RENDERER_TERRAIN
|
||||
equ trap_CG_RegisterSharedMemory -230 ; CG_SET_SHARED_BUFFER
|
||||
equ trap_FS_GetFileList -15 ; CG_FS_GETFILELIST
|
||||
equ trap_VM_LocalAlloc -231 ; CG_VM_LOCALALLOC
|
||||
equ trap_VM_LocalAllocUnaligned -232 ; CG_VM_LOCALALLOCUNALIGNED
|
||||
equ trap_VM_LocalTempAlloc -233 ; CG_VM_LOCALTEMPALLOC
|
||||
equ trap_VM_LocalTempFree -234 ; CG_VM_LOCALTEMPFREE
|
||||
equ trap_VM_LocalStringAlloc -235 ; CG_VM_LOCALSTRINGALLOC
|
||||
equ trap_UI_CloseAll -237 ; CG_UI_CLOSEALL
|
||||
equ trap_UI_SetActiveMenu -236 ; CG_UI_SETACTIVEMENU
|
||||
|
||||
|
||||
; hardcoded functions
|
||||
equ memset -101 ; CG_MEMSET
|
||||
equ memcpy -102 ; CG_MEMCPY
|
||||
equ strncpy -103 ; CG_STRNCPY
|
||||
equ sin -104 ; CG_SIN
|
||||
equ cos -105 ; CG_COS
|
||||
equ atan2 -106 ; CG_ATAN2
|
||||
equ sqrt -107 ; CG_SQRT
|
||||
equ matrixmultiply -116 ; CG_MATRIXMULTIPLY
|
||||
equ anglevectors -108 ; CG_ANGLEVECTORS
|
||||
equ perpendicularvector -109 ; CG_PERPENDICULARVECTOR
|
||||
equ floor -110 ; CG_FLOOR
|
||||
equ ceil -111 ; CG_CEIL
|
||||
equ acos -114 ; CG_ACOS
|
||||
equ asin -115 ; CG_ASIN
|
1056
code/cgame/cg_syscalls.c
Normal file
1056
code/cgame/cg_syscalls.c
Normal file
File diff suppressed because it is too large
Load diff
1454
code/cgame/cg_view.c
Normal file
1454
code/cgame/cg_view.c
Normal file
File diff suppressed because it is too large
Load diff
474
code/cgame/cg_weaponinit.c
Normal file
474
code/cgame/cg_weaponinit.c
Normal file
|
@ -0,0 +1,474 @@
|
|||
// Copyright (C) 2001-2002 Raven Software, Inc.
|
||||
//
|
||||
// cg_weaponinit.c -- weapon initialization
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "../game/bg_weapons.h"
|
||||
|
||||
// FIMXE: This is defined in a C++ header file.
|
||||
// We need to break it up or somethin so we don't have mutliple defs.
|
||||
#define GHOUL2_NORENDER 2
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_RegisterItemVisuals
|
||||
|
||||
The server says this item is used on this level
|
||||
=================
|
||||
*/
|
||||
void CG_RegisterItemVisuals( int itemNum )
|
||||
{
|
||||
itemInfo_t *itemInfo;
|
||||
gitem_t *item;
|
||||
char simpleName[MAX_QPATH];
|
||||
|
||||
if ( itemNum < 0 || itemNum >= bg_numItems )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_RegisterItemVisuals: itemNum %d out of range [0-%d]", itemNum, bg_numItems-1 );
|
||||
}
|
||||
|
||||
itemInfo = &cg_items[ itemNum ];
|
||||
if ( itemInfo->registered )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
item = &bg_itemlist[ itemNum ];
|
||||
|
||||
memset( itemInfo, 0, sizeof( &itemInfo ) );
|
||||
itemInfo->registered = qtrue;
|
||||
|
||||
itemInfo->models[0] = trap_R_RegisterModel( item->world_model[0] );
|
||||
|
||||
// Check to see if its a ghoul model we loaded
|
||||
if (!Q_stricmp(&item->world_model[0][strlen(item->world_model[0]) - 4], ".glm"))
|
||||
{
|
||||
trap_G2API_InitGhoul2Model(&itemInfo->g2Models[0], item->world_model[0], 0 , 0, 0, 0, 0);
|
||||
itemInfo->radius[0] = 60;
|
||||
|
||||
// Special case to make sure some sufaces are show that should be
|
||||
switch ( item->giTag )
|
||||
{
|
||||
case WP_AK74_ASSAULT_RIFLE:
|
||||
trap_G2API_SetSurfaceOnOff( itemInfo->g2Models[0], 0, "bayonet_off", 0 );
|
||||
break;
|
||||
|
||||
case WP_M4_ASSAULT_RIFLE:
|
||||
trap_G2API_SetSurfaceOnOff( itemInfo->g2Models[0], 0, "m203_off", 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
itemInfo->icon = trap_R_RegisterShaderNoMip( item->icon );
|
||||
|
||||
if (item->icon[0])
|
||||
{
|
||||
Com_sprintf(simpleName, sizeof(simpleName), "%s_simple", item->icon);
|
||||
itemInfo->mSimpleIcon = trap_R_RegisterShader(simpleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemInfo->mSimpleIcon = 0;
|
||||
}
|
||||
|
||||
|
||||
if ( item->giType == IT_WEAPON )
|
||||
{
|
||||
CG_RegisterWeapon( item->giTag );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_RegisterWeapon
|
||||
|
||||
The server says this item is used on this level
|
||||
=================
|
||||
*/
|
||||
void CG_RegisterWeapon(int weaponNum)
|
||||
{
|
||||
weaponInfo_t *weaponInfo;
|
||||
weaponData_t *weaponDat;
|
||||
TWeaponModel *weaponModel;
|
||||
TOptionalWeapon *optionalPart;
|
||||
gitem_t *item,*ammo;
|
||||
TWeaponParseInfo *wPI;
|
||||
int weaponIndex; // model index for view weapon models
|
||||
int bufferIndex; // weapon + buffer + rhand [+ lhand ]
|
||||
int rHandIndex;
|
||||
int lHandIndex;
|
||||
int boltonIndex;
|
||||
int boltIndex;
|
||||
int soundSet, i;
|
||||
int *indexes;
|
||||
|
||||
if(weaponNum==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boltonIndex = -1;
|
||||
|
||||
assert(weaponNum < WP_NUM_WEAPONS);
|
||||
|
||||
weaponInfo=&cg_weapons[weaponNum];
|
||||
if(weaponInfo->registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(weaponInfo,0,sizeof(*weaponInfo));
|
||||
|
||||
// Register the item visuals (icons etc).
|
||||
weaponInfo->item = item = BG_FindWeaponItem ( weaponNum );
|
||||
|
||||
// Must be initial loading
|
||||
if ( !weaponInfo->registered )
|
||||
{
|
||||
CG_LoadingItem( item - bg_itemlist );
|
||||
}
|
||||
|
||||
// Ok, successfully registered the entire weapon.
|
||||
weaponInfo->registered=qtrue;
|
||||
|
||||
weaponDat = &weaponData[weaponNum];
|
||||
|
||||
if(item->classname)
|
||||
{
|
||||
// Hmmm... this needs some work... some of it looks if now.
|
||||
CG_RegisterItemVisuals( item - bg_itemlist );
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Error( ERR_FATAL, "CG_RegisterWeapon: Couldn't find weapon item %i", weaponNum);
|
||||
}
|
||||
|
||||
// Register the weapon's world ammo model.
|
||||
for ( ammo = bg_itemlist + 1 ; ammo->classname ; ammo++ )
|
||||
{
|
||||
if ( ammo->giType == IT_AMMO && ammo->giTag == weaponNum )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( ammo->classname && ammo->world_model[0] )
|
||||
{
|
||||
trap_G2API_InitGhoul2Model(&weaponInfo->ammoG2Model,ammo->world_model[0],0,0,0,0,0);
|
||||
}
|
||||
|
||||
// Create the world model.
|
||||
weaponIndex = trap_G2API_InitGhoul2Model(&weaponInfo->weaponG2Model,weaponDat->worldModel,0,0,0,0,0);
|
||||
if(!trap_G2_HaveWeGhoul2Models(weaponInfo->weaponG2Model))
|
||||
{
|
||||
Com_Printf("CG_RegisterWeapon: Unable to load weapon world model: %s\n", weaponDat->worldModel);
|
||||
}
|
||||
|
||||
// Register the weapon model...
|
||||
indexes=weaponInfo->viewG2Indexes;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
indexes[i]=-1;
|
||||
}
|
||||
|
||||
wPI=&weaponParseInfo[weaponNum];
|
||||
|
||||
// Create the view weapon model in slot 0.
|
||||
indexes[0] = weaponIndex = trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
|
||||
wPI->mWeaponModel.mModel,0,0,0,0,0);
|
||||
|
||||
// Now build and assemble all the other bits.
|
||||
if(trap_G2_HaveWeGhoul2Models(weaponInfo->viewG2Model))
|
||||
{
|
||||
// Add a bolt to the weapon so buffer can be bolted on.
|
||||
boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,weaponIndex,wPI->mWeaponModel.mBufferBoltToBone);
|
||||
|
||||
// Every view weapon has a buffer, create this in slot 1.
|
||||
indexes[1]=bufferIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
|
||||
wPI->mWeaponModel.mBufferModel,
|
||||
weaponIndex+1,0,0,0,0);
|
||||
// Bolt the buffer to the weapon.
|
||||
trap_G2API_AttachG2Model(weaponInfo->viewG2Model,bufferIndex,
|
||||
weaponInfo->viewG2Model,boltIndex,weaponIndex);
|
||||
|
||||
// Right hand??
|
||||
if(wPI->mWeaponModel.mRightHandsBoltToBone[0])
|
||||
{
|
||||
// Add a right hand bolt to the buffer.
|
||||
boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
|
||||
wPI->mWeaponModel.mRightHandsBoltToBone);
|
||||
|
||||
// Right hand.. create this now in slot 2.
|
||||
indexes[2]=rHandIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
|
||||
"models/weapons/rhand/rhand.glm",
|
||||
weaponIndex+2,0,0,0,0);
|
||||
|
||||
// Bolt the right hand to the buffer.
|
||||
trap_G2API_AttachG2Model(weaponInfo->viewG2Model,rHandIndex,weaponInfo->viewG2Model,
|
||||
boltIndex,bufferIndex);
|
||||
}
|
||||
|
||||
// Left hand??
|
||||
if(wPI->mWeaponModel.mLeftHandsBoltToBone[0])
|
||||
{
|
||||
// Add a left hand bolt to the buffer.
|
||||
boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
|
||||
wPI->mWeaponModel.mLeftHandsBoltToBone);
|
||||
|
||||
// Left hand.. create this now in slot 3.
|
||||
indexes[3]=lHandIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
|
||||
"models/weapons/lhand/lhand.glm",
|
||||
weaponIndex+3,0,0,0,0);
|
||||
|
||||
// Bolt the left hand to the buffer.
|
||||
trap_G2API_AttachG2Model(weaponInfo->viewG2Model,lHandIndex,weaponInfo->viewG2Model,
|
||||
boltIndex,bufferIndex);
|
||||
}
|
||||
|
||||
// Boltons like the M4's grenade launcher?
|
||||
if(wPI->mWeaponModel.mBolton)
|
||||
{
|
||||
// Add a bolton bolt to the buffer.
|
||||
boltIndex=trap_G2API_AddBolt(weaponInfo->viewG2Model,bufferIndex,
|
||||
wPI->mWeaponModel.mBolton->mBoltToBone);
|
||||
|
||||
// Bolton.. create this now in slot 4.
|
||||
indexes[4]=boltonIndex=trap_G2API_InitGhoul2Model(&weaponInfo->viewG2Model,
|
||||
wPI->mWeaponModel.mBolton->mModel,
|
||||
weaponIndex+4,0,0,0,0);
|
||||
// Bolt the bolton to the buffer.
|
||||
if ( boltonIndex != -1 )
|
||||
{
|
||||
trap_G2API_AttachG2Model(weaponInfo->viewG2Model,boltonIndex,weaponInfo->viewG2Model,
|
||||
boltIndex,bufferIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn of any weapon surfaces that are never seen.
|
||||
weaponModel=&wPI->mWeaponModel;
|
||||
i=0;
|
||||
while(weaponModel->mRightSideSurfaces[i])
|
||||
{
|
||||
trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
|
||||
weaponModel->mRightSideSurfaces[i],GHOUL2_NORENDER);
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
while(weaponModel->mFrontSurfaces[i])
|
||||
{
|
||||
trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
|
||||
weaponModel->mFrontSurfaces[i],GHOUL2_NORENDER);
|
||||
i++;
|
||||
}
|
||||
if(weaponModel->mBolton && boltonIndex != -1 )
|
||||
{
|
||||
i=0;
|
||||
while(weaponModel->mBolton->mRightSide[i])
|
||||
{
|
||||
trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,boltonIndex,
|
||||
weaponModel->mBolton->mRightSide[i],GHOUL2_NORENDER);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Turn off optional parts as we don't want em.
|
||||
optionalPart=weaponModel->mOptionalList;
|
||||
while(optionalPart)
|
||||
{
|
||||
// No real way of knowing what single player intended so we have to
|
||||
// hard-code 'em.
|
||||
if((!strcmp(optionalPart->mName,"lasersight"))||
|
||||
(!strcmp(optionalPart->mName,"silencer"))||
|
||||
(!strcmp(optionalPart->mName,"utl")))
|
||||
{
|
||||
i=0;
|
||||
while(optionalPart->mSurfaces[i])
|
||||
{
|
||||
trap_G2API_SetSurfaceOnOff(weaponInfo->viewG2Model,weaponInfo->viewG2Indexes[0],
|
||||
optionalPart->mSurfaces[i],GHOUL2_NORENDER);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
optionalPart=optionalPart->mNext;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("CG_RegisterWeapon: Unable to load weapon view model: %s\n", wPI->mWeaponModel.mModel);
|
||||
}
|
||||
|
||||
weaponInfo->attack[ATTACK_NORMAL].missileTrailFunc = CG_ProjectileThink;
|
||||
weaponInfo->attack[ATTACK_ALTERNATE].missileTrailFunc = CG_ProjectileThink;
|
||||
|
||||
// Register weapon list menu icons.
|
||||
if (weaponDat->menuImage[0])
|
||||
{
|
||||
weaponInfo->weaponIcon = trap_R_RegisterShader( va( "gfx/menus/%s", weaponDat->menuImage) );
|
||||
}
|
||||
|
||||
// Register the alternate weapon ammo icon for the hud
|
||||
if (weaponDat->attack[ATTACK_ALTERNATE].icon[0] )
|
||||
{
|
||||
weaponInfo->attack[ATTACK_ALTERNATE].ammoIcon = trap_R_RegisterShader( va( "gfx/menus/%s", weaponDat->attack[ATTACK_ALTERNATE].icon ) );
|
||||
}
|
||||
|
||||
// Register attack stuff
|
||||
for ( i = ATTACK_NORMAL; i < ATTACK_MAX; i ++ )
|
||||
{
|
||||
attackData_t* attackData = &weaponDat->attack[i];
|
||||
attackInfo_t* attackInfo = &weaponInfo->attack[i];
|
||||
|
||||
// Primary muzzle-flash.
|
||||
if (attackData->muzzleEffect[0])
|
||||
attackInfo->muzzleEffect = trap_FX_RegisterEffect(attackData->muzzleEffect);
|
||||
if (attackData->muzzleEffectInWorld[0])
|
||||
attackInfo->muzzleEffectInWorld = trap_FX_RegisterEffect(attackData->muzzleEffectInWorld);
|
||||
if (!attackInfo->muzzleEffectInWorld)
|
||||
attackInfo->muzzleEffectInWorld = attackInfo->muzzleEffect;
|
||||
|
||||
// Primary shell eject.
|
||||
if (attackData->shellEject[0])
|
||||
attackInfo->shellEject = trap_FX_RegisterEffect(attackData->shellEject);
|
||||
if (attackData->tracerEffect[0])
|
||||
attackInfo->tracerEffect = trap_FX_RegisterEffect(attackData->tracerEffect);
|
||||
|
||||
// Primary explosion.
|
||||
if (attackData->explosionEffect[0])
|
||||
attackInfo->explosionEffect = trap_FX_RegisterEffect(attackData->explosionEffect);
|
||||
if (attackData->explosionSound[0])
|
||||
attackInfo->explosionSound = trap_S_RegisterSound(attackData->explosionSound);
|
||||
if (attackData->missileG2Model[0])
|
||||
trap_G2API_InitGhoul2Model(&attackInfo->missileG2Model,attackData->missileG2Model,0,0,0,0,0);
|
||||
|
||||
// Add the bolts for muzzle flash and shell eject onto the view model.
|
||||
if (trap_G2_HaveWeGhoul2Models(weaponInfo->viewG2Model))
|
||||
{
|
||||
// shell eject bone.
|
||||
if ( attackData->ejectBone[0] )
|
||||
{
|
||||
attackInfo->shellEjectBoltView =
|
||||
trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, attackData->ejectBone);
|
||||
}
|
||||
|
||||
// Muzzle flash bone.
|
||||
attackInfo->muzzleFlashBoltView = -1;
|
||||
if(attackData->muzzleEffect[0])
|
||||
{
|
||||
if ( attackData->muzzleEffectBone[0] )
|
||||
{
|
||||
attackInfo->muzzleFlashBoltView =
|
||||
trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, attackData->muzzleEffectBone );
|
||||
}
|
||||
else if (wPI->mWeaponModel.mBufferMuzzle[0])
|
||||
{
|
||||
attackInfo->muzzleFlashBoltView =
|
||||
trap_G2API_AddBolt(weaponInfo->viewG2Model, 1, wPI->mWeaponModel.mBufferMuzzle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the bolts for muzzle flash and shell eject onto the world model.
|
||||
if (trap_G2_HaveWeGhoul2Models(weaponInfo->weaponG2Model))
|
||||
{
|
||||
// shell eject bone.
|
||||
if (attackData->ejectBone[0])
|
||||
{
|
||||
attackInfo->shellEjectBoltWorld =
|
||||
trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, attackData->ejectBone);
|
||||
}
|
||||
else
|
||||
{
|
||||
attackInfo->shellEjectBoltWorld = -1;
|
||||
}
|
||||
|
||||
// Muzzle flash bone.
|
||||
attackInfo->muzzleFlashBoltWorld = -1;
|
||||
if ( attackData->muzzleEffectBone[0] )
|
||||
{
|
||||
attackInfo->muzzleFlashBoltWorld =
|
||||
trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, attackData->muzzleEffectBone );
|
||||
}
|
||||
else if (wPI->mWeaponModel.mBufferMuzzle[0])
|
||||
{
|
||||
attackInfo->muzzleFlashBoltWorld =
|
||||
trap_G2API_AddBolt(weaponInfo->weaponG2Model, 0, wPI->mWeaponModel.mBufferMuzzle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register sounds for weapon.
|
||||
for (soundSet = 0; soundSet < MAX_WEAPON_SOUNDS; soundSet++)
|
||||
{
|
||||
if (Q_stricmp(wPI->mSoundNames[soundSet], "fire")==0)
|
||||
{
|
||||
for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
|
||||
{
|
||||
if (wPI->mSounds[soundSet][i][0])
|
||||
{
|
||||
weaponInfo->attack[ATTACK_NORMAL].flashSound[i] = trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Q_stricmp(wPI->mSoundNames[soundSet], "altfire")==0)
|
||||
{
|
||||
for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
|
||||
{
|
||||
if (wPI->mSounds[soundSet][i][0])
|
||||
weaponInfo->attack[ATTACK_ALTERNATE].flashSound[i] = trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All other sounds.
|
||||
for (i=0; i<MAX_WEAPON_SOUND_SLOTS; i++)
|
||||
{
|
||||
if (wPI->mSounds[soundSet][i][0])
|
||||
weaponInfo->otherWeaponSounds[soundSet][i]=trap_S_RegisterSound(wPI->mSounds[soundSet][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special hard coded stuff
|
||||
switch ( weaponNum )
|
||||
{
|
||||
case WP_KNIFE:
|
||||
{
|
||||
attackInfo_t* attackInfo = &weaponInfo->attack[ATTACK_ALTERNATE];
|
||||
attackInfo->missileSound = trap_S_RegisterSound ( "sound/weapons/knife/throw_loop" );
|
||||
break;
|
||||
}
|
||||
|
||||
case WP_RPG7_LAUNCHER:
|
||||
{
|
||||
attackInfo_t* attackInfo = &weaponInfo->attack[ATTACK_NORMAL];
|
||||
attackInfo->missileSound = trap_S_RegisterSound ( "sound/weapons/rpg7/flyby" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_ShutDownWeapons
|
||||
|
||||
Clean out any g2 models
|
||||
=================
|
||||
*/
|
||||
void CG_ShutDownWeapons ( void )
|
||||
{
|
||||
int i;
|
||||
attackType_t a;
|
||||
|
||||
for (i=0; i < WP_NUM_WEAPONS; i++)
|
||||
{
|
||||
// free all ghoul2 models
|
||||
trap_G2API_CleanGhoul2Models(&cg_weapons[i].weaponG2Model);
|
||||
trap_G2API_CleanGhoul2Models(&cg_weapons[i].viewG2Model);
|
||||
trap_G2API_CleanGhoul2Models(&cg_weapons[i].ammoG2Model);
|
||||
|
||||
for ( a = ATTACK_NORMAL; a < ATTACK_MAX; a ++ )
|
||||
{
|
||||
trap_G2API_CleanGhoul2Models(&cg_weapons[i].attack[a].missileG2Model);
|
||||
}
|
||||
}
|
||||
}
|
1783
code/cgame/cg_weapons.c
Normal file
1783
code/cgame/cg_weapons.c
Normal file
File diff suppressed because it is too large
Load diff
83
code/cgame/cgame.bat
Normal file
83
code/cgame/cgame.bat
Normal file
|
@ -0,0 +1,83 @@
|
|||
@set include=
|
||||
|
||||
del /q vm
|
||||
mkdir vm
|
||||
cd vm
|
||||
set cc=..\..\..\bin\sof2lcc -DQ3_VM -DMISSIONPACK -DCGAME -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1
|
||||
|
||||
%cc% ../../game/bg_misc.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_weapons.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_player.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_pmove.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_slidemove.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_lib.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/bg_gametype.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/q_math.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../game/q_shared.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_consolecmds.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_draw.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_drawtools.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_effects.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_ents.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_event.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_gametype.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_gore.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_info.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_light.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_localents.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_main.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_miscents.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_players.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_playerstate.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_predict.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_scoreboard.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_servercmds.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_snapshot.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_view.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_weaponinit.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_weapons.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../../ui/ui_shared.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../cg_newDraw.c
|
||||
@if errorlevel 1 goto quit
|
||||
|
||||
..\..\..\bin\sof2asm -f ../cgame
|
||||
@if errorlevel 1 goto quit
|
||||
|
||||
mkdir "..\..\..\base\vm"
|
||||
copy *.map "..\..\..\base\vm"
|
||||
copy *.qvm "..\..\..\base\vm"
|
||||
|
||||
:quit
|
||||
cd ..
|
35
code/cgame/cgame.q3asm
Normal file
35
code/cgame/cgame.q3asm
Normal file
|
@ -0,0 +1,35 @@
|
|||
-o "sof2mp_cgame"
|
||||
cg_main
|
||||
..\cg_syscalls
|
||||
cg_consolecmds
|
||||
cg_draw
|
||||
cg_drawtools
|
||||
cg_effects
|
||||
cg_ents
|
||||
cg_event
|
||||
cg_gametype
|
||||
cg_gore
|
||||
cg_info
|
||||
cg_light
|
||||
cg_localents
|
||||
cg_miscents
|
||||
cg_players
|
||||
cg_playerstate
|
||||
cg_predict
|
||||
cg_scoreboard
|
||||
cg_servercmds
|
||||
cg_snapshot
|
||||
cg_view
|
||||
cg_weaponinit
|
||||
cg_weapons
|
||||
bg_slidemove
|
||||
bg_weapons
|
||||
bg_player
|
||||
bg_pmove
|
||||
bg_lib
|
||||
bg_misc
|
||||
bg_gametype
|
||||
q_math
|
||||
q_shared
|
||||
ui_shared
|
||||
cg_newDraw
|
3
code/cgame/sof2_cgame.def
Normal file
3
code/cgame/sof2_cgame.def
Normal file
|
@ -0,0 +1,3 @@
|
|||
EXPORTS
|
||||
vmMain
|
||||
dllEntry
|
760
code/cgame/sof2_cgame.dsp
Normal file
760
code/cgame/sof2_cgame.dsp
Normal file
|
@ -0,0 +1,760 @@
|
|||
# Microsoft Developer Studio Project File - Name="SoF2cgame" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=SoF2cgame - Win32 SH Debug SoF2
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "sof2_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 "sof2_cgame.mak" CFG="SoF2cgame - Win32 SH Debug SoF2"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "SoF2cgame - Win32 Release SoF2" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "SoF2cgame - Win32 Debug SoF2" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "SoF2cgame - Win32 SH Debug SoF2" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "SoF2cgame___Win32_Release_TA"
|
||||
# PROP BASE Intermediate_Dir "SoF2cgame___Win32_Release_TA"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../Release"
|
||||
# PROP Intermediate_Dir "..\Release/SoF2cgame"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G6 /W4 /GX /O2 /D "WIN32" /D "NDebug SoF2" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /W4 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_SOF2" /D "CGAME" /YX /FD /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "NDebug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD MTL /nologo /D "NDebug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDebug SoF2"
|
||||
# ADD RSC /l 0x409 /d "NDebug SoF2"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /out:"../Release/SoF2cgamex86.dll"
|
||||
# SUBTRACT BASE LINK32 /debug
|
||||
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map:"..\Release/sof2mp_cgamex86.map" /debug /machine:I386 /out:"../Release/sof2mp_cgamex86.dll"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "SoF2cgame___Win32_Debug_TA"
|
||||
# PROP BASE Intermediate_Dir "SoF2cgame___Win32_Debug_TA"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\Debug"
|
||||
# PROP Intermediate_Dir "..\Debug\SoF2cgame"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug SoF2" /D "_WINDOWS" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /MTd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_SOF2" /D "CGAME" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_Debug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD MTL /nologo /D "_Debug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_Debug SoF2"
|
||||
# ADD RSC /l 0x409 /d "_Debug SoF2"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /out:"..\Debug/SoF2cgamex86.dll"
|
||||
# SUBTRACT BASE LINK32 /profile /nodefaultlib
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x30000000" /subsystem:windows /dll /map:"..\Debug\sof2mp_cgamex86.map" /debug /machine:I386 /def:".\SoF2_cgame.def" /out:"..\Debug\sof2mp_cgamex86.dll"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "SoF2cgame___Win32_SH_Debug_SoF2"
|
||||
# PROP BASE Intermediate_Dir "SoF2cgame___Win32_SH_Debug_SoF2"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "SoF2cgame___Win32_SH_Debug_SoF2"
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G5 /MTd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_SOF2" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /MTd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_SOF2" /D "MEM_DEBUG" /D "CGAME" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_Debug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD MTL /nologo /D "_Debug SoF2" /mktyplib203 /o "NUL" /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_Debug SoF2"
|
||||
# ADD RSC /l 0x409 /d "_Debug SoF2"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map:"..\Debug\sof2mp_cgamex86.map" /debug /machine:I386 /def:".\SoF2_cgame.def" /out:"..\Debug\sof2mp_cgamex86.dll"
|
||||
# SUBTRACT BASE LINK32 /pdb:none
|
||||
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /pdb:"..\SHDebug/sof2mp_cgamex86.pdb" /map:"..\SHDebug\sof2mp_cgamex86.map" /debug /machine:I386 /def:".\SoF2_cgame.def" /out:"..\SHDebug\sof2mp_cgamex86.dll"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "SoF2cgame - Win32 Release SoF2"
|
||||
# Name "SoF2cgame - Win32 Debug SoF2"
|
||||
# Name "SoF2cgame - Win32 SH Debug SoF2"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "c"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_gametype.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_lib.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
# PROP BASE Exclude_From_Build 1
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
# PROP BASE Exclude_From_Build 1
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP BASE Exclude_From_Build 1
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_misc.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_player.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_pmove.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_slidemove.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_weapons.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_consolecmds.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_draw.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_drawtools.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_effects.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_ents.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_event.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_gametype.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_gore.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_info.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_light.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_localents.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_main.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_miscents.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_newDraw.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_players.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_playerstate.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_predict.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_scoreboard.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_servercmds.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_snapshot.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_syscalls.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_view.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_weaponinit.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_weapons.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\q_math.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\q_shared.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ui\ui_shared.c
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP Intermediate_Dir "..\SHDebug\SoF2cgame"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\animtable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_local.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_public.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\bg_weapons.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cg_lights.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=..\qcommon\disablewarnings.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ghoul2\G2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ghoul2\G2_gore_shared.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\g_local.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\g_public.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\game\g_team.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ui\keycodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ui\menudef.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=..\qcommon\tags.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tr_types.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ui\ui_shared.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cgame.bat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cgame.q3asm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SoF2_cgame.def
|
||||
|
||||
!IF "$(CFG)" == "SoF2cgame - Win32 Release SoF2"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 Debug SoF2"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "SoF2cgame - Win32 SH Debug SoF2"
|
||||
|
||||
# PROP BASE Exclude_From_Build 1
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
338
code/cgame/tr_types.h
Normal file
338
code/cgame/tr_types.h
Normal file
|
@ -0,0 +1,338 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
#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
|
||||
#define MAX_MINI_ENTITIES 1024
|
||||
|
||||
// renderfx flags
|
||||
#define RF_MINLIGHT 1 // allways have some light (viewmodel, some items)
|
||||
#define RF_THIRD_PERSON 2 // don't draw through eyes, only mirrors (player bodies, chat sprites)
|
||||
#define RF_FIRST_PERSON 4 // only draw through eyes (view weapon, damage blood blob)
|
||||
#define RF_DEPTHHACK 8 // for view weapon Z crunching
|
||||
#define RF_NOSHADOW 64 // don't add stencil shadows
|
||||
|
||||
#define RF_LIGHTING_ORIGIN 128 // 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 256 // use refEntity->shadowPlane
|
||||
#define RF_WRAP_FRAMES 512 // mod the model frames by the maxframes to allow continuous
|
||||
// animation without needing to know the frame count
|
||||
|
||||
#define RF_FORKED 0x00001000 // override lightning to have forks
|
||||
#define RF_TAPERED 0x00002000 // lightning tapers
|
||||
#define RF_GROW 0x00004000 // lightning grows from start to end during its life
|
||||
#define RF_NO_FOG 0x00008000 // no fog for g2 models
|
||||
|
||||
// refdef flags
|
||||
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
|
||||
#define RDF_PROJECTION2D 2
|
||||
#define RDF_HYPERSPACE 4 // teleportation effect
|
||||
|
||||
typedef byte color4ub_t[4];
|
||||
|
||||
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_POLY,
|
||||
RT_SPRITE,
|
||||
RT_ORIENTED_QUAD,
|
||||
RT_BEAM,
|
||||
RT_ELECTRICITY,
|
||||
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
|
||||
RT_LINE,
|
||||
RT_ORIENTEDLINE,
|
||||
RT_CYLINDER,
|
||||
RT_ENT_CHAIN,
|
||||
|
||||
RT_MAX_REF_ENTITY_TYPE
|
||||
} refEntityType_t;
|
||||
|
||||
typedef struct miniRefEntity_s
|
||||
{
|
||||
refEntityType_t reType;
|
||||
int renderfx;
|
||||
|
||||
qhandle_t hModel; // opaque type outside refresh
|
||||
|
||||
// most recent data
|
||||
vec3_t axis[3]; // rotation vectors
|
||||
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
|
||||
vec3_t origin; // also used as MODEL_BEAM's "from"
|
||||
|
||||
// previous data for frame interpolation
|
||||
vec3_t oldorigin; // also used as MODEL_BEAM's "to"
|
||||
|
||||
// texturing
|
||||
qhandle_t customShader; // use one image for the entire thing
|
||||
|
||||
// misc
|
||||
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
|
||||
vec2_t shaderTexCoord; // texture coordinates used by tcMod entity modifiers
|
||||
|
||||
// extra sprite information
|
||||
float radius;
|
||||
float rotation; // size 2 for RT_CYLINDER or number of verts in RT_ELECTRICITY
|
||||
|
||||
// misc
|
||||
float shaderTime; // subtracted from refdef time to control effect start times
|
||||
int frame; // also used as MODEL_BEAM's diameter
|
||||
|
||||
} miniRefEntity_t;
|
||||
|
||||
#pragma warning (disable : 4201 )
|
||||
typedef struct {
|
||||
// this stucture must remain identical as the miniRefEntity_t
|
||||
//
|
||||
//
|
||||
refEntityType_t reType;
|
||||
int renderfx;
|
||||
|
||||
qhandle_t hModel; // opaque type outside refresh
|
||||
|
||||
// most recent data
|
||||
vec3_t axis[3]; // rotation vectors
|
||||
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
|
||||
vec3_t origin; // also used as MODEL_BEAM's "from"
|
||||
|
||||
// previous data for frame interpolation
|
||||
vec3_t oldorigin; // also used as MODEL_BEAM's "to"
|
||||
|
||||
// texturing
|
||||
qhandle_t customShader; // use one image for the entire thing
|
||||
|
||||
// misc
|
||||
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
|
||||
vec2_t shaderTexCoord; // texture coordinates used by tcMod entity modifiers
|
||||
|
||||
// extra sprite information
|
||||
float radius;
|
||||
float rotation;
|
||||
|
||||
// misc
|
||||
float shaderTime; // subtracted from refdef time to control effect start times
|
||||
int frame; // also used as MODEL_BEAM's diameter
|
||||
//
|
||||
//
|
||||
// end miniRefEntity_t
|
||||
|
||||
//
|
||||
//
|
||||
// specific full refEntity_t data
|
||||
//
|
||||
//
|
||||
|
||||
// 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
|
||||
|
||||
// previous data for frame interpolation
|
||||
int oldframe;
|
||||
float backlerp; // 0.0 = current, 1.0 = old
|
||||
|
||||
// texturing
|
||||
int skinNum; // inline skin index
|
||||
qhandle_t customSkin; // NULL for default skin
|
||||
|
||||
// texturing
|
||||
union
|
||||
{
|
||||
// int skinNum; // inline skin index
|
||||
// ivec3_t terxelCoords; // coords of patch for RT_TERXELS
|
||||
struct
|
||||
{
|
||||
int miniStart;
|
||||
int miniCount;
|
||||
} uMini;
|
||||
} uRefEnt;
|
||||
|
||||
// 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
|
||||
{
|
||||
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;
|
||||
|
||||
vec3_t angles; // rotation angles - used for Ghoul2
|
||||
vec3_t modelScale; // axis scale for models
|
||||
void *ghoul2; // has to be at the end of the ref-ent in order for it to be created properly
|
||||
|
||||
} 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];
|
||||
|
||||
vec3_t viewangles;
|
||||
|
||||
} 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 {
|
||||
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[BIG_INFO_STRING];
|
||||
|
||||
int maxTextureSize; // queried from GL
|
||||
int maxActiveTextures; // multitexture ability
|
||||
|
||||
int tfSolidCompressed;
|
||||
float tfSolidCompressedBPT;
|
||||
int tfAlphaCompressed;
|
||||
float tfAlphaCompressedBPT;
|
||||
int tfSolidUncompressed;
|
||||
float tfSolidUncompressedBPT;
|
||||
int tfAlphaUncompressed;
|
||||
float tfAlphaUncompressedBPT;
|
||||
int tfLightmap;
|
||||
float tfLightmapBPT;
|
||||
int tfCinematic; // Specially for the Voodoo4 - glTexImage2D can only handle 16 bit
|
||||
float tfCinematicBPT;
|
||||
|
||||
int colorBits, depthBits, stencilBits;
|
||||
|
||||
glDriverType_t driverType;
|
||||
glHardwareType_t hardwareType;
|
||||
|
||||
qboolean deviceSupportsGamma;
|
||||
qboolean textureEnvAddAvailable;
|
||||
qboolean textureFilterAnisotropicAvailable;
|
||||
qboolean clampToEdgeAvailable;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VO_NONE = 0,
|
||||
VO_NIGHTVISION, // parm1 = visible distance, parm2 = not used
|
||||
VO_INFRARED, // parm1 = distance to see heat, parm2 = distance you can see them through walls
|
||||
} visual_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
|
5511
code/game/ai_main.c
Normal file
5511
code/game/ai_main.c
Normal file
File diff suppressed because it is too large
Load diff
363
code/game/ai_main.h
Normal file
363
code/game/ai_main.h
Normal file
|
@ -0,0 +1,363 @@
|
|||
#define DEFAULT_FORCEPOWERS "5-1-000000000000000000"
|
||||
|
||||
#define MAX_CHAT_BUFFER_SIZE 65536
|
||||
#define MAX_CHAT_LINE_SIZE 128
|
||||
|
||||
#define MAX_WPARRAY_SIZE 4096
|
||||
#define MAX_NEIGHBOR_SIZE 32
|
||||
|
||||
#define MAX_NEIGHBOR_LINK_DISTANCE 128
|
||||
#define MAX_NEIGHBOR_FORCEJUMP_LINK_DISTANCE 400
|
||||
|
||||
#define TABLE_BRANCH_DISTANCE 32
|
||||
#define MAX_NODETABLE_SIZE 4096
|
||||
|
||||
#define MAX_LOVED_ONES 4
|
||||
#define MAX_ATTACHMENT_NAME 64
|
||||
|
||||
#define MAX_FORCE_INFO_SIZE 2048
|
||||
|
||||
#define WPFLAG_JUMP 0x00000010 //jump when we hit this
|
||||
#define WPFLAG_DUCK 0x00000020 //duck while moving around here
|
||||
#define WPFLAG_NOVIS 0x00000400 //go here for a bit even with no visibility
|
||||
#define WPFLAG_SNIPEORCAMPSTAND 0x00000800 //a good position to snipe or camp - stand
|
||||
#define WPFLAG_WAITFORFUNC 0x00001000 //wait for a func brushent under this point before moving here
|
||||
#define WPFLAG_SNIPEORCAMP 0x00002000 //a good position to snipe or camp - crouch
|
||||
#define WPFLAG_ONEWAY_FWD 0x00004000 //can only go forward on the trial from here (e.g. went over a ledge)
|
||||
#define WPFLAG_ONEWAY_BACK 0x00008000 //can only go backward on the trail from here
|
||||
#define WPFLAG_GOALPOINT 0x00010000 //make it a goal to get here.. goal points will be decided by setting "weight" values
|
||||
#define WPFLAG_RED_FLAG 0x00020000 //red flag
|
||||
#define WPFLAG_BLUE_FLAG 0x00040000 //blue flag
|
||||
#define WPFLAG_NOMOVEFUNC 0x00200000 //don't move over if a func is under
|
||||
|
||||
#define WP_KEEP_FLAG_DIST 128
|
||||
|
||||
#define BWEAPONRANGE_MELEE 1
|
||||
#define BWEAPONRANGE_MID 2
|
||||
#define BWEAPONRANGE_LONG 3
|
||||
#define BWEAPONRANGE_SABER 4
|
||||
|
||||
#define MELEE_ATTACK_RANGE 256
|
||||
#define SABER_ATTACK_RANGE 128
|
||||
#define MAX_CHICKENWUSS_TIME 10000 //wait 10 secs between checking which run-away path to take
|
||||
|
||||
#define BOT_RUN_HEALTH 40
|
||||
#define BOT_WPTOUCH_DISTANCE 32
|
||||
#define ENEMY_FORGET_MS 10000
|
||||
//if our enemy isn't visible within 10000ms (aprx 10sec) then "forget" about him and treat him like every other threat, but still look for
|
||||
//more immediate threats while main enemy is not visible
|
||||
|
||||
#define BOT_PLANT_DISTANCE 256 //plant if within this radius from the last spotted enemy position
|
||||
#define BOT_PLANT_INTERVAL 15000 //only plant once per 15 seconds at max
|
||||
#define BOT_PLANT_BLOW_DISTANCE 256 //blow det packs if enemy is within this radius and I am further away than the enemy
|
||||
|
||||
#define BOT_MAX_WEAPON_GATHER_TIME 1000 //spend a max of 1 second after spawn issuing orders to gather weapons before attacking enemy base
|
||||
#define BOT_MAX_WEAPON_CHASE_TIME 15000 //time to spend gathering the weapon before persuing the enemy base (in case it takes longer than expected)
|
||||
|
||||
#define BOT_MAX_WEAPON_CHASE_CTF 5000 //time to spend gathering the weapon before persuing the enemy base (in case it takes longer than expected) [ctf-only]
|
||||
|
||||
#define BOT_MIN_SAGA_GOAL_SHOOT 1024
|
||||
#define BOT_MIN_SAGA_GOAL_TRAVEL 128
|
||||
|
||||
#define BASE_GUARD_DISTANCE 256 //guarding the flag
|
||||
#define BASE_FLAGWAIT_DISTANCE 256 //has the enemy flag and is waiting in his own base for his flag to be returned
|
||||
#define BASE_GETENEMYFLAG_DISTANCE 256 //waiting around to get the enemy's flag
|
||||
|
||||
#define BOT_FLAG_GET_DISTANCE 256
|
||||
|
||||
#define MAX_PROJECTILE_DISTANCE 256
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CTFSTATE_NONE,
|
||||
CTFSTATE_ATTACKER,
|
||||
CTFSTATE_DEFENDER,
|
||||
CTFSTATE_RETRIEVAL,
|
||||
CTFSTATE_GUARDCARRIER,
|
||||
CTFSTATE_GETFLAGHOME,
|
||||
CTFSTATE_MAXCTFSTATES
|
||||
} bot_ctf_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SAGASTATE_NONE,
|
||||
SAGASTATE_ATTACKER,
|
||||
SAGASTATE_DEFENDER,
|
||||
SAGASTATE_MAXSAGASTATES
|
||||
} bot_saga_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TEAMPLAYSTATE_NONE,
|
||||
TEAMPLAYSTATE_FOLLOWING,
|
||||
TEAMPLAYSTATE_ASSISTING,
|
||||
TEAMPLAYSTATE_REGROUP,
|
||||
TEAMPLAYSTATE_MAXTPSTATES
|
||||
} bot_teamplay_state_t;
|
||||
|
||||
typedef struct wpneighbor_s
|
||||
{
|
||||
int num;
|
||||
int forceJumpTo;
|
||||
} wpneighbor_t;
|
||||
|
||||
typedef struct wpobject_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int inuse;
|
||||
int index;
|
||||
float weight;
|
||||
float disttonext;
|
||||
int flags;
|
||||
int associated_entity;
|
||||
|
||||
int forceJumpTo;
|
||||
|
||||
int neighbornum;
|
||||
//int neighbors[MAX_NEIGHBOR_SIZE];
|
||||
wpneighbor_t neighbors[MAX_NEIGHBOR_SIZE];
|
||||
} wpobject_t;
|
||||
|
||||
typedef struct botattachment_s
|
||||
{
|
||||
int level;
|
||||
char name[MAX_ATTACHMENT_NAME];
|
||||
} botattachment_t;
|
||||
|
||||
typedef struct nodeobject_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int inuse;
|
||||
int index;
|
||||
float weight;
|
||||
int flags;
|
||||
int neighbornum;
|
||||
} nodeobject_t;
|
||||
|
||||
typedef struct boteventtracker_s
|
||||
{
|
||||
int eventSequence;
|
||||
int events[MAX_PS_EVENTS];
|
||||
float eventTime;
|
||||
} boteventtracker_t;
|
||||
|
||||
typedef struct botskills_s
|
||||
{
|
||||
int reflex;
|
||||
float accuracy;
|
||||
float turnspeed;
|
||||
float turnspeed_combat;
|
||||
float maxturn;
|
||||
int perfectaim;
|
||||
} botskills_t;
|
||||
|
||||
//bot state
|
||||
typedef struct bot_state_s
|
||||
{
|
||||
int inuse; //true if this state is used by a bot client
|
||||
int botthink_residual; //residual for the bot thinks
|
||||
int client; //client number of the bot
|
||||
int entitynum; //entity number of the bot
|
||||
playerState_t cur_ps; //current player state
|
||||
usercmd_t lastucmd; //usercmd from last frame
|
||||
bot_settings_t settings; //several bot settings
|
||||
float thinktime; //time the bot thinks this frame
|
||||
vec3_t origin; //origin of the bot
|
||||
vec3_t velocity; //velocity of the bot
|
||||
vec3_t eye; //eye coordinates of the bot
|
||||
int setupcount; //true when the bot has just been setup
|
||||
float ltime; //local bot time
|
||||
float entergame_time; //time the bot entered the game
|
||||
int ms; //move state of the bot
|
||||
int gs; //goal state of the bot
|
||||
int ws; //weapon state of the bot
|
||||
vec3_t viewangles; //current view angles
|
||||
vec3_t ideal_viewangles; //ideal view angles
|
||||
vec3_t viewanglespeed;
|
||||
|
||||
//rww - new AI values
|
||||
gentity_t *currentEnemy;
|
||||
gentity_t *revengeEnemy;
|
||||
|
||||
gentity_t *squadLeader;
|
||||
|
||||
gentity_t *lastHurt;
|
||||
gentity_t *lastAttacked;
|
||||
|
||||
gentity_t *wantFlag;
|
||||
|
||||
gentity_t *touchGoal;
|
||||
gentity_t *shootGoal;
|
||||
|
||||
gentity_t *dangerousObject;
|
||||
|
||||
vec3_t staticFlagSpot;
|
||||
|
||||
int revengeHateLevel;
|
||||
int isSquadLeader;
|
||||
|
||||
int squadRegroupInterval;
|
||||
int squadCannotLead;
|
||||
|
||||
int lastDeadTime;
|
||||
|
||||
wpobject_t *wpCurrent;
|
||||
wpobject_t *wpDestination;
|
||||
wpobject_t *wpStoreDest;
|
||||
vec3_t goalAngles;
|
||||
vec3_t goalMovedir;
|
||||
vec3_t goalPosition;
|
||||
|
||||
vec3_t lastEnemySpotted;
|
||||
vec3_t hereWhenSpotted;
|
||||
int lastVisibleEnemyIndex;
|
||||
int hitSpotted;
|
||||
|
||||
int wpDirection;
|
||||
|
||||
float destinationGrabTime;
|
||||
float wpSeenTime;
|
||||
float wpTravelTime;
|
||||
float wpDestSwitchTime;
|
||||
float wpSwitchTime;
|
||||
float wpDestIgnoreTime;
|
||||
|
||||
float timeToReact;
|
||||
|
||||
float enemySeenTime;
|
||||
|
||||
float chickenWussCalculationTime;
|
||||
|
||||
float beStill;
|
||||
float duckTime;
|
||||
float jumpTime;
|
||||
float jDelay;
|
||||
|
||||
float aimOffsetTime;
|
||||
float aimOffsetAmtYaw;
|
||||
float aimOffsetAmtPitch;
|
||||
|
||||
float frame_Waypoint_Len;
|
||||
int frame_Waypoint_Vis;
|
||||
float frame_Enemy_Len;
|
||||
int frame_Enemy_Vis;
|
||||
|
||||
int isCamper;
|
||||
float isCamping;
|
||||
wpobject_t *wpCamping;
|
||||
wpobject_t *wpCampingTo;
|
||||
qboolean campStanding;
|
||||
|
||||
int randomNavTime;
|
||||
int randomNav;
|
||||
|
||||
int meleeSpecialist;
|
||||
|
||||
int canChat;
|
||||
int chatFrequency;
|
||||
char currentChat[MAX_CHAT_LINE_SIZE];
|
||||
float chatTime;
|
||||
float chatTime_stored;
|
||||
int doChat;
|
||||
int chatTeam;
|
||||
gentity_t *chatObject;
|
||||
gentity_t *chatAltObject;
|
||||
|
||||
float meleeStrafeTime;
|
||||
int meleeStrafeDir;
|
||||
float meleeStrafeDisable;
|
||||
|
||||
int altChargeTime;
|
||||
|
||||
float escapeDirTime;
|
||||
|
||||
float dontGoBack;
|
||||
|
||||
int doAttack;
|
||||
int doAltAttack;
|
||||
|
||||
int forceWeaponSelect;
|
||||
int virtualWeapon;
|
||||
|
||||
int runningLikeASissy;
|
||||
int runningToEscapeThreat;
|
||||
|
||||
//char chatBuffer[MAX_CHAT_BUFFER_SIZE];
|
||||
//Since we're once again not allocating bot structs dynamically,
|
||||
//shoving a 64k chat buffer into one is a bad thing.
|
||||
|
||||
botskills_t skills;
|
||||
|
||||
botattachment_t loved[MAX_LOVED_ONES];
|
||||
int lovednum;
|
||||
|
||||
int loved_death_thresh;
|
||||
|
||||
int deathActivitiesDone;
|
||||
|
||||
float botWeaponWeights[WP_NUM_WEAPONS];
|
||||
|
||||
int ctfState;
|
||||
|
||||
int teamplayState;
|
||||
|
||||
int state_Forced; //set by player ordering menu
|
||||
|
||||
int noUseTime;
|
||||
|
||||
vec3_t launchAngle;
|
||||
//end rww
|
||||
} bot_state_t;
|
||||
|
||||
void *B_TempAlloc(int size);
|
||||
void B_TempFree(int size);
|
||||
|
||||
void *B_Alloc(int size);
|
||||
void B_Free(void *ptr);
|
||||
|
||||
//resets the whole bot state
|
||||
void BotResetState(bot_state_t *bs);
|
||||
//returns the number of bots in the game
|
||||
int NumBots(void);
|
||||
|
||||
void BotUtilizePersonality(bot_state_t *bs);
|
||||
int BotDoChat(bot_state_t *bs, char *section, int always);
|
||||
void StandardBotAI(bot_state_t *bs, float thinktime);
|
||||
void BotWaypointRender(void);
|
||||
int OrgVisibleBox(vec3_t org1, vec3_t mins, vec3_t maxs, vec3_t org2, int ignore);
|
||||
int BotIsAChickenWuss(bot_state_t *bs);
|
||||
int GetNearestVisibleWP(vec3_t org, int ignore);
|
||||
int GetBestIdleGoal(bot_state_t *bs);
|
||||
|
||||
char *ConcatArgs( int start );
|
||||
|
||||
extern vmCvar_t bot_attachments;
|
||||
extern vmCvar_t bot_camp;
|
||||
|
||||
extern vmCvar_t bot_wp_info;
|
||||
extern vmCvar_t bot_wp_edit;
|
||||
extern vmCvar_t bot_wp_clearweight;
|
||||
extern vmCvar_t bot_wp_distconnect;
|
||||
extern vmCvar_t bot_wp_visconnect;
|
||||
|
||||
extern wpobject_t *flagRed;
|
||||
extern wpobject_t *oFlagRed;
|
||||
extern wpobject_t *flagBlue;
|
||||
extern wpobject_t *oFlagBlue;
|
||||
|
||||
extern gentity_t *eFlagRed;
|
||||
extern gentity_t *eFlagBlue;
|
||||
|
||||
extern char gBotChatBuffer[MAX_CLIENTS][MAX_CHAT_BUFFER_SIZE];
|
||||
extern float gWPRenderTime;
|
||||
extern float gDeactivated;
|
||||
extern float gBotEdit;
|
||||
extern int gWPRenderedFrame;
|
||||
extern wpobject_t *gWPArray[MAX_WPARRAY_SIZE];
|
||||
extern int gWPNum;
|
||||
extern int gLastPrintedIndex;
|
||||
extern nodeobject_t nodetable[MAX_NODETABLE_SIZE];
|
||||
extern int nodenum;
|
||||
|
||||
extern float floattime;
|
||||
#define FloatTime() floattime
|
799
code/game/ai_util.c
Normal file
799
code/game/ai_util.c
Normal file
|
@ -0,0 +1,799 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// ai_util.c
|
||||
|
||||
#include "g_local.h"
|
||||
#include "q_shared.h"
|
||||
#include "botlib.h"
|
||||
#include "ai_main.h"
|
||||
|
||||
#ifdef BOT_ZMALLOC
|
||||
#define MAX_BALLOC 8192
|
||||
|
||||
void *BAllocList[MAX_BALLOC];
|
||||
#endif
|
||||
|
||||
char gBotChatBuffer[MAX_CLIENTS][MAX_CHAT_BUFFER_SIZE];
|
||||
//A total of 4194304 bytes. Not very nice at all, but we really
|
||||
//want to have at least 65k for the total chat buffer just in
|
||||
//case and we have no method of dynamic allocation here.
|
||||
|
||||
void *B_TempAlloc(int size)
|
||||
{
|
||||
return trap_VM_LocalTempAlloc(size);
|
||||
}
|
||||
|
||||
void B_TempFree(int size)
|
||||
{
|
||||
trap_VM_LocalTempFree(size);
|
||||
}
|
||||
|
||||
|
||||
void *B_Alloc(int size)
|
||||
{
|
||||
#ifdef BOT_ZMALLOC
|
||||
void *ptr = NULL;
|
||||
int i = 0;
|
||||
|
||||
#ifdef BOTMEMTRACK
|
||||
int free = 0;
|
||||
int used = 0;
|
||||
|
||||
while (i < MAX_BALLOC)
|
||||
{
|
||||
if (!BAllocList[i])
|
||||
{
|
||||
free++;
|
||||
}
|
||||
else
|
||||
{
|
||||
used++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
Com_Printf("Allocations used: %i\nFree allocation slots: %i\n", used, free);
|
||||
|
||||
i = 0;
|
||||
#endif
|
||||
|
||||
ptr = trap_BotGetMemoryGame(size);
|
||||
|
||||
while (i < MAX_BALLOC)
|
||||
{
|
||||
if (!BAllocList[i])
|
||||
{
|
||||
BAllocList[i] = ptr;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == MAX_BALLOC)
|
||||
{
|
||||
//If this happens we'll have to rely on this chunk being freed manually with B_Free, which it hopefully will be
|
||||
#ifdef DEBUG
|
||||
Com_Printf("WARNING: MAXIMUM B_ALLOC ALLOCATIONS EXCEEDED\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
|
||||
return trap_VM_LocalAlloc(size);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void B_Free(void *ptr)
|
||||
{
|
||||
#ifdef BOT_ZMALLOC
|
||||
int i = 0;
|
||||
|
||||
#ifdef BOTMEMTRACK
|
||||
int free = 0;
|
||||
int used = 0;
|
||||
|
||||
while (i < MAX_BALLOC)
|
||||
{
|
||||
if (!BAllocList[i])
|
||||
{
|
||||
free++;
|
||||
}
|
||||
else
|
||||
{
|
||||
used++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
Com_Printf("Allocations used: %i\nFree allocation slots: %i\n", used, free);
|
||||
|
||||
i = 0;
|
||||
#endif
|
||||
|
||||
while (i < MAX_BALLOC)
|
||||
{
|
||||
if (BAllocList[i] == ptr)
|
||||
{
|
||||
BAllocList[i] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == MAX_BALLOC)
|
||||
{
|
||||
//Likely because the limit was exceeded and we're now freeing the chunk manually as we hoped would happen
|
||||
#ifdef DEBUG
|
||||
Com_Printf("WARNING: Freeing allocation which is not in the allocation structure\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
trap_BotFreeMemoryGame(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void B_InitAlloc(void)
|
||||
{
|
||||
#ifdef BOT_ZMALLOC
|
||||
memset(BAllocList, 0, sizeof(BAllocList));
|
||||
#endif
|
||||
|
||||
memset(gWPArray, 0, sizeof(gWPArray));
|
||||
}
|
||||
|
||||
void B_CleanupAlloc(void)
|
||||
{
|
||||
#ifdef BOT_ZMALLOC
|
||||
int i = 0;
|
||||
|
||||
while (i < MAX_BALLOC)
|
||||
{
|
||||
if (BAllocList[i])
|
||||
{
|
||||
trap_BotFreeMemoryGame(BAllocList[i]);
|
||||
BAllocList[i] = NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int GetValueGroup(char *buf, char *group, char *outbuf)
|
||||
{
|
||||
char *place, *placesecond;
|
||||
int iplace;
|
||||
int failure;
|
||||
int i;
|
||||
int startpoint, startletter;
|
||||
int subg = 0;
|
||||
|
||||
i = 0;
|
||||
|
||||
iplace = 0;
|
||||
|
||||
place = strstr(buf, group);
|
||||
|
||||
if (!place)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
startpoint = place - buf + strlen(group) + 1;
|
||||
startletter = (place - buf) - 1;
|
||||
|
||||
failure = 0;
|
||||
|
||||
while (buf[startpoint+1] != '{' || buf[startletter] != '\n')
|
||||
{
|
||||
placesecond = strstr(place+1, group);
|
||||
|
||||
if (placesecond)
|
||||
{
|
||||
startpoint += (placesecond - place);
|
||||
startletter += (placesecond - place);
|
||||
place = placesecond;
|
||||
}
|
||||
else
|
||||
{
|
||||
failure = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (failure)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//we have found the proper group name if we made it here, so find the opening brace and read into the outbuf
|
||||
//until hitting the end brace
|
||||
|
||||
while (buf[startpoint] != '{')
|
||||
{
|
||||
startpoint++;
|
||||
}
|
||||
|
||||
startpoint++;
|
||||
|
||||
while (buf[startpoint] != '}' || subg)
|
||||
{
|
||||
if (buf[startpoint] == '{')
|
||||
{
|
||||
subg++;
|
||||
}
|
||||
else if (buf[startpoint] == '}')
|
||||
{
|
||||
subg--;
|
||||
}
|
||||
outbuf[i] = buf[startpoint];
|
||||
i++;
|
||||
startpoint++;
|
||||
}
|
||||
outbuf[i] = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GetPairedValue(char *buf, char *key, char *outbuf)
|
||||
{
|
||||
char *place, *placesecond;
|
||||
int startpoint, startletter;
|
||||
int i, found;
|
||||
|
||||
if (!buf || !key || !outbuf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (buf[i] && buf[i] != '\0')
|
||||
{
|
||||
if (buf[i] == '/')
|
||||
{
|
||||
if (buf[i+1] && buf[i+1] != '\0' && buf[i+1] == '/')
|
||||
{
|
||||
while (buf[i] != '\n')
|
||||
{
|
||||
buf[i] = '/';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
place = strstr(buf, key);
|
||||
|
||||
if (!place)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//tab == 9
|
||||
startpoint = place - buf + strlen(key);
|
||||
startletter = (place - buf) - 1;
|
||||
|
||||
found = 0;
|
||||
|
||||
while (!found)
|
||||
{
|
||||
if (startletter == 0 || !buf[startletter] || buf[startletter] == '\0' || buf[startletter] == 9 || buf[startletter] == ' ' || buf[startletter] == '\n')
|
||||
{
|
||||
if (buf[startpoint] == '\0' || buf[startpoint] == 9 || buf[startpoint] == ' ' || buf[startpoint] == '\n')
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
placesecond = strstr(place+1, key);
|
||||
|
||||
if (placesecond)
|
||||
{
|
||||
startpoint += placesecond - place;
|
||||
startletter += placesecond - place;
|
||||
place = placesecond;
|
||||
}
|
||||
else
|
||||
{
|
||||
place = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!found || !place || !buf[startpoint] || buf[startpoint] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (buf[startpoint] == ' ' || buf[startpoint] == 9 || buf[startpoint] == '\n')
|
||||
{
|
||||
startpoint++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (buf[startpoint] && buf[startpoint] != '\0' && buf[startpoint] != '\n')
|
||||
{
|
||||
outbuf[i] = buf[startpoint];
|
||||
i++;
|
||||
startpoint++;
|
||||
}
|
||||
|
||||
outbuf[i] = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BotDoChat(bot_state_t *bs, char *section, int always)
|
||||
{
|
||||
char *chatgroup;
|
||||
int rVal;
|
||||
int inc_1;
|
||||
int inc_2;
|
||||
int inc_n;
|
||||
int lines;
|
||||
int checkedline;
|
||||
int getthisline;
|
||||
gentity_t *cobject;
|
||||
|
||||
if (!bs->canChat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs->doChat)
|
||||
{ //already have a chat scheduled
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Q_irand(1, 10) > bs->chatFrequency && !always)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bs->chatTeam = 0;
|
||||
|
||||
chatgroup = (char *)B_TempAlloc(MAX_CHAT_BUFFER_SIZE);
|
||||
|
||||
rVal = GetValueGroup(gBotChatBuffer[bs->client], section, chatgroup);
|
||||
|
||||
if (!rVal) //the bot has no group defined for the specified chat event
|
||||
{
|
||||
B_TempFree(MAX_CHAT_BUFFER_SIZE); //chatgroup
|
||||
return 0;
|
||||
}
|
||||
|
||||
inc_1 = 0;
|
||||
inc_2 = 2;
|
||||
|
||||
while (chatgroup[inc_2] && chatgroup[inc_2] != '\0')
|
||||
{
|
||||
if (chatgroup[inc_2] != 13 && chatgroup[inc_2] != 9)
|
||||
{
|
||||
chatgroup[inc_1] = chatgroup[inc_2];
|
||||
inc_1++;
|
||||
}
|
||||
inc_2++;
|
||||
}
|
||||
chatgroup[inc_1] = '\0';
|
||||
|
||||
inc_1 = 0;
|
||||
|
||||
lines = 0;
|
||||
|
||||
while (chatgroup[inc_1] && chatgroup[inc_1] != '\0')
|
||||
{
|
||||
if (chatgroup[inc_1] == '\n')
|
||||
{
|
||||
lines++;
|
||||
}
|
||||
inc_1++;
|
||||
}
|
||||
|
||||
if (!lines)
|
||||
{
|
||||
B_TempFree(MAX_CHAT_BUFFER_SIZE); //chatgroup
|
||||
return 0;
|
||||
}
|
||||
|
||||
getthisline = Q_irand(0, (lines+1));
|
||||
|
||||
if (getthisline < 1)
|
||||
{
|
||||
getthisline = 1;
|
||||
}
|
||||
if (getthisline > lines)
|
||||
{
|
||||
getthisline = lines;
|
||||
}
|
||||
|
||||
checkedline = 1;
|
||||
|
||||
inc_1 = 0;
|
||||
|
||||
while (checkedline != getthisline)
|
||||
{
|
||||
if (chatgroup[inc_1] && chatgroup[inc_1] != '\0')
|
||||
{
|
||||
if (chatgroup[inc_1] == '\n')
|
||||
{
|
||||
inc_1++;
|
||||
checkedline++;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkedline == getthisline)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
inc_1++;
|
||||
}
|
||||
|
||||
//we're at the starting position of the desired line here
|
||||
inc_2 = 0;
|
||||
|
||||
while (chatgroup[inc_1] != '\n')
|
||||
{
|
||||
chatgroup[inc_2] = chatgroup[inc_1];
|
||||
inc_2++;
|
||||
inc_1++;
|
||||
}
|
||||
chatgroup[inc_2] = '\0';
|
||||
|
||||
//trap_EA_Say(bs->client, chatgroup);
|
||||
inc_1 = 0;
|
||||
inc_2 = 0;
|
||||
|
||||
if (strlen(chatgroup) > MAX_CHAT_LINE_SIZE)
|
||||
{
|
||||
B_TempFree(MAX_CHAT_BUFFER_SIZE); //chatgroup
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (chatgroup[inc_1])
|
||||
{
|
||||
if (chatgroup[inc_1] == '%' && chatgroup[inc_1+1] != '%')
|
||||
{
|
||||
inc_1++;
|
||||
|
||||
if (chatgroup[inc_1] == 's' && bs->chatObject)
|
||||
{
|
||||
cobject = bs->chatObject;
|
||||
}
|
||||
else if (chatgroup[inc_1] == 'a' && bs->chatAltObject)
|
||||
{
|
||||
cobject = bs->chatAltObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
cobject = NULL;
|
||||
}
|
||||
|
||||
if (cobject && cobject->client)
|
||||
{
|
||||
inc_n = 0;
|
||||
|
||||
while (cobject->client->pers.netname[inc_n])
|
||||
{
|
||||
bs->currentChat[inc_2] = cobject->client->pers.netname[inc_n];
|
||||
inc_2++;
|
||||
inc_n++;
|
||||
}
|
||||
inc_2--; //to make up for the auto-increment below
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->currentChat[inc_2] = chatgroup[inc_1];
|
||||
}
|
||||
inc_2++;
|
||||
inc_1++;
|
||||
}
|
||||
bs->currentChat[inc_2] = '\0';
|
||||
|
||||
if (strcmp(section, "GeneralGreetings") == 0)
|
||||
{
|
||||
bs->doChat = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->doChat = 1;
|
||||
}
|
||||
bs->chatTime_stored = (strlen(bs->currentChat)*45)+Q_irand(1300, 1500);
|
||||
bs->chatTime = level.time + bs->chatTime_stored;
|
||||
|
||||
B_TempFree(MAX_CHAT_BUFFER_SIZE); //chatgroup
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ParseEmotionalAttachments(bot_state_t *bs, char *buf)
|
||||
{
|
||||
int i = 0;
|
||||
int i_c = 0;
|
||||
char tbuf[16];
|
||||
|
||||
while (buf[i] && buf[i] != '}')
|
||||
{
|
||||
while (buf[i] == ' ' || buf[i] == '{' || buf[i] == 9 || buf[i] == 13 || buf[i] == '\n')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
if (buf[i] && buf[i] != '}')
|
||||
{
|
||||
i_c = 0;
|
||||
while (buf[i] != '{' && buf[i] != 9 && buf[i] != 13 && buf[i] != '\n')
|
||||
{
|
||||
bs->loved[bs->lovednum].name[i_c] = buf[i];
|
||||
i_c++;
|
||||
i++;
|
||||
}
|
||||
bs->loved[bs->lovednum].name[i_c] = '\0';
|
||||
|
||||
while (buf[i] == ' ' || buf[i] == '{' || buf[i] == 9 || buf[i] == 13 || buf[i] == '\n')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
i_c = 0;
|
||||
|
||||
while (buf[i] != '{' && buf[i] != 9 && buf[i] != 13 && buf[i] != '\n')
|
||||
{
|
||||
tbuf[i_c] = buf[i];
|
||||
i_c++;
|
||||
i++;
|
||||
}
|
||||
tbuf[i_c] = '\0';
|
||||
|
||||
bs->loved[bs->lovednum].level = atoi(tbuf);
|
||||
|
||||
bs->lovednum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (bs->lovednum >= MAX_LOVED_ONES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int ReadChatGroups(bot_state_t *bs, char *buf)
|
||||
{
|
||||
char *cgroupbegin;
|
||||
int cgbplace;
|
||||
int i;
|
||||
|
||||
cgroupbegin = strstr(buf, "BEGIN_CHAT_GROUPS");
|
||||
|
||||
if (!cgroupbegin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strlen(cgroupbegin) >= MAX_CHAT_BUFFER_SIZE)
|
||||
{
|
||||
Com_Printf(S_COLOR_RED "Error: Personality chat section exceeds max size\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cgbplace = cgroupbegin - buf+1;
|
||||
|
||||
while (buf[cgbplace] != '\n')
|
||||
{
|
||||
cgbplace++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (buf[cgbplace] && buf[cgbplace] != '\0')
|
||||
{
|
||||
gBotChatBuffer[bs->client][i] = buf[cgbplace];
|
||||
i++;
|
||||
cgbplace++;
|
||||
}
|
||||
|
||||
gBotChatBuffer[bs->client][i] = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char personalityBuffer[131072];
|
||||
|
||||
void BotUtilizePersonality(bot_state_t *bs)
|
||||
{
|
||||
fileHandle_t f;
|
||||
int len, rlen;
|
||||
int failed;
|
||||
int i;
|
||||
char *readbuf, *group;
|
||||
|
||||
len = trap_FS_FOpenFile(bs->settings.personalityfile, &f, FS_READ);
|
||||
|
||||
failed = 0;
|
||||
|
||||
if (!f)
|
||||
{
|
||||
Com_Printf(S_COLOR_RED "Error: Specified personality not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len >= 131072)
|
||||
{
|
||||
Com_Printf(S_COLOR_RED "Personality file exceeds maximum length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
trap_FS_Read(personalityBuffer, len, f);
|
||||
|
||||
rlen = len;
|
||||
|
||||
while (len < 131072)
|
||||
{ //kill all characters after the file length, since sometimes FS_Read doesn't do that entirely (or so it seems)
|
||||
personalityBuffer[len] = '\0';
|
||||
len++;
|
||||
}
|
||||
|
||||
len = rlen;
|
||||
|
||||
readbuf = (char *)trap_VM_LocalTempAlloc(1024);
|
||||
group = (char *)trap_VM_LocalTempAlloc(65536);
|
||||
|
||||
if (!GetValueGroup(personalityBuffer, "GeneralBotInfo", group))
|
||||
{
|
||||
Com_Printf(S_COLOR_RED "Personality file contains no GeneralBotInfo group\n");
|
||||
failed = 1; //set failed so we know to set everything to default values
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "reflex", readbuf))
|
||||
{
|
||||
bs->skills.reflex = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.reflex = 100; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "accuracy", readbuf))
|
||||
{
|
||||
bs->skills.accuracy = atof(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.accuracy = 10; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "turnspeed", readbuf))
|
||||
{
|
||||
bs->skills.turnspeed = atof(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.turnspeed = 0.01f; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "turnspeed_combat", readbuf))
|
||||
{
|
||||
bs->skills.turnspeed_combat = atof(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.turnspeed_combat = 0.05f; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "maxturn", readbuf))
|
||||
{
|
||||
bs->skills.maxturn = atof(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.maxturn = 360; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "perfectaim", readbuf))
|
||||
{
|
||||
bs->skills.perfectaim = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->skills.perfectaim = 0; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "chatability", readbuf))
|
||||
{
|
||||
bs->canChat = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->canChat = 0; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "chatfrequency", readbuf))
|
||||
{
|
||||
bs->chatFrequency = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->chatFrequency = 5; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "hatelevel", readbuf))
|
||||
{
|
||||
bs->loved_death_thresh = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->loved_death_thresh = 3; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "camper", readbuf))
|
||||
{
|
||||
bs->isCamper = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->isCamper = 0; //default
|
||||
}
|
||||
|
||||
if (!failed && GetPairedValue(group, "meleeSpecialist", readbuf))
|
||||
{
|
||||
bs->meleeSpecialist = atoi(readbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->meleeSpecialist = 0; //default
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < MAX_CHAT_BUFFER_SIZE)
|
||||
{ //clear out the chat buffer for this bot
|
||||
gBotChatBuffer[bs->client][i] = '\0';
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bs->canChat)
|
||||
{
|
||||
if (!ReadChatGroups(bs, personalityBuffer))
|
||||
{
|
||||
bs->canChat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetValueGroup(personalityBuffer, "BotWeaponWeights", group))
|
||||
{
|
||||
for (i=0; i < WP_NUM_WEAPONS; i++)
|
||||
{
|
||||
if (GetPairedValue(group, bg_weaponNames[i], readbuf))
|
||||
{
|
||||
bs->botWeaponWeights[i] = atoi(readbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs->lovednum = 0;
|
||||
|
||||
if (GetValueGroup(personalityBuffer, "EmotionalAttachments", group))
|
||||
{
|
||||
ParseEmotionalAttachments(bs, group);
|
||||
}
|
||||
|
||||
trap_VM_LocalTempFree(65536);
|
||||
trap_VM_LocalTempFree(1024);
|
||||
trap_FS_FCloseFile(f);
|
||||
}
|
2341
code/game/ai_wpnav.c
Normal file
2341
code/game/ai_wpnav.c
Normal file
File diff suppressed because it is too large
Load diff
0
code/game/anims.h
Normal file
0
code/game/anims.h
Normal file
205
code/game/be_aas.h
Normal file
205
code/game/be_aas.h
Normal file
|
@ -0,0 +1,205 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas.h
|
||||
*
|
||||
* desc: Area Awareness System, stuff exported to the AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_aas.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAX_STRINGFIELD
|
||||
#define MAX_STRINGFIELD 80
|
||||
#endif
|
||||
|
||||
//travel flags
|
||||
#define TFL_INVALID 0x00000001 //traveling temporary not possible
|
||||
#define TFL_WALK 0x00000002 //walking
|
||||
#define TFL_CROUCH 0x00000004 //crouching
|
||||
#define TFL_BARRIERJUMP 0x00000008 //jumping onto a barrier
|
||||
#define TFL_JUMP 0x00000010 //jumping
|
||||
#define TFL_LADDER 0x00000020 //climbing a ladder
|
||||
#define TFL_WALKOFFLEDGE 0x00000080 //walking of a ledge
|
||||
#define TFL_SWIM 0x00000100 //swimming
|
||||
#define TFL_WATERJUMP 0x00000200 //jumping out of the water
|
||||
#define TFL_TELEPORT 0x00000400 //teleporting
|
||||
#define TFL_ELEVATOR 0x00000800 //elevator
|
||||
#define TFL_ROCKETJUMP 0x00001000 //rocket jumping
|
||||
#define TFL_BFGJUMP 0x00002000 //bfg jumping
|
||||
#define TFL_GRAPPLEHOOK 0x00004000 //grappling hook
|
||||
#define TFL_DOUBLEJUMP 0x00008000 //double jump
|
||||
#define TFL_RAMPJUMP 0x00010000 //ramp jump
|
||||
#define TFL_STRAFEJUMP 0x00020000 //strafe jump
|
||||
#define TFL_JUMPPAD 0x00040000 //jump pad
|
||||
#define TFL_AIR 0x00080000 //travel through air
|
||||
#define TFL_WATER 0x00100000 //travel through water
|
||||
#define TFL_SLIME 0x00200000 //travel through slime
|
||||
#define TFL_LAVA 0x00400000 //travel through lava
|
||||
#define TFL_DONOTENTER 0x00800000 //travel through donotenter area
|
||||
#define TFL_FUNCBOB 0x01000000 //func bobbing
|
||||
#define TFL_FLIGHT 0x02000000 //flight
|
||||
#define TFL_BRIDGE 0x04000000 //move over a bridge
|
||||
//
|
||||
#define TFL_NOTTEAM1 0x08000000 //not team 1
|
||||
#define TFL_NOTTEAM2 0x10000000 //not team 2
|
||||
|
||||
//default travel flags
|
||||
#define TFL_DEFAULT TFL_WALK|TFL_CROUCH|TFL_BARRIERJUMP|\
|
||||
TFL_JUMP|TFL_LADDER|\
|
||||
TFL_WALKOFFLEDGE|TFL_SWIM|TFL_WATERJUMP|\
|
||||
TFL_TELEPORT|TFL_ELEVATOR|\
|
||||
TFL_AIR|TFL_WATER|TFL_JUMPPAD|TFL_FUNCBOB
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP // bsp clip, touch on edge
|
||||
} solid_t;
|
||||
|
||||
//a trace is returned when a box is swept through the AAS world
|
||||
typedef struct aas_trace_s
|
||||
{
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
int ent; // entity blocking the trace
|
||||
int lastarea; // last area the trace was in (zero if none)
|
||||
int area; // area blocking the trace (zero if none)
|
||||
int planenum; // number of the plane that was hit
|
||||
} aas_trace_t;
|
||||
|
||||
/* Defined in botlib.h
|
||||
|
||||
//bsp_trace_t hit surface
|
||||
typedef struct bsp_surface_s
|
||||
{
|
||||
char name[16];
|
||||
int flags;
|
||||
int value;
|
||||
} bsp_surface_t;
|
||||
|
||||
//a trace is returned when a box is swept through the BSP world
|
||||
typedef struct bsp_trace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
float exp_dist; // expanded plane distance
|
||||
int sidenum; // number of the brush side hit
|
||||
bsp_surface_t surface; // hit surface
|
||||
int contents; // contents on other side of surface hit
|
||||
int ent; // number of entity hit
|
||||
} bsp_trace_t;
|
||||
//
|
||||
*/
|
||||
|
||||
//entity info
|
||||
typedef struct aas_entityinfo_s
|
||||
{
|
||||
int valid; // true if updated this frame
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
float ltime; // local time
|
||||
float update_time; // time between last and current update
|
||||
int number; // number of the entity
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t lastvisorigin; // last visible origin
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int gametypeitems; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
} aas_entityinfo_t;
|
||||
|
||||
// area info
|
||||
typedef struct aas_areainfo_s
|
||||
{
|
||||
int contents;
|
||||
int flags;
|
||||
int presencetype;
|
||||
int cluster;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t center;
|
||||
} aas_areainfo_t;
|
||||
|
||||
// client movement prediction stop events, stop as soon as:
|
||||
#define SE_NONE 0
|
||||
#define SE_HITGROUND 1 // the ground is hit
|
||||
#define SE_LEAVEGROUND 2 // there's no ground
|
||||
#define SE_ENTERWATER 4 // water is entered
|
||||
#define SE_ENTERSLIME 8 // slime is entered
|
||||
#define SE_ENTERLAVA 16 // lava is entered
|
||||
#define SE_HITGROUNDDAMAGE 32 // the ground is hit with damage
|
||||
#define SE_GAP 64 // there's a gap
|
||||
#define SE_TOUCHJUMPPAD 128 // touching a jump pad area
|
||||
#define SE_TOUCHTELEPORTER 256 // touching teleporter
|
||||
#define SE_ENTERAREA 512 // the given stoparea is entered
|
||||
#define SE_HITGROUNDAREA 1024 // a ground face in the area is hit
|
||||
#define SE_HITBOUNDINGBOX 2048 // hit the specified bounding box
|
||||
#define SE_TOUCHCLUSTERPORTAL 4096 // touching a cluster portal
|
||||
|
||||
typedef struct aas_clientmove_s
|
||||
{
|
||||
vec3_t endpos; //position at the end of movement prediction
|
||||
int endarea; //area at end of movement prediction
|
||||
vec3_t velocity; //velocity at the end of movement prediction
|
||||
aas_trace_t trace; //last trace
|
||||
int presencetype; //presence type at end of movement prediction
|
||||
int stopevent; //event that made the prediction stop
|
||||
int endcontents; //contents at the end of movement prediction
|
||||
float time; //time predicted ahead
|
||||
int frames; //number of frames predicted ahead
|
||||
} aas_clientmove_t;
|
||||
|
||||
// alternate route goals
|
||||
#define ALTROUTEGOAL_ALL 1
|
||||
#define ALTROUTEGOAL_CLUSTERPORTALS 2
|
||||
#define ALTROUTEGOAL_VIEWPORTALS 4
|
||||
|
||||
typedef struct aas_altroutegoal_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int areanum;
|
||||
unsigned short starttraveltime;
|
||||
unsigned short goaltraveltime;
|
||||
unsigned short extratraveltime;
|
||||
} aas_altroutegoal_t;
|
||||
|
||||
// route prediction stop events
|
||||
#define RSE_NONE 0
|
||||
#define RSE_NOROUTE 1 //no route to goal
|
||||
#define RSE_USETRAVELTYPE 2 //stop as soon as on of the given travel types is used
|
||||
#define RSE_ENTERCONTENTS 4 //stop when entering the given contents
|
||||
#define RSE_ENTERAREA 8 //stop when entering the given area
|
||||
|
||||
typedef struct aas_predictroute_s
|
||||
{
|
||||
vec3_t endpos; //position at the end of movement prediction
|
||||
int endarea; //area at end of movement prediction
|
||||
int stopevent; //event that made the prediction stop
|
||||
int endcontents; //contents at the end of movement prediction
|
||||
int endtravelflags; //end travel flags
|
||||
int numareas; //number of areas predicted ahead
|
||||
int time; //time predicted ahead (in hundreth of a sec)
|
||||
} aas_predictroute_t;
|
32
code/game/be_ai_char.h
Normal file
32
code/game/be_ai_char.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_char.h
|
||||
*
|
||||
* desc: bot characters
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_char.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//loads a bot character from a file
|
||||
int BotLoadCharacter(char *charfile, float skill);
|
||||
//frees a bot character
|
||||
void BotFreeCharacter(int character);
|
||||
//returns a float characteristic
|
||||
float Characteristic_Float(int character, int index);
|
||||
//returns a bounded float characteristic
|
||||
float Characteristic_BFloat(int character, int index, float min, float max);
|
||||
//returns an integer characteristic
|
||||
int Characteristic_Integer(int character, int index);
|
||||
//returns a bounded integer characteristic
|
||||
int Characteristic_BInteger(int character, int index, int min, int max);
|
||||
//returns a string characteristic
|
||||
void Characteristic_String(int character, int index, char *buf, int size);
|
||||
//free cached bot characters
|
||||
void BotShutdownCharacters(void);
|
97
code/game/be_ai_chat.h
Normal file
97
code/game/be_ai_chat.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: be_ai_chat.h
|
||||
*
|
||||
* desc: char AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_chat.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define MAX_CHATTYPE_NAME 32
|
||||
#define MAX_MATCHVARIABLES 8
|
||||
|
||||
#define CHAT_GENDERLESS 0
|
||||
#define CHAT_GENDERFEMALE 1
|
||||
#define CHAT_GENDERMALE 2
|
||||
|
||||
#define CHAT_ALL 0
|
||||
#define CHAT_TEAM 1
|
||||
#define CHAT_TELL 2
|
||||
|
||||
//a console message
|
||||
typedef struct bot_consolemessage_s
|
||||
{
|
||||
int handle;
|
||||
float time; //message time
|
||||
int type; //message type
|
||||
char message[MAX_MESSAGE_SIZE]; //message
|
||||
struct bot_consolemessage_s *prev, *next; //prev and next in list
|
||||
} bot_consolemessage_t;
|
||||
|
||||
//match variable
|
||||
typedef struct bot_matchvariable_s
|
||||
{
|
||||
char offset;
|
||||
int length;
|
||||
} bot_matchvariable_t;
|
||||
//returned to AI when a match is found
|
||||
typedef struct bot_match_s
|
||||
{
|
||||
char string[MAX_MESSAGE_SIZE];
|
||||
int type;
|
||||
int subtype;
|
||||
bot_matchvariable_t variables[MAX_MATCHVARIABLES];
|
||||
} bot_match_t;
|
||||
|
||||
//setup the chat AI
|
||||
int BotSetupChatAI(void);
|
||||
//shutdown the chat AI
|
||||
void BotShutdownChatAI(void);
|
||||
//returns the handle to a newly allocated chat state
|
||||
int BotAllocChatState(void);
|
||||
//frees the chatstate
|
||||
void BotFreeChatState(int handle);
|
||||
//adds a console message to the chat state
|
||||
void BotQueueConsoleMessage(int chatstate, int type, char *message);
|
||||
//removes the console message from the chat state
|
||||
void BotRemoveConsoleMessage(int chatstate, int handle);
|
||||
//returns the next console message from the state
|
||||
int BotNextConsoleMessage(int chatstate, bot_consolemessage_t *cm);
|
||||
//returns the number of console messages currently stored in the state
|
||||
int BotNumConsoleMessages(int chatstate);
|
||||
//selects a chat message of the given type
|
||||
void BotInitialChat(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
//returns the number of initial chat messages of the given type
|
||||
int BotNumInitialChats(int chatstate, char *type);
|
||||
//find and select a reply for the given message
|
||||
int BotReplyChat(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
//returns the length of the currently selected chat message
|
||||
int BotChatLength(int chatstate);
|
||||
//enters the selected chat message
|
||||
void BotEnterChat(int chatstate, int clientto, int sendto);
|
||||
//get the chat message ready to be output
|
||||
void BotGetChatMessage(int chatstate, char *buf, int size);
|
||||
//checks if the first string contains the second one, returns index into first string or -1 if not found
|
||||
int StringContains(char *str1, char *str2, int casesensitive);
|
||||
//finds a match for the given string using the match templates
|
||||
int BotFindMatch(char *str, bot_match_t *match, unsigned long int context);
|
||||
//returns a variable from a match
|
||||
void BotMatchVariable(bot_match_t *match, int variable, char *buf, int size);
|
||||
//unify all the white spaces in the string
|
||||
void UnifyWhiteSpaces(char *string);
|
||||
//replace all the context related synonyms in the string
|
||||
void BotReplaceSynonyms(char *string, unsigned long int context);
|
||||
//loads a chat file for the chat state
|
||||
int BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
|
||||
//store the gender of the bot in the chat state
|
||||
void BotSetChatGender(int chatstate, int gender);
|
||||
//store the bot name in the chat state
|
||||
void BotSetChatName(int chatstate, char *name, int client);
|
||||
|
17
code/game/be_ai_gen.h
Normal file
17
code/game/be_ai_gen.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_gen.h
|
||||
*
|
||||
* desc: genetic selection
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_gen.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);
|
102
code/game/be_ai_goal.h
Normal file
102
code/game/be_ai_goal.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: be_ai_goal.h
|
||||
*
|
||||
* desc: goal AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_goal.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_AVOIDGOALS 256
|
||||
#define MAX_GOALSTACK 8
|
||||
|
||||
#define GFL_NONE 0
|
||||
#define GFL_ITEM 1
|
||||
#define GFL_ROAM 2
|
||||
#define GFL_DROPPED 4
|
||||
|
||||
//a bot goal
|
||||
typedef struct bot_goal_s
|
||||
{
|
||||
vec3_t origin; //origin of the goal
|
||||
int areanum; //area number of the goal
|
||||
vec3_t mins, maxs; //mins and maxs of the goal
|
||||
int entitynum; //number of the goal entity
|
||||
int number; //goal number
|
||||
int flags; //goal flags
|
||||
int iteminfo; //item information
|
||||
} bot_goal_t;
|
||||
|
||||
//reset the whole goal state, but keep the item weights
|
||||
void BotResetGoalState(int goalstate);
|
||||
//reset avoid goals
|
||||
void BotResetAvoidGoals(int goalstate);
|
||||
//remove the goal with the given number from the avoid goals
|
||||
void BotRemoveFromAvoidGoals(int goalstate, int number);
|
||||
//push a goal onto the goal stack
|
||||
void BotPushGoal(int goalstate, bot_goal_t *goal);
|
||||
//pop a goal from the goal stack
|
||||
void BotPopGoal(int goalstate);
|
||||
//empty the bot's goal stack
|
||||
void BotEmptyGoalStack(int goalstate);
|
||||
//dump the avoid goals
|
||||
void BotDumpAvoidGoals(int goalstate);
|
||||
//dump the goal stack
|
||||
void BotDumpGoalStack(int goalstate);
|
||||
//get the name name of the goal with the given number
|
||||
void BotGoalName(int number, char *name, int size);
|
||||
//get the top goal from the stack
|
||||
int BotGetTopGoal(int goalstate, bot_goal_t *goal);
|
||||
//get the second goal on the stack
|
||||
int BotGetSecondGoal(int goalstate, bot_goal_t *goal);
|
||||
//choose the best long term goal item for the bot
|
||||
int BotChooseLTGItem(int goalstate, vec3_t origin, int *inventory, int travelflags);
|
||||
//choose the best nearby goal item for the bot
|
||||
//the item may not be further away from the current bot position than maxtime
|
||||
//also the travel time from the nearby goal towards the long term goal may not
|
||||
//be larger than the travel time towards the long term goal from the current bot position
|
||||
int BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags,
|
||||
bot_goal_t *ltg, float maxtime);
|
||||
//returns true if the bot touches the goal
|
||||
int BotTouchingGoal(vec3_t origin, bot_goal_t *goal);
|
||||
//returns true if the goal should be visible but isn't
|
||||
int BotItemGoalInVisButNotVisible(int viewer, vec3_t eye, vec3_t viewangles, bot_goal_t *goal);
|
||||
//search for a goal for the given classname, the index can be used
|
||||
//as a start point for the search when multiple goals are available with that same classname
|
||||
int BotGetLevelItemGoal(int index, char *classname, bot_goal_t *goal);
|
||||
//get the next camp spot in the map
|
||||
int BotGetNextCampSpotGoal(int num, bot_goal_t *goal);
|
||||
//get the map location with the given name
|
||||
int BotGetMapLocationGoal(char *name, bot_goal_t *goal);
|
||||
//returns the avoid goal time
|
||||
float BotAvoidGoalTime(int goalstate, int number);
|
||||
//set the avoid goal time
|
||||
void BotSetAvoidGoalTime(int goalstate, int number, float avoidtime);
|
||||
//initializes the items in the level
|
||||
void BotInitLevelItems(void);
|
||||
//regularly update dynamic entity items (dropped weapons, flags etc.)
|
||||
void BotUpdateEntityItems(void);
|
||||
//interbreed the goal fuzzy logic
|
||||
void BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child);
|
||||
//save the goal fuzzy logic to disk
|
||||
void BotSaveGoalFuzzyLogic(int goalstate, char *filename);
|
||||
//mutate the goal fuzzy logic
|
||||
void BotMutateGoalFuzzyLogic(int goalstate, float range);
|
||||
//loads item weights for the bot
|
||||
int BotLoadItemWeights(int goalstate, char *filename);
|
||||
//frees the item weights of the bot
|
||||
void BotFreeItemWeights(int goalstate);
|
||||
//returns the handle of a newly allocated goal state
|
||||
int BotAllocGoalState(int client);
|
||||
//free the given goal state
|
||||
void BotFreeGoalState(int handle);
|
||||
//setup the goal AI
|
||||
int BotSetupGoalAI(void);
|
||||
//shut down the goal AI
|
||||
void BotShutdownGoalAI(void);
|
126
code/game/be_ai_move.h
Normal file
126
code/game/be_ai_move.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_move.h
|
||||
*
|
||||
* desc: movement AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_move.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//movement types
|
||||
#define MOVE_WALK 1
|
||||
#define MOVE_CROUCH 2
|
||||
#define MOVE_JUMP 4
|
||||
#define MOVE_GRAPPLE 8
|
||||
#define MOVE_ROCKETJUMP 16
|
||||
#define MOVE_BFGJUMP 32
|
||||
//move flags
|
||||
#define MFL_BARRIERJUMP 1 //bot is performing a barrier jump
|
||||
#define MFL_ONGROUND 2 //bot is in the ground
|
||||
#define MFL_SWIMMING 4 //bot is swimming
|
||||
#define MFL_AGAINSTLADDER 8 //bot is against a ladder
|
||||
#define MFL_WATERJUMP 16 //bot is waterjumping
|
||||
#define MFL_TELEPORTED 32 //bot is being teleported
|
||||
#define MFL_GRAPPLEPULL 64 //bot is being pulled by the grapple
|
||||
#define MFL_ACTIVEGRAPPLE 128 //bot is using the grapple hook
|
||||
#define MFL_GRAPPLERESET 256 //bot has reset the grapple
|
||||
#define MFL_WALK 512 //bot should walk slowly
|
||||
// move result flags
|
||||
#define MOVERESULT_MOVEMENTVIEW 1 //bot uses view for movement
|
||||
#define MOVERESULT_SWIMVIEW 2 //bot uses view for swimming
|
||||
#define MOVERESULT_WAITING 4 //bot is waiting for something
|
||||
#define MOVERESULT_MOVEMENTVIEWSET 8 //bot has set the view in movement code
|
||||
#define MOVERESULT_MOVEMENTWEAPON 16 //bot uses weapon for movement
|
||||
#define MOVERESULT_ONTOPOFOBSTACLE 32 //bot is ontop of obstacle
|
||||
#define MOVERESULT_ONTOPOF_FUNCBOB 64 //bot is ontop of a func_bobbing
|
||||
#define MOVERESULT_ONTOPOF_ELEVATOR 128 //bot is ontop of an elevator (func_plat)
|
||||
#define MOVERESULT_BLOCKEDBYAVOIDSPOT 256 //bot is blocked by an avoid spot
|
||||
//
|
||||
#define MAX_AVOIDREACH 1
|
||||
#define MAX_AVOIDSPOTS 32
|
||||
// avoid spot types
|
||||
#define AVOID_CLEAR 0 //clear all avoid spots
|
||||
#define AVOID_ALWAYS 1 //avoid always
|
||||
#define AVOID_DONTBLOCK 2 //never totally block
|
||||
// restult types
|
||||
#define RESULTTYPE_ELEVATORUP 1 //elevator is up
|
||||
#define RESULTTYPE_WAITFORFUNCBOBBING 2 //waiting for func bobbing to arrive
|
||||
#define RESULTTYPE_BADGRAPPLEPATH 4 //grapple path is obstructed
|
||||
#define RESULTTYPE_INSOLIDAREA 8 //stuck in solid area, this is bad
|
||||
|
||||
//structure used to initialize the movement state
|
||||
//the or_moveflags MFL_ONGROUND, MFL_TELEPORTED and MFL_WATERJUMP come from the playerstate
|
||||
typedef struct bot_initmove_s
|
||||
{
|
||||
vec3_t origin; //origin of the bot
|
||||
vec3_t velocity; //velocity of the bot
|
||||
vec3_t viewoffset; //view offset
|
||||
int entitynum; //entity number of the bot
|
||||
int client; //client number of the bot
|
||||
float thinktime; //time the bot thinks
|
||||
int presencetype; //presencetype of the bot
|
||||
vec3_t viewangles; //view angles of the bot
|
||||
int or_moveflags; //values ored to the movement flags
|
||||
} bot_initmove_t;
|
||||
|
||||
//NOTE: the ideal_viewangles are only valid if MFL_MOVEMENTVIEW is set
|
||||
typedef struct bot_moveresult_s
|
||||
{
|
||||
int failure; //true if movement failed all together
|
||||
int type; //failure or blocked type
|
||||
int blocked; //true if blocked by an entity
|
||||
int blockentity; //entity blocking the bot
|
||||
int traveltype; //last executed travel type
|
||||
int flags; //result flags
|
||||
int weapon; //weapon used for movement
|
||||
vec3_t movedir; //movement direction
|
||||
vec3_t ideal_viewangles; //ideal viewangles for the movement
|
||||
} bot_moveresult_t;
|
||||
|
||||
// bk001204: from code/botlib/be_ai_move.c
|
||||
// TTimo 04/12/2001 was moved here to avoid dup defines
|
||||
typedef struct bot_avoidspot_s
|
||||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
int type;
|
||||
} bot_avoidspot_t;
|
||||
|
||||
//resets the whole move state
|
||||
void BotResetMoveState(int movestate);
|
||||
//moves the bot to the given goal
|
||||
void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, int travelflags);
|
||||
//moves the bot in the specified direction using the specified type of movement
|
||||
int BotMoveInDirection(int movestate, vec3_t dir, float speed, int type);
|
||||
//reset avoid reachability
|
||||
void BotResetAvoidReach(int movestate);
|
||||
//resets the last avoid reachability
|
||||
void BotResetLastAvoidReach(int movestate);
|
||||
//returns a reachability area if the origin is in one
|
||||
int BotReachabilityArea(vec3_t origin, int client);
|
||||
//view target based on movement
|
||||
int BotMovementViewTarget(int movestate, bot_goal_t *goal, int travelflags, float lookahead, vec3_t target);
|
||||
//predict the position of a player based on movement towards a goal
|
||||
int BotPredictVisiblePosition(vec3_t origin, int areanum, bot_goal_t *goal, int travelflags, vec3_t target);
|
||||
//returns the handle of a newly allocated movestate
|
||||
int BotAllocMoveState(void);
|
||||
//frees the movestate with the given handle
|
||||
void BotFreeMoveState(int handle);
|
||||
//initialize movement state before performing any movement
|
||||
void BotInitMoveState(int handle, bot_initmove_t *initmove);
|
||||
//add a spot to avoid (if type == AVOID_CLEAR all spots are removed)
|
||||
void BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type);
|
||||
//must be called every map change
|
||||
void BotSetBrushModelTypes(void);
|
||||
//setup movement AI
|
||||
int BotSetupMoveAI(void);
|
||||
//shutdown movement AI
|
||||
void BotShutdownMoveAI(void);
|
||||
|
88
code/game/be_ai_weap.h
Normal file
88
code/game/be_ai_weap.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ai_weap.h
|
||||
*
|
||||
* desc: weapon AI
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ai_weap.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//projectile flags
|
||||
#define PFL_WINDOWDAMAGE 1 //projectile damages through window
|
||||
#define PFL_RETURN 2 //set when projectile returns to owner
|
||||
//weapon flags
|
||||
#define WFL_FIRERELEASED 1 //set when projectile is fired with key-up event
|
||||
//damage types
|
||||
#define DAMAGETYPE_IMPACT 1 //damage on impact
|
||||
#define DAMAGETYPE_RADIAL 2 //radial damage
|
||||
#define DAMAGETYPE_VISIBLE 4 //damage to all entities visible to the projectile
|
||||
|
||||
typedef struct projectileinfo_s
|
||||
{
|
||||
char name[MAX_STRINGFIELD];
|
||||
char model[MAX_STRINGFIELD];
|
||||
int flags;
|
||||
float gravity;
|
||||
int damage;
|
||||
float radius;
|
||||
int visdamage;
|
||||
int damagetype;
|
||||
int healthinc;
|
||||
float push;
|
||||
float detonation;
|
||||
float bounce;
|
||||
float bouncefric;
|
||||
float bouncestop;
|
||||
} projectileinfo_t;
|
||||
|
||||
typedef struct weaponinfo_s
|
||||
{
|
||||
int valid; //true if the weapon info is valid
|
||||
int number; //number of the weapon
|
||||
char name[MAX_STRINGFIELD];
|
||||
char model[MAX_STRINGFIELD];
|
||||
int level;
|
||||
int weaponindex;
|
||||
int flags;
|
||||
char projectile[MAX_STRINGFIELD];
|
||||
int numprojectiles;
|
||||
float hspread;
|
||||
float vspread;
|
||||
float speed;
|
||||
float acceleration;
|
||||
vec3_t recoil;
|
||||
vec3_t offset;
|
||||
vec3_t angleoffset;
|
||||
float extrazvelocity;
|
||||
int ammoamount;
|
||||
int ammoindex;
|
||||
float activate;
|
||||
float reload;
|
||||
float spinup;
|
||||
float spindown;
|
||||
projectileinfo_t proj; //pointer to the used projectile
|
||||
} weaponinfo_t;
|
||||
|
||||
//setup the weapon AI
|
||||
int BotSetupWeaponAI(void);
|
||||
//shut down the weapon AI
|
||||
void BotShutdownWeaponAI(void);
|
||||
//returns the best weapon to fight with
|
||||
int BotChooseBestFightWeapon(int weaponstate, int *inventory);
|
||||
//returns the information of the current weapon
|
||||
void BotGetWeaponInfo(int weaponstate, int weapon, weaponinfo_t *weaponinfo);
|
||||
//loads the weapon weights
|
||||
int BotLoadWeaponWeights(int weaponstate, char *filename);
|
||||
//returns a handle to a newly allocated weapon state
|
||||
int BotAllocWeaponState(void);
|
||||
//frees the weapon state
|
||||
void BotFreeWeaponState(int weaponstate);
|
||||
//resets the whole weapon state
|
||||
void BotResetWeaponState(int weaponstate);
|
52
code/game/be_ea.h
Normal file
52
code/game/be_ea.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_ea.h
|
||||
*
|
||||
* desc: elementary actions
|
||||
*
|
||||
* $Archive: /source/code/botlib/be_ea.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 10/05/99 3:32p $
|
||||
* $Date: 10/05/99 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//ClientCommand elementary actions
|
||||
void EA_Say(int client, char *str);
|
||||
void EA_SayTeam(int client, char *str);
|
||||
void EA_Command(int client, char *command );
|
||||
|
||||
void EA_Action(int client, int action);
|
||||
void EA_Crouch(int client);
|
||||
void EA_Walk(int client);
|
||||
void EA_MoveUp(int client);
|
||||
void EA_MoveDown(int client);
|
||||
void EA_MoveForward(int client);
|
||||
void EA_MoveBack(int client);
|
||||
void EA_MoveLeft(int client);
|
||||
void EA_MoveRight(int client);
|
||||
void EA_Attack(int client);
|
||||
void EA_Alt_Attack(int client);
|
||||
void EA_ForcePower(int client);
|
||||
void EA_Respawn(int client);
|
||||
void EA_Talk(int client);
|
||||
void EA_Gesture(int client);
|
||||
void EA_Use(int client);
|
||||
|
||||
//regular elementary actions
|
||||
void EA_SelectWeapon(int client, int weapon);
|
||||
void EA_Jump(int client);
|
||||
void EA_DelayedJump(int client);
|
||||
void EA_Move(int client, vec3_t dir, float speed);
|
||||
void EA_View(int client, vec3_t viewangles);
|
||||
|
||||
//send regular input to the server
|
||||
void EA_EndRegular(int client, float thinktime);
|
||||
void EA_GetInput(int client, float thinktime, bot_input_t *input);
|
||||
void EA_ResetInput(int client);
|
||||
//setup and shutdown routines
|
||||
int EA_Setup(void);
|
||||
void EA_Shutdown(void);
|
265
code/game/bg_gametype.c
Normal file
265
code/game/bg_gametype.c
Normal file
|
@ -0,0 +1,265 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
// bg_gametype.c -- dynamic gametype handling
|
||||
|
||||
#include "q_shared.h"
|
||||
#include "bg_public.h"
|
||||
#include "bg_local.h"
|
||||
|
||||
gametypeData_t bg_gametypeData[MAX_GAMETYPES];
|
||||
int bg_gametypeCount;
|
||||
|
||||
/*
|
||||
===============
|
||||
BG_ParseGametypePhotos
|
||||
|
||||
Parses the photo information for objectives dialog
|
||||
===============
|
||||
*/
|
||||
static qboolean BG_ParseGametypePhotos ( int gametypeIndex, TGPGroup group )
|
||||
{
|
||||
TGPGroup photo;
|
||||
int index;
|
||||
char temp[MAX_TOKENLENGTH];
|
||||
|
||||
// Convienience check
|
||||
if ( !group )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
photo = trap_GPG_GetSubGroups ( group );
|
||||
|
||||
while ( photo )
|
||||
{
|
||||
trap_GPG_GetName ( photo, temp );
|
||||
bg_gametypeData[gametypeIndex].photos[index].name = trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
trap_GPG_FindPairValue ( photo, "displayname", "unknown", temp );
|
||||
bg_gametypeData[gametypeIndex].photos[index].displayName = trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
index++;
|
||||
|
||||
photo = trap_GPG_GetNext ( photo );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
BG_ParseGametypeInfo
|
||||
|
||||
Parses minimal information about the given gametype. For the most part
|
||||
this information is the name of the gametype and some of its parameters.
|
||||
===============
|
||||
*/
|
||||
static qboolean BG_ParseGametypeInfo ( int gametypeIndex )
|
||||
{
|
||||
gametypeData_t* gametype;
|
||||
TGenericParser2 GP2;
|
||||
TGPGroup topGroup;
|
||||
TGPGroup gtGroup;
|
||||
char temp[1024];
|
||||
|
||||
// Get the pointer for the gametype data
|
||||
gametype = &bg_gametypeData[gametypeIndex];
|
||||
|
||||
// Open the gametype's script file
|
||||
GP2 = trap_GP_ParseFile( (char*)gametype->script, qtrue, qfalse);
|
||||
if (!GP2)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Top group should only contain the "gametype" sub group
|
||||
topGroup = trap_GP_GetBaseParseGroup(GP2);
|
||||
if ( !topGroup )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Grab the gametype sub group
|
||||
gtGroup = trap_GPG_FindSubGroup ( topGroup, "gametype" );
|
||||
if ( !gtGroup )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Parse out the name of the gametype
|
||||
trap_GPG_FindPairValue ( gtGroup, "displayname", "", temp );
|
||||
if ( !temp[0] )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
gametype->displayName = trap_VM_LocalStringAlloc ( temp );
|
||||
|
||||
// Description
|
||||
trap_GPG_FindPairValue ( gtGroup, "description", "", temp );
|
||||
if ( temp[0] )
|
||||
{
|
||||
gametype->description = trap_VM_LocalStringAlloc ( temp );
|
||||
}
|
||||
|
||||
// Are pickups enabled?
|
||||
trap_GPG_FindPairValue ( gtGroup, "pickups", "yes", temp );
|
||||
if ( !Q_stricmp ( temp, "no" ) )
|
||||
{
|
||||
gametype->pickupsDisabled = qtrue;
|
||||
}
|
||||
|
||||
// Are teams enabled?
|
||||
trap_GPG_FindPairValue ( gtGroup, "teams", "yes", temp );
|
||||
if ( !Q_stricmp ( temp, "yes" ) )
|
||||
{
|
||||
gametype->teams = qtrue;
|
||||
}
|
||||
|
||||
// Display kills
|
||||
trap_GPG_FindPairValue ( gtGroup, "showkills", "no", temp );
|
||||
if ( !Q_stricmp ( temp, "yes" ) )
|
||||
{
|
||||
gametype->showKills = qtrue;
|
||||
}
|
||||
|
||||
// Look for the respawn type
|
||||
trap_GPG_FindPairValue ( gtGroup, "respawn", "normal", temp );
|
||||
if ( !Q_stricmp ( temp, "none" ) )
|
||||
{
|
||||
gametype->respawnType = RT_NONE;
|
||||
}
|
||||
else if ( !Q_stricmp ( temp, "interval" ) )
|
||||
{
|
||||
gametype->respawnType = RT_INTERVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gametype->respawnType = RT_NORMAL;
|
||||
}
|
||||
|
||||
// What percentage doest he backpack replenish?
|
||||
trap_GPG_FindPairValue ( gtGroup, "backpack", "0", temp );
|
||||
gametype->backpack = atoi(temp);
|
||||
|
||||
// Get the photo information for objectives dialog
|
||||
BG_ParseGametypePhotos ( gametypeIndex, trap_GPG_FindSubGroup ( gtGroup, "photos" ) );
|
||||
|
||||
// Cleanup the generic parser
|
||||
trap_GP_Delete ( &GP2 );
|
||||
|
||||
return qtrue;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
BG_BuildGametypeList
|
||||
|
||||
Builds a list of the gametypes that are available and parses minimal
|
||||
information about those gametypes.
|
||||
===============
|
||||
*/
|
||||
qboolean BG_BuildGametypeList ( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
char filelist[4096];
|
||||
char* fileptr;
|
||||
char* s;
|
||||
int filelen;
|
||||
int filecount;
|
||||
int i;
|
||||
|
||||
bg_gametypeCount = 0;
|
||||
|
||||
// Retrieve the list of gametype files. The returned list is a
|
||||
// null separated list with the number of entries returned by the call
|
||||
filecount = trap_FS_GetFileList("scripts", ".gametype", filelist, 4096 );
|
||||
fileptr = filelist;
|
||||
|
||||
for ( i = 0; i < filecount; i++, fileptr += filelen+1)
|
||||
{
|
||||
// Grab the length so we can skip this file later
|
||||
filelen = strlen(fileptr);
|
||||
|
||||
// Build the full filename
|
||||
strcpy(filename, "scripts/");
|
||||
strcat(filename, fileptr );
|
||||
|
||||
// Fill in what we know so far
|
||||
bg_gametypeData[bg_gametypeCount].script = trap_VM_LocalStringAlloc ( filename );
|
||||
|
||||
// Kill the dot so we can use the filename as the short name
|
||||
s = strchr ( fileptr, '.' );
|
||||
*s = '\0';
|
||||
bg_gametypeData[bg_gametypeCount].name = trap_VM_LocalStringAlloc ( fileptr );
|
||||
|
||||
// TODO: Parse the gametype file
|
||||
BG_ParseGametypeInfo ( bg_gametypeCount++ );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
BG_FindGametype
|
||||
|
||||
Returns the gametype index using the given name. If the gametype isnt found
|
||||
then -1 will be returned (and this is bad)
|
||||
===============
|
||||
*/
|
||||
int BG_FindGametype ( const char* name )
|
||||
{
|
||||
int i;
|
||||
|
||||
// Loop through the known gametypes and compare their names to
|
||||
// the name given
|
||||
for ( i = 0; i < bg_gametypeCount; i ++ )
|
||||
{
|
||||
// Do the names match?
|
||||
if ( !Q_stricmp ( bg_gametypeData[i].name, name ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
BG_FindGametypeItem
|
||||
|
||||
Search through the item list for the gametype item with
|
||||
the given index.
|
||||
==============
|
||||
*/
|
||||
gitem_t *BG_FindGametypeItem ( int index )
|
||||
{
|
||||
return &bg_itemlist[index + MODELINDEX_GAMETYPE_ITEM];
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
BG_FindGametypeItemByID
|
||||
|
||||
Gametype will assign ids to the gametype items for them for future reference, the
|
||||
id is crammed into the quantity field of the gametype item. This function will
|
||||
find the gametype item with the given item id.
|
||||
==============
|
||||
*/
|
||||
gitem_t *BG_FindGametypeItemByID ( int itemid )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < MAX_GAMETYPE_ITEMS; i ++ )
|
||||
{
|
||||
if ( bg_itemlist[i + MODELINDEX_GAMETYPE_ITEM].quantity == itemid )
|
||||
{
|
||||
return &bg_itemlist[i + MODELINDEX_GAMETYPE_ITEM];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
1316
code/game/bg_lib.c
Normal file
1316
code/game/bg_lib.c
Normal file
File diff suppressed because it is too large
Load diff
71
code/game/bg_lib.h
Normal file
71
code/game/bg_lib.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
// bg_lib.h -- standard C library replacement routines used by code
|
||||
// compiled for the virtual machine
|
||||
|
||||
// This file is NOT included on native builds
|
||||
|
||||
typedef int size_t;
|
||||
|
||||
typedef char * va_list;
|
||||
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
|
||||
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
|
||||
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
|
||||
#define va_end(ap) ( ap = (va_list)0 )
|
||||
|
||||
#define CHAR_BIT 8 /* number of bits in a char */
|
||||
#define SCHAR_MIN (-128) /* minimum signed char value */
|
||||
#define SCHAR_MAX 127 /* maximum signed char value */
|
||||
#define UCHAR_MAX 0xff /* maximum unsigned char value */
|
||||
|
||||
#define SHRT_MIN (-32768) /* minimum (signed) short value */
|
||||
#define SHRT_MAX 32767 /* maximum (signed) short value */
|
||||
#define USHRT_MAX 0xffff /* maximum unsigned short value */
|
||||
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
|
||||
#define INT_MAX 2147483647 /* maximum (signed) int value */
|
||||
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
|
||||
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */
|
||||
#define LONG_MAX 2147483647L /* maximum (signed) long value */
|
||||
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */
|
||||
|
||||
// Misc functions
|
||||
typedef int cmp_t(const void *, const void *);
|
||||
void qsort(void *a, size_t n, size_t es, cmp_t *cmp);
|
||||
void srand( unsigned seed );
|
||||
int rand( void );
|
||||
|
||||
// String functions
|
||||
size_t strlen( const char *string );
|
||||
char *strcat( char *strDestination, const char *strSource );
|
||||
char *strcpy( char *strDestination, const char *strSource );
|
||||
int strcmp( const char *string1, const char *string2 );
|
||||
char *strchr( const char *string, int c );
|
||||
char *strstr( const char *string, const char *strCharSet );
|
||||
char *strncpy( char *strDest, const char *strSource, size_t count );
|
||||
int tolower( int c );
|
||||
int toupper( int c );
|
||||
|
||||
double atof( const char *string );
|
||||
double _atof( const char **stringPtr );
|
||||
int atoi( const char *string );
|
||||
int _atoi( const char **stringPtr );
|
||||
|
||||
int vsprintf( char *buffer, const char *fmt, va_list argptr );
|
||||
int sscanf( const char *buffer, const char *fmt, ... );
|
||||
|
||||
// Memory functions
|
||||
void *memmove( void *dest, const void *src, size_t count );
|
||||
void *memset( void *dest, int c, size_t count );
|
||||
void *memcpy( void *dest, const void *src, size_t count );
|
||||
|
||||
// Math functions
|
||||
double ceil( double x );
|
||||
double floor( double x );
|
||||
double sqrt( double x );
|
||||
double sin( double x );
|
||||
double cos( double x );
|
||||
double atan2( double y, double x );
|
||||
double tan( double x );
|
||||
int abs( int n );
|
||||
double fabs( double x );
|
||||
double acos( double x );
|
||||
double asin( double x );
|
||||
|
70
code/game/bg_local.h
Normal file
70
code/game/bg_local.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright (C) 2001-2002 Raven Software.
|
||||
//
|
||||
// bg_local.h -- local definitions for the bg (both games) files
|
||||
|
||||
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
|
||||
#define MIN_WALK_NORMAL_TERRAIN 0.625f // bit steeper for terrain
|
||||
|
||||
#define STEPSIZE 18
|
||||
|
||||
#define JUMP_VELOCITY 270
|
||||
|
||||
#define TIMER_LAND 130
|
||||
#define TIMER_GESTURE (34*66+50)
|
||||
|
||||
#define OVERCLIP 1.001f
|
||||
|
||||
// all of the locals will be zeroed before each
|
||||
// pmove, just to make damn sure we don't have
|
||||
// any differences when running on client or server
|
||||
typedef struct
|
||||
{
|
||||
vec3_t forward, right, up;
|
||||
float frametime;
|
||||
|
||||
int msec;
|
||||
|
||||
qboolean walking;
|
||||
qboolean groundPlane;
|
||||
trace_t groundTrace;
|
||||
|
||||
float impactSpeed;
|
||||
|
||||
vec3_t previous_origin;
|
||||
vec3_t previous_velocity;
|
||||
int previous_waterlevel;
|
||||
} pml_t;
|
||||
|
||||
extern pml_t pml;
|
||||
|
||||
// movement parameters
|
||||
extern float pm_stopspeed;
|
||||
extern float pm_duckScale;
|
||||
extern float pm_swimScale;
|
||||
extern float pm_wadeScale;
|
||||
|
||||
extern float pm_accelerate;
|
||||
extern float pm_airaccelerate;
|
||||
extern float pm_wateraccelerate;
|
||||
extern float pm_flyaccelerate;
|
||||
|
||||
extern float pm_friction;
|
||||
extern float pm_waterfriction;
|
||||
extern float pm_flightfriction;
|
||||
|
||||
extern int c_pmove;
|
||||
|
||||
void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce );
|
||||
void PM_AddTouchEnt( int entityNum );
|
||||
void PM_AddEvent( int newEvent );
|
||||
void PM_AddEventWithParm( int newEvent, int parm );
|
||||
|
||||
qboolean PM_SlideMove( qboolean gravity );
|
||||
void PM_StepSlideMove( qboolean gravity );
|
||||
|
||||
void PM_StartTorsoAnim ( playerState_t* ps, int anim, int time );
|
||||
void PM_ContinueLegsAnim ( playerState_t* ps, int anim );
|
||||
void PM_ForceLegsAnim ( playerState_t* ps, int anim );
|
||||
void PM_TorsoAnimation ( playerState_t* ps );
|
||||
void PM_SetAnim ( playerState_t* ps, int setAnimParts,int anim,int setAnimFlags, int blendTime);
|
||||
|
1622
code/game/bg_misc.c
Normal file
1622
code/game/bg_misc.c
Normal file
File diff suppressed because it is too large
Load diff
1741
code/game/bg_player.c
Normal file
1741
code/game/bg_player.c
Normal file
File diff suppressed because it is too large
Load diff
3901
code/game/bg_pmove.c
Normal file
3901
code/game/bg_pmove.c
Normal file
File diff suppressed because it is too large
Load diff
1137
code/game/bg_public.h
Normal file
1137
code/game/bg_public.h
Normal file
File diff suppressed because it is too large
Load diff
352
code/game/bg_slidemove.c
Normal file
352
code/game/bg_slidemove.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
// bg_slidemove.c -- part of bg_pmove functionality
|
||||
|
||||
#include "q_shared.h"
|
||||
#include "bg_public.h"
|
||||
#include "bg_local.h"
|
||||
|
||||
/*
|
||||
==================
|
||||
PM_SlideMove
|
||||
|
||||
Returns qtrue if the velocity was clipped in some way
|
||||
==================
|
||||
*/
|
||||
#define MAX_CLIP_PLANES 5
|
||||
|
||||
qboolean PM_SlideMove( qboolean gravity )
|
||||
{
|
||||
int bumpcount, numbumps;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
int numplanes;
|
||||
vec3_t planes[MAX_CLIP_PLANES];
|
||||
vec3_t primal_velocity;
|
||||
vec3_t clipVelocity;
|
||||
int i, j, k;
|
||||
trace_t trace;
|
||||
vec3_t end;
|
||||
float time_left;
|
||||
float into;
|
||||
vec3_t endVelocity;
|
||||
vec3_t endClipVelocity;
|
||||
|
||||
numbumps = 4;
|
||||
|
||||
VectorCopy (pm->ps->velocity, primal_velocity);
|
||||
|
||||
if ( gravity )
|
||||
{
|
||||
VectorCopy( pm->ps->velocity, endVelocity );
|
||||
endVelocity[2] -= pm->ps->gravity * pml.frametime;
|
||||
pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
|
||||
primal_velocity[2] = endVelocity[2];
|
||||
|
||||
if ( pml.groundPlane )
|
||||
{
|
||||
// slide along the ground plane
|
||||
PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
|
||||
pm->ps->velocity, OVERCLIP );
|
||||
}
|
||||
}
|
||||
|
||||
time_left = pml.frametime;
|
||||
|
||||
// never turn against the ground plane
|
||||
if ( pml.groundPlane )
|
||||
{
|
||||
numplanes = 1;
|
||||
VectorCopy( pml.groundTrace.plane.normal, planes[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
numplanes = 0;
|
||||
}
|
||||
|
||||
// never turn against original velocity
|
||||
VectorNormalize2( pm->ps->velocity, planes[numplanes] );
|
||||
numplanes++;
|
||||
|
||||
for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ )
|
||||
{
|
||||
// calculate position we are trying to move to
|
||||
VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
|
||||
|
||||
// see if we can make it there
|
||||
pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
|
||||
|
||||
if (trace.allsolid)
|
||||
{
|
||||
// entity is completely trapped in another solid
|
||||
pm->ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if (trace.fraction > 0)
|
||||
{
|
||||
// actually covered some distance
|
||||
VectorCopy (trace.endpos, pm->ps->origin);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1)
|
||||
{
|
||||
break; // moved the entire distance
|
||||
}
|
||||
|
||||
// save entity for contact
|
||||
PM_AddTouchEnt( trace.entityNum );
|
||||
|
||||
time_left -= time_left * trace.fraction;
|
||||
|
||||
if (numplanes >= MAX_CLIP_PLANES)
|
||||
{
|
||||
// this shouldn't really happen
|
||||
VectorClear( pm->ps->velocity );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// if this is the same plane we hit before, nudge velocity
|
||||
// out along it, which fixes some epsilon issues with
|
||||
// non-axial planes
|
||||
//
|
||||
for ( i = 0 ; i < numplanes ; i++ )
|
||||
{
|
||||
if ( DotProduct( trace.plane.normal, planes[i] ) > 0.99 )
|
||||
{
|
||||
VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i < numplanes )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy (trace.plane.normal, planes[numplanes]);
|
||||
numplanes++;
|
||||
|
||||
//
|
||||
// modify velocity so it parallels all of the clip planes
|
||||
//
|
||||
|
||||
// find a plane that it enters
|
||||
for ( i = 0 ; i < numplanes ; i++ )
|
||||
{
|
||||
into = DotProduct( pm->ps->velocity, planes[i] );
|
||||
if ( into >= 0.1 )
|
||||
{
|
||||
continue; // move doesn't interact with the plane
|
||||
}
|
||||
|
||||
// see how hard we are hitting things
|
||||
if ( -into > pml.impactSpeed )
|
||||
{
|
||||
pml.impactSpeed = -into;
|
||||
}
|
||||
|
||||
// slide along the plane
|
||||
PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
|
||||
|
||||
// slide along the plane
|
||||
PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
|
||||
|
||||
// see if there is a second plane that the new move enters
|
||||
for ( j = 0 ; j < numplanes ; j++ )
|
||||
{
|
||||
if ( j == i )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 )
|
||||
{
|
||||
continue; // move doesn't interact with the plane
|
||||
}
|
||||
|
||||
// try clipping the move to the plane
|
||||
PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
|
||||
PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );
|
||||
|
||||
// see if it goes back into the first clip plane
|
||||
if ( DotProduct( clipVelocity, planes[i] ) >= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// slide the original velocity along the crease
|
||||
CrossProduct (planes[i], planes[j], dir);
|
||||
VectorNormalize( dir );
|
||||
d = DotProduct( dir, pm->ps->velocity );
|
||||
VectorScale( dir, d, clipVelocity );
|
||||
|
||||
CrossProduct (planes[i], planes[j], dir);
|
||||
VectorNormalize( dir );
|
||||
d = DotProduct( dir, endVelocity );
|
||||
VectorScale( dir, d, endClipVelocity );
|
||||
|
||||
// see if there is a third plane the the new move enters
|
||||
for ( k = 0 ; k < numplanes ; k++ )
|
||||
{
|
||||
if ( k == i || k == j )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 )
|
||||
{
|
||||
continue; // move doesn't interact with the plane
|
||||
}
|
||||
|
||||
// stop dead at a tripple plane interaction
|
||||
VectorClear( pm->ps->velocity );
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have fixed all interactions, try another move
|
||||
VectorCopy( clipVelocity, pm->ps->velocity );
|
||||
VectorCopy( endClipVelocity, endVelocity );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( gravity )
|
||||
{
|
||||
VectorCopy( endVelocity, pm->ps->velocity );
|
||||
}
|
||||
|
||||
// don't change velocity if in a timer (FIXME: is this correct?)
|
||||
if ( pm->ps->pm_time )
|
||||
{
|
||||
VectorCopy( primal_velocity, pm->ps->velocity );
|
||||
}
|
||||
|
||||
return (qboolean)( bumpcount != 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
PM_StepSlideMove
|
||||
|
||||
==================
|
||||
*/
|
||||
void PM_StepSlideMove( qboolean gravity )
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t down;
|
||||
vec3_t up = {0, 0, 1};
|
||||
qboolean result = qtrue;
|
||||
vec3_t start_o;
|
||||
vec3_t start_v;
|
||||
vec3_t save_o;
|
||||
vec3_t save_v;
|
||||
int stepsize;
|
||||
float delta;
|
||||
|
||||
VectorCopy (pm->ps->origin, start_o);
|
||||
VectorCopy (pm->ps->velocity, start_v);
|
||||
|
||||
if ( PM_SlideMove( gravity ) == 0 )
|
||||
{
|
||||
// we got exactly where we wanted to go on the first try
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the standard stepsize
|
||||
stepsize = STEPSIZE;
|
||||
|
||||
// Add to the step size if we are crouched when jumping
|
||||
if ( pm->ps->pm_flags & PMF_CROUCH_JUMP )
|
||||
{
|
||||
stepsize += (DEFAULT_VIEWHEIGHT-CROUCH_VIEWHEIGHT);
|
||||
}
|
||||
|
||||
// Save the origin and velocity in case we have to undo
|
||||
VectorCopy ( pm->ps->origin, save_o );
|
||||
VectorCopy ( pm->ps->velocity, save_v );
|
||||
|
||||
// First lets see if there is any hope of steping up
|
||||
pm->maxs[2] -= stepsize;
|
||||
|
||||
VectorCopy ( start_o, pm->ps->origin );
|
||||
VectorCopy ( start_v, pm->ps->velocity );
|
||||
|
||||
pm->ps->origin[2] += stepsize;
|
||||
|
||||
// try the move with the altered hit box
|
||||
if ( PM_SlideMove( gravity ))
|
||||
{
|
||||
}
|
||||
|
||||
// See how far down now
|
||||
VectorCopy ( pm->ps->origin, down );
|
||||
down[2] -= stepsize;
|
||||
|
||||
// Trace it
|
||||
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
||||
|
||||
// Return the players hitbox to normal
|
||||
pm->maxs[2] += stepsize;
|
||||
|
||||
// No stepping up if you have upward velocity
|
||||
if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 || DotProduct(trace.plane.normal, up) < 0.7))
|
||||
{
|
||||
VectorCopy ( save_o, pm->ps->origin );
|
||||
VectorCopy ( save_v, pm->ps->velocity );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( trace.allsolid || trace.startsolid )
|
||||
{
|
||||
result = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( trace.fraction < 1.0 )
|
||||
PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
|
||||
|
||||
// Now double check not stuck
|
||||
VectorCopy ( trace.endpos, pm->ps->origin );
|
||||
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, pm->ps->origin, pm->ps->clientNum, pm->tracemask);
|
||||
|
||||
if ( trace.allsolid || trace.startsolid )
|
||||
result = qfalse;
|
||||
}
|
||||
|
||||
if ( !result )
|
||||
{
|
||||
VectorCopy ( save_o, pm->ps->origin );
|
||||
VectorCopy ( save_v, pm->ps->velocity );
|
||||
}
|
||||
|
||||
// use the step move
|
||||
delta = pm->ps->origin[2] - start_o[2];
|
||||
|
||||
// Shoould we send a step event?
|
||||
if ( delta > 2 )
|
||||
{
|
||||
if ( delta < 7 )
|
||||
{
|
||||
PM_AddEvent( EV_STEP_4 );
|
||||
}
|
||||
else if ( delta < 11 )
|
||||
{
|
||||
PM_AddEvent( EV_STEP_8 );
|
||||
}
|
||||
else if ( delta < 15 )
|
||||
{
|
||||
PM_AddEvent( EV_STEP_12 );
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_AddEvent( EV_STEP_16 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pm->debugLevel )
|
||||
{
|
||||
Com_Printf("%i:stepped\n", c_pmove);
|
||||
}
|
||||
}
|
||||
|
1234
code/game/bg_weapons.c
Normal file
1234
code/game/bg_weapons.c
Normal file
File diff suppressed because it is too large
Load diff
369
code/game/bg_weapons.h
Normal file
369
code/game/bg_weapons.h
Normal file
|
@ -0,0 +1,369 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
// bg_weapons.h - weapons data loading
|
||||
|
||||
#ifndef __BG_WEAPONS_H__
|
||||
#define __BG_WEAPONS_H__
|
||||
|
||||
// means of death
|
||||
typedef enum
|
||||
{
|
||||
MOD_UNKNOWN,
|
||||
|
||||
// Knife
|
||||
MOD_KNIFE,
|
||||
|
||||
// Pistols
|
||||
MOD_M1911A1_PISTOL,
|
||||
MOD_USSOCOM_PISTOL,
|
||||
|
||||
// Secondarys
|
||||
MOD_M590_SHOTGUN,
|
||||
MOD_MICRO_UZI_SUBMACHINEGUN,
|
||||
MOD_M3A1_SUBMACHINEGUN,
|
||||
|
||||
// Primaries
|
||||
MOD_USAS_12_SHOTGUN,
|
||||
MOD_M4_ASSAULT_RIFLE,
|
||||
MOD_AK74_ASSAULT_RIFLE,
|
||||
MOD_MSG90A1_SNIPER_RIFLE,
|
||||
MOD_M60_MACHINEGUN,
|
||||
MOD_MM1_GRENADE_LAUNCHER,
|
||||
MOD_RPG7_LAUNCHER,
|
||||
|
||||
// Grenades
|
||||
MOD_M67_GRENADE,
|
||||
MOD_M84_GRENADE,
|
||||
MOD_F1_GRENADE,
|
||||
MOD_L2A2_GRENADE,
|
||||
MOD_MDN11_GRENADE,
|
||||
MOD_SMOHG92_GRENADE,
|
||||
MOD_ANM14_GRENADE,
|
||||
MOD_M15_GRENADE,
|
||||
|
||||
MOD_WATER,
|
||||
MOD_CRUSH,
|
||||
MOD_TELEFRAG,
|
||||
MOD_FALLING,
|
||||
MOD_SUICIDE,
|
||||
MOD_TEAMCHANGE,
|
||||
MOD_TARGET_LASER,
|
||||
MOD_TRIGGER_HURT
|
||||
|
||||
} meansOfDeath_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WP_NONE,
|
||||
|
||||
// Knife
|
||||
WP_KNIFE,
|
||||
|
||||
// Pistols
|
||||
WP_M1911A1_PISTOL,
|
||||
WP_USSOCOM_PISTOL,
|
||||
|
||||
// Secondarys
|
||||
WP_M590_SHOTGUN,
|
||||
WP_MICRO_UZI_SUBMACHINEGUN,
|
||||
WP_M3A1_SUBMACHINEGUN,
|
||||
|
||||
// Primaries
|
||||
WP_USAS_12_SHOTGUN,
|
||||
WP_M4_ASSAULT_RIFLE,
|
||||
WP_AK74_ASSAULT_RIFLE,
|
||||
WP_MSG90A1,
|
||||
WP_M60_MACHINEGUN,
|
||||
WP_MM1_GRENADE_LAUNCHER,
|
||||
WP_RPG7_LAUNCHER,
|
||||
|
||||
// Grenades
|
||||
WP_M67_GRENADE,
|
||||
WP_M84_GRENADE,
|
||||
WP_F1_GRENADE,
|
||||
WP_L2A2_GRENADE,
|
||||
WP_MDN11_GRENADE,
|
||||
WP_SMOHG92_GRENADE,
|
||||
WP_ANM14_GRENADE,
|
||||
WP_M15_GRENADE,
|
||||
|
||||
WP_NUM_WEAPONS
|
||||
} weapon_t;
|
||||
|
||||
#define WP_DELAYED_CHANGE_BIT (1<<5)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AMMO_KNIFE,
|
||||
AMMO_045,
|
||||
AMMO_556,
|
||||
AMMO_9 ,
|
||||
AMMO_12 ,
|
||||
AMMO_762,
|
||||
AMMO_40,
|
||||
AMMO_RPG7,
|
||||
AMMO_M15,
|
||||
AMMO_M67,
|
||||
AMMO_M84,
|
||||
AMMO_F1,
|
||||
AMMO_L2A2,
|
||||
AMMO_MDN11,
|
||||
AMMO_SMOHG92,
|
||||
AMMO_ANM14,
|
||||
|
||||
AMMO_MAX,
|
||||
|
||||
AMMO_NONE,
|
||||
|
||||
} ammo_t;
|
||||
|
||||
#define WP_FIREMODE_NONE 0
|
||||
#define WP_FIREMODE_AUTO 1
|
||||
#define WP_FIREMODE_BURST 2
|
||||
#define WP_FIREMODE_SINGLE 3
|
||||
#define WP_FIREMODE_MAX 4
|
||||
|
||||
#define PROJECTILE_FIRE 0x0010 // projectile NOT bullet
|
||||
#define PROJECTILE_TIMED 0x0020 // projectile ONLY explodes after time is up
|
||||
#define PROJECTILE_GRAVITY 0x0040 // projectile obeys gravity
|
||||
#define PROJECTILE_DAMAGE_AREA 0x0080 // projectile does area damage over time
|
||||
#define UNLOCK_MUZZLEFLASH 0x0100 // muzzle flash is locked to muzzle bolt by default
|
||||
#define PROJECTILE_LIGHTGRAVITY 0x0200 // projectile has light gravity
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAT_NONE = 0,
|
||||
CAT_KNIFE,
|
||||
CAT_PISTOL,
|
||||
CAT_SHOTGUN,
|
||||
CAT_SUB,
|
||||
CAT_ASSAULT,
|
||||
CAT_SNIPER,
|
||||
CAT_HEAVY,
|
||||
CAT_GRENADE,
|
||||
CAT_MAX
|
||||
|
||||
} ECategory;
|
||||
|
||||
typedef struct attackData_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
char icon[MAX_QPATH];
|
||||
|
||||
const char* melee;
|
||||
|
||||
meansOfDeath_t mod; // means of death
|
||||
int ammoIndex; // Index to proper ammo slot
|
||||
union
|
||||
{
|
||||
int range; // Range of weapon
|
||||
int velocity; // speed of projectile
|
||||
} rV;
|
||||
|
||||
int clipSize; // how large is a clip
|
||||
int fireAmount; // how much ammo to use per shot
|
||||
int fireFromClip; // 0 = fire from approp. ammo pool, 1 = fire from clip
|
||||
int damage; // how much damage is done per hit
|
||||
float inaccuracy; // how inaccurate is weapon
|
||||
float maxInaccuracy; // maximum lvl of inaccuracy
|
||||
int pellets; // how many individual 'bullets' are shot with one trigger pull?
|
||||
int weaponFlags; // which fire modes are available, projectiles timed or impact, .etc
|
||||
int projectileLifetime; // how long does projectile live (before exploding)
|
||||
int splashRadius; // how large is splash damage radius
|
||||
int fireDelay; // Extra delay when firing
|
||||
qboolean gore; // is gore enabled for this attack?
|
||||
int extraClips; // Extra clips you get when starting
|
||||
float bounceScale; // how much something bounces
|
||||
|
||||
vec3_t minKickAngles;
|
||||
vec3_t maxKickAngles;
|
||||
|
||||
// Names of effects, sounds, models, bones
|
||||
char muzzleEffect[MAX_QPATH];
|
||||
char muzzleEffectBone[MAX_QPATH];
|
||||
char muzzleEffectInWorld[MAX_QPATH];
|
||||
char tracerEffect[MAX_QPATH];
|
||||
char ejectBone[MAX_QPATH];
|
||||
char shellEject[MAX_QPATH];
|
||||
char explosionSound[MAX_QPATH];
|
||||
char explosionEffect[MAX_QPATH];
|
||||
char missileG2Model[MAX_QPATH];
|
||||
|
||||
int animFire;
|
||||
int animFireZoomed;
|
||||
|
||||
} attackData_t;
|
||||
|
||||
typedef struct weaponData_s
|
||||
{
|
||||
char *classname; // Spawning name
|
||||
ECategory category; // what group of weapons is this one part of?
|
||||
qboolean safe;
|
||||
char worldModel[MAX_QPATH]; // world model
|
||||
char menuImage[MAX_QPATH]; // names of the icon files
|
||||
|
||||
int animDrop;
|
||||
int animRaise;
|
||||
int animIdle;
|
||||
int animIdleZoomed;
|
||||
int animReload;
|
||||
int animReloadStart;
|
||||
int animReloadEnd;
|
||||
|
||||
attackData_t attack[ATTACK_MAX];
|
||||
|
||||
|
||||
} weaponData_t;
|
||||
|
||||
typedef struct ammoData_s
|
||||
{
|
||||
char *name; // name of ammo
|
||||
char icon[32]; // Name of ammo icon file
|
||||
int max; // Max amount player can hold of ammo
|
||||
float goreScale;
|
||||
|
||||
} ammoData_t;
|
||||
|
||||
extern char *weaponNames[WP_NUM_WEAPONS];
|
||||
extern weaponData_t weaponData[WP_NUM_WEAPONS];
|
||||
extern char *ammoNames[AMMO_MAX];
|
||||
extern ammoData_t ammoData[AMMO_MAX];
|
||||
|
||||
// Specific weapon information
|
||||
|
||||
#define WP_FIRST_RANGED_WEAPON WP_M1911A1_PISTOL // this is the first weapon for next and prev weapon switching
|
||||
#define WP_FIRST_MELEE_WEAPON WP_KNIFE
|
||||
#define MAX_PLAYER_WEAPONS (WP_NUM_WEAPONS-1) // this is the max you can switch to and get with the give all.
|
||||
|
||||
#define MAX_WEAPON_SOUNDS 12
|
||||
#define MAX_WEAPON_SOUND_SLOTS 3
|
||||
|
||||
#define MAX_SIDE_SURFACES 16
|
||||
|
||||
typedef struct SOptionalWeapon
|
||||
{
|
||||
char mName[MAX_QPATH];
|
||||
char mMuzzle[MAX_QPATH];
|
||||
char *mSurfaces[MAX_SIDE_SURFACES];
|
||||
|
||||
struct SOptionalWeapon *mNext;
|
||||
} TOptionalWeapon;
|
||||
|
||||
typedef struct SBoltonWeapon
|
||||
{
|
||||
char mName[MAX_QPATH];
|
||||
char mModel[MAX_QPATH];
|
||||
char mParent[MAX_QPATH];
|
||||
char mBoltToBone[MAX_QPATH];
|
||||
char *mRightSide[MAX_SIDE_SURFACES];
|
||||
|
||||
char mJointBone[MAX_QPATH];
|
||||
char mJointParentBone[MAX_QPATH];
|
||||
char mJointForward[10];
|
||||
char mJointRight[10];
|
||||
char mJointUp[10];
|
||||
} TBoltonWeapon;
|
||||
|
||||
typedef struct SNoteTrack
|
||||
{
|
||||
char mNote[64];
|
||||
int mFrame;
|
||||
|
||||
struct SNoteTrack *mNext;
|
||||
} TNoteTrack;
|
||||
|
||||
#define MAX_WEAPON_ANIM_CHOICES 4
|
||||
|
||||
typedef struct SAnimInfoWeapon
|
||||
{
|
||||
char mName[MAX_QPATH];
|
||||
char mType[MAX_QPATH];
|
||||
char *mAnim[MAX_WEAPON_ANIM_CHOICES];
|
||||
char *mTransition[MAX_WEAPON_ANIM_CHOICES];
|
||||
char *mEnd[MAX_WEAPON_ANIM_CHOICES];
|
||||
float mSpeed;
|
||||
int mLODBias;
|
||||
int mNumChoices;
|
||||
|
||||
int mStartFrame[MAX_WEAPON_ANIM_CHOICES];
|
||||
int mNumFrames[MAX_WEAPON_ANIM_CHOICES];
|
||||
int mFPS[MAX_WEAPON_ANIM_CHOICES];
|
||||
|
||||
struct SNoteTrack *mNoteTracks[MAX_WEAPON_ANIM_CHOICES];
|
||||
struct SAnimInfoWeapon *mNext;
|
||||
} TAnimInfoWeapon;
|
||||
|
||||
typedef struct SAnimWeapon
|
||||
{
|
||||
char mName[MAX_QPATH];
|
||||
char mMuzzle[MAX_QPATH];
|
||||
|
||||
struct SAnimInfoWeapon *mInfos;
|
||||
struct SAnimInfoWeapon *mWeaponModelInfo; // "weaponmodel" info
|
||||
struct SAnimWeapon *mNext;
|
||||
|
||||
} TAnimWeapon;
|
||||
|
||||
typedef struct SWeaponModel
|
||||
{
|
||||
char mName[MAX_QPATH];
|
||||
char mModel[MAX_QPATH];
|
||||
char mBufferName[MAX_QPATH];
|
||||
char mBufferModel[MAX_QPATH];
|
||||
char mBufferBoltToBone[MAX_QPATH];
|
||||
char mBufferMuzzle[MAX_QPATH];
|
||||
char mBufferAltMuzzle[MAX_QPATH];
|
||||
char mLeftHandsBoltToBone[MAX_QPATH];
|
||||
char mRightHandsBoltToBone[MAX_QPATH];
|
||||
char *mFrontSurfaces[MAX_SIDE_SURFACES],
|
||||
*mRightSideSurfaces[MAX_SIDE_SURFACES],
|
||||
*mLeftSideSurfaces[MAX_SIDE_SURFACES];
|
||||
|
||||
struct SOptionalWeapon *mOptionalList;
|
||||
struct SBoltonWeapon *mBolton;
|
||||
} TWeaponModel;
|
||||
|
||||
#define MAX_CALLBACK_SURFACES 4
|
||||
|
||||
typedef struct SOnOffSurface
|
||||
{
|
||||
char mName[64];
|
||||
int mStatus;
|
||||
} TOnOffSurface;
|
||||
|
||||
typedef struct SSurfaceCallback
|
||||
{
|
||||
char mName[64];
|
||||
struct SOnOffSurface mOnOffSurfaces[MAX_CALLBACK_SURFACES];
|
||||
} TSurfaceCallback;
|
||||
|
||||
#define MAX_SURFACE_CALLBACKS 2
|
||||
|
||||
typedef struct SWeaponInfo
|
||||
{
|
||||
char *mName;
|
||||
float mForeshorten;
|
||||
vec3_t mViewOffset;
|
||||
char mSoundNames[MAX_WEAPON_SOUNDS][MAX_QPATH];
|
||||
char mSounds[MAX_WEAPON_SOUNDS][MAX_WEAPON_SOUND_SLOTS][MAX_QPATH];
|
||||
struct SSurfaceCallback mSurfaceCallbacks[MAX_SURFACE_CALLBACKS];
|
||||
struct SAnimWeapon *mAnimList;
|
||||
struct SWeaponModel mWeaponModel;
|
||||
} TWeaponParseInfo;
|
||||
|
||||
extern TWeaponParseInfo weaponParseInfo[WP_NUM_WEAPONS];
|
||||
extern char weaponLeftHand[MAX_QPATH];
|
||||
extern char weaponRightHand[MAX_QPATH];
|
||||
|
||||
qboolean BG_ParseInviewFile ( void);
|
||||
TAnimWeapon* BG_GetInviewAnim ( int weaponIdx,const char *animKey,int *animIndex);
|
||||
TAnimWeapon* BG_GetInviewAnimFromIndex ( int weaponIdx,int animIndex);
|
||||
TAnimInfoWeapon* BG_GetInviewModelAnim ( int weaponIdx,const char *modelKey,const char *animKey);
|
||||
qboolean BG_WeaponHasAlternateAmmo ( int weapon );
|
||||
int BG_FindFireMode ( weapon_t weapon, attackType_t attack, int firemode );
|
||||
|
||||
void BG_CalculateBulletEndpoint ( vec3_t muzzlePoint, vec3_t fireAngs, float inaccuracy, float range, vec3_t end, int *seed );
|
||||
int BG_GetMaxAmmo ( const playerState_t* ps, int ammoIndex );
|
||||
|
||||
#endif
|
||||
|
508
code/game/botlib.h
Normal file
508
code/game/botlib.h
Normal file
|
@ -0,0 +1,508 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
/*****************************************************************************
|
||||
* name: botlib.h
|
||||
*
|
||||
* desc: bot AI library
|
||||
*
|
||||
* $Archive: /source/code/game/botai.h $
|
||||
* $Author: Mrelusive $
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 03/01/00 3:32p $
|
||||
* $Date: 03/01/00 3:42p $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define BOTLIB_API_VERSION 2
|
||||
|
||||
struct aas_clientmove_s;
|
||||
struct aas_entityinfo_s;
|
||||
struct aas_areainfo_s;
|
||||
struct aas_altroutegoal_s;
|
||||
struct aas_predictroute_s;
|
||||
struct bot_consolemessage_s;
|
||||
struct bot_match_s;
|
||||
struct bot_goal_s;
|
||||
struct bot_moveresult_s;
|
||||
struct bot_initmove_s;
|
||||
struct weaponinfo_s;
|
||||
|
||||
#define BOTFILESBASEFOLDER "botfiles"
|
||||
//debug line colors
|
||||
#define LINECOLOR_NONE -1
|
||||
#define LINECOLOR_RED 1//0xf2f2f0f0L
|
||||
#define LINECOLOR_GREEN 2//0xd0d1d2d3L
|
||||
#define LINECOLOR_BLUE 3//0xf3f3f1f1L
|
||||
#define LINECOLOR_YELLOW 4//0xdcdddedfL
|
||||
#define LINECOLOR_ORANGE 5//0xe0e1e2e3L
|
||||
|
||||
//Print types
|
||||
#define PRT_MESSAGE 1
|
||||
#define PRT_WARNING 2
|
||||
#define PRT_ERROR 3
|
||||
#define PRT_FATAL 4
|
||||
#define PRT_EXIT 5
|
||||
|
||||
//console message types
|
||||
#define CMS_NORMAL 0
|
||||
#define CMS_CHAT 1
|
||||
|
||||
//botlib error codes
|
||||
#define BLERR_NOERROR 0 //no error
|
||||
#define BLERR_LIBRARYNOTSETUP 1 //library not setup
|
||||
#define BLERR_INVALIDENTITYNUMBER 2 //invalid entity number
|
||||
#define BLERR_NOAASFILE 3 //no AAS file available
|
||||
#define BLERR_CANNOTOPENAASFILE 4 //cannot open AAS file
|
||||
#define BLERR_WRONGAASFILEID 5 //incorrect AAS file id
|
||||
#define BLERR_WRONGAASFILEVERSION 6 //incorrect AAS file version
|
||||
#define BLERR_CANNOTREADAASLUMP 7 //cannot read AAS file lump
|
||||
#define BLERR_CANNOTLOADICHAT 8 //cannot load initial chats
|
||||
#define BLERR_CANNOTLOADITEMWEIGHTS 9 //cannot load item weights
|
||||
#define BLERR_CANNOTLOADITEMCONFIG 10 //cannot load item config
|
||||
#define BLERR_CANNOTLOADWEAPONWEIGHTS 11 //cannot load weapon weights
|
||||
#define BLERR_CANNOTLOADWEAPONCONFIG 12 //cannot load weapon config
|
||||
|
||||
//action flags
|
||||
#define ACTION_ATTACK 0x0000001
|
||||
#define ACTION_USE 0x0000002
|
||||
#define ACTION_RESPAWN 0x0000008
|
||||
#define ACTION_JUMP 0x0000010
|
||||
#define ACTION_MOVEUP 0x0000020
|
||||
#define ACTION_CROUCH 0x0000080
|
||||
#define ACTION_MOVEDOWN 0x0000100
|
||||
#define ACTION_MOVEFORWARD 0x0000200
|
||||
#define ACTION_MOVEBACK 0x0000800
|
||||
#define ACTION_MOVELEFT 0x0001000
|
||||
#define ACTION_MOVERIGHT 0x0002000
|
||||
#define ACTION_DELAYEDJUMP 0x0008000
|
||||
#define ACTION_TALK 0x0010000
|
||||
#define ACTION_GESTURE 0x0020000
|
||||
#define ACTION_WALK 0x0080000
|
||||
#define ACTION_FORCEPOWER 0x0100000
|
||||
#define ACTION_ALT_ATTACK 0x0200000
|
||||
/*
|
||||
#define ACTION_AFFIRMATIVE 0x0100000
|
||||
#define ACTION_NEGATIVE 0x0200000
|
||||
#define ACTION_GETFLAG 0x0800000
|
||||
#define ACTION_GUARDBASE 0x1000000
|
||||
#define ACTION_PATROL 0x2000000
|
||||
#define ACTION_FOLLOWME 0x8000000
|
||||
*/
|
||||
|
||||
//the bot input, will be converted to an usercmd_t
|
||||
typedef struct bot_input_s
|
||||
{
|
||||
float thinktime; //time since last output (in seconds)
|
||||
vec3_t dir; //movement direction
|
||||
float speed; //speed in the range [0, 400]
|
||||
vec3_t viewangles; //the view angles
|
||||
int actionflags; //one of the ACTION_? flags
|
||||
int weapon; //weapon to use
|
||||
} bot_input_t;
|
||||
|
||||
#ifndef BSPTRACE
|
||||
|
||||
#define BSPTRACE
|
||||
|
||||
//bsp_trace_t hit surface
|
||||
typedef struct bsp_surface_s
|
||||
{
|
||||
char name[16];
|
||||
int flags;
|
||||
int value;
|
||||
} bsp_surface_t;
|
||||
|
||||
//remove the bsp_trace_s structure definition l8r on
|
||||
//a trace is returned when a box is swept through the world
|
||||
typedef struct bsp_trace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
float exp_dist; // expanded plane distance
|
||||
int sidenum; // number of the brush side hit
|
||||
bsp_surface_t surface; // the hit point surface
|
||||
int contents; // contents on other side of surface hit
|
||||
int ent; // number of entity hit
|
||||
} bsp_trace_t;
|
||||
|
||||
#endif // BSPTRACE
|
||||
|
||||
//entity state
|
||||
typedef struct bot_entitystate_s
|
||||
{
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int gametypeitems; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
} bot_entitystate_t;
|
||||
|
||||
//bot AI library exported functions
|
||||
typedef struct botlib_import_s
|
||||
{
|
||||
//print messages from the bot library
|
||||
void (QDECL *Print)(int type, char *fmt, ...);
|
||||
//trace a bbox through the world
|
||||
void (*Trace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
|
||||
//trace a bbox against a specific entity
|
||||
void (*EntityTrace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask);
|
||||
//retrieve the contents at the given point
|
||||
int (*PointContents)(vec3_t point);
|
||||
//check if the point is in potential visible sight
|
||||
int (*inPVS)(vec3_t p1, vec3_t p2);
|
||||
//retrieve the BSP entity data lump
|
||||
char *(*BSPEntityData)(void);
|
||||
//
|
||||
void (*BSPModelMinsMaxsOrigin)(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
|
||||
//send a bot client command
|
||||
void (*BotClientCommand)(int client, char *command);
|
||||
//memory allocation
|
||||
void *(*GetMemory)(int size); // allocate from Zone
|
||||
void (*FreeMemory)(void *ptr); // free memory from Zone
|
||||
int (*AvailableMemory)(void); // available Zone memory
|
||||
void *(*HunkAlloc)(int size); // allocate from hunk
|
||||
//file system access
|
||||
int (*FS_FOpenFile)( const char *qpath, fileHandle_t *file, fsMode_t mode );
|
||||
int (*FS_Read)( void *buffer, int len, fileHandle_t f );
|
||||
int (*FS_Write)( const void *buffer, int len, fileHandle_t f );
|
||||
void (*FS_FCloseFile)( fileHandle_t f );
|
||||
int (*FS_Seek)( fileHandle_t f, long offset, int origin );
|
||||
//debug visualisation stuff
|
||||
int (*DebugLineCreate)(void);
|
||||
void (*DebugLineDelete)(int line);
|
||||
void (*DebugLineShow)(int line, vec3_t start, vec3_t end, int color);
|
||||
//
|
||||
int (*DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
|
||||
void (*DebugPolygonDelete)(int id);
|
||||
} botlib_import_t;
|
||||
|
||||
typedef struct aas_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_aas_entity.h
|
||||
//-----------------------------------
|
||||
void (*AAS_EntityInfo)(int entnum, struct aas_entityinfo_s *info);
|
||||
//-----------------------------------
|
||||
// be_aas_main.h
|
||||
//-----------------------------------
|
||||
int (*AAS_Initialized)(void);
|
||||
void (*AAS_PresenceTypeBoundingBox)(int presencetype, vec3_t mins, vec3_t maxs);
|
||||
float (*AAS_Time)(void);
|
||||
//--------------------------------------------
|
||||
// be_aas_sample.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_PointAreaNum)(vec3_t point);
|
||||
int (*AAS_PointReachabilityAreaIndex)( vec3_t point );
|
||||
int (*AAS_TraceAreas)(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
|
||||
int (*AAS_BBoxAreas)(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
|
||||
int (*AAS_AreaInfo)( int areanum, struct aas_areainfo_s *info );
|
||||
//--------------------------------------------
|
||||
// be_aas_bspq3.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_PointContents)(vec3_t point);
|
||||
int (*AAS_NextBSPEntity)(int ent);
|
||||
int (*AAS_ValueForBSPEpairKey)(int ent, char *key, char *value, int size);
|
||||
int (*AAS_VectorForBSPEpairKey)(int ent, char *key, vec3_t v);
|
||||
int (*AAS_FloatForBSPEpairKey)(int ent, char *key, float *value);
|
||||
int (*AAS_IntForBSPEpairKey)(int ent, char *key, int *value);
|
||||
//--------------------------------------------
|
||||
// be_aas_reach.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AreaReachability)(int areanum);
|
||||
//--------------------------------------------
|
||||
// be_aas_route.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AreaTravelTimeToGoalArea)(int areanum, vec3_t origin, int goalareanum, int travelflags);
|
||||
int (*AAS_EnableRoutingArea)(int areanum, int enable);
|
||||
int (*AAS_PredictRoute)(struct aas_predictroute_s *route, int areanum, vec3_t origin,
|
||||
int goalareanum, int travelflags, int maxareas, int maxtime,
|
||||
int stopevent, int stopcontents, int stoptfl, int stopareanum);
|
||||
//--------------------------------------------
|
||||
// be_aas_altroute.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_AlternativeRouteGoals)(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
|
||||
struct aas_altroutegoal_s *altroutegoals, int maxaltroutegoals,
|
||||
int type);
|
||||
//--------------------------------------------
|
||||
// be_aas_move.c
|
||||
//--------------------------------------------
|
||||
int (*AAS_Swimming)(vec3_t origin);
|
||||
int (*AAS_PredictClientMovement)(struct aas_clientmove_s *move,
|
||||
int entnum, vec3_t origin,
|
||||
int presencetype, int onground,
|
||||
vec3_t velocity, vec3_t cmdmove,
|
||||
int cmdframes,
|
||||
int maxframes, float frametime,
|
||||
int stopevent, int stopareanum, int visualize);
|
||||
} aas_export_t;
|
||||
|
||||
typedef struct ea_export_s
|
||||
{
|
||||
//ClientCommand elementary actions
|
||||
void (*EA_Command)(int client, char *command );
|
||||
void (*EA_Say)(int client, char *str);
|
||||
void (*EA_SayTeam)(int client, char *str);
|
||||
//
|
||||
void (*EA_Action)(int client, int action);
|
||||
void (*EA_Gesture)(int client);
|
||||
void (*EA_Talk)(int client);
|
||||
void (*EA_Attack)(int client);
|
||||
void (*EA_Use)(int client);
|
||||
void (*EA_Respawn)(int client);
|
||||
void (*EA_MoveUp)(int client);
|
||||
void (*EA_MoveDown)(int client);
|
||||
void (*EA_MoveForward)(int client);
|
||||
void (*EA_MoveBack)(int client);
|
||||
void (*EA_MoveLeft)(int client);
|
||||
void (*EA_MoveRight)(int client);
|
||||
void (*EA_Crouch)(int client);
|
||||
void (*EA_Alt_Attack)(int client);
|
||||
void (*EA_ForcePower)(int client);
|
||||
|
||||
void (*EA_SelectWeapon)(int client, int weapon);
|
||||
void (*EA_Jump)(int client);
|
||||
void (*EA_DelayedJump)(int client);
|
||||
void (*EA_Move)(int client, vec3_t dir, float speed);
|
||||
void (*EA_View)(int client, vec3_t viewangles);
|
||||
//send regular input to the server
|
||||
void (*EA_EndRegular)(int client, float thinktime);
|
||||
void (*EA_GetInput)(int client, float thinktime, bot_input_t *input);
|
||||
void (*EA_ResetInput)(int client);
|
||||
} ea_export_t;
|
||||
|
||||
typedef struct ai_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_ai_char.h
|
||||
//-----------------------------------
|
||||
int (*BotLoadCharacter)(char *charfile, float skill);
|
||||
void (*BotFreeCharacter)(int character);
|
||||
float (*Characteristic_Float)(int character, int index);
|
||||
float (*Characteristic_BFloat)(int character, int index, float min, float max);
|
||||
int (*Characteristic_Integer)(int character, int index);
|
||||
int (*Characteristic_BInteger)(int character, int index, int min, int max);
|
||||
void (*Characteristic_String)(int character, int index, char *buf, int size);
|
||||
//-----------------------------------
|
||||
// be_ai_chat.h
|
||||
//-----------------------------------
|
||||
int (*BotAllocChatState)(void);
|
||||
void (*BotFreeChatState)(int handle);
|
||||
void (*BotQueueConsoleMessage)(int chatstate, int type, char *message);
|
||||
void (*BotRemoveConsoleMessage)(int chatstate, int handle);
|
||||
int (*BotNextConsoleMessage)(int chatstate, struct bot_consolemessage_s *cm);
|
||||
int (*BotNumConsoleMessages)(int chatstate);
|
||||
void (*BotInitialChat)(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
int (*BotNumInitialChats)(int chatstate, char *type);
|
||||
int (*BotReplyChat)(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
|
||||
int (*BotChatLength)(int chatstate);
|
||||
void (*BotEnterChat)(int chatstate, int client, int sendto);
|
||||
void (*BotGetChatMessage)(int chatstate, char *buf, int size);
|
||||
int (*StringContains)(char *str1, char *str2, int casesensitive);
|
||||
int (*BotFindMatch)(char *str, struct bot_match_s *match, unsigned long int context);
|
||||
void (*BotMatchVariable)(struct bot_match_s *match, int variable, char *buf, int size);
|
||||
void (*UnifyWhiteSpaces)(char *string);
|
||||
void (*BotReplaceSynonyms)(char *string, unsigned long int context);
|
||||
int (*BotLoadChatFile)(int chatstate, char *chatfile, char *chatname);
|
||||
void (*BotSetChatGender)(int chatstate, int gender);
|
||||
void (*BotSetChatName)(int chatstate, char *name, int client);
|
||||
//-----------------------------------
|
||||
// be_ai_goal.h
|
||||
//-----------------------------------
|
||||
void (*BotResetGoalState)(int goalstate);
|
||||
void (*BotResetAvoidGoals)(int goalstate);
|
||||
void (*BotRemoveFromAvoidGoals)(int goalstate, int number);
|
||||
void (*BotPushGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
void (*BotPopGoal)(int goalstate);
|
||||
void (*BotEmptyGoalStack)(int goalstate);
|
||||
void (*BotDumpAvoidGoals)(int goalstate);
|
||||
void (*BotDumpGoalStack)(int goalstate);
|
||||
void (*BotGoalName)(int number, char *name, int size);
|
||||
int (*BotGetTopGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
int (*BotGetSecondGoal)(int goalstate, struct bot_goal_s *goal);
|
||||
int (*BotChooseLTGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags);
|
||||
int (*BotChooseNBGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags,
|
||||
struct bot_goal_s *ltg, float maxtime);
|
||||
int (*BotTouchingGoal)(vec3_t origin, struct bot_goal_s *goal);
|
||||
int (*BotItemGoalInVisButNotVisible)(int viewer, vec3_t eye, vec3_t viewangles, struct bot_goal_s *goal);
|
||||
int (*BotGetLevelItemGoal)(int index, char *classname, struct bot_goal_s *goal);
|
||||
int (*BotGetNextCampSpotGoal)(int num, struct bot_goal_s *goal);
|
||||
int (*BotGetMapLocationGoal)(char *name, struct bot_goal_s *goal);
|
||||
float (*BotAvoidGoalTime)(int goalstate, int number);
|
||||
void (*BotSetAvoidGoalTime)(int goalstate, int number, float avoidtime);
|
||||
void (*BotInitLevelItems)(void);
|
||||
void (*BotUpdateEntityItems)(void);
|
||||
int (*BotLoadItemWeights)(int goalstate, char *filename);
|
||||
void (*BotFreeItemWeights)(int goalstate);
|
||||
void (*BotInterbreedGoalFuzzyLogic)(int parent1, int parent2, int child);
|
||||
void (*BotSaveGoalFuzzyLogic)(int goalstate, char *filename);
|
||||
void (*BotMutateGoalFuzzyLogic)(int goalstate, float range);
|
||||
int (*BotAllocGoalState)(int client);
|
||||
void (*BotFreeGoalState)(int handle);
|
||||
//-----------------------------------
|
||||
// be_ai_move.h
|
||||
//-----------------------------------
|
||||
void (*BotResetMoveState)(int movestate);
|
||||
void (*BotMoveToGoal)(struct bot_moveresult_s *result, int movestate, struct bot_goal_s *goal, int travelflags);
|
||||
int (*BotMoveInDirection)(int movestate, vec3_t dir, float speed, int type);
|
||||
void (*BotResetAvoidReach)(int movestate);
|
||||
void (*BotResetLastAvoidReach)(int movestate);
|
||||
int (*BotReachabilityArea)(vec3_t origin, int testground);
|
||||
int (*BotMovementViewTarget)(int movestate, struct bot_goal_s *goal, int travelflags, float lookahead, vec3_t target);
|
||||
int (*BotPredictVisiblePosition)(vec3_t origin, int areanum, struct bot_goal_s *goal, int travelflags, vec3_t target);
|
||||
int (*BotAllocMoveState)(void);
|
||||
void (*BotFreeMoveState)(int handle);
|
||||
void (*BotInitMoveState)(int handle, struct bot_initmove_s *initmove);
|
||||
void (*BotAddAvoidSpot)(int movestate, vec3_t origin, float radius, int type);
|
||||
//-----------------------------------
|
||||
// be_ai_weap.h
|
||||
//-----------------------------------
|
||||
int (*BotChooseBestFightWeapon)(int weaponstate, int *inventory);
|
||||
void (*BotGetWeaponInfo)(int weaponstate, int weapon, struct weaponinfo_s *weaponinfo);
|
||||
int (*BotLoadWeaponWeights)(int weaponstate, char *filename);
|
||||
int (*BotAllocWeaponState)(void);
|
||||
void (*BotFreeWeaponState)(int weaponstate);
|
||||
void (*BotResetWeaponState)(int weaponstate);
|
||||
//-----------------------------------
|
||||
// be_ai_gen.h
|
||||
//-----------------------------------
|
||||
int (*GeneticParentsAndChildSelection)(int numranks, float *ranks, int *parent1, int *parent2, int *child);
|
||||
} ai_export_t;
|
||||
|
||||
//bot AI library imported functions
|
||||
typedef struct botlib_export_s
|
||||
{
|
||||
//Area Awareness System functions
|
||||
aas_export_t aas;
|
||||
//Elementary Action functions
|
||||
ea_export_t ea;
|
||||
//AI functions
|
||||
ai_export_t ai;
|
||||
//setup the bot library, returns BLERR_
|
||||
int (*BotLibSetup)(void);
|
||||
//shutdown the bot library, returns BLERR_
|
||||
int (*BotLibShutdown)(void);
|
||||
//sets a library variable returns BLERR_
|
||||
int (*BotLibVarSet)(char *var_name, char *value);
|
||||
//gets a library variable returns BLERR_
|
||||
int (*BotLibVarGet)(char *var_name, char *value, int size);
|
||||
|
||||
//sets a C-like define returns BLERR_
|
||||
int (*PC_AddGlobalDefine)(char *string);
|
||||
int (*PC_LoadSourceHandle)(const char *filename);
|
||||
int (*PC_FreeSourceHandle)(int handle);
|
||||
int (*PC_ReadTokenHandle)(int handle, pc_token_t *pc_token);
|
||||
int (*PC_SourceFileAndLine)(int handle, char *filename, int *line);
|
||||
int (*PC_LoadGlobalDefines)(const char* filename );
|
||||
void (*PC_RemoveAllGlobalDefines) ( void );
|
||||
|
||||
//start a frame in the bot library
|
||||
int (*BotLibStartFrame)(float time);
|
||||
//load a new map in the bot library
|
||||
int (*BotLibLoadMap)(const char *mapname);
|
||||
//entity updates
|
||||
int (*BotLibUpdateEntity)(int ent, bot_entitystate_t *state);
|
||||
//just for testing
|
||||
int (*Test)(int parm0, char *parm1, vec3_t parm2, vec3_t parm3);
|
||||
} botlib_export_t;
|
||||
|
||||
//linking of bot library
|
||||
botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import );
|
||||
|
||||
/* Library variables:
|
||||
|
||||
name: default: module(s): description:
|
||||
|
||||
"basedir" "" l_utils.c base directory
|
||||
"gamedir" "" l_utils.c game directory
|
||||
"cddir" "" l_utils.c CD directory
|
||||
|
||||
"log" "0" l_log.c enable/disable creating a log file
|
||||
"maxclients" "4" be_interface.c maximum number of clients
|
||||
"maxentities" "1024" be_interface.c maximum number of entities
|
||||
"bot_developer" "0" be_interface.c bot developer mode
|
||||
|
||||
"phys_friction" "6" be_aas_move.c ground friction
|
||||
"phys_stopspeed" "100" be_aas_move.c stop speed
|
||||
"phys_gravity" "800" be_aas_move.c gravity value
|
||||
"phys_waterfriction" "1" be_aas_move.c water friction
|
||||
"phys_watergravity" "400" be_aas_move.c gravity in water
|
||||
"phys_maxvelocity" "320" be_aas_move.c maximum velocity
|
||||
"phys_maxwalkvelocity" "320" be_aas_move.c maximum walk velocity
|
||||
"phys_maxcrouchvelocity" "100" be_aas_move.c maximum crouch velocity
|
||||
"phys_maxswimvelocity" "150" be_aas_move.c maximum swim velocity
|
||||
"phys_walkaccelerate" "10" be_aas_move.c walk acceleration
|
||||
"phys_airaccelerate" "1" be_aas_move.c air acceleration
|
||||
"phys_swimaccelerate" "4" be_aas_move.c swim acceleration
|
||||
"phys_maxstep" "18" be_aas_move.c maximum step height
|
||||
"phys_maxsteepness" "0.7" be_aas_move.c maximum floor steepness
|
||||
"phys_maxbarrier" "32" be_aas_move.c maximum barrier height
|
||||
"phys_maxwaterjump" "19" be_aas_move.c maximum waterjump height
|
||||
"phys_jumpvel" "270" be_aas_move.c jump z velocity
|
||||
"phys_falldelta5" "40" be_aas_move.c
|
||||
"phys_falldelta10" "60" be_aas_move.c
|
||||
"rs_waterjump" "400" be_aas_move.c
|
||||
"rs_teleport" "50" be_aas_move.c
|
||||
"rs_barrierjump" "100" be_aas_move.c
|
||||
"rs_startcrouch" "300" be_aas_move.c
|
||||
"rs_startgrapple" "500" be_aas_move.c
|
||||
"rs_startwalkoffledge" "70" be_aas_move.c
|
||||
"rs_startjump" "300" be_aas_move.c
|
||||
"rs_rocketjump" "500" be_aas_move.c
|
||||
"rs_bfgjump" "500" be_aas_move.c
|
||||
"rs_jumppad" "250" be_aas_move.c
|
||||
"rs_aircontrolledjumppad" "300" be_aas_move.c
|
||||
"rs_funcbob" "300" be_aas_move.c
|
||||
"rs_startelevator" "50" be_aas_move.c
|
||||
"rs_falldamage5" "300" be_aas_move.c
|
||||
"rs_falldamage10" "500" be_aas_move.c
|
||||
"rs_maxjumpfallheight" "450" be_aas_move.c
|
||||
|
||||
"max_aaslinks" "4096" be_aas_sample.c maximum links in the AAS
|
||||
"max_routingcache" "4096" be_aas_route.c maximum routing cache size in KB
|
||||
"forceclustering" "0" be_aas_main.c force recalculation of clusters
|
||||
"forcereachability" "0" be_aas_main.c force recalculation of reachabilities
|
||||
"forcewrite" "0" be_aas_main.c force writing of aas file
|
||||
"aasoptimize" "0" be_aas_main.c enable aas optimization
|
||||
"sv_mapChecksum" "0" be_aas_main.c BSP file checksum
|
||||
"bot_visualizejumppads" "0" be_aas_reach.c visualize jump pads
|
||||
|
||||
"bot_reloadcharacters" "0" - reload bot character files
|
||||
"ai_gametype" "0" be_ai_goal.c game type
|
||||
"droppedweight" "1000" be_ai_goal.c additional dropped item weight
|
||||
"weapindex_rocketlauncher" "5" be_ai_move.c rl weapon index for rocket jumping
|
||||
"weapindex_bfg10k" "9" be_ai_move.c bfg weapon index for bfg jumping
|
||||
"weapindex_grapple" "10" be_ai_move.c grapple weapon index for grappling
|
||||
"entitytypemissile" "3" be_ai_move.c ET_MISSILE
|
||||
"offhandgrapple" "0" be_ai_move.c enable off hand grapple hook
|
||||
"cmd_grappleon" "grappleon" be_ai_move.c command to activate off hand grapple
|
||||
"cmd_grappleoff" "grappleoff" be_ai_move.c command to deactivate off hand grapple
|
||||
"itemconfig" "items.c" be_ai_goal.c item configuration file
|
||||
"weaponconfig" "weapons.c" be_ai_weap.c weapon configuration file
|
||||
"synfile" "syn.c" be_ai_chat.c file with synonyms
|
||||
"rndfile" "rnd.c" be_ai_chat.c file with random strings
|
||||
"matchfile" "match.c" be_ai_chat.c file with match strings
|
||||
"nochat" "0" be_ai_chat.c disable chats
|
||||
"max_messages" "1024" be_ai_chat.c console message heap size
|
||||
"max_weaponinfo" "32" be_ai_weap.c maximum number of weapon info
|
||||
"max_projectileinfo" "32" be_ai_weap.c maximum number of projectile info
|
||||
"max_iteminfo" "256" be_ai_goal.c maximum number of item info
|
||||
"max_levelitems" "256" be_ai_goal.c maximum number of level items
|
||||
|
||||
*/
|
||||
|
124
code/game/chars.h
Normal file
124
code/game/chars.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
// Copyright (C) 2001-2002 Raven Software
|
||||
//
|
||||
//===========================================================================
|
||||
//
|
||||
// Name: chars.h
|
||||
// Function: bot characteristics
|
||||
// Programmer: Mr Elusive (MrElusive@idsoftware.com)
|
||||
// Last update: 1999-09-08
|
||||
// Tab Size: 4 (real tabs)
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//========================================================
|
||||
//========================================================
|
||||
//name
|
||||
#define CHARACTERISTIC_NAME 0 //string
|
||||
//gender of the bot
|
||||
#define CHARACTERISTIC_GENDER 1 //string ("male", "female", "it")
|
||||
//attack skill
|
||||
// > 0.0 && < 0.2 = don't move
|
||||
// > 0.3 && < 1.0 = aim at enemy during retreat
|
||||
// > 0.0 && < 0.4 = only move forward/backward
|
||||
// >= 0.4 && < 1.0 = circle strafing
|
||||
// > 0.7 && < 1.0 = random strafe direction change
|
||||
#define CHARACTERISTIC_ATTACK_SKILL 2 //float [0, 1]
|
||||
//weapon weight file
|
||||
#define CHARACTERISTIC_WEAPONWEIGHTS 3 //string
|
||||
//view angle difference to angle change factor
|
||||
#define CHARACTERISTIC_VIEW_FACTOR 4 //float <0, 1]
|
||||
//maximum view angle change
|
||||
#define CHARACTERISTIC_VIEW_MAXCHANGE 5 //float [1, 360]
|
||||
//reaction time in seconds
|
||||
#define CHARACTERISTIC_REACTIONTIME 6 //float [0, 5]
|
||||
//accuracy when aiming
|
||||
#define CHARACTERISTIC_AIM_ACCURACY 7 //float [0, 1]
|
||||
//weapon specific aim accuracy
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_MACHINEGUN 8 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_SHOTGUN 9 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_ROCKETLAUNCHER 10 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_GRENADELAUNCHER 11 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_LIGHTNING 12
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_PLASMAGUN 13 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_RAILGUN 14
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_BFG10K 15 //float [0, 1]
|
||||
//skill when aiming
|
||||
// > 0.0 && < 0.9 = aim is affected by enemy movement
|
||||
// > 0.4 && <= 0.8 = enemy linear leading
|
||||
// > 0.8 && <= 1.0 = enemy exact movement leading
|
||||
// > 0.5 && <= 1.0 = prediction shots when enemy is not visible
|
||||
// > 0.6 && <= 1.0 = splash damage by shooting nearby geometry
|
||||
#define CHARACTERISTIC_AIM_SKILL 16 //float [0, 1]
|
||||
//weapon specific aim skill
|
||||
#define CHARACTERISTIC_AIM_SKILL_ROCKETLAUNCHER 17 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_SKILL_GRENADELAUNCHER 18 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_SKILL_PLASMAGUN 19 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_SKILL_BFG10K 20 //float [0, 1]
|
||||
//========================================================
|
||||
//chat
|
||||
//========================================================
|
||||
//file with chats
|
||||
#define CHARACTERISTIC_CHAT_FILE 21 //string
|
||||
//name of the chat character
|
||||
#define CHARACTERISTIC_CHAT_NAME 22 //string
|
||||
//characters per minute type speed
|
||||
#define CHARACTERISTIC_CHAT_CPM 23 //integer [1, 4000]
|
||||
//tendency to insult/praise
|
||||
#define CHARACTERISTIC_CHAT_INSULT 24 //float [0, 1]
|
||||
//tendency to chat misc
|
||||
#define CHARACTERISTIC_CHAT_MISC 25 //float [0, 1]
|
||||
//tendency to chat at start or end of level
|
||||
#define CHARACTERISTIC_CHAT_STARTENDLEVEL 26 //float [0, 1]
|
||||
//tendency to chat entering or exiting the game
|
||||
#define CHARACTERISTIC_CHAT_ENTEREXITGAME 27 //float [0, 1]
|
||||
//tendency to chat when killed someone
|
||||
#define CHARACTERISTIC_CHAT_KILL 28 //float [0, 1]
|
||||
//tendency to chat when died
|
||||
#define CHARACTERISTIC_CHAT_DEATH 29 //float [0, 1]
|
||||
//tendency to chat when enemy suicides
|
||||
#define CHARACTERISTIC_CHAT_ENEMYSUICIDE 30 //float [0, 1]
|
||||
//tendency to chat when hit while talking
|
||||
#define CHARACTERISTIC_CHAT_HITTALKING 31 //float [0, 1]
|
||||
//tendency to chat when bot was hit but didn't dye
|
||||
#define CHARACTERISTIC_CHAT_HITNODEATH 32 //float [0, 1]
|
||||
//tendency to chat when bot hit the enemy but enemy didn't dye
|
||||
#define CHARACTERISTIC_CHAT_HITNOKILL 33 //float [0, 1]
|
||||
//tendency to randomly chat
|
||||
#define CHARACTERISTIC_CHAT_RANDOM 34 //float [0, 1]
|
||||
//tendency to reply
|
||||
#define CHARACTERISTIC_CHAT_REPLY 35 //float [0, 1]
|
||||
//========================================================
|
||||
//movement
|
||||
//========================================================
|
||||
//tendency to crouch
|
||||
#define CHARACTERISTIC_CROUCHER 36 //float [0, 1]
|
||||
//tendency to jump
|
||||
#define CHARACTERISTIC_JUMPER 37 //float [0, 1]
|
||||
//tendency to walk
|
||||
#define CHARACTERISTIC_WALKER 48 //float [0, 1]
|
||||
//tendency to jump using a weapon
|
||||
#define CHARACTERISTIC_WEAPONJUMPING 38 //float [0, 1]
|
||||
//tendency to use the grapple hook when available
|
||||
#define CHARACTERISTIC_GRAPPLE_USER 39 //float [0, 1] //use this!!
|
||||
//========================================================
|
||||
//goal
|
||||
//========================================================
|
||||
//item weight file
|
||||
#define CHARACTERISTIC_ITEMWEIGHTS 40 //string
|
||||
//the aggression of the bot
|
||||
#define CHARACTERISTIC_AGGRESSION 41 //float [0, 1]
|
||||
//the self preservation of the bot (rockets near walls etc.)
|
||||
#define CHARACTERISTIC_SELFPRESERVATION 42 //float [0, 1]
|
||||
//how likely the bot is to take revenge
|
||||
#define CHARACTERISTIC_VENGEFULNESS 43 //float [0, 1] //use this!!
|
||||
//tendency to camp
|
||||
#define CHARACTERISTIC_CAMPER 44 //float [0, 1]
|
||||
//========================================================
|
||||
//========================================================
|
||||
//tendency to get easy frags
|
||||
#define CHARACTERISTIC_EASY_FRAGGER 45 //float [0, 1]
|
||||
//how alert the bot is (view distance)
|
||||
#define CHARACTERISTIC_ALERTNESS 46 //float [0, 1]
|
||||
//how much the bot fires it's weapon
|
||||
#define CHARACTERISTIC_FIRETHROTTLE 47 //float [0, 1]
|
||||
|
1404
code/game/g_active.c
Normal file
1404
code/game/g_active.c
Normal file
File diff suppressed because it is too large
Load diff
319
code/game/g_antilag.c
Normal file
319
code/game/g_antilag.c
Normal file
|
@ -0,0 +1,319 @@
|
|||
// Copyright (C) 2000-2001 Raven Software, Inc.
|
||||
//
|
||||
// g_antilag.c -- handles server side anti-lag
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
G_UpdateClientAntiLag
|
||||
================
|
||||
*/
|
||||
void G_UpdateClientAntiLag ( gentity_t* ent )
|
||||
{
|
||||
int head;
|
||||
int newtime;
|
||||
|
||||
head = ent->client->antilagHead;
|
||||
|
||||
// If on a new frame snap the head up to the end of the last frame and
|
||||
// add a new head
|
||||
if ( ent->client->antilag[head].leveltime < level.time )
|
||||
{
|
||||
ent->client->antilag[head].time = level.previousTime;
|
||||
|
||||
// Move to the next position
|
||||
if ( (++ent->client->antilagHead) > MAX_ANTILAG )
|
||||
{
|
||||
ent->client->antilagHead = 0;
|
||||
}
|
||||
|
||||
head = ent->client->antilagHead;
|
||||
}
|
||||
|
||||
// Bots only move once per frame
|
||||
if ( ent->r.svFlags & SVF_BOT )
|
||||
{
|
||||
newtime = level.time;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate the actual server time
|
||||
newtime = level.previousTime + trap_Milliseconds() - level.frameStartTime;
|
||||
|
||||
if ( newtime > level.time )
|
||||
{
|
||||
newtime = level.time;
|
||||
}
|
||||
else if ( newtime <= level.previousTime )
|
||||
{
|
||||
newtime = level.previousTime + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the clients current state into the antilag cache
|
||||
ent->client->antilag[head].leveltime = level.time;
|
||||
ent->client->antilag[head].time = newtime;
|
||||
VectorCopy ( ent->r.currentOrigin, ent->client->antilag[head].rOrigin );
|
||||
VectorCopy ( ent->r.currentAngles, ent->client->antilag[head].rAngles );
|
||||
VectorCopy ( ent->r.mins, ent->client->antilag[head].mins );
|
||||
VectorCopy ( ent->r.maxs, ent->client->antilag[head].maxs );
|
||||
|
||||
VectorCopy ( ent->client->ghoulLegsAngles, ent->client->antilag[head].legsAngles );
|
||||
VectorCopy ( ent->client->ghoulLowerTorsoAngles, ent->client->antilag[head].lowerTorsoAngles );
|
||||
VectorCopy ( ent->client->ghoulUpperTorsoAngles, ent->client->antilag[head].upperTorsoAngles );
|
||||
VectorCopy ( ent->client->ghoulHeadAngles, ent->client->antilag[head].headAngles );
|
||||
|
||||
ent->client->antilag[head].legsAnim = ent->s.legsAnim;
|
||||
ent->client->antilag[head].torsoAnim = ent->s.torsoAnim;
|
||||
ent->client->antilag[head].pm_flags = ent->client->ps.pm_flags;
|
||||
ent->client->antilag[head].leanTime = ent->client->ps.leanTime;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
G_UndoClientAntiLag
|
||||
================
|
||||
*/
|
||||
void G_UndoClientAntiLag ( gentity_t* ent )
|
||||
{
|
||||
// If the client isnt already in the past then
|
||||
// dont bother doing anything
|
||||
if ( ent->client->antilagUndo.leveltime != level.time )
|
||||
return;
|
||||
|
||||
// Move the client back into reality by moving over the undo information
|
||||
VectorCopy ( ent->client->antilagUndo.rOrigin, ent->r.currentOrigin );
|
||||
VectorCopy ( ent->client->antilagUndo.rAngles, ent->r.currentAngles );
|
||||
VectorCopy ( ent->client->antilagUndo.mins, ent->r.mins );
|
||||
VectorCopy ( ent->client->antilagUndo.maxs, ent->r.maxs );
|
||||
|
||||
VectorCopy ( ent->client->antilagUndo.legsAngles, ent->client->ghoulLegsAngles );
|
||||
VectorCopy ( ent->client->antilagUndo.lowerTorsoAngles, ent->client->ghoulLowerTorsoAngles );
|
||||
VectorCopy ( ent->client->antilagUndo.upperTorsoAngles, ent->client->ghoulUpperTorsoAngles );
|
||||
VectorCopy ( ent->client->antilagUndo.headAngles, ent->client->ghoulHeadAngles );
|
||||
|
||||
ent->s.legsAnim = ent->client->antilagUndo.legsAnim;
|
||||
ent->s.torsoAnim = ent->client->antilagUndo.torsoAnim;
|
||||
ent->client->ps.pm_flags = ent->client->antilagUndo.pm_flags;
|
||||
ent->client->ps.leanTime = ent->client->antilagUndo.leanTime;
|
||||
|
||||
// Mark the undo information so it cant be used again
|
||||
ent->client->antilagUndo.leveltime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
G_ApplyClientAntiLag
|
||||
================
|
||||
*/
|
||||
void G_ApplyClientAntiLag ( gentity_t* ent, int time )
|
||||
{
|
||||
float lerp;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
// Find the two pieces of history information that sandwitch the
|
||||
// time we are looking for
|
||||
from = ent->client->antilagHead;
|
||||
to = ent->client->antilagHead;
|
||||
do
|
||||
{
|
||||
if ( ent->client->antilag[from].time <= time )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
to = from;
|
||||
from--;
|
||||
|
||||
if ( from < 0 )
|
||||
{
|
||||
from = MAX_ANTILAG - 1;
|
||||
}
|
||||
}
|
||||
while ( from != ent->client->antilagHead );
|
||||
|
||||
// If the from is equal to the to then there wasnt even
|
||||
// one piece of information worth using so just use the current time frame
|
||||
if ( from == to )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the undo information if its not already saved
|
||||
if ( ent->client->antilagUndo.leveltime != level.time )
|
||||
{
|
||||
// Save the undo information
|
||||
ent->client->antilagUndo.leveltime = level.time;
|
||||
|
||||
VectorCopy ( ent->r.currentOrigin, ent->client->antilagUndo.rOrigin );
|
||||
VectorCopy ( ent->r.currentAngles, ent->client->antilagUndo.rAngles );
|
||||
VectorCopy ( ent->r.mins, ent->client->antilagUndo.mins );
|
||||
VectorCopy ( ent->r.maxs, ent->client->antilagUndo.maxs );
|
||||
|
||||
VectorCopy ( ent->client->ghoulLegsAngles, ent->client->antilagUndo.legsAngles );
|
||||
VectorCopy ( ent->client->ghoulLowerTorsoAngles, ent->client->antilagUndo.lowerTorsoAngles );
|
||||
VectorCopy ( ent->client->ghoulUpperTorsoAngles, ent->client->antilagUndo.upperTorsoAngles );
|
||||
VectorCopy ( ent->client->ghoulHeadAngles, ent->client->antilagUndo.headAngles );
|
||||
|
||||
ent->client->antilagUndo.legsAnim = ent->s.legsAnim;
|
||||
ent->client->antilagUndo.torsoAnim = ent->s.torsoAnim;
|
||||
ent->client->antilagUndo.pm_flags = ent->client->ps.pm_flags;
|
||||
ent->client->antilagUndo.leanTime = ent->client->ps.leanTime;
|
||||
}
|
||||
|
||||
// If the best history found was the last in the list then
|
||||
// dont lerp, just use the last one
|
||||
if ( from == ent->client->antilagHead )
|
||||
{
|
||||
VectorCopy ( ent->client->antilag[to].rOrigin, ent->r.currentOrigin );
|
||||
VectorCopy ( ent->client->antilag[to].rAngles, ent->r.currentAngles );
|
||||
VectorCopy ( ent->client->antilag[to].mins, ent->r.maxs );
|
||||
VectorCopy ( ent->client->antilag[to].maxs, ent->r.mins );
|
||||
|
||||
VectorCopy ( ent->client->antilag[to].legsAngles, ent->client->ghoulLegsAngles );
|
||||
VectorCopy ( ent->client->antilag[to].lowerTorsoAngles, ent->client->ghoulLowerTorsoAngles );
|
||||
VectorCopy ( ent->client->antilag[to].upperTorsoAngles, ent->client->ghoulUpperTorsoAngles );
|
||||
VectorCopy ( ent->client->antilag[to].headAngles, ent->client->ghoulHeadAngles );
|
||||
|
||||
ent->s.legsAnim = ent->client->antilag[to].legsAnim;
|
||||
ent->s.torsoAnim = ent->client->antilag[to].torsoAnim;
|
||||
ent->client->ps.pm_flags = ent->client->antilag[to].pm_flags;
|
||||
ent->client->ps.leanTime = ent->client->antilag[to].leanTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the lerp value to use for the vectors
|
||||
lerp = (float)(time - ent->client->antilag[from].time) / (float)(ent->client->antilag[to].time - ent->client->antilag[from].time);
|
||||
|
||||
// Lerp all the vectors between the before and after history information
|
||||
LerpVector ( ent->client->antilag[from].rOrigin, ent->client->antilag[to].rOrigin, lerp, ent->r.currentOrigin );
|
||||
LerpVector ( ent->client->antilag[from].rAngles, ent->client->antilag[to].rAngles, lerp, ent->r.currentAngles );
|
||||
LerpVector ( ent->client->antilag[from].maxs, ent->client->antilag[to].maxs, lerp, ent->r.maxs );
|
||||
LerpVector ( ent->client->antilag[from].mins, ent->client->antilag[to].mins, lerp, ent->r.mins );
|
||||
|
||||
LerpVector ( ent->client->antilag[from].legsAngles, ent->client->antilag[to].legsAngles, lerp, ent->client->ghoulLegsAngles );
|
||||
LerpVector ( ent->client->antilag[from].lowerTorsoAngles, ent->client->antilag[to].lowerTorsoAngles, lerp, ent->client->ghoulLowerTorsoAngles );
|
||||
LerpVector ( ent->client->antilag[from].upperTorsoAngles, ent->client->antilag[to].upperTorsoAngles, lerp, ent->client->ghoulUpperTorsoAngles );
|
||||
LerpVector ( ent->client->antilag[from].headAngles, ent->client->antilag[to].headAngles, lerp, ent->client->ghoulHeadAngles );
|
||||
|
||||
ent->client->ps.leanTime = ent->client->antilag[from].leanTime + (ent->client->antilag[from].leanTime-ent->client->antilag[to].leanTime) * lerp;
|
||||
|
||||
ent->s.legsAnim = ent->client->antilag[to].legsAnim;
|
||||
ent->s.torsoAnim = ent->client->antilag[to].torsoAnim;
|
||||
ent->client->ps.pm_flags = ent->client->antilag[to].pm_flags;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
G_UndoAntiLag
|
||||
================
|
||||
*/
|
||||
void G_UndoAntiLag ( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
// Undo all history
|
||||
for ( i = 0; i < level.numConnectedClients; i ++ )
|
||||
{
|
||||
gentity_t* other = &g_entities[level.sortedClients[i]];
|
||||
|
||||
if ( other->client->pers.connected != CON_CONNECTED )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip clients that are spectating
|
||||
if ( G_IsClientSpectating ( other->client ) || G_IsClientDead ( other->client ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( other->r.svFlags & SVF_DOUBLED_BBOX )
|
||||
{
|
||||
// Put the hitbox back the way it was
|
||||
other->r.maxs[0] /= 2;
|
||||
other->r.maxs[1] /= 2;
|
||||
other->r.mins[0] /= 2;
|
||||
other->r.mins[1] /= 2;
|
||||
|
||||
other->r.svFlags &= (~SVF_DOUBLED_BBOX);
|
||||
}
|
||||
|
||||
G_UndoClientAntiLag ( other );
|
||||
|
||||
// Relink the entity into the world
|
||||
trap_LinkEntity ( other );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
G_ApplyAntiLag
|
||||
================
|
||||
*/
|
||||
void G_ApplyAntiLag ( gentity_t* ref, qboolean enlargeHitBox )
|
||||
{
|
||||
int i;
|
||||
int reftime;
|
||||
|
||||
// Figure out the reference time based on the reference clients server time
|
||||
reftime = ref->client->pers.cmd.serverTime;
|
||||
if ( reftime > level.time )
|
||||
{
|
||||
reftime = level.time;
|
||||
}
|
||||
|
||||
// Move all the clients back into the reference clients time frame.
|
||||
for ( i = 0; i < level.numConnectedClients; i ++ )
|
||||
{
|
||||
gentity_t* other = &g_entities[level.sortedClients[i]];
|
||||
|
||||
if ( other->client->pers.connected != CON_CONNECTED )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip the reference client
|
||||
if ( other == ref )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip entities not in use
|
||||
if ( !other->inuse )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip clients that are spectating
|
||||
if ( G_IsClientSpectating ( other->client ) || G_IsClientDead ( other->client ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dont bring them back in time unless requested
|
||||
if ( !(ref->r.svFlags & SVF_BOT) & ref->client->pers.antiLag )
|
||||
{
|
||||
// Apply the antilag to this player
|
||||
G_ApplyClientAntiLag ( other, reftime );
|
||||
}
|
||||
|
||||
if ( enlargeHitBox )
|
||||
{
|
||||
// Adjust the hit box to account for hands and such
|
||||
// that are sticking out of the normal bounding box
|
||||
other->r.maxs[0] *= 2;
|
||||
other->r.maxs[1] *= 2;
|
||||
other->r.mins[0] *= 2;
|
||||
other->r.mins[1] *= 2;
|
||||
other->r.svFlags |= SVF_DOUBLED_BBOX;
|
||||
}
|
||||
|
||||
// Relink the entity into the world
|
||||
trap_LinkEntity ( other );
|
||||
}
|
||||
}
|
1082
code/game/g_bot.c
Normal file
1082
code/game/g_bot.c
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue