Compare commits

..

3 commits

Author SHA1 Message Date
archive
a8a1ed1116 as released 1999-05-07 1999-05-07 00:00:00 +00:00
archive
659a4a3268 as released 1999-04-30 1999-04-30 00:00:00 +00:00
archive
10fd0b8e66 as released 1999-03-18 1999-03-18 00:00:00 +00:00
338 changed files with 29497 additions and 11170 deletions

Binary file not shown.

Binary file not shown.

View file

@ -19,4 +19,5 @@ $book b_andmap 0 0 640 480
$load art/gfx/book/book_hive.pcx
$book b_hivemap 0 0 640 480
// end

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,9 @@ $pic i_tome 0 0 32 32
$load art/gfx/pics/i_teleport.pcx
$pic i_tele 0 0 32 32
$load art/gfx/pics/i_tornado.pcx
$pic i_tornado 0 0 32 32
$load art/gfx/pics/i_lightning-shield.pcx
$pic i_shield 0 0 32 32
@ -93,3 +96,10 @@ $pic powerup2 0 0 64 16
$load art/gfx/pics/lifebar_back.pcx
$pic lifebar_back 0 0 8 16
$load art/gfx/pics/arm_silver.tga
$pic arm_silver 0 0 32 32
$load art/gfx/pics/arm_gold.tga
$pic arm_gold 0 0 32 32

View file

@ -4,67 +4,67 @@
$picdir menu
$load art/gfx/pics/num_neg.pcx
$load art/gfx/pics/num_neg.tga
$pic num_neg 0 0 8 16
$load art/gfx/pics/num_0.pcx
$load art/gfx/pics/num_0.tga
$pic num_0 0 0 8 16
$load art/gfx/pics/num_1.pcx
$load art/gfx/pics/num_1.tga
$pic num_1 0 0 8 16
$load art/gfx/pics/num_2.pcx
$load art/gfx/pics/num_2.tga
$pic num_2 0 0 8 16
$load art/gfx/pics/num_3.pcx
$load art/gfx/pics/num_3.tga
$pic num_3 0 0 8 16
$load art/gfx/pics/num_4.pcx
$load art/gfx/pics/num_4.tga
$pic num_4 0 0 8 16
$load art/gfx/pics/num_5.pcx
$load art/gfx/pics/num_5.tga
$pic num_5 0 0 8 16
$load art/gfx/pics/num_6.pcx
$load art/gfx/pics/num_6.tga
$pic num_6 0 0 8 16
$load art/gfx/pics/num_7.pcx
$load art/gfx/pics/num_7.tga
$pic num_7 0 0 8 16
$load art/gfx/pics/num_8.pcx
$load art/gfx/pics/num_8.tga
$pic num_8 0 0 8 16
$load art/gfx/pics/num_9.pcx
$load art/gfx/pics/num_9.tga
$pic num_9 0 0 8 16
$load art/gfx/pics/num_red0.pcx
$load art/gfx/pics/num_red0.tga
$pic num_red0 0 0 8 16
$load art/gfx/pics/num_red1.pcx
$load art/gfx/pics/num_red1.tga
$pic num_red1 0 0 8 16
$load art/gfx/pics/num_red2.pcx
$load art/gfx/pics/num_red2.tga
$pic num_red2 0 0 8 16
$load art/gfx/pics/num_red3.pcx
$load art/gfx/pics/num_red3.tga
$pic num_red3 0 0 8 16
$load art/gfx/pics/num_red4.pcx
$load art/gfx/pics/num_red4.tga
$pic num_red4 0 0 8 16
$load art/gfx/pics/num_red5.pcx
$load art/gfx/pics/num_red5.tga
$pic num_red5 0 0 8 16
$load art/gfx/pics/num_red6.pcx
$load art/gfx/pics/num_red6.tga
$pic num_red6 0 0 8 16
$load art/gfx/pics/num_red7.pcx
$load art/gfx/pics/num_red7.tga
$pic num_red7 0 0 8 16
$load art/gfx/pics/num_red8.pcx
$load art/gfx/pics/num_red8.tga
$pic num_red8 0 0 8 16
$load art/gfx/pics/num_red9.pcx
$load art/gfx/pics/num_red9.tga
$pic num_red9 0 0 8 16
// end

View file

@ -51,7 +51,8 @@ $load art/gfx/sprites/s_waterwake.pcx
$spriteframe 0 0 64 64
$spritename wake_add
$load art/gfx/sprites/s_wake_add.pcx
;$load art/gfx/sprites/s_wake_add.pcx
$load art/gfx/sprites/s_waterwake_a.pcx
$spriteframe 0 0 64 64
$spritename scorchmark

View file

@ -0,0 +1,9 @@
$fm_cd objects\chandelier\chan1
$fm_origin 0 0 0
$fm_base base skin
$fm_skin skin
$fm_scale 1
//
$fm_frame poly

View file

@ -0,0 +1,634 @@
$fm_cd player/corvette
$fm_origin 0 0 0
$fm_skeleton 5
$fm_cluster cluster
$fm_referenced 0 elf_Lhandroot elf_Rhandroot elf_Rfootroot elf_Lfootroot elf_Bstaffroot elf_bladeroot elf_hellroot
// elf_head elf_eyes - not used
$fm_basest base skin stbase
$fm_node_order base2 _back _StOff _BOff _Armor _RArm _RhandHi _StafActv _bladstf _helstf _LArm _LhandHi _BowActv _Rleg _Lleg _head
$fm_skin skin
$fm_scale 1
//
$fm_frame partfly
//
$fm_frame 180turn1 180turn2 180turn3 180turn4 180turn5
$fm_frame 180turn6 180turn7 180turn8 180turn9
//
$fm_frame 4swim1 4swim2 4swim3 4swim4 4swim5
$fm_frame 4swim6 4swim7 4swim8 4swim9 4swim10
//
$fm_frame asscrtch1 asscrtch2 asscrtch3 asscrtch4 asscrtch5
$fm_frame asscrtch6 asscrtch7 asscrtch8 asscrtch9 asscrtch10
$fm_frame asscrtch11 asscrtch12 asscrtch13 asscrtch14 asscrtch15
$fm_frame asscrtch16 asscrtch17 asscrtch18 asscrtch19 asscrtch20
$fm_frame asscrtch21 asscrtch22 asscrtch23 asscrtch24 asscrtch25
//
$fm_frame backroll1 backroll2 backroll3 backroll4 backroll5
$fm_frame backroll6 backroll7 backroll8 backroll9
//
$fm_frame ballspell1 ballspell2 ballspell3 ballspell4 ballspell5
$fm_frame ballspell6 ballspell7 ballspell8
//
$fm_frame bkflip1 bkflip2 bkflip3 bkflip4 bkflip5
$fm_frame bkflip6 bkflip7 bkflip8 bkflip9 bkflip10
$fm_frame bkflip11 bkflip12 bkflip13 bkflip14 bkflip15
$fm_frame bkflip16 bkflip17 bkflip18 bkflip19 bkflip20
$fm_frame bkflip21 bkflip22 bkflip23 bkflip24 bkflip25
//
$fm_frame bkswim1 bkswim2 bkswim3 bkswim4 bkswim5
$fm_frame bkswim6 bkswim7
//
$fm_frame blowback1 blowback2 blowback3 blowback4 blowback5
$fm_frame blowback6 blowback7 blowback8 blowback9 blowback10
$fm_frame blowback11 blowback12 blowback13 blowback14 blowback15
$fm_frame blowback16 blowback17 blowback18 blowback19 blowback20
$fm_frame blowback21 blowback22 blowback23 blowback24
//
$fm_frame breath1 breath2 breath3 breath4 breath5
$fm_frame breath6 breath7 breath8 breath9 breath10
$fm_frame breath11 breath12 breath13 breath14 breath15
$fm_frame breath16 breath17 breath18 breath19 breath20
$fm_frame breath21 breath22 breath23
//
$fm_frame burning1 burning2 burning3 burning4 burning5
$fm_frame burning6 burning7 burning8 burning9 burning10
$fm_frame burning11 burning12 burning13 burning14 burning15
$fm_frame burning16 burning17 burning18 burning19 burning20
$fm_frame burning21 burning22 burning23 burning24 burning25
$fm_frame burning26 burning27 burning28 burning29 burning30
$fm_frame burning31 burning32 burning33 burning34 burning35
//
$fm_frame chngsplA1 chngsplA2 chngsplA3 chngsplA4 chngsplA5
$fm_frame chngsplA6 chngsplA7 chngsplA8 chngsplA9
//
$fm_frame choking1 choking2 choking3 choking4 choking5
$fm_frame choking6 choking7 choking8 choking9 choking10
$fm_frame choking11 choking12 choking13 choking14 choking15
$fm_frame choking16 choking17 choking18 choking19 choking20
$fm_frame choking21 choking22 choking23 choking24 choking25
$fm_frame choking26 choking27 choking28 choking29 choking30
$fm_frame choking31 choking32 choking33 choking34 choking35
//
$fm_frame conjure1 conjure2 conjure3 conjure4 conjure5
$fm_frame conjure6 conjure7 conjure8 conjure9 conjure10
$fm_frame conjure11 conjure12 conjure13 conjure14 conjure15
// $fm_frame conjure16
//
$fm_frame creep1 creep2 creep3 creep4 creep5
$fm_frame creep6 creep7 creep8 creep9 creep10
$fm_frame creep11 creep12
//
$fm_frame creepL1 creepL2 creepL3 creepL4 creepL5
$fm_frame creepL6 creepL7 creepL8 creepL9 creepL10
$fm_frame creepL11 creepL12
//
$fm_frame creepR1 creepR2 creepR3 creepR4 creepR5
$fm_frame creepR6 creepR7 creepR8 creepR9 creepR10
$fm_frame creepR11 creepR12
//
$fm_frame crepbak1 crepbak2 crepbak3 crepbak4 crepbak5
$fm_frame crepbak6 crepbak7 crepbak8 crepbak9 crepbak10
$fm_frame crepbak11 crepbak12
//
$fm_frame crhpvt1 crhpvt2 crhpvt3 crhpvt4
//
$fm_frame deathA1 deathA2 deathA3 deathA4 deathA5
$fm_frame deathA6 deathA7 deathA8 deathA9 deathA10
$fm_frame deathA11 deathA12 deathA13 deathA14
//
$fm_frame draw1 draw2 draw3 draw4 draw5
//
$fm_frame drop1 drop2 drop3 drop4
//
$fm_frame drown1 drown2 drown3 drown4 drown5
$fm_frame drown6 drown7 drown8 drown9 drown10
$fm_frame drown11 drown12 drown13 drown14 drown15
$fm_frame drown16 drown17 drown18 drown19 drown20
$fm_frame drown21 drown22 drown23 drown24 drown25
$fm_frame drown26 drown27 drown28 drown29 drown30
$fm_frame drown31 drown32 drown33 drown34 drown35
$fm_frame drown36 drown37 drown38 drown39 drown40
//
$fm_frame drownidle1 drownidle2 drownidle3 drownidle4 drownidle5
$fm_frame drownidle6 drownidle7 drownidle8 drownidle9 drownidle10
$fm_frame drownidle11 drownidle12 drownidle13 drownidle14 drownidle15
$fm_frame drownidle16 drownidle17 drownidle18 drownidle19 drownidle20
$fm_frame drownidle21 drownidle22 drownidle23 drownidle24 drownidle25
$fm_frame drownidle26 drownidle27 drownidle28 drownidle29 drownidle30
$fm_frame drownidle31 drownidle32
//
$fm_frame faceplant1 faceplant2 faceplant3 faceplant4 faceplant5
$fm_frame faceplant6 faceplant7 faceplant8 faceplant9 faceplant10
$fm_frame faceplant11 faceplant12 faceplant13 faceplant14 faceplant15
$fm_frame faceplant16 faceplant17 faceplant18 faceplant19 faceplant20
$fm_frame faceplant21 faceplant22 faceplant23 faceplant24
//
$fm_frame falling1 falling2 falling3 falling4 falling5
$fm_frame falling6 falling7 falling8 falling9 falling10
$fm_frame falling11 falling12 falling13 falling14 falling15
//
$fm_frame fastleft1 fastleft2 fastleft3 fastleft4 fastleft5
$fm_frame fastleft6 fastleft7 fastleft8
//
$fm_frame fastrite1 fastrite2 fastrite3 fastrite4 fastrite5
$fm_frame fastrite6 fastrite7 fastrite8
//
$fm_frame getbow1 getbow2 getbow3 getbow4 getbow5
$fm_frame getbow6 getbow7 getbow8 getbow9
//
$fm_frame getstaff1 getstaff2 getstaff3 getstaff4 getstaff5
$fm_frame getstaff6 getstaff7 getstaff8
//
$fm_frame gofast1 gofast2 gofast3 gofast4
//
$fm_frame gorun1 gorun2 gorun3
//
$fm_frame grab1 grab2 grab3 grab4 grab5
$fm_frame grab6 grab7 grab8
//
$fm_frame grabrope1 grabrope2 grabrope3 grabrope4 grabrope5
$fm_frame grabrope6 grabrope7
//
$fm_frame helstf1 helstf2 helstf3 helstf4 helstf5
$fm_frame helstf6 helstf7
//
$fm_frame idlswm1 idlswm2 idlswm3 idlswm4 idlswm5
$fm_frame idlswm6 idlswm7 idlswm8 idlswm9 idlswm10
$fm_frame idlswm11 idlswm12 idlswm13 idlswm14 idlswm15
//
$fm_frame idlundr1 idlundr2 idlundr3 idlundr4 idlundr5
$fm_frame idlundr6 idlundr7 idlundr8 idlundr9 idlundr10
$fm_frame idlundr11 idlundr12 idlundr13 idlundr14 idlundr15
$fm_frame idlundr16 idlundr17 idlundr18 idlundr19 idlundr20
//
$fm_frame jog1 jog2 jog3 jog4 jog5
$fm_frame jog6 jog7 jog8
//
$fm_frame jogback1 jogback2 jogback3 jogback4 jogback5
$fm_frame jogback6
//
$fm_frame jump1 jump2 jump3 jump4 jump5
$fm_frame jump6 jump7 jump8 jump9 jump10
$fm_frame jump11 jump12 jump13 jump14 jump15
$fm_frame jump16 jump17 jump18 jump19 jump20
$fm_frame jump21
//
$fm_frame jumpback1 jumpback2 jumpback3 jumpback4 jumpback5
$fm_frame jumpback6 jumpback7 jumpback8 jumpback9 jumpback10
$fm_frame jumpback11 jumpback12 jumpback13 jumpback14 jumpback15
$fm_frame jumpback16 jumpback17 jumpback18 jumpback19 jumpback20
$fm_frame jumpback21 jumpback22 jumpback23 jumpback24
//
$fm_frame jumpleft1 jumpleft2 jumpleft3 jumpleft4 jumpleft5
$fm_frame jumpleft6 jumpleft7 jumpleft8 jumpleft9 jumpleft10
$fm_frame jumpleft11 jumpleft12 jumpleft13 jumpleft14 jumpleft15
$fm_frame jumpleft16 jumpleft17 jumpleft18 jumpleft19 jumpleft20
$fm_frame jumpleft21 jumpleft22 jumpleft23 jumpleft24
//
$fm_frame jumprite1 jumprite2 jumprite3 jumprite4 jumprite5
$fm_frame jumprite6 jumprite7 jumprite8 jumprite9 jumprite10
$fm_frame jumprite11 jumprite12 jumprite13 jumprite14 jumprite15
$fm_frame jumprite16 jumprite17 jumprite18 jumprite19 jumprite20
$fm_frame jumprite21 jumprite22 jumprite23 jumprite24
//
$fm_frame kodown1 kodown2 kodown3 kodown4 kodown5
$fm_frame kodown6 kodown7 kodown8 kodown9 kodown10
$fm_frame kodown11 kodown12 kodown13 kodown14 kodown15
$fm_frame kodown16 kodown17 kodown18 kodown19 kodown20
$fm_frame kodown21 kodown22
//
$fm_frame Lclimb1 Lclimb2 Lclimb3 Lclimb4
//
$fm_frame Lclmbstrt1 Lclmbstrt2 Lclmbstrt3
//
$fm_frame Lcrepbck1 Lcrepbck2 Lcrepbck3 Lcrepbck4 Lcrepbck5
$fm_frame Lcrepbck6 Lcrepbck7 Lcrepbck8 Lcrepbck9 Lcrepbck10
$fm_frame Lcrepbck11 Lcrepbck12
//
$fm_frame Letgo1 Letgo2 Letgo3 Letgo4 Letgo5
//
$fm_frame Lflip1 Lflip2 Lflip3 Lflip4 Lflip5
$fm_frame Lflip6 Lflip7 Lflip8 Lflip9 Lflip10
$fm_frame Lflip11 Lflip12 Lflip13 Lflip14
//
$fm_frame lftflip1 lftflip2 lftflip3 lftflip4 lftflip5
$fm_frame lftflip6 lftflip7 lftflip8 lftflip9
//
$fm_frame Lhndset1 Lhndset2 Lhndset3 Lhndset4 Lhndset5
//
$fm_frame Lhop1 Lhop2 Lhop3
//
$fm_frame Lidle1 Lidle2 Lidle3 Lidle4 Lidle5
$fm_frame Lidle6 Lidle7 Lidle8 Lidle9 Lidle10
$fm_frame Lidle11 Lidle12 Lidle13 Lidle14 Lidle15
$fm_frame Lidle16 Lidle17 Lidle18 Lidle19 Lidle20
$fm_frame Lidle21
//
$fm_frame Ljogback1 Ljogback2 Ljogback3 Ljogback4 Ljogback5
$fm_frame Ljogback6
//
$fm_frame lklft1 lklft2 lklft3 lklft4 lklft5
$fm_frame lklft6 lklft7 lklft8 lklft9 lklft10
$fm_frame lklft11 lklft12 lklft13 lklft14 lklft15
$fm_frame lklft16 lklft17 lklft18 lklft19 lklft20
$fm_frame lklft21 lklft22
//
$fm_frame lkrt1 lkrt2 lkrt3 lkrt4 lkrt5
$fm_frame lkrt6 lkrt7 lkrt8 lkrt9 lkrt10
$fm_frame lkrt11 lkrt12 lkrt13 lkrt14 lkrt15
$fm_frame lkrt16 lkrt17 lkrt18 lkrt19 lkrt20
$fm_frame lkrt21 lkrt22
//
$fm_frame lookbck1 lookbck2 lookbck3 lookbck4 lookbck5
$fm_frame lookbck6 lookbck7 lookbck8 lookbck9 lookbck10
$fm_frame lookbck11 lookbck12 lookbck13 lookbck14 lookbck15
$fm_frame lookbck16 lookbck17 lookbck18 lookbck19 lookbck20
$fm_frame lookbck21 lookbck22 lookbck23 lookbck24 lookbck25
$fm_frame lookbck26 lookbck27 lookbck28 lookbck29
//
$fm_frame Lpivot1 Lpivot2 Lpivot3 Lpivot4
//
$fm_frame Lsprint1 Lsprint2 Lsprint3 Lsprint4 Lsprint5
$fm_frame Lsprint6
//
$fm_frame Lstair1 Lstair2 Lstair3 Lstair4
//
$fm_frame Lstep1 Lstep2 Lstep3 Lstep4 Lstep5
//
$fm_frame Lstrafe1 Lstrafe2 Lstrafe3 Lstrafe4 Lstrafe5
$fm_frame Lstrafe6 Lstrafe7 Lstrafe8
//
$fm_frame LswichL2R1 LswichL2R2 LswichL2R3 LswichL2R4 LswichL2R5
$fm_frame LswichL2R6 LswichL2R7
//
$fm_frame LswichR2L1 LswichR2L2 LswichR2L3 LswichR2L4 LswichR2L5
$fm_frame LswichR2L6 LswichR2L7
//
$fm_frame newspin1 newspin2 newspin3 newspin4 newspin5
$fm_frame newspin6 newspin7 newspin8
//
$fm_frame ovrhang1 ovrhang2 ovrhang3 ovrhang4 ovrhang5
$fm_frame ovrhang6 ovrhang7 ovrhang8 ovrhang9 ovrhang10
$fm_frame ovrhang11 ovrhang12 ovrhang13 ovrhang14 ovrhang15
$fm_frame ovrhang16 ovrhang17 ovrhang18
//
$fm_frame pestA1 pestA2 pestA3 pestA4 pestA5
$fm_frame pestA6 pestA7 pestA8 pestA9 pestA10
$fm_frame pestA11 pestA12 pestA13 pestA14
//
$fm_frame pestB1 pestB2 pestB3 pestB4 pestB5
$fm_frame pestB6 pestB7 pestB8 pestB9 pestB10
$fm_frame pestB11 pestB12 pestB13 pestB14 pestB15
$fm_frame pestB16 pestB17 pestB18 pestB19 pestB20
$fm_frame pestB21 pestB22
//
$fm_frame phbuton1 phbuton2 phbuton3 phbuton4 phbuton5
$fm_frame phbuton6 phbuton7 phbuton8 phbuton9
//
$fm_frame pullup1 pullup2 pullup3 pullup4 pullup5
$fm_frame pullup6 pullup7 pullup8 pullup9 pullup10
$fm_frame pullup11 pullup12
//
$fm_frame Rclimb1 Rclimb2 Rclimb3 Rclimb4
//
$fm_frame Rclmbstrt1 Rclmbstrt2 Rclmbstrt3
//
$fm_frame Rcrepbck1 Rcrepbck2 Rcrepbck3 Rcrepbck4 Rcrepbck5
$fm_frame Rcrepbck6 Rcrepbck7 Rcrepbck8 Rcrepbck9 Rcrepbck10
$fm_frame Rcrepbck11 Rcrepbck12
//
$fm_frame ready1 ready2 ready3 ready4 ready5
$fm_frame ready6 ready7 ready8 ready9 ready10
$fm_frame ready11 ready12 ready13 ready14 ready15
$fm_frame ready16 ready17 ready18 ready19 ready20
$fm_frame ready21 ready22 ready23 ready24 ready25
$fm_frame ready26
//
$fm_frame recover1 recover2 recover3 recover4 recover5
$fm_frame recover6 recover7
//
$fm_frame redybow1 redybow2 redybow3 redybow4 redybow5
//
$fm_frame resurf1 resurf2 resurf3 resurf4 resurf5
//
$fm_frame Retgo1 Retgo2 Retgo3 Retgo4 Retgo5
//
$fm_frame Rflip1 Rflip2 Rflip3 Rflip4 Rflip5
$fm_frame Rflip6 Rflip7 Rflip8 Rflip9 Rflip10
$fm_frame Rflip11 Rflip12 Rflip13 Rflip14
//
$fm_frame ritflip1 ritflip2 ritflip3 ritflip4 ritflip5
$fm_frame ritflip6 ritflip7 ritflip8 ritflip9
//
$fm_frame Rhndset1 Rhndset2 Rhndset3
//
$fm_frame Rhop1 Rhop2 Rhop3 Rhop4 Rhop5
$fm_frame Rhop6 Rhop7
//
$fm_frame Ridle1 Ridle2 Ridle3 Ridle4 Ridle5
$fm_frame Ridle6 Ridle7 Ridle8 Ridle9 Ridle10
$fm_frame Ridle11 Ridle12 Ridle13 Ridle14 Ridle15
$fm_frame Ridle16 Ridle17 Ridle18 Ridle19 Ridle20
$fm_frame Ridle21
//
$fm_frame Rjogback1 Rjogback2 Rjogback3 Rjogback4 Rjogback5
$fm_frame Rjogback6
//
$fm_frame rollA1 rollA10 rollA11 rollA12 rollA13
$fm_frame rollA14 rollA15 rollA2 rollA3 rollA4
$fm_frame rollA5 rollA6 rollA7 rollA8 rollA9
$fm_frame roll1 roll2 roll3 roll4 roll5
$fm_frame roll6 roll7 roll8 roll9
//
$fm_frame Rsprint1 Rsprint2 Rsprint3 Rsprint4 Rsprint5
$fm_frame Rsprint6
//
$fm_frame Rstair1 Rstair2 Rstair3 Rstair4
//
$fm_frame Rstep1 Rstep2 Rstep3 Rstep4 Rstep5
//
$fm_frame Rstrafe1 Rstrafe2 Rstrafe3 Rstrafe4 Rstrafe5
$fm_frame Rstrafe6 Rstrafe7 Rstrafe8
//
$fm_frame RswichL2R1 RswichL2R2 RswichL2R3 RswichL2R4 RswichL2R5
$fm_frame RswichL2R6 RswichL2R7
//
$fm_frame RswichR2L1 RswichR2L2 RswichR2L3 RswichR2L4 RswichR2L5
$fm_frame RswichR2L6 RswichR2L7
//
$fm_frame run1 run2 run3 run4 run5
$fm_frame run6
//
$fm_frame shoot1 shoot2 shoot3 shoot4 shoot5
//
$fm_frame shrine1 shrine2 shrine3 shrine4 shrine5
$fm_frame shrine6 shrine7 shrine8 shrine9 shrine10
//
$fm_frame slid4d1 slid4d2 slid4d3 slid4d4 slid4d5
$fm_frame slid4d6 slid4d7 slid4d8 slid4d9 slid4d10
$fm_frame slid4d11 slid4d12
//
$fm_frame slidbak1 slidbak2 slidbak3 slidbak4 slidbak5
$fm_frame slidbak6 slidbak7 slidbak8 slidbak9 slidbak10
$fm_frame slidbak11 slidbak12
//
$fm_frame smlpna1 smlpna2 smlpna3 smlpna4
//
$fm_frame smlpnb1 smlpnb2 smlpnb3 smlpnb4
//
$fm_frame spining1 spining2 spining3 spining4 spining5
$fm_frame spining6 spining7
//
$fm_frame subckswm1 subckswm2 subckswm3 subckswm4 subckswm5
$fm_frame subckswm6 subckswm7
//
$fm_frame subdive1 subdive2 subdive3 subdive4 subdive5
$fm_frame subdive6 subdive7 subdive8 subdive9
//
$fm_frame swcharo1 swcharo2 swcharo3 swcharo4 swcharo5
$fm_frame swcharo6 swcharo7
//
$fm_frame swimL1 swimL2 swimL3 swimL4 swimL5
//
$fm_frame swimR1 swimR2 swimR3 swimR4 swimR5
//
$fm_frame swipeA1 swipeA2 swipeA3 swipeA4 swipeA5
$fm_frame swipeA6 swipeA7 swipeA8 swipeA9 swipeA10
$fm_frame swipeA11
//
$fm_frame swipeB1 swipeB2 swipeB3 swipeB4 swipeB5
$fm_frame swipeB6 swipeB7 swipeB8 swipeB9 swipeB10
$fm_frame swipeB11 swipeB12
//
$fm_frame swmfast1 swmfast2 swmfast3 swmfast4 swmfast5
$fm_frame swmfast6 swmfast7
//
$fm_frame swmgrab1 swmgrab2 swmgrab3 swmgrab4 swmgrab5
$fm_frame swmgrab6 swmgrab7 swmgrab8 swmgrab9 swmgrab10
$fm_frame swmgrab11
//
$fm_frame swmL1 swmL2 swmL3 swmL4 swmL5
$fm_frame swmL6 swmL7 swmL8 swmL9
//
$fm_frame swmR1 swmR2 swmR3 swmR4 swmR5
$fm_frame swmR6 swmR7 swmR8 swmR9
//
$fm_frame t4swim1 t4swim2
//
$fm_frame tbswim1 tbswim2 tbswim3 tbswim4 tbswim5
//
$fm_frame throw1 throw2 throw3 throw4 throw5
$fm_frame throw6 throw7 throw8 throw9 throw10
$fm_frame throw11
//
$fm_frame tnsubckswm1 tnsubckswm2
//
$fm_frame trnshrine1 trnshrine2 trnshrine3
//
$fm_frame trnswmL1 trnswmL2
//
$fm_frame trnswmR1 trnswmR2
//
$fm_frame tswimL1 tswimL2 tswimL3 tswimL4
//
$fm_frame tswimR1 tswimR2 tswimR3 tswimR4
//
$fm_frame undrswmA1 undrswmA2 undrswmA3 undrswmA4 undrswmA5
$fm_frame undrswmA6 undrswmA7 undrswmA8 undrswmA9 undrswmA10
$fm_frame undrswmA11
//
$fm_frame unstff1 unstff2 unstff3 unstff4 unstff5
$fm_frame unstff6
//
$fm_frame vault1 vault2 vault3 vault4 vault5
$fm_frame vault6 vault7 vault8 vault9 vault10
$fm_frame vault11 vault12 vault13 vault14 vault15
$fm_frame vault16 vault17
//
$fm_frame wipebrow1 wipebrow2 wipebrow3 wipebrow4 wipebrow5
$fm_frame wipebrow6 wipebrow7 wipebrow8 wipebrow9 wipebrow10
$fm_frame wipebrow11 wipebrow12 wipebrow13 wipebrow14 wipebrow15
$fm_frame wipebrow16 wipebrow17 wipebrow18 wipebrow19
//
// ***NOTE I GOTTA RELEASE THESE EVEN IF THEY'RE NOT USED! THEY'RE COOL!
// NEW STAFF MOVES
//
$fm_frame roundbck1 roundbck2 roundbck3 roundbck4 roundbck5
$fm_frame roundbck6 roundbck7 roundbck8
//
$fm_frame spikedwn1 spikedwn2 spikedwn3 spikedwn4 spikedwn5
$fm_frame spikedwn6 spikedwn7 spikedwn8
//
$fm_frame pullout1 pullout2 pullout3 pullout4 pullout5
$fm_frame pullout6 pullout7 pullout8 pullout9 pullout10
$fm_frame pullout11
// FLYING ANIMS
//
$fm_frame strtfly1 strtfly2 strtfly3 strtfly4 strtfly5
$fm_frame strtfly6 strtfly7 strtfly8 strtfly9 strtfly10
//
$fm_frame flydle1 flydle2 flydle3 flydle4 flydle5
$fm_frame flydle6 flydle7 flydle8 flydle9 flydle10
$fm_frame flydle11 flydle12
//
$fm_frame t4fly1 t4fly2 t4fly3
//
$fm_frame 4fly1 4fly2
//
$fm_frame stp4fly1 stp4fly2 stp4fly3 stp4fly4 stp4fly5
$fm_frame stp4fly6 stp4fly7 stp4fly8 stp4fly9
//
$fm_frame t2flydle1 t2flydle2 t2flydle3 t2flydle4
//
$fm_frame bckfly1 bckfly2
// OLD USUSED ANIMS
//
//$fm_frame H2OpainA1
//
//$fm_frame H2OpainB1
//
//$fm_frame trnsbksprg1 trnsbksprg2 trnsbksprg3

View file

@ -0,0 +1,166 @@
$fm_cd monsters\gorgon
$fm_origin 0 0 16
$fm_basest base skin stbase
$fm_skin skin
$fm_skin skindmg
$fm_scale 1
//
$fm_frame atka1 atka2 atka3 atka4
//
$fm_frame atkb1 atkb2 atkb3 atkb4
//
$fm_frame atkc1 atkc2 atkc3 atkc4
//
$fm_frame atkd1 atkd2 atkd3 atkd4
//
$fm_frame atke1 atke2 atke3 atke4
//
$fm_frame deatha1 deatha10 deatha11 deatha12 deatha13
$fm_frame deatha14 deatha15 deatha16 deatha17 deatha18
$fm_frame deatha19 deatha2 deatha3 deatha4 deatha5
$fm_frame deatha6 deatha7 deatha8 deatha9 death1
$fm_frame death2 death3 death4 death5 death6
$fm_frame death7 death8 death9 death10 death11
$fm_frame death12 death13 death14 death15 death16
$fm_frame death17 death18 death19
//
$fm_frame eatinga1 eatinga2 eatinga3 eatinga4 eatinga5
$fm_frame eatinga6 eatinga7 eatinga8 eatinga9 eatinga10
//
$fm_frame eatingb1 eatingb2 eatingb3 eatingb4 eatingb5
$fm_frame eatingb6 eatingb7 eatingb8 eatingb9 eatingb10
$fm_frame eatingb11 eatingb12 eatingb13 eatingb14 eatingb15
$fm_frame eatingb16 eatingb17 eatingb18 eatingb19 eatingb20
$fm_frame eatingb21
//
$fm_frame hit1 hit2 hit3 hit4 hit5
$fm_frame hit6 hit7 hit8 hit9 hit10
$fm_frame hit11 hit12
//
$fm_frame hop1 hop2 hop3 hop4 hop5
$fm_frame hop6 hop7 hop8 hop9 hop10
//
$fm_frame idleb1 idleb2 idleb3 idleb4 idleb5
$fm_frame idleb6 idleb7 idleb8 idleb9 idleb10
$fm_frame idleb11 idleb12 idleb13 idleb14 idleb15
$fm_frame idleb16 idleb17 idleb18 idleb19 idleb20
$fm_frame idleb21
//
$fm_frame jumpa1 jumpa2 jumpa3 jumpa4 jumpa5
$fm_frame jumpa6 jumpa7 jumpa8 jumpa9 jumpa10
$fm_frame jumpa11 jumpa12 jumpa13 jumpa14 jumpa15
$fm_frame jumpa16 jumpa17
//
$fm_frame jumpb1 jumpb2 jumpb3 jumpb4 jumpb5
$fm_frame jumpb6 jumpb7 jumpb8 jumpb9 jumpb10
$fm_frame jumpb11 jumpb12 jumpb13 jumpb14 jumpb15
$fm_frame jumpb16 jumpb17 jumpb18 jumpb19
//
$fm_frame loklft1 loklft2 loklft3 loklft4 loklft5
$fm_frame loklft6 loklft7 loklft8 loklft9 loklft10
$fm_frame loklft11 loklft12 loklft13 loklft14 loklft15
$fm_frame loklft16 loklft17 loklft18 loklft19 loklft20
$fm_frame loklft21 loklft22
//
$fm_frame lokrt1 lokrt2 lokrt3 lokrt4 lokrt5
$fm_frame lokrt6 lokrt7 lokrt8 lokrt9 lokrt10
$fm_frame lokrt11 lokrt12 lokrt13 lokrt14 lokrt15
$fm_frame lokrt16 lokrt17 lokrt18 lokrt19 lokrt20
//
$fm_frame oldbase3
//
$fm_frame painb1 painb2 painb3 painb4 painb5
$fm_frame painc1 painc2 painc3 painc4 painc5
$fm_frame pain1 pain2 pain3 pain4 pain5
$fm_frame pain6 pain7 pain8 pain9
//
$fm_frame react1 react2 react3 react4 react5
$fm_frame react6 react7 react8 react9 react10
//
$fm_frame rollover1 rollover2 rollover3 rollover4 rollover5
//
$fm_frame runatk1 runatk2 runatk3 runatk4 runatk5
$fm_frame runatk6 runatk7 runatk8 run1 run2
$fm_frame run3 run4 run5 run6 run7
$fm_frame run8
//
$fm_frame slide1 slide2 slide3 slide4 slide5
$fm_frame slide6 slide7 slide8 slide9 slide10
$fm_frame slide11 slide12 slide13 slide14 slide15
$fm_frame slide16 slide17 slide18 slide19 slide20
$fm_frame slide21 slide22 slide23 slide24 slide25
$fm_frame slide26 slide27 slide28 slide29 slide30
$fm_frame slide31
//
$fm_frame snap1 snap2 snap3 snap4 snap5
$fm_frame snap6 snap7
//
$fm_frame speak1 speak2 speak3 speak4 speak5
$fm_frame speak6 speak7 speak8 speak9 speak10
$fm_frame speak11 speak12 speak13 speak14 speak15
$fm_frame speak16 speak17 speak18 speak19
//
$fm_frame swim1 swim2 swim3 swim4 swim5
$fm_frame swim6 swim7 swim8 swim9 swim10
$fm_frame swim11 swim12 swim13 swim14 swim15
$fm_frame swim16 swim17 swim18 swim19
//
$fm_frame swimata1 swimata2 swimata3 swimata4 swimata5
$fm_frame swimata6 swimata7 swimata8 swimata9 swimata10
$fm_frame swimata11 swimata12 swimata13 swimata14
//
$fm_frame swimatb1 swimatb2 swimatb3 swimatb4 swimatb5
$fm_frame swimatb6 swimatb7 swimatb8 swimatb9 swimatb10
$fm_frame swimatb11 swimatb12 swimatb13 swimatb14
//
$fm_frame twitch
//
$fm_frame twitch_1 twitch_2
//
$fm_frame wait1 wait2 wait3 wait4 wait5
$fm_frame wait6 wait7 wait8
//
$fm_frame walk1 walk2 walk3 walk4 walk5
$fm_frame walk6 walk7 walk8 walk9 walk10
$fm_frame walk11 walk12
//
$fm_frame wlklft1 wlklft2 wlklft3 wlklft4 wlklft5
$fm_frame wlklft6 wlklft7 wlklft8 wlklft9 wlklft10
$fm_frame wlklft11 wlklft12
//
$fm_frame wlkrt1 wlkrt2 wlkrt3 wlkrt4 wlkrt5
$fm_frame wlkrt6 wlkrt7 wlkrt8 wlkrt9 wlkrt10
$fm_frame wlkrt11 wlkrt12

View file

@ -45,3 +45,9 @@ $pic dot 0 0 8 8
$load art/gfx/pics/biggerdot.tga
$pic bigdot 0 0 16 16
// TEMPORARY
$load art/gfx/temp/ddlogo.pcx
$pic ddlogo 0 0 256 256

View file

@ -0,0 +1,145 @@
$fm_cd monsters\plaguelf
$fm_origin 0 0 0
$fm_basest base skin stbase
$fm_skin skin
$fm_skin skindmg
$fm_skin skin1
$fm_skin skin1dmg
$fm_skin skin2
$fm_skin skin2dmg
$fm_scale 1
//
$fm_frame partfly
//
$fm_frame torsooff
//
$fm_frame attckA1 attckA2 attckA3 attckA4 attckA5
$fm_frame attckA6 attckA7
//
$fm_frame attckB1 attckB2 attckB3 attckB4 attckB5
$fm_frame attckB6 attckB7 attckB8 attckB9
//
$fm_frame crazyA1 crazyA2 crazyA3 crazyA4 crazyA5
$fm_frame crazyA6 crazyA7 crazyA8 crazyA9 crazyA10
$fm_frame crazyA11 crazyA12
//
$fm_frame crazyB1 crazyB2 crazyB3 crazyB4 crazyB5
$fm_frame crazyB6 crazyB7 crazyB8 crazyB9 crazyB10
$fm_frame crazyB11 crazyB12
//
$fm_frame cursing1 cursing2 cursing3 cursing4 cursing5
$fm_frame cursing6 cursing7 cursing8 cursing9 cursing10
$fm_frame cursing11 cursing12 cursing13 cursing14 cursing15
$fm_frame cursing16 cursing17 cursing18 cursing19 cursing20
$fm_frame cursing21 cursing22 cursing23 cursing24 cursing25
$fm_frame cursing26 cursing27 cursing28 cursing29 cursing30
$fm_frame cursing31 cursing32 cursing33 cursing34 cursing35
$fm_frame cursing36 cursing37 cursing38 cursing39 cursing40
$fm_frame cursing41 cursing42 cursing43 cursing44 cursing45
$fm_frame cursing46 cursing47 cursing48 cursing49 cursing50
$fm_frame cursing51 cursing52 cursing53 cursing54 cursing55
$fm_frame cursing56 cursing57 cursing58 cursing59 cursing60
$fm_frame cursing61 cursing62 cursing63 cursing64
//
$fm_frame deathb1 deathb10 deathb11 deathb12 deathb13
$fm_frame deathb2 deathb3 deathb4 deathb5
$fm_frame deathb6 deathb7 deathb8 deathb9 deathc1
$fm_frame deathc10 deathc11 deathc12 deathc13
$fm_frame deathc2 deathc3 deathc4 deathc5 deathc6
$fm_frame deathc7 deathc8 deathc9 deathd1 deathd10
$fm_frame deathd11 deathd12 deathd13 deathd2
$fm_frame deathd3 deathd4 deathd5 deathd6 deathd7
$fm_frame deathd8 deathd9 death1 death2 death3
$fm_frame death4 death5 death6 death7 death8
$fm_frame death9 death10 death11 death12 death13
$fm_frame death14
//
$fm_frame fist1 fist2 fist3 fist4 fist5
$fm_frame fist6 fist7
//
$fm_frame handslid1 handslid2 handslid3 handslid4 handslid5
$fm_frame handslid6 handslid7 handslid8
//
$fm_frame lean1 lean2 lean3 lean4 lean5
$fm_frame lean6 lean7 lean8 lean9 lean10
$fm_frame lean11 lean12 lean13 lean14 lean15
$fm_frame lean16 lean17 lean18 lean19 lean20
$fm_frame lean21 lean22 lean23 lean24 lean25
$fm_frame lean26 lean27 lean28 lean29 lean30
$fm_frame lean31 lean32 lean33 lean34
//
$fm_frame painA1 painA2 painA3 painA4 painA5
$fm_frame painA6 painA7
//
$fm_frame point1 point2 point3 point4 point5
$fm_frame point6 point7 point8 point9 point10
$fm_frame point11 point12 point13 point14 point15
$fm_frame point16 point17 point18 point19 point20
$fm_frame point21 point22 point23 point24 point25
$fm_frame point26 point27 point28 point29 point30
//
$fm_frame runatk1 runatk2 runatk3 runatk4 runatk5
$fm_frame runatk6 runatk7 runatk8 runA1 runA2
$fm_frame runA3 runA4 runA5 runA6 runA7
$fm_frame runA8
//
$fm_frame scared1 scared2 scared3 scared4 scared5
$fm_frame scared6 scared7 scared8 scared9 scared10
$fm_frame scared11 scared12 scared13 scared14 scared15
$fm_frame scared16 scared17 scared18 scared19 scared20
$fm_frame scared21 scared22 scared23 scared24 scared25
$fm_frame scared26 scared27 scared28 scared29 scared30
$fm_frame scared31 scared32 scared33 scared34 scared35
$fm_frame scared36 scared37 scared38 scared39
//
$fm_frame shake1 shake2 shake3 shake4 shake5
$fm_frame shake6 shake7 shake8 shake9 shake10
$fm_frame shake11 shake12 shake13 shake14 shake15
$fm_frame shake16 shake17 shake18 shake19 shake20
$fm_frame shake21 shake22 shake23 shake24 shake25
//
$fm_frame walkA1 walkA2 walkA3 walkA4 walkA5
$fm_frame walkA6 walkA7 walkA8 walkA9 walkA10
$fm_frame walkA11 walkA12
$fm_frame death13end deathb13end deathc13end deathd13end
$fm_frame skewered
$fm_frame jump1 jump2 jump3 jump4 jump5 jump6 jump7 jump8 jump9 jump10
$fm_frame jump11 jump12 jump13 jump14 jump15 jump16 jump17 jump18 jump19 jump20
$fm_frame recover1 recover2 recover3 recover4 recover5
$fm_frame fetal1 fetal2 fetal3 fetal4 fetal5 fetal6 fetal7 fetal8 fetal9 fetal10
$fm_frame fetal11 fetal12 fetal13 fetal14 fetal15 fetal16 fetal17 fetal18 fetal19 fetal20
$fm_frame fetal21 fetal22 fetal23 fetal24 fetal25 fetal26
$fm_frame reach1 reach2 reach3 reach4 reach5
$fm_frame reach6 reach7 reach8 reach9 reach10
$fm_frame reach11 reach12 reach13 reach14 reach15
$fm_frame reach16 reach17 reach18 reach19 reach20
$fm_frame reach21 reach22 reach23 reach24 reach25
$fm_frame reach26 reach27 reach28 reach29 reach30
$fm_frame reach31 reach32 reach33 reach34 reach35
$fm_frame reach36 reach37 reach38

View file

@ -0,0 +1,241 @@
# Microsoft Developer Studio Project File - Name="Player" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Player - 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 "Player.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 "Player.mak" CFG="Player - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Player - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Player - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Player - Win32 Final" (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)" == "Player - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /Zi /O2 /I "../qcommon" /I "../game" /I "../client" /I "../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PLAYER_DLL" /D "_DEVEL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib H2Common.lib /nologo /base:"0x110d0000" /version:1.0 /subsystem:windows /dll /profile /debug /machine:I386 /libpath:"..\Release"
!ELSEIF "$(CFG)" == "Player - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /Gi /ZI /Od /I "../qcommon" /I "../game" /I "../client" /I "../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PLAYER_DLL" /D "_DEVEL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib H2Common.lib /nologo /base:"0x110d0000" /version:1.0 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
!ELSEIF "$(CFG)" == "Player - Win32 Final"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Player___Win32_Final"
# PROP BASE Intermediate_Dir "Player___Win32_Final"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\Final"
# PROP Intermediate_Dir ".\Final"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /Zi /O2 /I "./qcommon" /I "./game" /I "./client" /I "./server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PLAYER_DLL" /FR".\Release/" /YX /FD /c
# ADD CPP /nologo /MT /W3 /O2 /I "../qcommon" /I "../game" /I "../client" /I "../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PLAYER_DLL" /Fr /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib H2Common.lib quake2.lib /nologo /version:1.0 /subsystem:windows /dll /profile /debug /machine:I386 /libpath:"..\Release"
# 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:"0x110d0000" /version:1.0 /subsystem:windows /dll /machine:I386 /out:"..\base/Player.dll" /libpath:"..\Final" /release
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "Player - Win32 Release"
# Name "Player - Win32 Debug"
# Name "Player - Win32 Final"
# Begin Group "Source Files"
# PROP Default_Filter "*.c *.cpp"
# Begin Source File
SOURCE=.\main.c
# End Source File
# Begin Source File
SOURCE=.\p_actions.c
# End Source File
# Begin Source File
SOURCE=.\p_anim_branch.c
# End Source File
# Begin Source File
SOURCE=.\p_anim_data.c
# End Source File
# Begin Source File
SOURCE=.\p_animactor.c
# End Source File
# Begin Source File
SOURCE=.\p_anims.c
# End Source File
# Begin Source File
SOURCE=.\p_chicken.c
# End Source File
# Begin Source File
SOURCE=.\p_chicken_anim.c
# End Source File
# Begin Source File
SOURCE=.\p_ctrl.c
# End Source File
# Begin Source File
SOURCE=.\p_items.c
# End Source File
# Begin Source File
SOURCE=.\p_main.c
# End Source File
# Begin Source File
SOURCE=.\p_weapon.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "*.h"
# Begin Source File
SOURCE=..\client\client.h
# End Source File
# Begin Source File
SOURCE=.\p_actions.h
# End Source File
# Begin Source File
SOURCE=.\p_anim_branch.h
# End Source File
# Begin Source File
SOURCE=.\p_anim_data.h
# End Source File
# Begin Source File
SOURCE=.\p_animactor.h
# End Source File
# Begin Source File
SOURCE=.\p_anims.h
# End Source File
# Begin Source File
SOURCE=.\p_chicken.h
# End Source File
# Begin Source File
SOURCE=.\p_ctrl.h
# End Source File
# Begin Source File
SOURCE=.\p_items.h
# End Source File
# Begin Source File
SOURCE=.\p_main.h
# End Source File
# Begin Source File
SOURCE=.\P_NewMove.h
# End Source File
# Begin Source File
SOURCE=.\p_types.h
# End Source File
# Begin Source File
SOURCE=.\p_weapon.h
# End Source File
# Begin Source File
SOURCE=.\Player.h
# End Source File
# End Group
# Begin Source File
SOURCE=..\Final\H2Common.lib
# End Source File
# Begin Source File
SOURCE=..\Final\quake2.lib
# End Source File
# End Target
# End Project

View file

@ -0,0 +1,135 @@
#ifndef PLAYER_H
#define PLAYER_H
#ifdef PLAYER_DLL
#define PLAYER_API __declspec(dllexport)
#else
#define PLAYER_API __declspec(dllimport)
#endif // PLAYER_DLL
#include "p_types.h"
// **************
// Movement rates
// **************
#define IN_MOVE_CREEP_MIN 16
#define IN_MOVE_CREEP 32
#define IN_MOVE_WALK_MIN 48
#define IN_MOVE_WALK 64
#define IN_MOVE_RUN_MIN 80
#define IN_MOVE_RUN 96
#define IN_MOVE_THRESHOLD IN_MOVE_CREEP_MIN
#define BUTTON_WALK 0
enum movefwd_e
{
MOVE_BACK_RUN,
MOVE_BACK_WALK,
MOVE_BACK_CREEP,
MOVE_FWD_NONE,
MOVE_FWD_CREEP,
MOVE_FWD_WALK,
MOVE_FWD_RUN,
MOVE_FWD_MAX
};
enum moveright_e
{
MOVE_LEFT_RUN,
MOVE_LEFT_WALK,
MOVE_LEFT_CREEP,
MOVE_RIGHT_NONE,
MOVE_RIGHT_CREEP,
MOVE_RIGHT_WALK,
MOVE_RIGHT_RUN,
MOVE_RIGHT_MAX
};
enum moveplus_e
{
MOVE_NORM,
MOVE_NOFWD,
MOVE_NOSIDE,
};
#define DEFAULT_PLAYER_LIB "Player"
typedef struct
{
paceldata_t *PlayerSeqData,*PlayerChickenData;
int p_num_items;
gitem_t *p_itemlist;
} player_export_t;
void P_Freelib(void);
unsigned int P_Load(char *name);
#ifdef PLAYER_DLL
PLAYER_API void P_Init(void);
PLAYER_API void P_Shutdown(void);
#else
void (*P_Init)(void);
void (*P_Shutdown)(void);
void (*P_PlayerReleaseRope)(playerinfo_t *playerinfo);
void (*P_KnockDownPlayer)(playerinfo_t *playerinfo);
void (*P_PlayFly)(playerinfo_t *playerinfo, float dist);
void (*P_PlaySlap)(playerinfo_t *playerinfo, float dist);
void (*P_PlayScratch)(playerinfo_t *playerinfo, float dist);
void (*P_PlaySigh)(playerinfo_t *playerinfo, float dist);
void (*P_SpawnDustPuff)(playerinfo_t *playerinfo, float dist);
void (*P_PlayerInterruptAction)(playerinfo_t *playerinfo);
qboolean (*P_BranchCheckDismemberAction)(playerinfo_t *playerinfo, int weapon);
void (*P_TurnOffPlayerEffects)(playerinfo_t *playerinfo);
void (*P_AnimUpdateFrame)(playerinfo_t *playerinfo);
void (*P_PlayerFallingDamage)(playerinfo_t *playerinfo);
void (*P_PlayerBasicAnimReset)(playerinfo_t *playerinfo);
void (*P_PlayerAnimReset)(playerinfo_t *playerinfo);
void (*P_PlayerAnimSetLowerSeq)(playerinfo_t *playerinfo, int seq);
void (*P_PlayerAnimSetUpperSeq)(playerinfo_t *playerinfo, int seq);
void (*P_PlayerAnimUpperIdle)(playerinfo_t *playerinfo);
void (*P_PlayerAnimLowerIdle)(playerinfo_t *playerinfo);
void (*P_PlayerAnimUpperUpdate)(playerinfo_t *playerinfo);
void (*P_PlayerAnimLowerUpdate)(playerinfo_t *playerinfo);
void (*P_PlayerAnimSetVault)(playerinfo_t *playerinfo, int seq);
void (*P_PlayerPlayPain)(playerinfo_t *playerinfo, int type);
void (*P_PlayerIntLand)(playerinfo_t *playerinfo_t, float landspeed);
void (*P_PlayerInit)(playerinfo_t *playerinfo, int complete_reset);
void (*P_PlayerClearEffects)(playerinfo_t *playerinfo);
void (*P_PlayerUpdate)(playerinfo_t *playerinfo);
void (*P_PlayerUpdateCmdFlags)(playerinfo_t *playerinfo);
void (*P_PlayerUpdateModelAttributes)(playerinfo_t *playerinfo);
void (*P_Weapon_Ready)(playerinfo_t *playerinfo,gitem_t *Weapon);
void (*P_Weapon_EquipSpell)(playerinfo_t *playerinfo,gitem_t *Weapon);
void (*P_Weapon_EquipSwordStaff)(playerinfo_t *playerinfo,gitem_t *Weapon);
void (*P_Weapon_EquipHellStaff)(playerinfo_t *playerinfo,gitem_t *Weapon);
void (*P_Weapon_EquipBow)(playerinfo_t *playerinfo,gitem_t *Weapon);
void (*P_Weapon_EquipArmor)(playerinfo_t *playerinfo, gitem_t *Weapon);
int (*P_Weapon_CurrentShotsLeft)(playerinfo_t *playerinfo);
int (*P_Defence_CurrentShotsLeft)(playerinfo_t *playerinfo, int intent);
#endif // PLAYER_DLL
// This is the only function actually exported at the linker level.
typedef player_export_t (*GetPlayerAPI_t)(void);
#endif // PLAYER_H

View file

@ -0,0 +1,24 @@
#include "Player.h"
#include "p_anim_data.h"
PLAYER_API void P_Init(void)
{
InitItems();
}
PLAYER_API void P_Shutdown(void)
{
}
PLAYER_API player_export_t GetPlayerAPI(void)
{
player_export_t playerExport;
playerExport.PlayerSeqData=PlayerSeqData;
playerExport.PlayerChickenData=PlayerChickenData;
playerExport.p_num_items=p_num_items;
playerExport.p_itemlist=p_itemlist;
return(playerExport);
}

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
#define _P_ACTIONS2_H_
#include "p_types.h"
#include "p_anims2.h"
#include "p_anims.h"
#define SOUND_SWIM_FORWARD 0
#define SOUND_SWIM_BACK 1
@ -17,10 +17,7 @@
#define SOUND_SWIM_UNDER 3
void PlayerActionHandFXStart(playerinfo_t *playerinfo, float value);
void PlayerActionHandFXEnd(playerinfo_t *playerinfo, float value);
void PlayerActionSpellBegin(playerinfo_t *playerinfo, float value);
void PlayerActionSpellEnd(playerinfo_t *playerinfo, float value);
void PlayerActionSphereTrailEnd(playerinfo_t *playerinfo, float value);
void PlayerActionSpellChange(playerinfo_t *playerinfo, float value);
void PlayerActionWeaponChange(playerinfo_t *playerinfo, float value);
@ -41,7 +38,6 @@ void PlayerActionHellstaffAttack(playerinfo_t *playerinfo, float value);
void PlayerActionSpellDefensive(playerinfo_t *playerinfo, float value);
void PlayerActionSwordTrailStart(playerinfo_t *playerinfo, float value);
void PlayerActionSwordTrailEnd(playerinfo_t *playerinfo, float value);
void PlayerActionRedRainBowTrailStart(playerinfo_t *playerinfo, float value);
void PlayerActionPhoenixBowTrailStart(playerinfo_t *playerinfo, float value);
void PlayerActionBowTrailEnd(playerinfo_t *playerinfo, float value);
@ -109,6 +105,7 @@ void PlayerActionCheckDoubleJump( playerinfo_t *playerinfo );
void PlayerMoveAdd(playerinfo_t *playerinfo);
void PlayerActionFlip(playerinfo_t *playerinfo, float value);
void PlayerActionTurn180(playerinfo_t *playerinfo);
void PlayerActionSetQTEndTime(playerinfo_t *playerinfo,float QTEndTime);
void PlayerActionCheckCreepForward( playerinfo_t *playerinfo );
void PlayerActionCheckCreepBack( playerinfo_t *playerinfo );
void PlayerActionCheckVaultKick ( playerinfo_t *playerinfo );
@ -126,19 +123,17 @@ void PlayerActionCheckUncrouchToFinishSeq(playerinfo_t *playerinfo);
void PlayerActionCheckStrafe ( playerinfo_t *playerinfo );
void PlayerJumpNudge(playerinfo_t *playerinfo, float fwd, float right, float up);
void PlayerActionCheckHitGround(playerinfo_t *playerinfo);
void PlayerSetDeathLoop1(playerinfo_t *playerinfo);
void PlayerActionCheckBranchWalking ( playerinfo_t *playerinfo );
void PlayerActionCheckBranchRunningStrafe ( playerinfo_t *playerinfo );
H2COMMON_API void PlayerReleaseRope(playerinfo_t *playerinfo);
H2COMMON_API void KnockDownPlayer(playerinfo_t *playerinfo);
H2COMMON_API void PlayFly(playerinfo_t *playerinfo, float dist);
H2COMMON_API void PlaySlap(playerinfo_t *playerinfo, float dist);
H2COMMON_API void PlayScratch(playerinfo_t *playerinfo, float dist);
H2COMMON_API void PlaySigh(playerinfo_t *playerinfo, float dist);
H2COMMON_API void SpawnDustPuff(playerinfo_t *playerinfo, float dist);
PLAYER_API void PlayerReleaseRope(playerinfo_t *playerinfo);
PLAYER_API void KnockDownPlayer(playerinfo_t *playerinfo);
PLAYER_API void PlayFly(playerinfo_t *playerinfo, float dist);
PLAYER_API void PlaySlap(playerinfo_t *playerinfo, float dist);
PLAYER_API void PlayScratch(playerinfo_t *playerinfo, float dist);
PLAYER_API void PlaySigh(playerinfo_t *playerinfo, float dist);
PLAYER_API void SpawnDustPuff(playerinfo_t *playerinfo, float dist);
qboolean PlayerActionCheckCreepMoveBack( playerinfo_t *playerinfo );
qboolean PlayerActionCheckCreepMoveForward( playerinfo_t *playerinfo );
@ -164,6 +159,6 @@ void PlayerActionCheckWalkBackUnStrafe(playerinfo_t *playerinfo);
void PlayerActionCheckRun( playerinfo_t *playerinfo );
// JWEIER NEW ACTIONS END
extern H2COMMON_API void PlayerInterruptAction(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerInterruptAction(playerinfo_t *playerinfo);
#endif //_P_ACTIONS2_H_

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,13 @@
#ifndef _P_ANIM_BRANCH2_H_
#define _P_ANIM_BRANCH2_H_
//Chicken Branch
// Chicken Branch.
int ChickenBranchLwrStanding(playerinfo_t *playerinfo);
int ChickenBranchidle(playerinfo_t *playerinfo);
//Player Lower Branch
// Player Lower Branch.
int BranchLwrStanding(playerinfo_t *playerinfo);
int BranchLwrStandingRun(playerinfo_t *playerinfo);
int BranchLwrRunning(playerinfo_t *playerinfo);
@ -29,7 +31,9 @@ int BranchLwrClimbing(playerinfo_t *playerinfo);
int BranchLwrKnockDown(playerinfo_t *playerinfo);
int BranchLwrRunningStrafe(playerinfo_t *playerinfo);
//Player Upper Branch
// Player Upper Branch.
int BranchIdle(playerinfo_t *playerinfo);
int BranchUprReady(playerinfo_t *playerinfo);
int BranchUprRdySpell(playerinfo_t *playerinfo);
int BranchUprRdyStaff(playerinfo_t *playerinfo);
@ -38,6 +42,6 @@ int BranchCheckAmmo(playerinfo_t *playerinfo);
int BranchCheckHellAmmo(playerinfo_t *playerinfo);
int BranchCheckMana(playerinfo_t *playerinfo);
PLAYER_API qboolean BranchCheckDismemberAction(playerinfo_t *playerinfo, int weapon);
H2COMMON_API qboolean BranchCheckDismemberAction(playerinfo_t *playerinfo, int weapon);
#endif // _P_ANIM_BRANCH2_H_

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@
#ifndef _P_ANIM_DATA2_H_
#define _P_ANIM_DATA2_H_
#include "p_anims2.h"
#include "p_anims.h"
typedef struct seqctrl_s
{
@ -43,12 +43,25 @@ enum footsteptype_e
STEP_MAX
};
enum trailtype_e
{
TRAIL_SPIN1,
TRAIL_SPIN2,
TRAIL_STAND,
TRAIL_STEP,
TRAIL_BACK,
TRAIL_STAB,
TRAIL_COUNTERLEFT,
TRAIL_COUNTERRIGHT,
TRAIL_MAX
};
extern char *SeqName[ASEQ_MAX];
extern int PlayerAnimWeaponSwitchSeq[WEAPON_READY_MAX][WEAPON_READY_MAX];
extern seqctrl_t SeqCtrl[ASEQ_MAX];
extern H2COMMON_API paceldata_t PlayerSeqData[ASEQ_MAX];
extern PLAYER_API paceldata_t PlayerSeqData[ASEQ_MAX];
extern seqctrl_t ChickenCtrl[ASEQ_MAX];
extern H2COMMON_API paceldata_t PlayerChickenData[ASEQ_MAX];
extern PLAYER_API paceldata_t PlayerChickenData[ASEQ_MAX];
extern panimmove_t
player_move_nothing,
@ -317,9 +330,8 @@ extern panimmove_t
player_move_overhang,
player_move_death_b,
player_move_death_fly_forward_go,
player_move_death_fly_forward_loop,
player_move_death_fly_forward_end,
player_move_death_fly_forward,
player_move_death_fly_back,
player_move_death_choke,
player_move_idle_lookback,
@ -338,7 +350,23 @@ extern panimmove_t
player_move_swim_fast_go,
player_move_swim_fast,
player_move_staffatkback;
player_move_staffatkback,
player_move_staffdownstab,
player_move_staffstabhold,
player_move_staffpullout,
player_move_staffblockleft,
player_move_staffblockleft2,
player_move_staffblockleftatk,
player_move_staffblockright,
player_move_staffblockright2,
player_move_staffblockrightatk,
player_move_staffblockedleft,
player_move_staffblockedright,
player_move_staffspinblockedleft,
player_move_staffspinblockedright,
player_move_stafflowerdownstab,
player_move_stafflowerpullout;
#endif // _P_ANIM_DATA2_H_

View file

@ -0,0 +1,870 @@
//
// p_animactor.c
//
// Heretic II
// Copyright 1998 Raven Software
//
#include "player.h"
#include "p_types.h"
#include "p_actions.h"
#include "p_anim_data.h"
#include "p_animactor.h"
#include "p_anims.h"
#include "p_anim_branch.h"
#include "p_ctrl.h"
#include "p_main.h"
#include "angles.h"
#include "g_teleport.h"
#include "vector.h"
#include "utilities.h"
#include "fx.h"
#define PLAYER_SCREAM_THRESHOLD -600
/*
===============
NormalizeAngle
===============
*/
float NormalizeAngle(float angle)
{
// Returns the remainder.
angle = fmod(angle, ANGLE_360);
// Makes the angle signed.
if(angle >= ANGLE_180)
{
angle -= ANGLE_360;
}
if(angle <= -ANGLE_180)
{
angle += ANGLE_360;
}
return(angle);
}
// ************************************************************************************************
// CalcJointAngles
// ----------------
// ************************************************************************************************
static void CalcJointAngles(playerinfo_t *playerinfo)
{
vec3_t targetvector;
// Adjust the player model's joint angles. The rules are:
// If there is a target to look at, the torso and head will shift to face the target.
// If the player is standing still, the torso will shift to face where the view is going.
// If there is a target to look at, the torso will shift to face the target instead.
// If the player is moving, only the head will shift, unless there is a target, in which case it will face it.
playerinfo->headjointonly=false;
VectorClear(playerinfo->targetjointangles);
if(playerinfo->enemystate==NULL)
{
// No target to be seen...
if(playerinfo->pm_w_flags)
{
// ...and we're swimming...
// PITCH.
playerinfo->targetjointangles[PITCH]=-(playerinfo->aimangles[PITCH]-playerinfo->angles[PITCH])*ANGLE_TO_RAD;
if(playerinfo->targetjointangles[PITCH]>ANGLE_90)
playerinfo->targetjointangles[PITCH]=ANGLE_90;
else if(playerinfo->targetjointangles[PITCH]<-ANGLE_90)
playerinfo->targetjointangles[PITCH]=-ANGLE_90;
if(playerinfo->targetjointangles[PITCH]>=0)
playerinfo->targetjointangles[PITCH]/=3.0;
else
playerinfo->targetjointangles[PITCH]/=1.5;
if(playerinfo->pm_w_flags&(WF_DIVING|WF_SWIMFREE))
{
// ...and we're below the surface, so just allow the head to PITCH. Of course,
// we need invert the angle too.
playerinfo->headjointonly=true;
playerinfo->targetjointangles[PITCH]=-playerinfo->targetjointangles[PITCH];
}
}
else if(playerinfo->pm_flags&PMF_STANDSTILL)
{
// ...and we're standing still with our feet on something solid, so allow head and torso
// to PITCH and YAW.
// PITCH.
playerinfo->targetjointangles[PITCH]=-(playerinfo->aimangles[PITCH]-playerinfo->angles[PITCH])*ANGLE_TO_RAD;
if (playerinfo->targetjointangles[PITCH]>ANGLE_90)
playerinfo->targetjointangles[PITCH]=ANGLE_90;
else if (playerinfo->targetjointangles[PITCH]<-ANGLE_90)
playerinfo->targetjointangles[PITCH]=-ANGLE_90;
playerinfo->targetjointangles[PITCH]/=3.0;
// YAW.
playerinfo->targetjointangles[YAW]=((playerinfo->aimangles[YAW]-playerinfo->angles[YAW])*ANGLE_TO_RAD);
if(playerinfo->targetjointangles[YAW]<-ANGLE_180)
playerinfo->targetjointangles[YAW]+=ANGLE_360;
else if(playerinfo->targetjointangles[YAW]>ANGLE_180)
playerinfo->targetjointangles[YAW]-=ANGLE_360;
playerinfo->targetjointangles[YAW]/=3.0;
}
else
{
// ...and we're moving - on land or flying or whatever.
playerinfo->headjointonly=true;
// PITCH.
playerinfo->targetjointangles[PITCH]=-(playerinfo->aimangles[PITCH]-playerinfo->angles[PITCH])*ANGLE_TO_RAD;
if (playerinfo->targetjointangles[PITCH]>ANGLE_90)
playerinfo->targetjointangles[PITCH]=ANGLE_90;
else if (playerinfo->targetjointangles[PITCH]<-ANGLE_90)
playerinfo->targetjointangles[PITCH]=-ANGLE_90;
playerinfo->targetjointangles[PITCH]/=3.0;
// YAW.
playerinfo->targetjointangles[YAW]=0;
}
}
else
{
// We have a target...
if(!playerinfo->pm_w_flags)
{
// ...and we aren't swimming, so calculate angles to target.
VectorCopy(playerinfo->enemystate->origin,targetvector);
VectorSubtract(targetvector, playerinfo->origin, targetvector);
vectoangles(targetvector, playerinfo->targetjointangles);
// PITCH.
playerinfo->targetjointangles[PITCH] -= playerinfo->angles[PITCH];
playerinfo->targetjointangles[PITCH] *= ANGLE_TO_RAD;
playerinfo->targetjointangles[PITCH] = NormalizeAngle(playerinfo->targetjointangles[PITCH]);
if (playerinfo->targetjointangles[PITCH] > ANGLE_90)
playerinfo->targetjointangles[PITCH] = ANGLE_90;
else if (playerinfo->targetjointangles[PITCH] < -ANGLE_90)
playerinfo->targetjointangles[PITCH] = -ANGLE_90;
playerinfo->targetjointangles[PITCH] /= 3.0;
// YAW.
playerinfo->targetjointangles[YAW] -= playerinfo->angles[YAW];
playerinfo->targetjointangles[YAW] *= ANGLE_TO_RAD;
playerinfo->targetjointangles[YAW] = NormalizeAngle(playerinfo->targetjointangles[YAW]);
if (playerinfo->targetjointangles[YAW] > ANGLE_90)
playerinfo->targetjointangles[YAW] = ANGLE_90;
else if (playerinfo->targetjointangles[YAW] < -ANGLE_90)
playerinfo->targetjointangles[YAW] = -ANGLE_90;
playerinfo->targetjointangles[YAW] /= 3.0;
}
}
}
PLAYER_API void TurnOffPlayerEffects(playerinfo_t *playerinfo)
{
// Make sure all effects are removed.
switch(playerinfo->pers.handfxtype)
{
case HANDFX_FIREBALL:
case HANDFX_MISSILE:
case HANDFX_SPHERE:
case HANDFX_MACEBALL:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID26,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_SPELLHANDS);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID26,
playerinfo->self,
FX_SPELLHANDS);
break;
case HANDFX_REDRAIN:
case HANDFX_POWERREDRAIN:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID27,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_WEAPON_REDRAINGLOW);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID27,
playerinfo->self,
FX_WEAPON_REDRAINGLOW);
break;
case HANDFX_PHOENIX:
case HANDFX_POWERPHOENIX:
case HANDFX_FIREWALL:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID28,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FIREHANDS);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID28,
playerinfo->self,
FX_FIREHANDS);
break;
case HANDFX_STAFF1:
case HANDFX_STAFF2:
case HANDFX_STAFF3:
if(playerinfo->effects)
{
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID29,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_STAFF);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID29,
playerinfo->self,
FX_STAFF);
playerinfo->effects&=~EF_BLOOD_ENABLED;
}
break;
case HANDFX_NONE:
default:
// Nothing to remove.
break;
}
playerinfo->pers.handfxtype=HANDFX_NONE;
}
PLAYER_API void AnimUpdateFrame(playerinfo_t *playerinfo)
{
panimmove_t *move;
float yaw_delta;
// Check for death.
if (playerinfo->deadflag==DEAD_DEAD)
return;
if ((playerinfo->flags & PLAYER_FLAG_KNOCKDOWN) && (!(playerinfo->deadflag)))
{
// We don't want to do this again next frame.
playerinfo->flags &= ~PLAYER_FLAG_KNOCKDOWN;
PlayerInterruptAction(playerinfo);
if (!(playerinfo->deadflag))
{ // Don't do it if dying.
PlayerAnimSetLowerSeq(playerinfo,ASEQ_KNOCKDOWN);
}
return;
}
// Handle teleporting (and chicken morphing) only on game side.
if(!playerinfo->isclient)
{
if(playerinfo->G_HandleTeleport(playerinfo))
return;
}
//Handle a dive request
if (playerinfo->flags & PLAYER_FLAG_DIVE && (playerinfo->seqcmd[ACMDL_FWD] || playerinfo->seqcmd[ACMDL_CROUCH]) )
{
playerinfo->flags&=~PLAYER_FLAG_DIVE;
playerinfo->pm_w_flags |= WF_DIVING;
playerinfo->pm_w_flags &= ~(WF_SURFACE|WF_DIVE);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_DIVE);
}
//Auto grab a rope
if (playerinfo->flags & PLAYER_FLAG_RELEASEROPE)
{
if (playerinfo->flags & PLAYER_FLAG_ONROPE)
{
//Turn off the rope graphic immediately
((edict_t *)playerinfo->self)->targetEnt->count = 0;
((edict_t *)playerinfo->self)->targetEnt->rope_grab->s.effects &= ~EF_ALTCLIENTFX;
((edict_t *)playerinfo->self)->targetEnt->enemy = NULL;
((edict_t *)playerinfo->self)->targetEnt = NULL;
((edict_t *)playerinfo->self)->monsterinfo.jump_time = playerinfo->leveltime + 2;
playerinfo->flags &= ~PLAYER_FLAG_RELEASEROPE;
playerinfo->flags &= ~PLAYER_FLAG_ONROPE;
if(!(playerinfo->edictflags & FL_CHICKEN))
{
if (((edict_t *)playerinfo->self)->health <= 0)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_DEATH_A);
}
else
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_CLIMB_OFF);
}
}
}
else
{
playerinfo->flags &= ~PLAYER_FLAG_RELEASEROPE;
}
}
else if ( (!(playerinfo->flags & PLAYER_FLAG_ONROPE)) &&
(!(playerinfo->flags & PLAYER_FLAG_RELEASEROPE)) &&
(playerinfo->targetEnt) &&
(!(playerinfo->groundentity)) &&
(((edict_t *)playerinfo->self)->monsterinfo.jump_time < playerinfo->leveltime) &&
(PlayerActionCheckRopeGrab(playerinfo,0)) &&
(!(playerinfo->deadflag)) ) //Climb a rope?
{
((edict_t *)playerinfo->self)->monsterinfo.jump_time = playerinfo->leveltime + 4;
playerinfo->flags |= PLAYER_FLAG_ONROPE;
if(playerinfo->isclient)
{
playerinfo->CL_Sound(SND_PRED_ID37,
playerinfo->origin,
CHAN_VOICE,
"player/ropegrab.wav",
0.75,
ATTN_NORM,
0);
}
else
{
playerinfo->G_Sound(SND_PRED_ID37,
playerinfo->leveltime,
playerinfo->self,
CHAN_VOICE,
playerinfo->G_SoundIndex("player/ropegrab.wav"),
0.75,
ATTN_NORM,
0);
}
PlayerAnimSetLowerSeq(playerinfo, ASEQ_CLIMB_ON);
}
// Think rate handled different on client.
if(!playerinfo->isclient)
playerinfo->nextthink=playerinfo->leveltime+0.1;//FRAMETIME;
if (!(playerinfo->edictflags & FL_CHICKEN) && (!(playerinfo->deadflag)))
{
//FIXME: Implement this with a debounce time
/*
if (!playerinfo->groundentity)
{
if (playerinfo->velocity[2] < PLAYER_SCREAM_THRESHOLD)
{
if(playerinfo->isclient)
playerinfo->CL_Sound(playerinfo->origin, CHAN_VOICE, "player/falldeath1.wav", 0.75, ATTN_NORM, 0);
else
playerinfo->G_Sound(playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("player/falldeath1.wav"), 0.75, ATTN_NORM, 0);
}
}
*/
if (playerinfo->flags & PLAYER_FLAG_SLIDE)
{
//Make sure the player doesn't try to slide underwater
if (playerinfo->waterlevel < 2)
{
if (playerinfo->flags & PLAYER_FLAG_COLLISION)
{// See if the player is in a jump.
switch(playerinfo->lowerseq)
{
case ASEQ_POLEVAULT2:
case ASEQ_POLEVAULT1_W:
case ASEQ_POLEVAULT1_R:
// Check for an autovault.
if (playerinfo->upperidle)
{
if (playerinfo->seqcmd[ACMDL_BACK])
{
// Otherwise do a backflip.
playerinfo->upvel += 225;
PlayerAnimSetLowerSeq(playerinfo, ASEQ_JUMPFLIPB);
if(playerinfo->isclient)
playerinfo->CL_Sound(SND_PRED_ID38,playerinfo->origin, CHAN_VOICE, "*offwall.wav", 0.75, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID38,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*offwall.wav"), 0.75, ATTN_NORM, 0);
return;
}
}
break;
}
}
yaw_delta = (float) Q_fabs(playerinfo->ideal_yaw - playerinfo->angles[YAW]);
if (yaw_delta < 270.0 && yaw_delta > 90.0)
{
if (playerinfo->lowerseq != ASEQ_SLIDE_BACKWARD)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_SLIDE_BACKWARD);
}
}
else if (playerinfo->lowerseq != ASEQ_SLIDE_FORWARD)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_SLIDE_FORWARD);
}
}
}
else if (playerinfo->flags & PLAYER_FLAG_COLLISION)
{
// See if the player is in a jump.
switch(playerinfo->lowerseq)
{
//
case ASEQ_POLEVAULT2:
case ASEQ_POLEVAULT1_W:
case ASEQ_POLEVAULT1_R:
case ASEQ_JUMPFWD_SGO:
case ASEQ_JUMPFWD_WGO:
case ASEQ_JUMPFWD_RGO:
case ASEQ_JUMPFWD:
case ASEQ_FORWARD_FLIP_L:
case ASEQ_FORWARD_FLIP_R:
// Check for an autovault.
if ( (playerinfo->waterlevel < 2) && (playerinfo->upperidle) )
{
if (PlayerActionCheckVault(playerinfo, 0))
{
; // If successful, do nothing else.
}
else if (playerinfo->seqcmd[ACMDL_BACK])
{
// Otherwise do a backflip.
playerinfo->upvel += 225;
PlayerAnimSetLowerSeq(playerinfo, ASEQ_JUMPFLIPB);
if(playerinfo->isclient)
playerinfo->CL_Sound(SND_PRED_ID39,playerinfo->origin, CHAN_VOICE, "*offwall.wav", 0.75, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID39,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*offwall.wav"), 0.75, ATTN_NORM, 0);
}
else if (PlayerSeqData2[playerinfo->lowerseq].collideseq != ASEQ_NONE)
{
// Check to see what to play on a collision.
PlayerAnimSetLowerSeq(playerinfo, PlayerSeqData2[playerinfo->lowerseq].collideseq);
}
}
break;
//
case ASEQ_RUNF_GO:
case ASEQ_RUNF:
case ASEQ_WALKF_GO:
case ASEQ_WALKF:
case ASEQ_SSWIMF_GO:
case ASEQ_SSWIMF:
case ASEQ_SSWIMF_END:
case ASEQ_SSWIM_FAST_GO:
case ASEQ_SSWIM_FAST:
// Check for an autovault.
if (playerinfo->waterlevel < 2 && playerinfo->upperidle)
{
if (PlayerActionCheckVault(playerinfo, 0))
{
; // If successful, do nothing else.
}
/* else if (PlayerSeqData2[playerinfo->lowerseq].collideseq != ASEQ_NONE)
{
// Check to see what to play on a collision.
PlayerAnimSetLowerSeq(playerinfo, PlayerSeqData2[playerinfo->lowerseq].collideseq);
}
*/
}
break;
default:
// Check to see what to play on a collision.
//if (PlayerSeqData2[playerinfo->lowerseq].collideseq != ASEQ_NONE)
// PlayerAnimSetLowerSeq(playerinfo, PlayerSeqData2[playerinfo->lowerseq].collideseq);
break;
}
}
}
// If we are a chicken, don't do this.
if (playerinfo->seqcmd[ACMDL_JUMP] && !(playerinfo->edictflags & FL_CHICKEN))
{
if (!(playerinfo->watertype & CONTENTS_SLIME))
{
switch( playerinfo->lowerseq )
{
//
case ASEQ_RUNF_GO:
case ASEQ_RUNF:
case ASEQ_RUNF_END:
PlayerAnimSetLowerSeq(playerinfo, BranchLwrRunning(playerinfo));
break;
//
case ASEQ_WALKF_GO:
case ASEQ_WALKF:
case ASEQ_WALKF_END:
PlayerAnimSetLowerSeq(playerinfo, BranchLwrWalking(playerinfo));
break;
//
case ASEQ_STAND:
PlayerAnimSetLowerSeq(playerinfo, BranchLwrStanding(playerinfo));
break;
}
}
}
// *************************
// ** Lower frame handler **
// *************************
move = playerinfo->lowermove;
assert(move);
if (playerinfo->lowerframe >= move->numframes-1)
{
if (move->endfunc)
{
move->endfunc (playerinfo);
// Regrab move, endfunc is very likely to change it.
move = playerinfo->lowermove;
assert(move);
// Check for death.
if(playerinfo->deadflag==DEAD_DEAD)
return;
}
}
if (playerinfo->lowerframeptr < move->frame || playerinfo->lowerframeptr >= move->frame + move->numframes)
{
playerinfo->lowerframeptr = move->frame;
playerinfo->lowerframe = 0;
}
else
{
playerinfo->lowerframe++;
if (playerinfo->lowerframe >= move->numframes)
{
playerinfo->lowerframe = 0;
playerinfo->lowerframeptr = move->frame;
}
else
{
playerinfo->lowerframeptr = move->frame + playerinfo->lowerframe;
}
}
playerinfo->frame = playerinfo->lowerframeptr->framenum;
if (playerinfo->lowerframeptr->movefunc)
{
playerinfo->lowerframeptr->movefunc(playerinfo,
playerinfo->lowerframeptr->var1, playerinfo->lowerframeptr->var2, playerinfo->lowerframeptr->var3);
}
if (playerinfo->lowerframeptr->actionfunc)
{
playerinfo->lowerframeptr->actionfunc(playerinfo, playerinfo->lowerframeptr->var4);
}
if (playerinfo->lowerframeptr->thinkfunc)
playerinfo->lowerframeptr->thinkfunc (playerinfo);
if (PlayerSeqData2[playerinfo->lowerseq].nosplit)
{
// Straighten out joints, i.e. no torso aiming.
playerinfo->ResetJointAngles(playerinfo);
playerinfo->swapFrame = playerinfo->frame;
return;
}
// *************************
// ** Upper frame handler **
// *************************
if (playerinfo->upperidle)
{
PlayerAnimUpperIdle(playerinfo);
}
if (playerinfo->upperseq)
{
move = playerinfo->uppermove;
assert(move);
if (playerinfo->upperframe >= move->numframes-1)
{
if (move->endfunc)
{
move->endfunc (playerinfo);
// Regrab move, endfunc is very likely to change it.
move = playerinfo->uppermove;
assert(move);
// Check for death.
if(playerinfo->deadflag==DEAD_DEAD)
return;
}
}
if (playerinfo->upperseq)
{
if (playerinfo->upperframeptr < move->frame || playerinfo->upperframeptr >= move->frame + move->numframes)
{
playerinfo->upperframeptr = move->frame;
playerinfo->upperframe = 0;
}
else
{
playerinfo->upperframe++;
if (playerinfo->upperframe >= move->numframes)
{
playerinfo->upperframe = 0;
playerinfo->upperframeptr = move->frame;
}
else
{
playerinfo->upperframeptr = move->frame + playerinfo->upperframe;
}
}
playerinfo->swapFrame = playerinfo->upperframeptr->framenum;
if (playerinfo->upperframeptr->movefunc)
{
playerinfo->upperframeptr->movefunc(playerinfo,
playerinfo->upperframeptr->var1, playerinfo->upperframeptr->var2, playerinfo->upperframeptr->var3);
}
if (playerinfo->upperframeptr->actionfunc)
{
playerinfo->upperframeptr->actionfunc(playerinfo, playerinfo->upperframeptr->var4);
}
if (playerinfo->upperframeptr->thinkfunc)
playerinfo->upperframeptr->thinkfunc (playerinfo);
// Check if the lower frame is idle, if so, force ours.
if((playerinfo->loweridle)&&(!(PlayerSeqData[playerinfo->upperseq].playerflags&PLAYER_FLAG_LEAVELOWER)))
{
playerinfo->frame = playerinfo->swapFrame;
}
if((PlayerSeqData2[playerinfo->upperseq].nosplit)&&(!(playerinfo->edictflags&FL_CHICKEN)))
{
// Straighten out joints, i.e. no torso aiming.
playerinfo->ResetJointAngles(playerinfo);
return;
}
}
else
{
playerinfo->swapFrame = playerinfo->frame;
}
}
else
{
playerinfo->swapFrame = playerinfo->frame;
if (PlayerSeqData2[playerinfo->lowerseq].nosplit)
{
// No torso aiming.
return;
}
}
// Handle torso twisting (but only when we are in Elven form).
if(!(playerinfo->edictflags&FL_CHICKEN))
{
// Calculate joint angle values.
CalcJointAngles(playerinfo);
// Now set joints in motion.
playerinfo->SetJointAngles(playerinfo);
}
}
PLAYER_API void PlayerFallingDamage(playerinfo_t *playerinfo)
{
float delta;
vec3_t endpos;
delta=playerinfo->velocity[2]-playerinfo->oldvelocity[2];//falling -200 to standstill 0 gives a delta of 200
if(!playerinfo->groundentity)
{
// If we were falling, and we're now underwater, we should STOP FALLING, capiche?
VectorCopy(playerinfo->origin,endpos);
endpos[2]+=playerinfo->mins[2];
if((playerinfo->flags&PLAYER_FLAG_FALLING)&&
(playerinfo->PointContents(endpos)&(CONTENTS_SLIME|CONTENTS_LAVA))&&
(playerinfo->waterlevel==1))
{
PlayerIntLand(playerinfo,delta);
}
else if((playerinfo->waterlevel==3)&&(playerinfo->flags&PLAYER_FLAG_FALLING))
{
// We were falling, and we're now underwater so we should STOP FALLING. Capiche?
PlayerIntLand(playerinfo,delta);
}
return;
}
if((playerinfo->flags&PLAYER_FLAG_FALLING)&&(playerinfo->waterlevel<=2))
{
PlayerIntLand(playerinfo,delta);
}
delta=delta*delta*0.0001;//it's now positive no matter what
// Never take falling damage if completely underwater.
if(playerinfo->waterlevel==3)
return;
if(playerinfo->waterlevel==2)
delta*=0.25;
if(playerinfo->waterlevel==1)
delta*=0.5;
if(playerinfo->seqcmd[ACMDL_CROUCH])
delta*=0.75;//rolling absorbs some
if(delta<1.0)
return;
if(delta<15.0)
{
// Unimplemented.
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID11,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FOOTSTEP,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID11,
playerinfo->self,
FX_FOOTSTEP,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
return;
}
if(delta > 30.0)
{
// Apply damage to player entity if we are running server (game) side.
if(!playerinfo->isclient)
playerinfo->G_PlayerFallingDamage(playerinfo,delta);
}
else
{
// Unimplemented.
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID12,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FALLSHORT,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID12,
playerinfo->self,
FX_FALLSHORT,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
return;
}
}

View file

@ -0,0 +1,17 @@
//
// p_animactor.h
//
// Heretic II
// Copyright 1998 Raven Software
//
#ifndef _P_ANIMACTOR_H_
#define _P_ANIMACTOR_H_
#include "p_types.h"
extern PLAYER_API void TurnOffPlayerEffects(playerinfo_t *playerinfo);
extern PLAYER_API void AnimUpdateFrame(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerFallingDamage(playerinfo_t *playerinfo);
#endif // _P_ANIMACTOR_H_

View file

@ -0,0 +1,595 @@
//
// p_anims.c
//
// Heretic II
// Copyright 1998 Raven Software
//
#include "player.h"
#include "p_types.h"
#include "p_animactor.h"
#include "p_anim_branch.h"
#include "p_anim_data.h"
#include "p_anims.h"
#include "p_main.h"
#include "g_Skeletons.h"
#include "angles.h"
#include "fx.h"
#include "random.h"
#include "vector.h"
#include "effectflags.h"
PLAYER_API void PlayerAnimSetUpperSeq(playerinfo_t *playerinfo, int seq)
{
assert(playerinfo);
if (playerinfo->upperseq != seq)
{
// We don't set all the data up right because it's up to AnimUpdateFrame to do this.
playerinfo->upperseq = seq;
playerinfo->upperframe = -1;
playerinfo->upperidle = false;
}
playerinfo->uppermove = PlayerSeqData[seq].move;
playerinfo->uppermove_index=seq;
assert(playerinfo->uppermove);
if (playerinfo->upperseq == ASEQ_NONE)
playerinfo->upperidle = true;
}
PLAYER_API void PlayerAnimSetLowerSeq(playerinfo_t *playerinfo, int seq)
{
paceldata_t *seqdata;
assert(playerinfo);
if (playerinfo->lowerseq != seq)
{
// We don't set all the data up right because it's up to AnimUpdateFrame to do this.
playerinfo->lowerseq = seq;
playerinfo->lowerframe = -1;
playerinfo->loweridle = false;
}
if (playerinfo->edictflags & FL_CHICKEN)
playerinfo->lowermove = PlayerChickenData[seq].move;
else
playerinfo->lowermove = PlayerSeqData[seq].move;
assert(playerinfo->lowermove);
playerinfo->lowermove_index=seq;
// The lower two bytes of the player flags are stomped by the sequences' flags.
if (playerinfo->edictflags & FL_CHICKEN)
{
seqdata = &PlayerChickenData[seq];
}
else
{
seqdata = &PlayerSeqData[seq];
playerinfo->viewheight = PlayerSeqData2[seq].viewheight;
}
playerinfo->flags = seqdata->playerflags | (playerinfo->flags & PLAYER_FLAG_PERSMASK);
// Set / reset flag that says I am flying..
if (seqdata->fly)
playerinfo->edictflags |= FL_FLY;
else
playerinfo->edictflags &= ~FL_FLY;
// Set / reset flag that says I am standing still.
if (playerinfo->flags & PLAYER_FLAG_STAND)
playerinfo->pm_flags |= PMF_STANDSTILL;
else
playerinfo->pm_flags &= ~PMF_STANDSTILL;
// Set / reset flag that says I am movelocked.
if(!playerinfo->isclient)
{
if (seqdata->lockmove)
playerinfo->pm_flags |= PMF_LOCKMOVE;
else
playerinfo->pm_flags &= ~PMF_LOCKMOVE;
}
}
PLAYER_API void PlayerBasicAnimReset(playerinfo_t *playerinfo)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_STAND);
playerinfo->lowerframeptr = playerinfo->lowermove->frame;
PlayerAnimSetUpperSeq(playerinfo, ASEQ_NONE);
playerinfo->upperframeptr = playerinfo->uppermove->frame;
playerinfo->effects|=EF_SWAPFRAME;
playerinfo->effects &= ~(EF_DISABLE_EXTRA_FX | EF_ON_FIRE | EF_TRAILS_ENABLED);
PlayerSetHandFX(playerinfo, HANDFX_NONE, -1);
if (playerinfo->pers.weaponready == WEAPON_READY_NONE) // Just in case we die with WEAPON_READY_NONE
playerinfo->pers.weaponready = WEAPON_READY_HANDS;
playerinfo->switchtoweapon = playerinfo->pers.weaponready;
playerinfo->pers.newweapon = NULL;
// Straighten out joints, i.e. reset torso twisting.
if(!(playerinfo->edictflags&FL_CHICKEN))
playerinfo->ResetJointAngles(playerinfo);
memset(playerinfo->seqcmd,0,ACMD_MAX*sizeof(int));
}
PLAYER_API void PlayerAnimReset(playerinfo_t *playerinfo)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_STAND);
playerinfo->lowerframeptr = playerinfo->lowermove->frame;
PlayerAnimSetUpperSeq(playerinfo, ASEQ_NONE);
playerinfo->upperframeptr = playerinfo->uppermove->frame;
playerinfo->pers.armortype = ARMOR_TYPE_NONE;
playerinfo->pers.bowtype = BOW_TYPE_NONE;
playerinfo->pers.stafflevel = STAFF_LEVEL_BASIC;
playerinfo->pers.helltype = HELL_TYPE_BASIC;
playerinfo->pers.altparts = 0;
playerinfo->pers.weaponready = WEAPON_READY_HANDS;
playerinfo->switchtoweapon = WEAPON_READY_HANDS;
playerinfo->pers.newweapon = NULL;
PlayerUpdateModelAttributes(playerinfo);
playerinfo->pers.handfxtype = HANDFX_NONE;
PlayerSetHandFX(playerinfo, HANDFX_NONE, -1);
playerinfo->effects|=EF_SWAPFRAME;
playerinfo->effects &= ~(EF_DISABLE_EXTRA_FX | EF_ON_FIRE | EF_TRAILS_ENABLED);
// Straighten out joints, i.e. no torso aiming.
if(!(playerinfo->edictflags&FL_CHICKEN))
playerinfo->ResetJointAngles(playerinfo);
memset(playerinfo->seqcmd,0,ACMD_MAX*sizeof(int));
}
int PlayerAnimWeaponSwitch(playerinfo_t *playerinfo)
{
qboolean BranchCheckDismemberAction(playerinfo_t *playerinfo, int weapon);
int newseq;
assert(playerinfo);
// See if we have the arm to do that magic.
if (playerinfo->switchtoweapon != playerinfo->pers.weaponready)
{
if (!BranchCheckDismemberAction(playerinfo, playerinfo->switchtoweapon))
return ASEQ_NONE;
newseq = PlayerAnimWeaponSwitchSeq[playerinfo->pers.weaponready][playerinfo->switchtoweapon];
if (newseq)
{
PlayerAnimSetUpperSeq(playerinfo, newseq);
return newseq;
}
}
else if (playerinfo->pers.newweapon)
{
if (!BranchCheckDismemberAction(playerinfo, playerinfo->pers.newweapon->tag))
return ASEQ_NONE;
newseq = PlayerAnimWeaponSwitchSeq[playerinfo->pers.weaponready][playerinfo->pers.weaponready];
if (newseq)
{
PlayerAnimSetUpperSeq(playerinfo, newseq);
return newseq;
}
}
return ASEQ_NONE;
}
PLAYER_API void PlayerAnimUpperIdle(playerinfo_t *playerinfo)
{
int ret;
if (ret = BranchUprReady(playerinfo))
{
PlayerAnimSetUpperSeq(playerinfo, ret);
assert(playerinfo->uppermove);
}
assert(playerinfo->uppermove);
}
PLAYER_API void PlayerAnimLowerIdle(playerinfo_t *playerinfo)
{
int ret;
if (playerinfo->flags & PLAYER_FLAG_SURFSWIM)
{
if (ret = BranchLwrSurfaceSwim(playerinfo))
{
PlayerAnimSetLowerSeq(playerinfo, ret);
}
}
else if (playerinfo->flags & PLAYER_FLAG_UNDERWATER)
{
if (ret = BranchLwrUnderwaterSwim(playerinfo))
{
PlayerAnimSetLowerSeq(playerinfo, ret);
}
}
else if (playerinfo->flags & PLAYER_FLAG_ONROPE)
{
if (ret = BranchLwrClimbing(playerinfo))
{
PlayerAnimSetLowerSeq(playerinfo, ret);
}
}
else if (ret = BranchLwrStanding(playerinfo))
{
PlayerAnimSetLowerSeq(playerinfo, ret);
}
else
{
if (playerinfo->leveltime - playerinfo->idletime > 15.0)
{
if (playerinfo->lowerseq >= ASEQ_IDLE_READY_GO && playerinfo->lowerseq <= ASEQ_IDLE_LOOKR && playerinfo->lowerseq != ASEQ_IDLE_READY_END)
{
// Only certain idle should be called out of here.
switch(playerinfo->irand(playerinfo, 0, 3))
{
case 0:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_LOOKL);
break;
case 1:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_LOOKR);
break;
case 2:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_READY_END);
break;
default:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_READY);
break;
}
}
// if we are in a cinematic, always do this idle, since its silent
else
if (playerinfo->sv_cinematicfreeze)
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_LOOKBACK);
else if ((playerinfo->pers.weaponready == WEAPON_READY_BOW) || (playerinfo->isclient))
{
// Because the bow doesn't look right in some idles.
switch(playerinfo->irand(playerinfo, 0, 2))
{
case 0:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_SCRATCH_ASS);
break;
case 1:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_LOOKBACK);
break;
default:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_READY_GO);
break;
}
}
else if ((playerinfo->pers.weaponready == WEAPON_READY_SWORDSTAFF))
{
// Because the staff doesn't look right in some idles.
switch(playerinfo->irand(playerinfo, 0, 3))
{
case 0:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_FLY1);
break;
case 1:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_FLY2);
break;
case 2:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_WIPE_BROW);
break;
default:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_READY_GO);
break;
}
}
else
{
switch(playerinfo->irand(playerinfo, 0, 6))
{
case 0:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_FLY1);
break;
case 1:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_FLY2);
break;
case 2:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_SCRATCH_ASS);
break;
case 3:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_LOOKBACK);
break;
case 4:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_WIPE_BROW);
break;
default:
PlayerAnimSetLowerSeq(playerinfo, ASEQ_IDLE_READY_GO);
break;
}
}
}
}
}
PLAYER_API void PlayerAnimUpperUpdate(playerinfo_t *playerinfo)
{
seqctrl_t *seqctrl;
int newseq=ASEQ_NONE;
/*
// first check if the lower anim forces the lower anim to lock in sync with it.
if (PlayerSeqData2[playerinfo->lowerseq].nosplit)
{
// A seq value of NONE indicates that it is not asserting a move, copy the companion half.
playerinfo->upperseq = ASEQ_NONE;
playerinfo->upperidle = true;
return;
}
*/
// Init some values.
playerinfo->upperidle = false;
// Grab the sequence ctrl struct.
seqctrl = &SeqCtrl[playerinfo->upperseq];
// First check the branch function. This evaluates "extra" command flags for a potential
// modification of the "simple" procedure.
if (seqctrl->branchfunc)
{
newseq = seqctrl->branchfunc(playerinfo);
}
if (newseq == ASEQ_NONE)
{
if (seqctrl->command != ACMD_NONE)
{
if (playerinfo->seqcmd[seqctrl->command])
{
newseq = seqctrl->continueseq;
}
else
{
newseq = seqctrl->ceaseseq;
}
}
else
{
newseq = seqctrl->ceaseseq;
}
}
// Now check for idles. If the upper half has an idle, then the upper half is copied.
if(newseq == ASEQ_NONE)
{
if (playerinfo->lowerseq == ASEQ_NONE)
{
newseq=BranchIdle(playerinfo);
playerinfo->loweridle = true;
}
playerinfo->upperidle = true;
}
PlayerAnimSetUpperSeq(playerinfo, newseq);
}
PLAYER_API void PlayerAnimLowerUpdate(playerinfo_t *playerinfo)
{
seqctrl_t *seqctrl;
paceldata_t *seqdata;
int newseq=ASEQ_NONE;
/*
// First check if the lower anim is locked by the upper anim.
if (PlayerSeqData2[playerinfo->upperseq].nosplit)
{
// A NONE sequence indicates that the sequence should just mimic the companion half's anim.
playerinfo->lowerseq = ASEQ_NONE;
playerinfo->loweridle = true;
return;
}
*/
// Init some values.
playerinfo->loweridle = false;
// Grab the sequence ctrl struct.
if (playerinfo->edictflags & FL_CHICKEN)
seqctrl = &ChickenCtrl[playerinfo->lowerseq];
else
seqctrl = &SeqCtrl[playerinfo->lowerseq];
// Check for noclip, just to make things more robust.
if (playerinfo->movetype == PHYSICSTYPE_NOCLIP)
{
if (playerinfo->lowerseq != ASEQ_STAND)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_STAND);
}
}
if (!newseq) // That is if that waterseq transition wasn't necessary...
{
// First check the branch function. This evaluates "extra" command flags for a potential
// modification of the "simple" procedure.
if (seqctrl->branchfunc)
{
newseq = seqctrl->branchfunc(playerinfo);
}
}
// If even after the special-case BranchFunc didn't indicate a new sequence...
if (!newseq)
{
// The seqctrl indicates the control flag that this sequence is dependent on.
// We've defined a continue and terminate sequence depending on it.
if (seqctrl->command != ACMD_NONE)
{
if (playerinfo->seqcmd[seqctrl->command])
{
newseq = seqctrl->continueseq;
}
else
{
newseq = seqctrl->ceaseseq;
}
}
else
{
newseq = seqctrl->ceaseseq;
}
}
// Get the pointer to the correct entry in the SeqData table.
if (playerinfo->edictflags & FL_CHICKEN)
seqdata = &PlayerChickenData[newseq];
else
seqdata = &PlayerSeqData[newseq];
// Now check for idles. If the lower half has an idle, then the upper half is copied.
/* if (playerinfo->lowerseq == ASEQ_NONE)
{
if (playerinfo->upperseq == ASEQ_NONE)
{
playerinfo->upperseq = BranchIdle(self);
playerinfo->upperidle = true;
}
playerinfo->loweridle = true;
playerinfo->flags = seqdata->playerflags | (playerinfo->flags & PLAYER_FLAG_PERSMASK);
}
*/
PlayerAnimSetLowerSeq(playerinfo, newseq);
}
PLAYER_API void PlayerAnimSetVault(playerinfo_t *playerinfo, int seq)
{
assert(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, seq);
playerinfo->fwdvel = 0.0;
playerinfo->sidevel = 0.0;
playerinfo->upvel = 0.0;
playerinfo->edictflags |= FL_FLY | FL_LOCKMOVE;
playerinfo->flags = PlayerSeqData[ASEQ_VAULT_LOW].playerflags | (playerinfo->flags & PLAYER_FLAG_PERSMASK);
playerinfo->pm_flags |= PMF_LOCKMOVE;
VectorClear(playerinfo->velocity);
if(playerinfo->waterlevel>1)
playerinfo->waterlevel = 1;
}
PLAYER_API void PlayerPlayPain(playerinfo_t *playerinfo, int type)
{
int chance = irand(0,100);
if(playerinfo->isclient)
{
if (!playerinfo->edictflags & FL_CHICKEN)
{ // Chicken plays no pain sound.
switch (type)
{
// Normal.
case 0:
if(chance < 50)
playerinfo->CL_Sound(SND_PRED_ID40,playerinfo->origin, CHAN_VOICE, "*pain1.wav", 1.0, ATTN_NORM, 0);
else
playerinfo->CL_Sound(SND_PRED_ID41,playerinfo->origin, CHAN_VOICE, "*pain2.wav", 1.0, ATTN_NORM, 0);
break;
// Gas.
case 1:
if(chance < 33)
playerinfo->CL_Sound(SND_PRED_ID42,playerinfo->origin, CHAN_VOICE, "*cough1.wav", 1.0, ATTN_NORM, 0);
else if (chance < 66)
playerinfo->CL_Sound(SND_PRED_ID43,playerinfo->origin, CHAN_VOICE, "*cough2.wav", 1.0, ATTN_NORM, 0);
else
playerinfo->CL_Sound(SND_PRED_ID44,playerinfo->origin, CHAN_VOICE, "*cough3.wav", 1.0, ATTN_NORM, 0);
break;
// Small
case 2:
playerinfo->CL_Sound(SND_PRED_ID45,playerinfo->origin, CHAN_VOICE, "*ow.wav", 1.0, ATTN_NORM, 0);
break;
}
}
}
else
{
if (!playerinfo->edictflags & FL_CHICKEN)
{ // Chicken plays no pain sound.
switch (type)
{
// Normal.
case 0:
if(chance < 50)
playerinfo->G_Sound(SND_PRED_ID40,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*pain1.wav"), 1.0, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID41,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*pain2.wav"), 1.0, ATTN_NORM, 0);
break;
// Gas.
case 1:
if(chance < 33)
playerinfo->G_Sound(SND_PRED_ID42,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*cough1.wav"), 1.0, ATTN_NORM, 0);
else if (chance < 66)
playerinfo->G_Sound(SND_PRED_ID43,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*cough2.wav"), 1.0, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID44,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*cough3.wav"), 1.0, ATTN_NORM, 0);
break;
// Small.
case 2:
playerinfo->G_Sound(SND_PRED_ID45,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*ow.wav"), 1.0, ATTN_NORM, 0);
break;
}
}
}
}

View file

@ -10,16 +10,16 @@
#include "p_types.h"
extern H2COMMON_API void PlayerBasicAnimReset(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimReset(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimSetLowerSeq(playerinfo_t *playerinfo, int seq);
extern H2COMMON_API void PlayerAnimSetUpperSeq(playerinfo_t *playerinfo, int seq);
extern H2COMMON_API void PlayerAnimUpperIdle(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimLowerIdle(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimUpperUpdate(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimLowerUpdate(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerAnimSetVault(playerinfo_t *playerinfo, int seq);
extern H2COMMON_API void PlayerPlayPain(playerinfo_t *playerinfo, int type);
extern PLAYER_API void PlayerBasicAnimReset(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimReset(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimSetLowerSeq(playerinfo_t *playerinfo, int seq);
extern PLAYER_API void PlayerAnimSetUpperSeq(playerinfo_t *playerinfo, int seq);
extern PLAYER_API void PlayerAnimUpperIdle(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimLowerIdle(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimUpperUpdate(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimLowerUpdate(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerAnimSetVault(playerinfo_t *playerinfo, int seq);
extern PLAYER_API void PlayerPlayPain(playerinfo_t *playerinfo, int type);
extern int PlayerAnimWeaponSwitch(playerinfo_t *playerinfo);
@ -67,7 +67,18 @@ enum seq_anim_e
ASEQ_WSWORD_STD2,
ASEQ_WSWORD_STEP2,
ASEQ_WSWORD_STEP,
ASEQ_WSWORD_ROUND_BACK,
ASEQ_WSWORD_BACK,
ASEQ_WSWORD_DOWNSTAB,
ASEQ_WSWORD_STABHOLD,
ASEQ_WSWORD_PULLOUT,
ASEQ_WSWORD_BLOCK_L,
ASEQ_WSWORD_BLOCK2_L,
ASEQ_WSWORD_BLOCKATK_L,
ASEQ_WSWORD_BLOCK_R,
ASEQ_WSWORD_BLOCK2_R,
ASEQ_WSWORD_BLOCKATK_R,
ASEQ_WSWORD_BLOCKED_L,
ASEQ_WSWORD_BLOCKED_R,
ASEQ_WFIREBALL,
ASEQ_WARRAY,
ASEQ_WSPHERE_GO,
@ -185,6 +196,10 @@ enum seq_anim_e
ASEQ_SSWIMR_END,
ASEQ_WSWORD_SPIN,
ASEQ_WSWORD_SPIN2,
ASEQ_WSWORD_SPINBLOCKED,
ASEQ_WSWORD_SPINBLOCKED2,
ASEQ_WSWORD_LOWERDOWNSTAB,
ASEQ_WSWORD_LOWERPULLOUT,
ASEQ_PULLUP_HALFWALL,
ASEQ_TUMBLEON1,
ASEQ_TUMBLEON2,
@ -287,9 +302,8 @@ enum seq_anim_e
ASEQ_WSTRAFEB_RIGHT,
ASEQ_OVERHANG,
ASEQ_DEATH_B,
ASEQ_DEATH_FLY1_GO,
ASEQ_DEATH_FLY1_LOOP,
ASEQ_DEATH_FLY1_END,
ASEQ_DEATH_FLYFWD,
ASEQ_DEATH_FLYBACK,
ASEQ_DEATH_CHOKE,
ASEQ_IDLE_LOOKBACK,
ASEQ_IDLE_SCRATCH_ASS,

View file

@ -0,0 +1,294 @@
//==============================================================================
//
// p_chicken.c
//
// Heretic II
// Copyright 1998 Raven Software
//
//
// AI :
//
// STAND1 : Looking straight ahead
//
// Ported from m_chicken.c by Marcus Whitlock
//
//==============================================================================
#include "player.h"
#include "g_Physics.h"
#include "g_teleport.h"
#include "g_Skeletons.h"
#include "p_types.h"
#include "p_anims.h"
#include "p_chicken.h"
#include "fx.h"
#include "random.h"
#include "vector.h"
#include "Utilities.h"
#include "p_main.h"
#define CHICKEN_GLIDE 150
#define CHICKEN_GLIDE_FORWARD 200
void ChickenStepSound(playerinfo_t *playerinfo, float value)
{
char *name;
if (playerinfo->edictflags & FL_SUPER_CHICKEN)
{
name = (irand(0,1)) ? "monsters/tbeast/step1.wav" : "monsters/tbeast/step2.wav";
if(playerinfo->isclient)
{
playerinfo->CL_Sound(SND_PRED_ID46,
playerinfo->origin,
CHAN_WEAPON,
name,
1.0,
ATTN_NORM,
0);
}
else
{
playerinfo->G_Sound(SND_PRED_ID46,
playerinfo->leveltime,
playerinfo->self,
CHAN_WEAPON,
playerinfo->G_SoundIndex(name),
1.0,
ATTN_NORM,
0);
}
}
}
void ChickenAssert(playerinfo_t *playerinfo)
{
//This should never be called, if it is, a sequence has been selected that cannot be addressed by the chicken
PlayerAnimSetLowerSeq(playerinfo, ASEQ_STAND);
PlayerAnimSetUpperSeq(playerinfo, ASEQ_NONE);
assert(0);
}
// ***********************************************************************************************
// PlayerChickenBite
// -----------------
// ************************************************************************************************
void PlayerChickenBite(playerinfo_t *playerinfo)
{
if(!playerinfo->isclient)
playerinfo->G_PlayerActionChickenBite(playerinfo);
}
// ***********************************************************************************************
// PlayerChickenSqueal
// -------------------
// ************************************************************************************************
void PlayerChickenSqueal(playerinfo_t *playerinfo)
{
if(playerinfo->isclient)
{
playerinfo->CL_Sound(SND_PRED_ID47,
playerinfo->origin,
CHAN_WEAPON,
"",
1.0,
ATTN_NORM,
0);
}
else
{
playerinfo->G_Sound(SND_PRED_ID47,
playerinfo->leveltime,
playerinfo->self,
CHAN_WEAPON,
playerinfo->G_SoundIndex(""),
1.0,
ATTN_NORM,
0);
}
}
// ***********************************************************************************************
// PlayerChickenNoise
// -------------------
// ************************************************************************************************
void PlayerChickenCluck(playerinfo_t *playerinfo, float force)
{
char *soundname;
assert(playerinfo);
if ( (!force) && (irand(0,10)) )
return;
if (playerinfo->edictflags & FL_SUPER_CHICKEN)
soundname = (irand(0,1)) ? "monsters/superchicken/cluck1.wav" : "monsters/superchicken/cluck2.wav";
else
soundname = (irand(0,1)) ? "monsters/chicken/cluck1.wav" : "monsters/chicken/cluck2.wav";
if(playerinfo->isclient)
playerinfo->CL_Sound(SND_PRED_ID48,playerinfo->origin, CHAN_WEAPON, soundname, 1.0, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID48,playerinfo->leveltime,playerinfo->self, CHAN_WEAPON, playerinfo->G_SoundIndex(soundname), 1.0, ATTN_NORM, 0);
}
// ***********************************************************************************************
// PlayerChickenJump
// -----------------
// ************************************************************************************************
int PlayerChickenJump(playerinfo_t *playerinfo)
{
trace_t trace;
vec3_t endpos;
char *soundname;
int id;
VectorCopy(playerinfo->origin,endpos);
endpos[2]+=(playerinfo->mins[2]-2.0);
if(playerinfo->isclient)
{
playerinfo->CL_Trace(playerinfo->origin,
playerinfo->mins,
playerinfo->maxs,
endpos,
MASK_PLAYERSOLID,
CEF_CLIP_TO_WORLD,
&trace);
}
else
{
playerinfo->G_Trace(playerinfo->origin,
playerinfo->mins,
playerinfo->maxs,
endpos,
playerinfo->self,
MASK_PLAYERSOLID,&trace);
}
if((playerinfo->groundentity||trace.fraction<0.2)&&playerinfo->waterlevel<2)
playerinfo->upvel=200;
PlayerAnimSetLowerSeq(playerinfo,ASEQ_FALL);
id = irand(0,6);
if (playerinfo->edictflags & FL_SUPER_CHICKEN)
{
switch ( id )
{
case 0:
soundname = "monsters/superchicken/jump1.wav";
break;
case 1:
soundname = "monsters/superchicken/jump2.wav";
break;
case 2:
soundname = "monsters/superchicken/jump3.wav";
break;
default:
return ASEQ_FALL;
break;
}
}
else
{
switch ( id )
{
case 0:
soundname = "monsters/chicken/jump1.wav";
break;
case 1:
soundname = "monsters/chicken/jump2.wav";
break;
case 2:
soundname = "monsters/chicken/jump3.wav";
break;
default:
return ASEQ_FALL;
break;
}
}
if(playerinfo->isclient)
playerinfo->CL_Sound(SND_PRED_ID49,playerinfo->origin, CHAN_WEAPON, soundname, 1.0, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID49,playerinfo->leveltime,playerinfo->self, CHAN_WEAPON, playerinfo->G_SoundIndex(soundname), 1.0, ATTN_NORM, 0);
return ASEQ_FALL;
}
void PlayerChickenCheckFlap ( playerinfo_t *playerinfo )
{
vec3_t vf;
if (playerinfo->seqcmd[ACMDL_JUMP])
{
playerinfo->flags |= PLAYER_FLAG_USE_ENT_POS;
AngleVectors(playerinfo->angles, vf, NULL, NULL);
vf[2] = 0;
VectorScale(vf, CHICKEN_GLIDE_FORWARD, playerinfo->velocity);
playerinfo->velocity[2] += CHICKEN_GLIDE;
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID13,
playerinfo->G_GetEntityStatePtr((edict_t *)playerinfo->self),
FX_CHICKEN_EXPLODE,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"");
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID13,
playerinfo->self,
FX_CHICKEN_EXPLODE,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"");
PlayerAnimSetLowerSeq(playerinfo,ASEQ_JUMPFWD);
}
}
void PlayerChickenFlap ( playerinfo_t *playerinfo )
{
vec3_t vf;
playerinfo->flags |= PLAYER_FLAG_USE_ENT_POS;
AngleVectors(playerinfo->angles, vf, NULL, NULL);
vf[2] = 0;
VectorScale(vf, CHICKEN_GLIDE_FORWARD, playerinfo->velocity);
playerinfo->velocity[2] += CHICKEN_GLIDE;
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID14,
playerinfo->self,
FX_CHICKEN_EXPLODE,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"");
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID14,
playerinfo->self,
FX_CHICKEN_EXPLODE,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"");
}

View file

@ -0,0 +1,332 @@
//==============================================================================
//
// p_chicken_anim.c
//
// Heretic II
// Copyright 1998 Raven Software
//
// Player chicken animations.
//
//==============================================================================
#include "player.h"
#include "p_types.h"
#include "p_anims.h"
#include "p_actions.h"
#include "p_chicken.h"
#include "p_anim_branch.h"
#include "m_chicken_anim.h"
#define PLAYER_WALK_SPEED 240
#define PLAYER_STRAFE_SPEED 185
#define PLAYER_RUN_SPEED 300
panimframe_t chickenp_frames_dummy [] =
{
FRAME_wait1, NULL, 0, 0, 0, NULL, 0, ChickenAssert,
};
panimmove_t chickenp_move_dummy = {1, chickenp_frames_dummy, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_stand [] =
{
FRAME_wait1, NULL, 0, 0, 0, PlayerChickenCluck, 0, ChickenBranchidle,
FRAME_wait2, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_wait3, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_wait4, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_wait5, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_wait6, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
};
panimmove_t chickenp_move_stand = {6, chickenp_frames_stand, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_stand1 [] =
{
FRAME_peck1, NULL, 0, 0, 0, PlayerChickenCluck, 0, ChickenBranchidle,
FRAME_peck2, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck3, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck4, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck5, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck6, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck7, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck8, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck9, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck10,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck11,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck12,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck13,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck14,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck15,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck16,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck17,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck18,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck19,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck20,NULL, 0, 0, 0, PlayerChickenCluck, 0, ChickenBranchidle,
FRAME_peck21,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck22,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck23,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck24,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck25,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck26,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck27,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck28,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_peck29,NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
};
panimmove_t chickenp_move_stand1 = {29, chickenp_frames_stand1, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_stand2 [] =
{
FRAME_cluck1, NULL, 0, 0, 0, PlayerChickenCluck, 0, ChickenBranchidle,
FRAME_cluck2, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck3, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck4, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck5, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck6, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck7, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck8, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck9, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck10, NULL, 0, 0, 0, PlayerChickenCluck, 1, ChickenBranchidle,
FRAME_cluck11, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck12, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck13, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck14, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck15, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck16, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck17, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck18, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
FRAME_cluck19, NULL, 0, 0, 0, NULL, 0, ChickenBranchidle,
};
panimmove_t chickenp_move_stand2 = {19, chickenp_frames_stand2, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken running -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_run [] =
{
FRAME_run1, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run2, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run3, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_run4, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run5, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run6, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_run = {6, chickenp_frames_run, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken walking -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_walk [] =
{
FRAME_walk1, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk2, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk3, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_walk4, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk5, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk6, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk7, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_walk8, PlayerMoveFunc, PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_walk = {8, chickenp_frames_walk, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken running -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_runb [] =
{
FRAME_run6, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_run5, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run4, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run3, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_run2, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run1, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_runb = {6, chickenp_frames_runb, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken walking backwards -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_back [] =
{
FRAME_walk8, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk7, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_walk6, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk5, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk4, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk3, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_walk2, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_walk1, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_back = {8, chickenp_frames_back, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken biting -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_bite [] =
{
FRAME_attack1, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_attack2, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_attack3, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_attack4, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_attack5, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_attack6, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_bite = {12, chickenp_frames_bite, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken strafing -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_strafel [] =
{
FRAME_run1, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run2, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run3, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_run4, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run5, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run6, PlayerMoveFunc, 0, -PLAYER_STRAFE_SPEED, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_strafel = {6, chickenp_frames_strafel, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_strafer [] =
{
FRAME_run1, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run2, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run3, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
FRAME_run4, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run5, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_run6, PlayerMoveFunc, 0, PLAYER_STRAFE_SPEED, 0, ChickenStepSound, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_strafer = {6, chickenp_frames_strafer, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken jumping start - standing
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_jump [] =
{
FRAME_jump1, NULL, 0, 0, 0, NULL, 0, NULL,
// FRAME_jump2, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_jump3, NULL, 0, 0, 0, NULL, 0, NULL,
// FRAME_jump4, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_jump5, NULL, 0, 0, 0, NULL, 0, NULL,
// FRAME_jump6, NULL, 0, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_jump = {3, chickenp_frames_jump, PlayerChickenJump};
/*----------------------------------------------------------------------
Chicken jumping loop - used for falling too
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_jump_loop [] =
{
FRAME_jump6, NULL, 0, 0, 0, NULL, 0, PlayerChickenCheckFlap,
};
panimmove_t chickenp_move_jump_loop = {1, chickenp_frames_jump_loop, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken flap
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_jump_flap [] =
{
FRAME_jump7, NULL, 0, 0, 0, NULL, 0, PlayerChickenFlap,
};
panimmove_t chickenp_move_jump_flap = {1, chickenp_frames_jump_flap, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken jumping walking start-
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_wjump [] =
{
FRAME_jump3, PlayerMoveFunc, PLAYER_WALK_SPEED /2 , 0, 0, NULL, 0, NULL,
FRAME_jump4, PlayerMoveFunc, PLAYER_WALK_SPEED , 0, 0, NULL, 0, NULL,
FRAME_jump5, PlayerMoveFunc, PLAYER_WALK_SPEED * 2, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_wjump = {3, chickenp_frames_wjump, PlayerChickenJump};
/*----------------------------------------------------------------------
Chicken jumping running start-
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_rjump [] =
{
FRAME_jump3, PlayerMoveFunc, PLAYER_RUN_SPEED / 2, 0, 0, NULL, 0, NULL,
FRAME_jump4, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_jump5, PlayerMoveFunc, PLAYER_RUN_SPEED * 2, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_rjump = {3, chickenp_frames_rjump, PlayerChickenJump};
/*----------------------------------------------------------------------
Chicken jumping walk back start-
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_wjumpb [] =
{
FRAME_jump3, PlayerMoveFunc, -PLAYER_WALK_SPEED / 2, 0, 0, NULL, 0, NULL,
FRAME_jump4, PlayerMoveFunc, -PLAYER_WALK_SPEED, 0, 0, NULL, 0, NULL,
FRAME_jump5, PlayerMoveFunc, -PLAYER_WALK_SPEED * 2, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_wjumpb = {3, chickenp_frames_wjumpb, PlayerChickenJump};
/*----------------------------------------------------------------------
Chicken jumping running back start-
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_rjumpb [] =
{
FRAME_jump3, PlayerMoveFunc, -PLAYER_RUN_SPEED / 2, 0, 0, NULL, 0, NULL,
FRAME_jump4, PlayerMoveFunc, -PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_jump5, PlayerMoveFunc, -PLAYER_RUN_SPEED * 2, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_rjumpb = {3, chickenp_frames_rjumpb, PlayerChickenJump};
/*----------------------------------------------------------------------
Chicken attacking -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_attack [] =
{
FRAME_attack1, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_attack2, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_attack3, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_attack4, NULL, 0, 0, 0, NULL, 0, NULL,
FRAME_attack5, NULL, 0, 0, 0, NULL, 0, PlayerChickenBite,
FRAME_attack6, NULL, 0, 0, 0, NULL, 0, NULL
};
panimmove_t chickenp_move_attack = {6, chickenp_frames_attack, PlayerAnimLowerUpdate};
/*----------------------------------------------------------------------
Chicken running attacking -
-----------------------------------------------------------------------*/
panimframe_t chickenp_frames_runattack [] =
{
FRAME_rattack1, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, PlayerChickenBite,
FRAME_rattack2, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_rattack3, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, NULL,
FRAME_rattack4, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_rattack5, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_rattack6, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, ChickenStepSound, 0, NULL,
};
panimmove_t chickenp_move_runattack = {6, chickenp_frames_runattack, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_swim_idle [] =
{
FRAME_wait1, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_wait2, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_wait3, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_wait4, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_wait5, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_wait6, NULL, 0, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
};
panimmove_t chickenp_move_swim_idle = {6, chickenp_frames_swim_idle, PlayerAnimLowerUpdate};
panimframe_t chickenp_frames_swim [] =
{
FRAME_jump6, PlayerMoveFunc, PLAYER_RUN_SPEED, 0, 0, NULL, 0, NULL,
FRAME_jump7, PlayerMoveFunc, PLAYER_RUN_SPEED/2, 0, 0, NULL, 0, PlayerAnimLowerUpdate,
FRAME_jump8, PlayerMoveFunc, PLAYER_RUN_SPEED/4, 0, 0, NULL, 0, NULL,
};
panimmove_t chickenp_move_swim = {3, chickenp_frames_swim, PlayerAnimLowerUpdate};

View file

@ -0,0 +1,261 @@
//
// p_ctrl.c
//
// Heretic II
// Copyright 1998 Raven Software
//
#include "player.h"
#include "p_types.h"
#include "p_actions.h"
#include "p_anims.h"
#include "p_ctrl.h"
#include "p_main.h"
#include "surfaceprops.h"
#include "random.h"
#include "fx.h"
PLAYER_API void PlayerIntLand(playerinfo_t *playerinfo, float landspeed)
{
char LandSound[64];
char *material=NULL;
qboolean hardfall=false;
// Initialise the appropriate landing sound.
material=GetClientGroundSurfaceMaterialName(playerinfo);
strcpy(LandSound,"player/");
if(material)
{
// Okay, lame, but if a material is not found, then it ignores the string being set up.
strcat(LandSound, material);
}
if (playerinfo->edictflags & FL_CHICKEN)
{
playerinfo->flags &= ~ PLAYER_FLAG_FALLING;
}
else if (playerinfo->advancedstaff && playerinfo->seqcmd[ACMDU_ATTACK] &&
(playerinfo->upperseq == ASEQ_WSWORD_DOWNSTAB || playerinfo->upperseq == ASEQ_WSWORD_STABHOLD))
{
if (landspeed < 600.0)
{
// Land heavy.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_WSWORD_LOWERPULLOUT);
playerinfo->fwdvel = 0.0;
playerinfo->velocity[0] *= 0.5;
playerinfo->velocity[1] *= 0.5;
strcpy(LandSound,"*offwall.wav");
}
else
{
// Land hard, so roll.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
playerinfo->fwdvel = 150;
strcat(LandSound,"roll.wav");
hardfall = true;
}
}
else if (playerinfo->seqcmd[ACMDL_CROUCH])
{
PlayerInterruptAction(playerinfo);
if (landspeed > 50.0)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
strcat(LandSound,"roll.wav");
}
else
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_CROUCH_GO);
strcat(LandSound,"land1.wav");
}
}
else if(playerinfo->lowerseq == ASEQ_FORWARD_FLIP_L ||
playerinfo->lowerseq == ASEQ_FORWARD_FLIP_R ||
playerinfo->upperseq == ASEQ_FORWARD_FLIP_L ||
playerinfo->upperseq == ASEQ_FORWARD_FLIP_R)
{
PlayerInterruptAction(playerinfo);
if(playerinfo->maxs[2] == 25)//fixme! have a global CROUCHING_MAX_Z and STANDING_MAX_Z
{//already ready to stand up
PlayerAnimSetLowerSeq(playerinfo, ASEQ_CROUCH_GO);
strcat(LandSound,"land1.wav");
}
else
{//still crouch height
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLL_FROM_FFLIP);
strcat(LandSound,"roll.wav");
}
}
else if (playerinfo->seqcmd[ACMDL_WALK_F])
{
if (landspeed > 600)
{
// Can't avoid heavy fall/rolling.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
strcat(LandSound,"roll.wav");
}
else
{
// Drop straight into a walk.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_WALKF);
strcat(LandSound,"land1.wav");
}
}
else if (playerinfo->seqcmd[ACMDL_RUN_F])
{
if (landspeed > 600)
{
// Can't avoid heavy fall/rolling.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
strcat(LandSound,"roll.wav");
}
else
{
// Drop straight into a run.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_RUNF);
strcat(LandSound,"land1.wav");
}
}
else if (playerinfo->seqcmd[ACMDL_JUMP])
{
if (landspeed > 600)
{
// Can't avoid heavy fall/rolling.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
strcat(LandSound,"roll.wav");
}
else
{
// Drop straight into another jump.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_JUMPSTD_GO);
strcat(LandSound,"walk");
if (irand(0,1))
strcat(LandSound, "1.wav");
else
strcat(LandSound, "2.wav");
}
}
else
{
if (landspeed < 50.0)
{
PlayerAnimSetLowerSeq(playerinfo, ASEQ_STAND);
playerinfo->fwdvel = 150;
strcat(LandSound,"shuffle1.wav");
}
else if (landspeed < 300.0)
{
// Land light.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_LANDLIGHT);
playerinfo->fwdvel = 0.0;
playerinfo->velocity[0] *= 0.5;
playerinfo->velocity[1] *= 0.5;
strcat(LandSound,"land1.wav");
}
else if (landspeed < 600.0)
{
// Land heavy.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_LANDHEAVY);
playerinfo->fwdvel = 0.0;
playerinfo->velocity[0] *= 0.5;
playerinfo->velocity[1] *= 0.5;
strcat(LandSound,"land2.wav");
}
else
{
// Land hard, so roll.
PlayerInterruptAction(playerinfo);
PlayerAnimSetLowerSeq(playerinfo, ASEQ_ROLLDIVEF_W);
playerinfo->fwdvel = 150;
strcat(LandSound,"roll.wav");
hardfall = true;
}
}
// Play the appropriate landing sound.
if(material)
{
if(playerinfo->isclient)
{
playerinfo->CL_Sound(SND_PRED_ID51,
playerinfo->origin,
CHAN_VOICE,
LandSound,
1,
ATTN_NORM,
0);
}
else
{
playerinfo->G_Sound(SND_PRED_ID51,
playerinfo->leveltime,
playerinfo->self,
CHAN_VOICE,
playerinfo->G_SoundIndex(LandSound),
1,
ATTN_NORM,
0);
}
}
if (hardfall)
{ // Grunt.
if(playerinfo->isclient)
{
playerinfo->CL_Sound(SND_PRED_ID52,
playerinfo->origin,
CHAN_FOOTSTEP,
"*fall.wav",
1,
ATTN_NORM,
0);
}
else
{
playerinfo->G_Sound(SND_PRED_ID52,
playerinfo->leveltime,
playerinfo->self,
CHAN_FOOTSTEP,
playerinfo->G_SoundIndex("*fall.wav"),
1,
ATTN_NORM,
0);
}
}
playerinfo->flags &= ~ PLAYER_FLAG_FALLING;
// Don't do dust in the water!
if(playerinfo->waterlevel==0)
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID15,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_DUST_PUFF,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID15,
playerinfo->self,
FX_DUST_PUFF,
CEF_OWNERS_ORIGIN,
playerinfo->origin,
"");
}

View file

@ -8,8 +8,8 @@
#ifndef _P_CTRL2_H_
#define _P_CTRL2_H_
#include "p_actions2.h"
#include "p_actions.h"
extern H2COMMON_API void PlayerIntLand(playerinfo_t *playerinfo_t, float landspeed);
extern PLAYER_API void PlayerIntLand(playerinfo_t *playerinfo_t, float landspeed);
#endif //_P_CTRL2_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,64 @@
#ifndef P_ITEMS_H
#define P_ITEMS_H
// ************************************************************************************************
// itemhealth_t
// ------
// ************************************************************************************************
typedef enum
{
ITEM_HEALTH1,
ITEM_HEALTH2
} itemhealth_t;
// ************************************************************************************************
// itemweapon_t
// ------
// ************************************************************************************************
typedef enum
{
ITEM_WEAPON_SWORDSTAFF,
ITEM_WEAPON_FLYINGFIST,
ITEM_WEAPON_HELLSTAFF,
ITEM_WEAPON_MAGICMISSILE,
ITEM_WEAPON_REDRAINBOW,
ITEM_WEAPON_SPHEREOFANNIHILATION,
ITEM_WEAPON_PHOENIXBOW,
ITEM_WEAPON_MACEBALLS,
ITEM_WEAPON_FIREWALL,
} itemweapon_t;
// ************************************************************************************************
// itemdefense_t
// ------
// ************************************************************************************************
typedef enum
{
ITEM_DEFENSE_REPULSION,
ITEM_DEFENSE_METEORBARRIER,
ITEM_DEFENSE_POLYMORPH,
ITEM_DEFENSE_TELEPORT,
ITEM_DEFENSE_SHIELD,
ITEM_DEFENSE_TORNADO,
ITEM_DEFENSE_POWERUP,
} itemdefense_t;
// ************************************************************************************************
// itemammo_t
// ------
// ************************************************************************************************
typedef enum
{
ITEM_AMMO_MANA_DEFENSIVE_HALF,
ITEM_AMMO_MANA_DEFENSIVE_FULL,
ITEM_AMMO_MANA_OFFENSIVE_HALF,
ITEM_AMMO_MANA_OFFENSIVE_FULL,
ITEM_AMMO_MANA_COMBO_QUARTER,
ITEM_AMMO_MANA_COMBO_HALF,
ITEM_AMMO_HELLSTAFF,
ITEM_AMMO_REDRAIN,
ITEM_AMMO_PHOENIX,
} itemammo_t;
#endif

View file

@ -0,0 +1,997 @@
//
// p_main.c
//
// Heretic II
// Copyright 1998 Raven Software
//
#include "player.h"
#include "p_animactor.h"
#include "p_anim_data.h"
#include "p_anims.h"
#include "p_main.h"
#include "p_weapon.h"
#include "p_types.h"
#include "fx.h"
#include "m_player.h"
#include "reference.h"
#include "vector.h"
//FIXME: Include header
qboolean BranchCheckDismemberAction(playerinfo_t *playerinfo, int weapon);
void FMNodeUpdate(playerinfo_t *playerinfo,int weapon,int armor);
PLAYER_API void PlayerInit(playerinfo_t *playerinfo, int complete_reset)
{
if(!complete_reset)
PlayerBasicAnimReset(playerinfo);
else
PlayerAnimReset(playerinfo);
playerinfo->flags=PLAYER_FLAG_NONE;
}
PLAYER_API void PlayerClearEffects(playerinfo_t *playerinfo)
{
// Remove all special effects from the player.
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID30,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_REMOVE_EFFECTS);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID30,
playerinfo->self,
FX_REMOVE_EFFECTS);
}
PLAYER_API void PlayerUpdateCmdFlags(playerinfo_t *playerinfo)
{
usercmd_t *pcmd;
pcmd=&(playerinfo->pcmd);
// Look for the attack button being pressed.
if (pcmd->buttons & BUTTON_ATTACK)
{
playerinfo->seqcmd[ACMDU_ATTACK] = true;
}
else
{
playerinfo->seqcmd[ACMDU_ATTACK] = false;
}
// Look for the action button being pressed.
if (pcmd->buttons & BUTTON_ACTION)
{
playerinfo->seqcmd[ACMDL_ACTION] = true;
}
else
{
playerinfo->seqcmd[ACMDL_ACTION] = false;
}
// Look for the quickturn button being pressed.
if (pcmd->buttons & BUTTON_QUICKTURN)
{
playerinfo->seqcmd[ACMDL_QUICKTURN] = true;
}
else
{
playerinfo->seqcmd[ACMDL_QUICKTURN] = false;
}
// Look for the jump / crouch buttons being pressed.
if (pcmd->upmove > 0)
{
playerinfo->seqcmd[ACMDL_JUMP] = true;
playerinfo->seqcmd[ACMDL_CROUCH] = false;
}
else if (pcmd->upmove < 0)
{
playerinfo->seqcmd[ACMDL_JUMP] = false;
playerinfo->seqcmd[ACMDL_CROUCH] = true;
}
else
{
playerinfo->seqcmd[ACMDL_JUMP] = false;
playerinfo->seqcmd[ACMDL_CROUCH] = false;
}
// Look for the turn left / turn right buttons being pressed.
if(Q_fabs(playerinfo->turncmd) > 2)
{
if (playerinfo->turncmd < -2)
{
if(playerinfo->loweridle)
playerinfo->seqcmd[ACMDL_ROTATE_R] = true;
else
playerinfo->seqcmd[ACMDL_ROTATE_R] = false;
playerinfo->seqcmd[ACMDL_ROTATE_L] = false;
}
else if (playerinfo->turncmd > 2)
{
if(playerinfo->loweridle)
playerinfo->seqcmd[ACMDL_ROTATE_L] = true;
else
playerinfo->seqcmd[ACMDL_ROTATE_L] = false;
playerinfo->seqcmd[ACMDL_ROTATE_R] = false;
}
}
else
{
playerinfo->seqcmd[ACMDL_ROTATE_R] = false;
playerinfo->seqcmd[ACMDL_ROTATE_L] = false;
}
playerinfo->turncmd = 0;
// Look for the autoaim button being pressed.
if (pcmd->buttons & BUTTON_AUTOAIM)
{
playerinfo->autoaim = true;
}
else
{
playerinfo->autoaim = false;
}
// Clear out ALL forward/backward movement flags.
memset(&(playerinfo->seqcmd[ACMDL_CREEP_F]), 0, (ACMDL_BACK-ACMDL_CREEP_F+1)*sizeof(int));
// Look for forward/backpeddle buttons being pressed.
if (pcmd->forwardmove > 10)
{
playerinfo->seqcmd[ACMDL_FWD] = true;
if (pcmd->buttons & BUTTON_CREEP)
playerinfo->seqcmd[ACMDL_CREEP_F] = true;
else if (pcmd->buttons & BUTTON_RUN)
playerinfo->seqcmd[ACMDL_RUN_F] = true;
else
playerinfo->seqcmd[ACMDL_WALK_F] = true;
}
else if (pcmd->forwardmove < -10)
{
playerinfo->seqcmd[ACMDL_BACK] = true;
if (pcmd->buttons & BUTTON_CREEP)
playerinfo->seqcmd[ACMDL_CREEP_B] = true;
else if (pcmd->buttons & BUTTON_RUN)
playerinfo->seqcmd[ACMDL_RUN_B] = true;
else
playerinfo->seqcmd[ACMDL_WALK_B] = true;
}
else
{
// No movement.
}
if (pcmd->sidemove > 2)
{
playerinfo->seqcmd[ACMDL_STRAFE_R] = true;
playerinfo->seqcmd[ACMDL_STRAFE_L] = false;
}
else if (pcmd->sidemove < -2)
{
playerinfo->seqcmd[ACMDL_STRAFE_L] = true;
playerinfo->seqcmd[ACMDL_STRAFE_R] = false;
}
else
{
playerinfo->seqcmd[ACMDL_STRAFE_L] = false;
playerinfo->seqcmd[ACMDL_STRAFE_R] = false;
}
playerinfo->showpuzzleinventory = false;
if (pcmd->buttons & BUTTON_INVENTORY)
{
playerinfo->showpuzzleinventory = true;
}
playerinfo->fwdvel=0;
playerinfo->sidevel=0;
playerinfo->upvel=0;
}
int PlayerCheckSlide(playerinfo_t *playerinfo)
{
trace_t trace;
vec3_t vf, vr, vu;
vec3_t startpos, endpos, mins, maxs;
float dot;
VectorCopy(playerinfo->origin, startpos);
VectorCopy(playerinfo->origin, endpos);
endpos[2] -= 32;
VectorSet(mins, -4, -4, -4);
VectorSet(maxs, 4, 4, 4);
AngleVectors(playerinfo->angles, vf, vr, vu);
if(playerinfo->isclient)
playerinfo->CL_Trace(startpos,mins,maxs,endpos,MASK_PLAYERSOLID,CEF_CLIP_TO_WORLD,&trace);
else
playerinfo->G_Trace(startpos,mins,maxs,endpos,playerinfo->self,MASK_PLAYERSOLID,&trace);
if (trace.fraction < 1)
{
dot = DotProduct(vf, trace.plane.normal);
}
return false;
}
PLAYER_API void PlayerUpdate(playerinfo_t *playerinfo)
{
int slideseq;
vec3_t endpos;
if (playerinfo->deadflag==DEAD_DEAD || playerinfo->deadflag==DEAD_DYING)
return;
if (playerinfo->groundentity == NULL)
{
if ((slideseq = PlayerCheckSlide(playerinfo)))
{
PlayerAnimSetLowerSeq(playerinfo, slideseq);
}
}
VectorCopy(playerinfo->origin, endpos);
endpos[2] += playerinfo->mins[2];
if ((playerinfo->PointContents(endpos) & (CONTENTS_SLIME|CONTENTS_LAVA)))
{
}
// At the very first point, evaluate whether we are in a water or air sequence, and then
// whether the player is in water or air.
else if (PlayerSeqData[playerinfo->lowerseq].playerflags & PLAYER_FLAG_WATER)
{
// Then we SHOULD be in water for this particular move.
if ((playerinfo->waterlevel > 2) && (PlayerSeqData2[playerinfo->lowerseq].waterseq == ASEQ_SSWIM_IDLE))
{
// We're completely under the water.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_USWIM_IDLE);
}
else if (playerinfo->waterlevel < 1 || (playerinfo->waterlevel < 2 && playerinfo->groundentity))
{
// If we are not in the water at all currently OR if our toes are in yet our feet are
// touching the ground then we abandon the water sequence. Waterseq here represents the
// proper sequence to go to when LEAVING water.
//NOTENOTE: This is the offending code that killed the pullups out of water. Here's a patch...
if (PlayerSeqData2[playerinfo->lowerseq].waterseq != ASEQ_NONE)
PlayerAnimSetLowerSeq(playerinfo, PlayerSeqData2[playerinfo->lowerseq].waterseq);
}
}
else
{
// We should NOT be in water for this particular move.
if ((playerinfo->waterlevel > 2) && (PlayerSeqData2[playerinfo->lowerseq].waterseq == ASEQ_SSWIM_IDLE))
{
// We're completely under the water.
PlayerAnimSetLowerSeq(playerinfo, ASEQ_USWIM_IDLE);
}
else if (playerinfo->waterlevel >= 2)
{
// We're now in water, go to the appropriate water sequence. Waterseq here represents
// the proper sequence to go to when ENTERING water.
if (PlayerSeqData2[playerinfo->lowerseq].waterseq != ASEQ_NONE)
PlayerAnimSetLowerSeq(playerinfo, PlayerSeqData2[playerinfo->lowerseq].waterseq);
}
}
if (playerinfo->remember_buttons & BUTTON_DEFEND)
{
// Not a chicken, so...
if(!playerinfo->isclient && playerinfo->pers.defence)
{
if(Defence_CurrentShotsLeft(playerinfo, 0)>0)
{
playerinfo->PlayerActionSpellDefensive(playerinfo);
}
else
{
//Play a sound to tell the player they're out of mana
if(playerinfo->isclient)
playerinfo->CL_Sound(SND_PRED_ID50,playerinfo->origin, CHAN_VOICE, "*nomana.wav", 0.75, ATTN_NORM, 0);
else
playerinfo->G_Sound(SND_PRED_ID50,playerinfo->leveltime,playerinfo->self, CHAN_VOICE, playerinfo->G_SoundIndex("*nomana.wav"), 0.75, ATTN_NORM, 0);
}
}
playerinfo->remember_buttons &= ~BUTTON_DEFEND;
}
if(!playerinfo->isclient)
{
// Check to see if the lightning shield is engaged.
if (playerinfo->shield_timer > playerinfo->leveltime)
playerinfo->G_PlayerSpellShieldAttack(playerinfo);
else
playerinfo->G_PlayerSpellStopShieldAttack(playerinfo);
}
}
// This function should be called anytime the player's skin, armor, weapon, damaged parts, etc are changed.
PLAYER_API void PlayerUpdateModelAttributes(playerinfo_t *playerinfo)
{//FIXME: make sure to see if you HAVE the weapon node you turn off (dropped weapons)
int i;
qboolean ghost,inverttex;
assert(playerinfo);
// if we are chicken, we shouldn't be doing any of this stuff
if(playerinfo->edictflags & FL_CHICKEN)
return;
// Start by setting all the attached weapon types.
// Check bow for existence and current ammo
// Until later in this function, have the bow default to on the player's back if existent, gone if not.
// Since his left hand is not holding a bow as a default, turn it on.
playerinfo->fmnodeinfo[MESH__LHANDHI].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__BOWACTV].flags |= FMNI_NO_DRAW;
switch(playerinfo->pers.bowtype)
{
case BOW_TYPE_REDRAIN:
playerinfo->fmnodeinfo[MESH__BOFF].flags &= ~FMNI_NO_DRAW;
// No special texture.
playerinfo->pers.altparts &= ~((1<<MESH__BOWACTV) | (1<<MESH__BOFF));
break;
case BOW_TYPE_PHOENIX:
playerinfo->fmnodeinfo[MESH__BOFF].flags &= ~FMNI_NO_DRAW;
playerinfo->pers.altparts |= ((1<<MESH__BOWACTV) | (1<<MESH__BOFF));
break;
case BOW_TYPE_NONE:
default:
playerinfo->fmnodeinfo[MESH__BOFF].flags |= FMNI_NO_DRAW;
break;
}
// Check staff for powerup.
// Until later in this function, have the staff default to on the player's belt.
playerinfo->fmnodeinfo[MESH__RHANDHI].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__STAFACTV].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__BLADSTF].flags |= FMNI_NO_DRAW;
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
playerinfo->fmnodeinfo[MESH__STOFF].flags &= ~FMNI_NO_DRAW;
switch(playerinfo->pers.stafflevel)
{
case STAFF_LEVEL_POWER1:
case STAFF_LEVEL_POWER2:
// Use alternate power texture...
playerinfo->pers.altparts |= ((1<<MESH__STAFACTV) | (1<<MESH__BLADSTF) | (1<<MESH__STOFF));
break;
case STAFF_LEVEL_BASIC:
default:
// No special texture
playerinfo->pers.altparts &= ~((1<<MESH__STAFACTV) | (1<<MESH__BLADSTF) | (1<<MESH__STOFF));
break;
}
// Check hellstaff for powerup.
// Assume the hellstaff is currently not readied.
playerinfo->fmnodeinfo[MESH__HELSTF].flags |= FMNI_NO_DRAW;
switch(playerinfo->pers.helltype)
{
case HELL_TYPE_POWER:
// Use alternate power texutre...
playerinfo->pers.altparts |= (1<<MESH__HELSTF);
break;
case HELL_TYPE_BASIC:
playerinfo->pers.altparts &= ~(1<<MESH__HELSTF);
break;
case HELL_TYPE_NONE:
default:
break;
}
// Check if the player's a ghost.
if (playerinfo->ghost_timer > playerinfo->leveltime)
{
// Set the ghost time.
playerinfo->renderfx |= RF_TRANS_GHOST;
ghost = true;
}
else
{
playerinfo->renderfx &= ~RF_TRANS_GHOST;
ghost = false;
}
// Check armor and level...
switch(playerinfo->pers.armortype)
{
case ARMOR_TYPE_SILVER:
playerinfo->fmnodeinfo[MESH__ARMOR].flags &= ~FMNI_NO_DRAW;
playerinfo->pers.altparts &= ~(1<<MESH__ARMOR);
break;
case ARMOR_TYPE_GOLD:
playerinfo->fmnodeinfo[MESH__ARMOR].flags |= FMNI_USE_SKIN;
playerinfo->fmnodeinfo[MESH__ARMOR].flags &= ~FMNI_NO_DRAW;
playerinfo->pers.altparts |= 1<<MESH__ARMOR;
if (playerinfo->skinnum & 0x01) // If the main skinnum is odd, then opposite
playerinfo->fmnodeinfo[MESH__ARMOR].skin = playerinfo->skinnum;
else
playerinfo->fmnodeinfo[MESH__ARMOR].skin = playerinfo->skinnum+1;
break;
case ARMOR_TYPE_NONE:
default:
playerinfo->fmnodeinfo[MESH__ARMOR].flags |= FMNI_NO_DRAW;
break;
}
// First get the proper skin and set it.
// The reflection setting is very important to this.
if (playerinfo->reflect_timer > playerinfo->leveltime)
{
// We are reflective.
playerinfo->skinnum = SKIN_REFLECTION;
playerinfo->renderfx |= RF_REFLECTION;
// No pain or power skins if alttex (metal texture).
// Also, make sure that the alternate skin is not used when the reflection map is on.
for (i=1; i<16; i++)
{
playerinfo->fmnodeinfo[i].flags &= ~FMNI_USE_SKIN;
}
}
else
{
playerinfo->renderfx &= ~RF_REFLECTION;
// Set normal skin texture.
// First check if the first "node" is damaged, because it is an exception to the rest.
if (playerinfo->pers.altparts & (1<<MESH_BASE2))
{
// The front of the body is damaged.
// This is a little weird, because the player's main skin is what defines the damage to the front chest node.
// Hence if the chest front is damaged, then the *default* skin becomes damaged, and all the *non* damaged skins are exlusions.
//all the others will use this playerinfo->skinnum if damaged, playerinfo->skinnum - 1 if not
inverttex = true;
//set the main skin (and node 0) to damaged skin
// playerinfo->skinnum = (playerinfo->plaguelevel * DAMAGE_NUM_LEVELS) + 1;
// We now don't set the skinnum to the plague level... It is up to the clientinfo to set up the right plague skin.
playerinfo->skinnum = 1;
}
else
{
// Set the normal skin level.
//all the others will use this playerinfo->skinnum + 1 if damaged, playerinfo->skinnum if not
inverttex = false;
//set the main skin (and node 0) to damaged skin
// playerinfo->skinnum = (playerinfo->plaguelevel * DAMAGE_NUM_LEVELS);
// We now don't set the skinnum to the plague level... It is up to the clientinfo to set up the right plague skin.
playerinfo->skinnum = 0;
}
//set node 0 to same skin as whole model
playerinfo->fmnodeinfo[MESH_BASE2].skin = playerinfo->skinnum;
// Set appropriate textures and pain skins.
// Fifteen other body parts.
for (i=1; i<16; i++)
{
if (playerinfo->pers.altparts & (1<<i))
{
// The part is damaged or powered.
if (!inverttex)
{
playerinfo->fmnodeinfo[i].flags |= FMNI_USE_SKIN;
playerinfo->fmnodeinfo[i].skin = playerinfo->skinnum + 1;
}
else
{
// The damaged skin is a default.
playerinfo->fmnodeinfo[i].flags &= ~FMNI_USE_SKIN;
}
}
else
{
// The part is not damaged or powered.
if (!inverttex)
{
// The undamaged skin is a default.
playerinfo->fmnodeinfo[i].flags &= ~FMNI_USE_SKIN;
}
else
{
playerinfo->fmnodeinfo[i].flags |= FMNI_USE_SKIN;
playerinfo->fmnodeinfo[i].skin = playerinfo->skinnum - 1;
}
}
}
}
//If the switch is valid
if (BranchCheckDismemberAction(playerinfo, playerinfo->pers.weapon->tag))
{//FIXME: doesn't allow for dropping of weapons
// Now turn on the appropriate weapon bits.
switch(playerinfo->pers.weaponready)
{
case WEAPON_READY_STAFFSTUB:
// Staff in right hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_RARM))
{
playerinfo->fmnodeinfo[MESH__STOFF].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__STAFACTV].flags &= ~FMNI_NO_DRAW;
}
// Empty left hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
playerinfo->fmnodeinfo[MESH__LHANDHI].flags &= ~FMNI_NO_DRAW;
break;
case WEAPON_READY_SWORDSTAFF:
// Staff in right hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_RARM))
{
playerinfo->fmnodeinfo[MESH__STOFF].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__BLADSTF].flags &= ~FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__STAFACTV].flags &= ~FMNI_NO_DRAW;
}
// Empty left hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
playerinfo->fmnodeinfo[MESH__LHANDHI].flags &= ~FMNI_NO_DRAW;
/*
if (playerinfo->leveltime > 1.0)
{
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_STAFF_CREATEPOOF,
CEF_OWNERS_ORIGIN,
NULL,
"");
}
*/
break;
case WEAPON_READY_HELLSTAFF:
// Staff in right hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_RARM))
{
playerinfo->fmnodeinfo[MESH__STOFF].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__HELSTF].flags &= ~FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__STAFACTV].flags &= ~FMNI_NO_DRAW;
}
// Empty left hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
playerinfo->fmnodeinfo[MESH__LHANDHI].flags &= ~FMNI_NO_DRAW;
/*
if (playerinfo->leveltime > 1.0)
{
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_STAFF_CREATEPOOF,
CEF_OWNERS_ORIGIN|CEF_FLAG6,
NULL,
"");
}
*/
break;
case WEAPON_READY_BOW:
// Empty right hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_RARM))
playerinfo->fmnodeinfo[MESH__RHANDHI].flags &= ~FMNI_NO_DRAW;
// Bow in left hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
{
playerinfo->fmnodeinfo[MESH__BOFF].flags |= FMNI_NO_DRAW;
playerinfo->fmnodeinfo[MESH__BOWACTV].flags &= ~FMNI_NO_DRAW;
}
break;
case WEAPON_READY_HANDS:
default:
// Empty right hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_RARM))
playerinfo->fmnodeinfo[MESH__RHANDHI].flags &= ~FMNI_NO_DRAW;
// Empty left hand.
if (!(playerinfo->flags & PLAYER_FLAG_NO_LARM))
playerinfo->fmnodeinfo[MESH__LHANDHI].flags &= ~FMNI_NO_DRAW;
break;
}
}
}
void PlayerSetHandFX(playerinfo_t *playerinfo, int handfx, int lifetime)
{
int powerlevel;
/*
// FIXME: This could be bad...
if(playerinfo->handfxtype==handfx)
{
// There should be nothing to do.
return;
}
*/
// Check currently in place effects.
/* switch(playerinfo->pers.handfxtype)
{
case HANDFX_FIREBALL:
case HANDFX_MISSILE:
case HANDFX_MACEBALL:
case HANDFX_FIREWALL:
case HANDFX_STAFF1:
case HANDFX_STAFF2:
case HANDFX_STAFF3:
// Do nothing, these effects end on their own anyway.
break;
case HANDFX_SPHERE:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID31,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_SPELLHANDS);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID31,
playerinfo->self,
FX_SPELLHANDS);
break;
case HANDFX_REDRAIN:
case HANDFX_POWERREDRAIN:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID32,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_WEAPON_REDRAINGLOW);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID32,
playerinfo->self,
FX_WEAPON_REDRAINGLOW);
break;
case HANDFX_PHOENIX:
case HANDFX_POWERPHOENIX:
if(playerinfo->effects)
if(!playerinfo->isclient)
playerinfo->G_RemoveEffects(EFFECT_PRED_ID33,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FIREHANDS);
else
playerinfo->CL_RemoveEffects(EFFECT_PRED_ID33,
playerinfo->self,
FX_FIREHANDS);
break;
case HANDFX_NONE:
default:
// Nothing to remove.
break;
}
*/
// To kill previous effects, we just Reset the EF_FLAG
// Now start the appropriate hand effect on the hand effect -
// CEF_FLAG6 = 1 = do both left and right hand, else just do right hand.
// CEF_FLAG7 & 8 = spell color type.
// 0 = red, 2 = green, 1 = blue 3 = yellow.
playerinfo->effects &= ~EF_TRAILS_ENABLED;
playerinfo->pers.handfxtype=handfx;
switch(handfx)
{
case HANDFX_FIREBALL:
// Red effect on the right throwing hand.
if (lifetime == 0)
lifetime = 4; // .4 seconds is normal fireball throw time.
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID16,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
(byte)lifetime);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID16,
playerinfo->self,
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
(byte)lifetime);
break;
case HANDFX_MISSILE:
// Green effect on the right throwing hand.
if (lifetime == 0)
lifetime = 6; // .6 seconds is normal fireball throw time
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID17,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG8,
NULL,
"b",
(byte)lifetime);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID17,
playerinfo->self,
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG8,
NULL,
"b",
(byte)lifetime);
break;
case HANDFX_FIREWALL:
if (lifetime == 0)
lifetime = 11; // 1.1 seconds is normal fireball throw time
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID19,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FIREHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG6,
NULL,
"b",
lifetime);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID19,
playerinfo->self,
FX_FIREHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG6,
NULL,
"b",
lifetime);
break;
case HANDFX_STAFF1:
case HANDFX_STAFF2:
case HANDFX_STAFF3:
playerinfo->effects &= ~EF_BLOOD_ENABLED;
// Add a trail effect to the staff.
if (playerinfo->powerup_timer > playerinfo->leveltime)
powerlevel = playerinfo->pers.stafflevel+1;
else
powerlevel = playerinfo->pers.stafflevel;
if (powerlevel >= STAFF_LEVEL_MAX)
powerlevel = STAFF_LEVEL_MAX-1;
if(!playerinfo->isclient)
{
playerinfo->G_CreateEffect(EFFECT_PRED_ID20,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_STAFF,
CEF_OWNERS_ORIGIN,
NULL,
"bb",
(byte)powerlevel,
(byte)lifetime);
}
else
{
playerinfo->CL_CreateEffect(EFFECT_PRED_ID20,
playerinfo->self,
FX_STAFF,
CEF_OWNERS_ORIGIN,
NULL,
"bb",
(byte)powerlevel,
(byte)lifetime);
}
break;
case HANDFX_SPHERE:
// Blue effect on both hands.
if (lifetime == 0)
lifetime = 8;
playerinfo->effects |= EF_TRAILS_ENABLED; // Set up for hand trails
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID18,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG6|CEF_FLAG7,
NULL,
"b",
-1);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID18,
playerinfo->self,
FX_SPELLHANDS,
CEF_OWNERS_ORIGIN|CEF_FLAG6|CEF_FLAG7,
NULL,
"b",
-1);
break;
case HANDFX_REDRAIN:
playerinfo->effects |= EF_TRAILS_ENABLED; // Set up for hand trails
if(!playerinfo->isclient)
{
playerinfo->G_CreateEffect(EFFECT_PRED_ID21,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_WEAPON_REDRAINGLOW,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
}
else
{
playerinfo->CL_CreateEffect(EFFECT_PRED_ID21,
playerinfo->self,
FX_WEAPON_REDRAINGLOW,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
}
break;
case HANDFX_POWERREDRAIN:
playerinfo->effects |= EF_TRAILS_ENABLED; // Set up for hand trails
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID22,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_WEAPON_REDRAINGLOW,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"b",
-1);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID22,
playerinfo->self,
FX_WEAPON_REDRAINGLOW,
CEF_OWNERS_ORIGIN | CEF_FLAG6,
NULL,
"b",
-1);
break;
case HANDFX_PHOENIX:
playerinfo->effects |= EF_TRAILS_ENABLED; // Set up for hand trails
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID23,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FIREHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID23,
playerinfo->self,
FX_FIREHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
break;
case HANDFX_POWERPHOENIX:
playerinfo->effects |= EF_TRAILS_ENABLED; // Set up for hand trails
if(!playerinfo->isclient)
playerinfo->G_CreateEffect(EFFECT_PRED_ID24,
playerinfo->G_GetEntityStatePtr(playerinfo->self),
FX_FIREHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
else
playerinfo->CL_CreateEffect(EFFECT_PRED_ID24,
playerinfo->self,
FX_FIREHANDS,
CEF_OWNERS_ORIGIN,
NULL,
"b",
-1);
break;
case HANDFX_MACEBALL:
// Nothin' for these yet.
break;
case HANDFX_NONE:
default:
// Don't start anything.
break;
}
}

View file

@ -20,21 +20,20 @@
#define PLAYER_FLAG_TURNDAMP 0x00000020
#define PLAYER_FLAG_SURFSWIM 0x00000040
#define PLAYER_FLAG_UNDERWATER 0x00000080
//#define PLAYER_FLAG_COLLISION 0x00000100 //Move out of lower segment
//#define PLAYER_FLAG_DIVE 0x00000200 //Move out of lower segment
//#define PLAYER_FLAG_SLIDE 0x00000400 //Move out of lower segment
#define PLAYER_FLAG_RESIZED 0x00000100
#define PLAYER_FLAG_ONROPE 0x00000200
#define PLAYER_FLAG_STAND 0x00000400
//#define PLAYER_FLAG_KNOCKDOWN 0x00002000 //Move out of lower segment
#define PLAYER_FLAG_TURN180 0x00000800
//#define PLAYER_FLAG_RELEASEROPE 0x00008000 //Move out of lower segment
#define PLAYER_FLAG_LEAVELOWER 0x00001000
#define PLAYER_FLAG_WATER (PLAYER_FLAG_UNDERWATER | PLAYER_FLAG_SURFSWIM)
// We MASK out the low two bytes every time an animation is set.
#define PLAYER_FLAG_ANIMMASK 0x0000FFFF
#define PLAYER_FLAG_PERSMASK 0xFFFF0000
// The two high bytes are persistent.
#define PLAYER_FLAG_TELEPORT 0x00010000
#define PLAYER_FLAG_MORPHING 0x00020000
#define PLAYER_FLAG_LOCKMOVE_WAS_SET 0x00040000
@ -49,18 +48,15 @@
#define PLAYER_FLAG_KNOCKDOWN 0x08000000
#define PLAYER_FLAG_RELEASEROPE 0x10000000
//#define PLAYER_FLAG_RESIZED 0x01000000 //Move out of upper segment
#define PLAYER_FLAG_WATER (PLAYER_FLAG_UNDERWATER | PLAYER_FLAG_SURFSWIM)
extern H2COMMON_API void PlayerInit(playerinfo_t *playerinfo, int complete_reset);
extern H2COMMON_API void PlayerClearEffects(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerUpdate(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerUpdateCmdFlags(playerinfo_t *playerinfo);
extern H2COMMON_API void PlayerUpdateModelAttributes(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerInit(playerinfo_t *playerinfo, int complete_reset);
extern PLAYER_API void PlayerClearEffects(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerUpdate(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerUpdateCmdFlags(playerinfo_t *playerinfo);
extern PLAYER_API void PlayerUpdateModelAttributes(playerinfo_t *playerinfo);
extern void PlayerSetHandFX(playerinfo_t *playerinfo, int handfxtype, int lifetime);
//Information for creep fall checking
// Information for creep fall checking.
#define CREEP_MAXFALL 18
#define CREEP_STEPDIST 30

View file

@ -51,7 +51,6 @@ typedef struct
typedef struct
{
panimmove_t *move;
void (*animfunc)(playerinfo_t *playerinfo, int animcell);
short fly;
short lockmove;
int playerflags;
@ -183,41 +182,6 @@ typedef enum
#define PNOISE_WEAPON 1
#define PNOISE_IMPACT 2
// ************************************************************************************************
// skintype_e
// -----------
// Indicates what skin Corvus has. On the model, there is actually a pain skin in between each of these
// ************************************************************************************************
enum skincooptype_e
{
SKIN_TYPE_COOP_CORVUS,
SKIN_TYPE_COOP_NUBIAN,
SKIN_TYPE_COOP_ROGUE,
SKIN_TYPE_COOP_BRIGAND,
SKIN_NUM_COOP_TYPES
};
enum skindeathmatchtype_e
{
SKIN_TYPE_DM_VALKYRIE,
SKIN_TYPE_DM_SPIDER,
SKIN_TYPE_DM_THIEFKING,
SKIN_TYPE_DM_RONIN,
SKIN_TYPE_DM_SOULTAKER,
SKIN_TYPE_DM_PATCHWORK,
SKIN_TYPE_DM_DEMON,
SKIN_TYPE_DM_MVP,
SKIN_NUM_DM_TYPES
};
// For code clarity
#define PLAGUE_NUM_LEVELS 3
#define DAMAGE_NUM_LEVELS 2
#define SKIN_DM_OFFSET (PLAGUE_NUM_LEVELS * DAMAGE_NUM_LEVELS * SKIN_NUM_COOP_TYPES)
#define REFLECTION_SKIN (SKIN_DM_OFFSET + (DAMAGE_NUM_LEVELS * SKIN_NUM_DM_TYPES))
// ************************************************************************************************
// IT_XXX
@ -231,6 +195,8 @@ enum skindeathmatchtype_e
#define IT_STAY_COOP 8
#define IT_PUZZLE 16
#define IT_DEFENSE 32
#define IT_OFFENSE 64
#define IT_HEALTH 128
// ************************************************************************************************
// gitem_t
@ -244,8 +210,8 @@ typedef struct gitem_s
char *classname;
char *pickup_name;
short msg_pickup; // pickup
short msg_nouse; // can`t use
short msg_pickup; // Pickup string id.
short msg_nouse; // Can`t use.
// Access function pointers.
@ -281,16 +247,30 @@ typedef struct gitem_s
char *icon;
} gitem_t;
extern H2COMMON_API gitem_t *p_itemlist;
extern H2COMMON_API int p_num_items;
#ifdef PLAYER_DLL
extern PLAYER_API gitem_t *p_itemlist;
extern PLAYER_API int p_num_items;
extern PLAYER_API int GetItemIndex(gitem_t* x);
extern PLAYER_API gitem_t *GetItemByIndex(int index);
extern PLAYER_API gitem_t *FindItemByClassname(char *classname);
extern PLAYER_API gitem_t *FindItem(char *pickupname);
extern PLAYER_API void InitItems(void);
#define ITEM_INDEX(x) GetItemIndex(x)
extern H2COMMON_API int GetItemIndex(gitem_t* x);
extern H2COMMON_API gitem_t *GetItemByIndex(int index);
extern H2COMMON_API gitem_t *FindItemByClassname(char *classname);
extern H2COMMON_API gitem_t *FindItem(char *pickupname);
extern H2COMMON_API void InitItems(void);
#else
extern int (*P_GetItemIndex)(gitem_t* x);
extern gitem_t* (*P_GetItemByIndex)(int index);
extern gitem_t* (*P_FindItemByClassname)(char *classname);
extern gitem_t* (*P_FindItem)(char *pickupname);
extern void (*P_InitItems)(void);
#define ITEM_INDEX(x) P_GetItemIndex(x)
#endif // PLAYER_DLL
// ************************************************************************************************
// inventory_t
@ -345,6 +325,7 @@ typedef struct
byte stafflevel; // Current powerup level for the staff.
byte helltype; // Current skin on the hellstaff.
byte handfxtype; // Current spell effect Corvus has attached to his refpoints.
float armor_count; // Not used on client.
short skintype; // Skin index that reflects plague stages and alternate skins
unsigned int altparts; // Missing hands, heads etc.
@ -473,6 +454,121 @@ typedef enum handfx_e
HANDFX_MAX,
} handfx_t;
// Unique sound IDs required for correct prediction of sounds played from player.dll. Each ID MUST
// be used ONCE only as it identifies the exact sound call in the player .dll that is responsible
// for playing a sound. These can be be compared with ID's recieved from the server sent sound
// packets (generated by running player.dll code on the server) so that we can decide whether to
// play the server sent sound or not (it may have already been played on the client by client
// prediction. IDs must never exeed +127.
enum
{
SND_PRED_NULL = -1,
SND_PRED_ID0 = 0,
SND_PRED_ID1,
SND_PRED_ID2,
SND_PRED_ID3,
SND_PRED_ID4, // Unused.
SND_PRED_ID5,
SND_PRED_ID6,
SND_PRED_ID7,
SND_PRED_ID8,
SND_PRED_ID9,
SND_PRED_ID10,
SND_PRED_ID11,
SND_PRED_ID12,
SND_PRED_ID13,
SND_PRED_ID14,
SND_PRED_ID15,
SND_PRED_ID16,
SND_PRED_ID17,
SND_PRED_ID18,
SND_PRED_ID19,
SND_PRED_ID20,
SND_PRED_ID21,
SND_PRED_ID22,
SND_PRED_ID23,
SND_PRED_ID24,
SND_PRED_ID25,
SND_PRED_ID26,
SND_PRED_ID27,
SND_PRED_ID28,
SND_PRED_ID29,
SND_PRED_ID30,
SND_PRED_ID31,
SND_PRED_ID32,
SND_PRED_ID33,
SND_PRED_ID34,
SND_PRED_ID35,
SND_PRED_ID36,
SND_PRED_ID37,
SND_PRED_ID38,
SND_PRED_ID39,
SND_PRED_ID40,
SND_PRED_ID41,
SND_PRED_ID42,
SND_PRED_ID43,
SND_PRED_ID44,
SND_PRED_ID45,
SND_PRED_ID46,
SND_PRED_ID47,
SND_PRED_ID48,
SND_PRED_ID49,
SND_PRED_ID50,
SND_PRED_ID51,
SND_PRED_ID52,
SND_PRED_ID53,
SND_PRED_MAX = 127
};
// Unique client-effect IDs required for correct prediction of effects started from player.dll. Each ID MUST
// be used ONCE only as it identifies the exact client-effects call in the player .dll that is responsible
// for starting a client-effect. These can be be compared with ID's recieved from the server sent client-effects
// (generated by running player.dll code on the server) so that we can decide whether to start the server sent
// client-effect or not (it may have already been started on the client by client prediction. IDs must never
// exeed +127.
enum
{
EFFECT_PRED_NULL = -1,
EFFECT_PRED_ID0 = 0,
EFFECT_PRED_ID1,
EFFECT_PRED_ID2,
EFFECT_PRED_ID3,
EFFECT_PRED_ID4,
EFFECT_PRED_ID5,
EFFECT_PRED_ID6,
EFFECT_PRED_ID7,
EFFECT_PRED_ID8,
EFFECT_PRED_ID9,
EFFECT_PRED_ID10,
EFFECT_PRED_ID11,
EFFECT_PRED_ID12,
EFFECT_PRED_ID13,
EFFECT_PRED_ID14,
EFFECT_PRED_ID15,
EFFECT_PRED_ID16,
EFFECT_PRED_ID17,
EFFECT_PRED_ID18,
EFFECT_PRED_ID19,
EFFECT_PRED_ID20,
EFFECT_PRED_ID21,
EFFECT_PRED_ID22,
EFFECT_PRED_ID23,
EFFECT_PRED_ID24,
EFFECT_PRED_ID25,
EFFECT_PRED_ID26,
EFFECT_PRED_ID27,
EFFECT_PRED_ID28,
EFFECT_PRED_ID29,
EFFECT_PRED_ID30,
EFFECT_PRED_ID31,
EFFECT_PRED_ID32,
EFFECT_PRED_ID33,
EFFECT_PRED_ID34,
EFFECT_PRED_MAX =127
};
// ************************************************************************************************
// playerinfo_t
// ------------
@ -487,17 +583,18 @@ typedef struct playerinfo_s
// Client side function callbacks (approximating functionality of server function callbacks).
void (*CL_Sound)(vec3_t origin,int channel,char *soundname,float fvol,int attenuation,float timeofs);
void (*CL_Sound)(byte EventId,vec3_t origin,int channel,char *soundname,float fvol,int attenuation,float timeofs);
void (*CL_Trace)(vec3_t start,vec3_t mins,vec3_t maxs,vec3_t end,int brushmask,int flags,trace_t *trace);
void (*CL_CreateEffect)(void);
void (*CL_RemoveEffects)(void);
int (*CL_CreateEffect)(byte EventId,void *owner,unsigned short type,int flags,vec3_t position,char *format,...);
void (*CL_RemoveEffects)(byte EventId,void *owner,int fx);
// Server (game) function callbacks (approximating functionality of client-side function callbacks).
void (*G_Sound)(edict_t *entity,int channel,int sound_num,float volume,float attenuation,float timeofs);
void (*G_L_Sound)(edict_t *entity,int sound_num);
void (*G_Sound)(byte EventId,float leveltime,edict_t *entity,int channel,int sound_num,float volume,float attenuation,float timeofs);
void (*G_Trace)(vec3_t start,vec3_t mins,vec3_t maxs,vec3_t end,edict_t *passent,int contentmask,trace_t *trace);
void (*G_CreateEffect)(entity_state_t *state,int type,int flags,vec3_t origin,char *format,...);
void (*G_RemoveEffects)(entity_state_t *state,int type);
void (*G_CreateEffect)(byte EventId,entity_state_t *state,int type,int flags,vec3_t origin,char *format,...);
void (*G_RemoveEffects)(byte Eventid,entity_state_t *state,int type);
// Server (game) function callbacks that have no client side equivalent.
@ -514,7 +611,6 @@ typedef struct playerinfo_s
qboolean (*G_PlayerActionCheckPushPull_Ent)(edict_t *ent);
void (*G_PlayerActionMoveItem)(playerinfo_t *playerinfo,float distance);
qboolean (*G_PlayerActionCheckPushButton)(playerinfo_t *playerinfo);
void (*G_PlayerActionCheckHitGround)(playerinfo_t *playerinfo);
void (*G_PlayerActionPushButton)(playerinfo_t *playerinfo);
qboolean (*G_PlayerActionCheckPushLever)(playerinfo_t *playerinfo);
void (*G_PlayerActionPushLever)(playerinfo_t *playerinfo);
@ -567,6 +663,7 @@ typedef struct playerinfo_s
// Game .dll variables.
float leveltime;
float quickturnEndTime;
// Server variables.
@ -630,17 +727,18 @@ typedef struct playerinfo_s
byte plaguelevel; // Current plague level: 0=none, 2=max.
// Shrine stuff. Used by the player to determine the time for the torch to be lit, reflection
// to work and invisibilty to work (xxx_timer).
float light_timer; // Not used on client.
float reflect_timer; // FIXME not transmitted yet.
float ghost_timer; // FIXME not transmitted yet.
float powerup_timer; // FIXME not transmitted yet.
float powerup_timer;
float lungs_timer; // Not used on client.
float shield_timer; // FIXME not transmitted yet.
float armor_count; // Not used on client.
float speed_timer; // FIXME not transmitted yet.
float block_timer; // FIXME not transmitted yet.
float cinematic_starttime; // Not used on client. Time cinematic started.
float cin_shield_timer; // What the shield timer was set at the beginning of the cinematic
@ -655,6 +753,7 @@ typedef struct playerinfo_s
vec3_t LastWatersplashPos; // Not used on client.
vec3_t oldvelocity;
qboolean chargingspell;
float quickturn_rate;
// From edict_t.
@ -681,6 +780,7 @@ typedef struct playerinfo_s
int effects;
int renderfx;
int skinnum;
int clientnum;
fmnodeinfo_t fmnodeinfo[MAX_FM_MESH_NODES];
// From pmove_state_t.
@ -695,6 +795,8 @@ typedef struct playerinfo_s
vec3_t offsetangles;
qboolean advancedstaff;
// Torso angle twisting stuff which is derived entirely from various inputs to the animation
// system.
@ -717,6 +819,7 @@ typedef struct playerinfo_s
float idletime;
vec3_t grabloc;
float grabangle;
} playerinfo_t;
#endif // _P_TYPES_H_

View file

@ -0,0 +1,292 @@
//
// p_weapon.c
//
// Heretic II
// Copyright 1998 Raven Software
//
#include "player.h"
#include "p_types.h"
#include "p_main.h"
#include "p_weapon.h"
#include "g_items.h"
#include "cl_strings.h"
//FIXME: Include header
qboolean BranchCheckDismemberAction(playerinfo_t *playerinfo, int weapon);
// ************************************************************************************************
// Weapon_Ready
// ------------
// Make the specified weapon ready if the owner has enough ammo for it. Assumes that the owner does
// actually have the weapon. Called by Cmd_InvUse_f() and other functions which do check the
// availability first anyhow.
// ************************************************************************************************
PLAYER_API void Weapon_Ready(playerinfo_t *playerinfo, gitem_t *Weapon)
{
// gi.dprintf("Weapon=%s\n",Weapon->pickup_name);
assert(Weapon);
// See if we're already using the weapon.
if(Weapon==playerinfo->pers.weapon)
return;
//Make sure we have an arm to do it
if (!BranchCheckDismemberAction(playerinfo, Weapon->tag))
return;
// Change to this weapon and set the weapon owner's ammo_index to reflect this.
playerinfo->pers.lastweapon=playerinfo->pers.weapon;
playerinfo->pers.weapon=Weapon;
if(playerinfo->pers.weapon && playerinfo->pers.weapon->ammo)
playerinfo->weap_ammo_index = ITEM_INDEX(FindItem(playerinfo->pers.weapon->ammo));
else
playerinfo->weap_ammo_index=0;
}
// ************************************************************************************************
// Weapon_EquipSwordStaff
// ----------------------
// ************************************************************************************************
PLAYER_API void Weapon_EquipSwordStaff(playerinfo_t *playerinfo,gitem_t *Weapon)
{
assert(playerinfo);
// See if we're already using the sword-staff.
if(Weapon==playerinfo->pers.weapon)
return;
// See if we're already switching...
if(playerinfo->pers.newweapon != NULL)
return;
//Make sure we have an arm to do it
if (!BranchCheckDismemberAction(playerinfo, Weapon->tag))
return;
if (playerinfo->pm_w_flags & WF_SURFACE || playerinfo->waterlevel >= 2)
return;
playerinfo->pers.newweapon = Weapon;
playerinfo->switchtoweapon = WEAPON_READY_SWORDSTAFF;
}
// ***********************************************************************************************
// Weapon_EquipSpell
// -----------------
// ************************************************************************************************
PLAYER_API void Weapon_EquipSpell(playerinfo_t *playerinfo,gitem_t *Weapon)
{
assert(playerinfo);
// See if we're already using this particular spell.
if(Weapon==playerinfo->pers.weapon)
return;
// See if we're already switching...
if(playerinfo->pers.newweapon != NULL)
{
if (playerinfo->switchtoweapon != WEAPON_READY_HANDS)
return;
}
// Make sure we have an arm to do it.
if (!BranchCheckDismemberAction(playerinfo, Weapon->tag))
return;
// In blade only DM, don't put away the staff and change weapons.
if(playerinfo->dmflags&DF_NO_OFFENSIVE_SPELL)
if (playerinfo->pm_w_flags & WF_SURFACE || playerinfo->waterlevel >= 2)
return;
// if its anything other than the flying fist, see if we have mana for it.
if (Weapon->tag != ITEM_WEAPON_FLYINGFIST)
{
if (playerinfo->pers.inventory.Items[ITEM_INDEX(FindItem(Weapon->ammo))] < Weapon->quantity)
{
playerinfo->G_gamemsg_centerprintf (playerinfo->self, GM_NOMANA);
return;
}
}
playerinfo->pers.newweapon = Weapon;
playerinfo->switchtoweapon = WEAPON_READY_HANDS;
}
// ************************************************************************************************
// Weapon_EquipHellStaff
// ---------------------
// ************************************************************************************************
PLAYER_API void Weapon_EquipHellStaff(playerinfo_t *playerinfo,gitem_t *Weapon)
{
gitem_t *AmmoItem;
int AmmoIndex;
assert(playerinfo);
// See if we're already using the hell-staff.
if(Weapon==playerinfo->pers.weapon)
return;
// See if we're already switching...
if(playerinfo->pers.newweapon != NULL)
return;
//Make sure we have an arm to do it
if (!BranchCheckDismemberAction(playerinfo, Weapon->tag))
return;
if (playerinfo->pm_w_flags & WF_SURFACE || playerinfo->waterlevel >= 2)
return;
// see if we actually have any ammo for it
AmmoItem=FindItem(Weapon->ammo);
AmmoIndex=ITEM_INDEX(AmmoItem);
if(!playerinfo->pers.inventory.Items[AmmoIndex])
{
playerinfo->G_gamemsg_centerprintf (playerinfo->self, GM_NOAMMO);
return;
}
playerinfo->pers.newweapon = Weapon;
playerinfo->switchtoweapon = WEAPON_READY_HELLSTAFF;
}
// ************************************************************************************************
// Weapon_EquipBow
// ---------------
// ************************************************************************************************
PLAYER_API void Weapon_EquipBow(playerinfo_t *playerinfo,gitem_t *Weapon)
{
gitem_t *AmmoItem;
int AmmoIndex;
assert(playerinfo);
// See if we're already using the bow.
if(Weapon==playerinfo->pers.weapon)
return;
// See if we're already switching...
if(playerinfo->pers.newweapon != NULL)
{
if (playerinfo->switchtoweapon != WEAPON_READY_BOW)
return;
}
//Make sure we have an arm to do it
if (!BranchCheckDismemberAction(playerinfo, Weapon->tag))
return;
if (playerinfo->pm_w_flags & WF_SURFACE || playerinfo->waterlevel >= 2)
return;
// see if we actually have any ammo for it
AmmoItem=FindItem(Weapon->ammo);
AmmoIndex=ITEM_INDEX(AmmoItem);
if(!playerinfo->pers.inventory.Items[AmmoIndex])
{
playerinfo->G_gamemsg_centerprintf (playerinfo->self, GM_NOAMMO);
return;
}
playerinfo->pers.newweapon = Weapon;
playerinfo->switchtoweapon = WEAPON_READY_BOW;
}
// ************************************************************************************************
// Weapon_EquipArmor - this is interesting - its never called from anywhere.
// ---------------
// ************************************************************************************************
PLAYER_API void Weapon_EquipArmor(playerinfo_t *playerinfo,gitem_t *Weapon)
{
assert(playerinfo);
// See if we're already using the armor.
if (playerinfo->pers.armortype)
{
playerinfo->pers.armortype = ARMOR_TYPE_NONE;
PlayerUpdateModelAttributes(playerinfo);
}
else
{
playerinfo->pers.armortype = ARMOR_TYPE_SILVER;
PlayerUpdateModelAttributes(playerinfo);
}
}
// ************************************************************************************************
// Weapon_CurrentShotsLeft
// -----------------------
// Returns the number of shots that a weapon owner could make with the currently selected weapon,
// in respect to the amount of ammo for that weapon that the player has in their inventory.
// ************************************************************************************************
PLAYER_API int Weapon_CurrentShotsLeft(playerinfo_t *playerinfo)
{
gitem_t *Weapon,
*AmmoItem;
int AmmoIndex;
Weapon=playerinfo->pers.weapon;
// If the weapon uses ammo, return the number of shots left, else return -1 (e.g. Sword-staff).
if(Weapon->ammo&&(Weapon->quantity))
{
AmmoItem=FindItem(Weapon->ammo);
AmmoIndex=ITEM_INDEX(AmmoItem);
if (playerinfo->pers.weapon->tag == ITEM_WEAPON_MACEBALLS && playerinfo->powerup_timer > playerinfo->leveltime)
return(playerinfo->pers.inventory.Items[AmmoIndex]/(Weapon->quantity*2.0)); // Double consumption for mace.
else
return(playerinfo->pers.inventory.Items[AmmoIndex]/Weapon->quantity);
}
else
return(0);
}
// ************************************************************************************************
// Defence_CurrentShotsLeft
// -----------------------
// Returns the number of shots that a weapon owner could make with the currently selected weapon,
// in respect to the amount of ammo for that weapon that the player has in their inventory.
// ************************************************************************************************
PLAYER_API int Defence_CurrentShotsLeft(playerinfo_t *playerinfo, int intent)
{
gitem_t *Defence,
*ManaItem;
int ManaIndex;
Defence = playerinfo->pers.defence;
// If the weapon uses ammo, return the number of shots left, else return -1 (e.g. Sword-staff).
if(Defence->ammo && Defence->quantity)
{
ManaItem = FindItem(Defence->ammo);
ManaIndex = ITEM_INDEX(ManaItem);
return(playerinfo->pers.inventory.Items[ManaIndex]/Defence->quantity);
}
else
return(0);
}

View file

@ -0,0 +1,28 @@
//
// p_weapon2.h
//
// Heretic II
// Copyright 1998 Raven Software
//
#ifndef P_WEAPON2_H
#define P_WEAPON2_H
#include "p_types.h"
// ************************************************************************************************
// Weapon_XXX
// ----------
// Applicable to all player-weapon types.
// ************************************************************************************************
PLAYER_API void Weapon_Ready(playerinfo_t *playerinfo,gitem_t *Weapon);
PLAYER_API void Weapon_EquipSpell(playerinfo_t *playerinfo,gitem_t *Weapon);
PLAYER_API void Weapon_EquipSwordStaff(playerinfo_t *playerinfo,gitem_t *Weapon);
PLAYER_API void Weapon_EquipHellStaff(playerinfo_t *playerinfo,gitem_t *Weapon);
PLAYER_API void Weapon_EquipBow(playerinfo_t *playerinfo,gitem_t *Weapon);
PLAYER_API void Weapon_EquipArmor(playerinfo_t *playerinfo, gitem_t *Weapon);
PLAYER_API int Weapon_CurrentShotsLeft(playerinfo_t *playerinfo);
PLAYER_API int Defence_CurrentShotsLeft(playerinfo_t *playerinfo, int intent);
#endif // P_WEAPON_H

View file

@ -33,7 +33,7 @@ void WaterSplash(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *effect;
paletteRGBA_t color;
fxi.GetEffect(owner, flags, "b", &cnt);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_SPLASH].formatString, &cnt);
effect = ClientEntity_new(type, flags, origin, NULL, 500);
effect->flags |= CEF_NO_DRAW | CEF_NOMOVE;

View file

@ -5,145 +5,153 @@
// NB. The assassin tport go is not precached
ClientEffect_t clientEffectSpawners[NUM_FX] =
{ // ***NOTE*** We currently have 113 client effects, and we don't want to exceed 32768! Ha!
{ RemoveEffects, NULL },
{ FXflametest, NULL},
{ GenericExplosion1, NULL },
{ GenericExplosion2, NULL },
{ WaterSplash, PreCacheWaterSplash },
{ GenericGibTrail, NULL },
{ FXBlood, PreCacheSplat },
{ FXBloodTrail, PreCacheSplat },
{ FXLinkedBlood, NULL },
{ FXGenericSparks, PreCacheSparks },
{ PlayerTeleportin, PreCacheTeleport },
{ FXHealthPickup, PreCacheHealth },
{ FXWeaponPickup, PreCacheItemWeapons },
{ FXDefensePickup, PreCacheItemDefense },
{ FXPuzzlePickup, PreCachePuzzleItems },
{ FXAmmoPickup, PreCacheItemAmmo },
{ FXFlyingFist, PreCacheFist },
{ FXFlyingFistExplode, NULL },
{ FXBlueRing, PreCacheBluering },
{ FXMeteorBarrier, PreCacheMeteor }, // see fx.h for an explanation of this
{ FXMeteorBarrier, PreCacheMeteor },
{ FXMeteorBarrier, PreCacheMeteor },
{ FXMeteorBarrier, PreCacheMeteor },
{ FXMeteorBarrierTravel, PreCacheMeteor },
{ FXMeteorBarrierExplode, NULL },
{ FXLightningShield, PreCacheShield },
{ FXSphereOfAnnihilation, PreCacheSphere },
{ FXSphereOfAnnihilationGlowballs, NULL },
{ FXSphereOfAnnihilationExplode, NULL },
{ FXSphereOfAnnihilationPower, NULL},
{ FXSpherePlayerExplode, NULL },
{ FXMagicMissile, PreCacheArray },
{ FXMagicMissileExplode, NULL },
{ FXBlast, NULL },
{ FXRedRainMissile, PreCacheRedrain },
{ FXRedRain, NULL },
{ FXRedRainGlow, NULL },
{ FXMaceball, PreCacheMaceball },
{ FXMaceballBounce, NULL },
{ FXMaceballExplode, NULL },
{ FXPhoenixMissile, PreCachePhoenix },
{ FXPhoenixExplode, NULL },
{ FXMorphMissile, PreCacheMorph },
{ FXMorphMissile_initial, NULL },
{ FXMorphExplode, NULL },
{ FXFireWave, PreCacheWall },
{ FXFireWaveWorm, PreCacheWall },
{ FXFireBurst, NULL },
{ FXRipperExplode, NULL},
{ FXWaterEntrySplash, NULL },
{ FXWaterRipples, PreCacheRipples },
{ FXWaterWake, PreCacheWake },
{ FXBubbler, PreCacheBubbler },
{ FXScorchmark, PreCacheScorch },
{ FXDebris, PreCacheDebris },
{ FXFleshDebris, PreCacheDebris },
{ FXShadow, PrecacheShadow },
{ FXAnimate, PreCacheFXAnimate },
{ FXFountain, NULL },
{ FXWaterfallBase, NULL },
{ FXDripper, PreCacheDripper },
{ FXMist, PreCacheMist },
{ FXPlagueMist, NULL },
{ FXPlagueMistExplode, NULL },
{ FXSpellHands, PreCacheHands },
{ FXLensFlare, PreCacheFlare },
{ FXStaff, PreCacheStaff },
{ FXSpoo, PreCacheSpoo },
{ FXHalo, PreCacheHalos },
{ FXRemoteCamera, NULL },
{ FXHellbolt, PreCacheHellstaff },
{ FXHellboltExplode, NULL },
{ FXHellstaffPower, PreCacheHellstaff },
{ FXHellstaffPowerBurn, NULL },
{ FXSpellChange, NULL },
{ FXStaffCreate, NULL },
{ FXStaffCreatePoof, NULL },
{ FXStaffRemove, NULL },
{ FXDustPuffOnGround, NULL },
{ FXFire, NULL },
{ FXSound, NULL },
{ FXPickup, PreCachePickup },
{ FXGenericHitPuff, NULL },
{ FXDust, PreCacheRockchunks },
{ FXEnvSmoke, PreCacheSmoke },
{ FXSpooSplat, NULL },
{ FXBodyPart, NULL },
{ PlayerTeleportout, NULL },
{ FXPlayerPersistant, NULL },
{ FXplayertorch, PreCacheTorch },
{ FXTomeOfPower, NULL },
{ FXFireOnEntity, NULL },
{ FXFlareup, PreCacheFlareup },
{ FXShrinePlayerEffect, PreCacheShrine },
{ FXShrineManaEffect, NULL },
{ FXShrineLungsEffect, NULL },
{ FXShrineLightEffect, NULL },
{ FXShrineReflectEffect, NULL },
{ FXShrineArmorEffect, NULL },
{ FXShrineHealthEffect, NULL },
{ FXShrineStaffEffect, NULL },
{ FXShrineGhostEffect, NULL },
{ FXShrineSpeedEffect, NULL },
{ FXShrinePowerUpEffect, NULL },
{ FXRope, PreCacheRope },
{ FXFireHands, NULL },
{ FXShrineBall, NULL },
{ FXShrineBallExplode, NULL },
{ FXOgleHitPuff, PrecacheOgleHitPuff },
{ FXHPMissile, PreCacheHPMissile },
{ FXIEffects, PreCacheIEffects },
{ FXChickenExplode, NULL},
{ FXFlamethrower, NULL},
{ FXTeleportPad, NULL}, // 110 fx to here
{ FXQuake, NULL }, //FX_QUAKE
{ FXLightning, PreCacheLightning},
{ FXPowerLightning, PreCacheLightning},
{ FXBubble, PreCacheBubbler},
{ FXTPortSmoke, PreCacheTPortSmoke }, //FX_TPORTSMOKE - 117
{ FXWaterParticles, PreCacheWaterParticles }, //FX_WATER_PARTICLES - 119
{ FXMEffects, PreCacheMEffects}, //FX_M_EFFECTS - 120 - all of Morcalavin's effects
{ FXHPStaff, PreCacheHPStaff}, //FX_HP_STAFF - 121 - staff effects for the high priestess
{ FXRandWaterBubble, NULL},
{ FXMagicPortal, PreCachePortal},
{ FXTBEffects, PreCacheTB}, //FX_TB_EFFECTS - 124
{ FXTestBBox, NULL},
{ FXBodyPart, NULL },//FX_THROWWEAPON - uses body part, which just detects type for certain things - 126!!!
{ FXSsithraArrow, PrecacheSsithraArrow },
{ FXPESpell, PrecachePESpell },
{ FXLightningHit, PreCacheHitPuff }, // FX_LIGHTNING_HIT
{ NullEffect, NULL }, // FX_FOOTSTEP, //114// Unimplemented fx
{ NullEffect, NULL }, // FX_FALLSHORT, //115// Unimplemented fx
{ FXStaffStrike, PreCacheStaffHit },
{ FXCreateArmorHit, PreCacheArmorHit},
{ FXBarrelExplode, PreCacheObjects},
{ FXCWatcherEffects, PreCacheCWModels},
{ FXCorpseRemove, PreCacheCrosshair}, // naughty little hack here, crosshair has nothing to do with corpse removal
{ FXLeader, NULL},
{
// ***NOTE*** We currently have 113 client effects, and we don't want to exceed 32768! Ha!
{ RemoveEffects, NULL, "s" },
{ FXflametest, NULL, NULL },
{ GenericExplosion1, NULL, NULL },
{ GenericExplosion2, NULL, NULL },
{ WaterSplash, PreCacheWaterSplash, "b" },
{ GenericGibTrail, NULL, NULL },
{ FXBlood, PreCacheSplat, "ub" },
{ FXBloodTrail, PreCacheSplat, "d" },
{ FXLinkedBlood, NULL, "bb" },
{ FXGenericSparks, PreCacheSparks, "d" },
{ PlayerTeleportin, PreCacheTeleport, NULL },
{ FXHealthPickup, PreCacheHealth, NULL },
{ FXWeaponPickup, PreCacheItemWeapons, "b" },
{ FXDefensePickup, PreCacheItemDefense, "b" },
{ FXPuzzlePickup, PreCachePuzzleItems, "bv" },
{ FXAmmoPickup, PreCacheItemAmmo, "b" },
{ FXFlyingFist, PreCacheFist, "t" },
{ FXFlyingFistExplode, NULL, "d" },
{ FXBlueRing, PreCacheBluering, NULL },
{ FXMeteorBarrier, PreCacheMeteor, NULL }, // see fx.h for an explanation of this
{ FXMeteorBarrier, PreCacheMeteor, NULL },
{ FXMeteorBarrier, PreCacheMeteor, NULL },
{ FXMeteorBarrier, PreCacheMeteor, NULL },
{ FXMeteorBarrierTravel, PreCacheMeteor, NULL },
{ FXMeteorBarrierExplode, NULL, "d" },
{ FXLightningShield, PreCacheShield, NULL },
{ FXSphereOfAnnihilation, PreCacheSphere, "s" },
{ FXSphereOfAnnihilationGlowballs, NULL, "s" },
{ FXSphereOfAnnihilationExplode, NULL, "db" },
{ FXSphereOfAnnihilationPower, NULL, "xbb" },
{ FXSpherePlayerExplode, NULL, "db" },
{ FXMagicMissile, PreCacheArray, "ss" },
{ FXMagicMissileExplode, NULL, "d" },
{ FXBlast, NULL, "sssssss" },
{ FXRedRainMissile, PreCacheRedrain, "t" },
{ FXRedRain, NULL, NULL },
{ FXRedRainGlow, NULL, "b" },
{ FXMaceball, PreCacheMaceball, NULL },
{ FXMaceballBounce, NULL, "d" },
{ FXMaceballExplode, NULL, "d" },
{ FXPhoenixMissile, PreCachePhoenix, "t" },
{ FXPhoenixExplode, NULL, "td" },
{ FXMorphMissile, PreCacheMorph, "bb" },
{ FXMorphMissile_initial, NULL, "bssssss" },
{ FXMorphExplode, NULL, "d" },
{ FXFireWave, PreCacheWall, "ss" },
{ FXFireWaveWorm, PreCacheWall, "t" },
{ FXFireBurst, NULL, "ss" },
{ FXRipperExplode, NULL, "vbssssssss"},
{ FXWaterEntrySplash, NULL, "bd" },
{ FXWaterRipples, PreCacheRipples, NULL },
{ FXWaterWake, PreCacheWake, "sbv" },
{ FXBubbler, PreCacheBubbler, "b" },
{ FXScorchmark, PreCacheScorch, "d" },
{ FXDebris, PreCacheDebris, "bbdb" },
{ FXFleshDebris, PreCacheDebris, "bdb" },
{ FXShadow, PrecacheShadow, "f" },
{ FXAnimate, PreCacheFXAnimate, "bbbv" },
{ FXFountain, NULL, "vsb" },
{ FXWaterfallBase, NULL, "bbb" },
{ FXDripper, PreCacheDripper, "bb" },
{ FXMist, PreCacheMist, "b" },
{ FXPlagueMist, NULL, "vb" },
{ FXPlagueMistExplode, NULL, "b" },
{ FXSpellHands, PreCacheHands, "b" },
{ FXLensFlare, PreCacheFlare, "bbbf" },
{ FXStaff, PreCacheStaff, "bb" },
{ FXSpoo, PreCacheSpoo, NULL },
{ FXHalo, PreCacheHalos, NULL },
{ FXRemoteCamera, NULL, "s" },
{ FXHellbolt, PreCacheHellstaff, "t" },
{ FXHellboltExplode, NULL, "d" },
{ FXHellstaffPower, PreCacheHellstaff, "tb" },
{ FXHellstaffPowerBurn, NULL, "t" },
{ FXSpellChange, NULL, "db" },
{ FXStaffCreate, NULL, NULL },
{ FXStaffCreatePoof, NULL, NULL },
{ FXStaffRemove, NULL, NULL },
{ FXDustPuffOnGround, NULL, NULL },
{ FXFire, NULL, "b" },
{ FXSound, NULL, "bbbb" },
{ FXPickup, PreCachePickup, NULL },
{ FXGenericHitPuff, NULL, "db" },
{ FXDust, PreCacheRockchunks, "bdb" },
{ FXEnvSmoke, PreCacheSmoke, "bdbbb" },
{ FXSpooSplat, NULL, "d" },
{ FXBodyPart, NULL, "ssbbb" },
{ PlayerTeleportout, NULL, NULL },
{ FXPlayerPersistant, NULL, NULL },
{ FXplayertorch, PreCacheTorch, NULL },
{ FXTomeOfPower, NULL, NULL },
{ FXFireOnEntity, NULL, "bbb" },
{ FXFlareup, PreCacheFlareup, NULL },
{ FXShrinePlayerEffect, PreCacheShrine, "b" },
{ FXShrineManaEffect, NULL, NULL },
{ FXShrineLungsEffect, NULL, NULL },
{ FXShrineLightEffect, NULL, NULL },
{ FXShrineReflectEffect, NULL, NULL },
{ FXShrineArmorEffect, NULL, NULL },
{ FXShrineHealthEffect, NULL, NULL },
{ FXShrineStaffEffect, NULL, NULL },
{ FXShrineGhostEffect, NULL, NULL },
{ FXShrineSpeedEffect, NULL, NULL },
{ FXShrinePowerUpEffect, NULL, NULL },
{ FXRope, PreCacheRope, "ssbvvv" },
{ FXFireHands, NULL, "b" },
{ FXShrineBall, NULL, "db" },
{ FXShrineBallExplode, NULL, "db" },
{ FXOgleHitPuff, PrecacheOgleHitPuff, "v" },
{ FXHPMissile, PreCacheHPMissile, "vb" },
{ FXIEffects, PreCacheIEffects, "bv" },
{ FXChickenExplode, NULL, NULL },
{ FXFlamethrower, NULL, "df" },
{ FXTeleportPad, NULL, NULL }, // 110 fx to here
{ FXQuake, NULL, "bbb" }, // FX_QUAKE
{ FXLightning, PreCacheLightning, "vbb" },
{ FXPowerLightning, PreCacheLightning, "vb" },
{ FXBubble, PreCacheBubbler, NULL },
{ FXTPortSmoke, PreCacheTPortSmoke, NULL }, // FX_TPORTSMOKE - 117
{ FXWaterParticles, PreCacheWaterParticles, NULL }, // FX_WATER_PARTICLES - 119
{ FXMEffects, PreCacheMEffects, "bv" }, // FX_M_EFFECTS - 120 - all of Morcalavin's effects
{ FXHPStaff, PreCacheHPStaff, "bs" }, // FX_HP_STAFF - 121 - staff effects for the high priestess
{ FXRandWaterBubble, NULL, NULL },
{ FXMagicPortal, PreCachePortal, "vbb" },
{ FXTBEffects, PreCacheTB, "bv" }, // FX_TB_EFFECTS - 124
{ FXTestBBox, NULL, "fff" },
{ FXBodyPart, NULL, "ssbbb" }, // FX_THROWWEAPON - uses body part, which just detects type for certain things - 126!!!
{ FXSsithraArrow, PrecacheSsithraArrow, "bv" },
{ FXPESpell, PrecachePESpell, "bv" },
{ FXLightningHit, PreCacheHitPuff, "t" }, // FX_LIGHTNING_HIT
{ NullEffect, NULL, NULL }, // FX_FOOTSTEP, //114// Unimplemented fx
{ NullEffect, NULL, NULL }, // FX_FALLSHORT, //115// Unimplemented fx
{ FXStaffStrike, PreCacheStaffHit, "db" },
{ FXCreateArmorHit, PreCacheArmorHit, "d" },
{ FXBarrelExplode, PreCacheObjects, NULL, },
{ FXCWatcherEffects, PreCacheCWModels, "bv" },
{ FXCorpseRemove, PreCacheCrosshair, NULL }, // naughty little hack here, crosshair has nothing to do with corpse removal
{ FXLeader, NULL, NULL },
{ FXTornado, PreCacheTorn, NULL },
{ FXTornadoBall, NULL, NULL },
{ FXTornadoBallExplode, NULL, NULL },
{ FXFeetTrail, NULL, NULL },
{ FXGenericSparks, PreCacheSparks, "d" },
{ NULL, NULL, NULL }, // FX_CROSSHAIR
};
CE_ClassStatics_t classStatics[NUM_CLASSIDS];
@ -164,7 +172,7 @@ void RemoveEffects(centity_t *owner, int type, int flags, vec3_t origin)
assert(owner);
// assert(owner->effects); // FIXME: This assert fires, but it should not. We shouldn't be here anyway.
fxi.GetEffect(owner, flags, "s", &fx);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_REMOVE_EFFECTS].formatString, &fx);
RemoveEffectTypeList(&owner->effects, fx, owner);
}

View file

@ -24,8 +24,8 @@ CFG=Client Effects - Win32 Debug
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Heretic2/Code/Client Effects", TNFAAAAA"
# PROP Scc_LocalPath "."
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /Zi /O2 /I "../client" /I "../qcommon" /I "../game" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /D "_DEVEL" /FR /YX /FD /c
# ADD CPP /nologo /MT /W3 /Zi /O2 /I "../client" /I "../qcommon" /I "../game" /I "../player" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /D "_DEVEL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /Gi /Zi /Od /I "../client" /I "../qcommon" /I "../game" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /D "_DEVEL" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /Gi /Zi /Od /I "../client" /I "../qcommon" /I "../game" /I "../player" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /D "_DEVEL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@ -98,8 +98,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /Zi /O2 /I "../client" /I "../qcommon" /I "../game" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /FR /YX /FD /c
# ADD CPP /nologo /MT /W3 /O2 /I "../client" /I "../qcommon" /I "../game" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /YX /FD /c
# SUBTRACT CPP /Fr
# ADD CPP /nologo /MT /W3 /O2 /I "../client" /I "../qcommon" /I "../game" /I "../player" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_HERETIC2_" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -109,8 +108,8 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib H2Common.lib quake2.lib /nologo /version:1.0 /subsystem:windows /dll /profile /debug /machine:I386 /libpath:"../Release"
# ADD LINK32 winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib H2Common.lib quake2.lib /release /nologo /base:"0x110e0000" /version:1.0 /subsystem:windows /dll /machine:I386 /out:"..\base/Client Effects.dll" /libpath:"../Final"
# SUBTRACT LINK32 /profile /debug
# ADD LINK32 winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib H2Common.lib /nologo /base:"0x11110000" /version:1.0 /subsystem:windows /dll /machine:I386 /def:".\Client Effects.def" /out:"..\base/Client Effects.dll" /libpath:"../Final" /release
# SUBTRACT LINK32 /pdb:none
!ENDIF
@ -400,6 +399,10 @@ SOURCE=.\fx_tome.c
# End Source File
# Begin Source File
SOURCE=.\fx_tornado.c
# End Source File
# Begin Source File
SOURCE=.\fx_Wall.c
# End Source File
# Begin Source File
@ -444,10 +447,6 @@ SOURCE=..\qcommon\Message.c
# End Source File
# Begin Source File
SOURCE=".\Monster Weapon Effects.c"
# End Source File
# Begin Source File
SOURCE="..\qcommon\NetMsg Read.c"
# End Source File
# Begin Source File
@ -592,10 +591,6 @@ SOURCE=..\qcommon\motion.h
# End Source File
# Begin Source File
SOURCE=..\qcommon\p_types.h
# End Source File
# Begin Source File
SOURCE=.\Particle.h
# End Source File
# Begin Source File
@ -693,7 +688,26 @@ SOURCE=..\client\vid.h
# Begin Source File
SOURCE=".\Client Effects.def"
!IF "$(CFG)" == "Client Effects - Win32 Release"
!ELSEIF "$(CFG)" == "Client Effects - Win32 Debug"
!ELSEIF "$(CFG)" == "Client Effects - Win32 Final"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# End Group
# Begin Source File
SOURCE=..\Final\H2Common.lib
# End Source File
# Begin Source File
SOURCE=..\Final\quake2.lib
# End Source File
# End Target
# End Project

View file

@ -22,6 +22,7 @@ typedef struct ClientEffect_s
{
void (*SpawnCFX)(centity_t *owner, int type, int flags, vec3_t origin);
void (*PrecacheCFX)(void);
char *formatString;
} ClientEffect_t;
extern ClientEffect_t clientEffectSpawners[];
@ -184,6 +185,10 @@ void FXBarrelExplode(centity_t *owner,int Type,int Flags,vec3_t Origin);
void FXCWatcherEffects(centity_t *owner,int Type,int Flags,vec3_t Origin);
void FXCorpseRemove(centity_t *Owner, int Type, int Flags, vec3_t Origin);
void FXLeader(centity_t *Owner, int Type, int Flags, vec3_t Origin);
void FXTornado(centity_t *Owner, int Type, int Flags, vec3_t Origin);
void FXTornadoBall(centity_t *owner, int type, int flags, vec3_t origin);
void FXTornadoBallExplode(centity_t *owner, int type, int flags, vec3_t origin);
void FXFeetTrail(centity_t *owner, int type, int flags, vec3_t origin);
// client effect used by another client effect - needs its own wrapper
@ -251,5 +256,6 @@ void PreCacheArmorHit(void);
void PreCacheHitPuff(void);
void PreCacheObjects(void);
void PreCacheCWModels(void);
void PreCacheTorn(void);
// end

View file

@ -20,6 +20,7 @@
#include "ce_DLight.h"
#include "q_Sprite.h"
#include "g_playstats.h"
#include "Skeletons.h"
extern int numprocessedparticles;
extern int numrenderedparticles;
@ -118,6 +119,7 @@ client_entity_t *ClientEntity_new(int type, int flags, vec3_t origin, vec3_t dir
newEnt->nextThinkTime = fxi.cl->time + nextThinkTime;
newEnt->startTime = fxi.cl->time;
newEnt->Update = RemoveSelfAI;
newEnt->r.rootJoint = NULL_ROOT_JOINT;
newEnt->r.swapFrame = -1;
return newEnt;

View file

@ -0,0 +1,143 @@
#include "Decal.h"
#include "Client Effects.h"
int num_decals;
Decal_t decallist[MAX_DECALS];
/*
=====================
V_AddDecal
Uses:
1 int comp
1 ++
1 offset
16 Assignments
There's a better way in Wolf which does more work on the client side. . .
=====================
*/
void V_AddDecal(vec3_t pos, vec3_t up, vec3_t right, vec3_t normal, int flags, int removetime, char *modelname)
{
Decal_t *decal;
if (fxi.cls->r_numdlights >= MAX_DLIGHTS)
{
return;
}
decal = &fxi.cls->r_decals[fxi.cls->r_numdecals++];
VectorCopy(decal->pos, pos);
VectorCopy(decal->up, up);
VectorCopy(decal->right, right);
VectorCopy(decal->normal, normal);
decal->flags = flags;
decal->removetime = removetime;
decal->modelname = modelname;
}
void CL_ClearDecals()
{
memset(decallist, 0, sizeof(Decal_t) * MAX_DECALS);
num_decals = 0;
}
// this allows abstraction to a more efficient system if needed
Decal_t *CL_AllocateDecal()
{
int i;
for(i=0; i<MAX_DECALS; i++)
{
if(decallist[i].flags)
{
continue;
}
else
{
if(num_decals < i+1)
{
num_decals = i+1;
}
memset(&decallist[i], 0, sizeof(Decal_t));
return &decallist[i];
}
}
return 0;
}
// frame updating
void CL_UpdateDecals(void)
{
int i;
for(i=0; i<MAX_DECALS; i++)
{
if(decallist[i].flags)
{
if(decallist[i].flags & DECALFLAG_TIMED)
{
if(fxi.cl->time > decallist[i].removetime)
{
memset(&decallist[i], 0, sizeof(Decal_t));
}
}
if(decallist[i].flags & DECALFLAG_ANIMATE)
{
decallist[i].frame++;
}
}
}
}
#if 1
// later we may want to add bound checks or the like here
void CL_AddDecals(void)
{
int i;
vec3_t vpn, dir; //vector to decal from viewer
float dist;
AngleVectors (fxi.cl->refdef.viewangles, vpn, NULL, NULL);
fxi.cls->r_numdecals = 0;
for(i=0; i<MAX_DECALS; i++)
{
if(decallist[i].flags)
{
VectorSubtract(decallist[i].pos, fxi.cl->refdef.vieworg, dir);
dist = VectorNormalize(dir);
if(dist > 150)
{ // if far enough away
if(DotProduct(dir, vpn) < .4)
{ // and not within the front cone
continue;
}
}
fxi.cls->r_decals[fxi.cls->r_numdecals++] = *(decallist + i);
}
}
}
#endif
/*
// an example of how to use the decal functions
void CL_DecalAdd(vec3_t pos, vec3_t up, vec3_t right, char *modelname, int flags)
{
Decal_t *newdecal;
if(newdecal = CL_AllocateDecal())
{
VectorCopy(pos, newdecal->pos);
if(flags & DECALFLAG_ORIENTED)
{
VectorCopy(pos, newdecal->up);
VectorCopy(pos, newdecal->right);
CrossProduct(up, right, newdecal->normal);
}
strcpy(newdecal->modelname, modelname);
newdecal->flags = flags | DECALFLAG_ACTIVE; //active guarantees at least one flag
}
}
*/

View file

@ -0,0 +1,15 @@
typedef float vec3_t[3];
#define DECALFLAG_ACTIVE 1 // actually, any flag at all counts as active
#define DECALFLAG_ORIENTED 2 // otherwise screen is used for up, right, normal
#define DECALFLAG_ANIMATE 4 // required for animation to occur, removed at end
#define DECALFLAG_TIMED 8 // remove after removetime set
extern struct cvar_s *cl_testdecals;
extern void CL_AddDecals(void);
extern void V_TestDecals (void);
extern void CL_UpdateDecals(void);

View file

@ -0,0 +1,212 @@
// TMix (c) Raven Software (Pagan).
// 96 textures processed.
// 56% of total area consumed
// 0 of textures were unable to be placed.
typedef struct glxy_s
{
float xl, yt, xr, yb;
int w, h, baseline;
} glxy_t;
#define glxy(label, x, y, w, h, b) glxy_t label = {(x / 256.000000), (y / 128.000000), ((x + w) / 256.000000), ((y + h) / 128.000000), w, h, b };
// Format: xpos,ypos,width,height,baseline
glxy(PERCENT, 0, 0, 17, 21, 20);
glxy(U_W, 18, 0, 24, 14, 12);
glxy(AT, 42, 0, 19, 18, 14);
glxy(U_A, 62, 0, 20, 17, 16);
glxy(U_P, 82, 0, 17, 20, 14);
glxy(POUND, 100, 0, 19, 18, 17);
glxy(U_M, 120, 0, 19, 17, 13);
glxy(U_N, 140, 0, 19, 17, 15);
glxy(U_D, 160, 0, 16, 19, 16);
glxy(U_B, 176, 0, 16, 18, 16);
glxy(U_K, 192, 0, 19, 15, 14);
glxy(STRING, 212, 0, 13, 21, 18);
glxy(U_Q, 226, 0, 18, 16, 14);
glxy(U_R, 18, 14, 14, 20, 14);
glxy(U_E, 192, 16, 15, 18, 15);
glxy(U_H, 226, 16, 17, 16, 14);
glxy(L_B, 244, 0, 11, 22, 18);
glxy(L_H, 32, 18, 14, 19, 16);
glxy(N_2, 46, 18, 17, 15, 13);
glxy(QUERY, 64, 18, 13, 19, 18);
glxy(U_L, 100, 18, 16, 16, 15);
glxy(U_T, 116, 18, 16, 16, 14);
glxy(U_Y, 132, 18, 14, 18, 13);
glxy(L_K, 176, 18, 15, 17, 15);
glxy(L_M, 78, 20, 19, 13, 9);
glxy(L_W, 146, 20, 19, 13, 11);
glxy(U_C, 0, 22, 15, 16, 15);
glxy(AST, 208, 22, 12, 19, 18);
glxy(U_V, 220, 32, 15, 16, 14);
glxy(U_X, 236, 32, 14, 17, 14);
glxy(U_Z, 16, 34, 15, 16, 14);
glxy(L_Y, 46, 34, 13, 18, 9);
glxy(HASH, 78, 34, 15, 15, 13);
glxy(U_F, 94, 34, 14, 16, 14);
glxy(U_G, 108, 34, 11, 19, 14);
glxy(U_S, 146, 34, 14, 16, 14);
glxy(N_5, 160, 34, 14, 16, 13);
glxy(CARET, 192, 34, 13, 17, 16);
glxy(L_F, 120, 34, 11, 19, 16);
glxy(L_J, 132, 36, 9, 21, 15);
glxy(L_P, 174, 36, 12, 18, 8);
glxy(PLUS, 0, 38, 14, 15, 14);
glxy(L_D, 32, 38, 11, 18, 15);
glxy(L_V, 60, 38, 14, 15, 12);
glxy(N_4, 206, 42, 14, 14, 12);
glxy(U_U, 220, 48, 14, 14, 12);
glxy(FSLASH, 14, 50, 10, 18, 17);
glxy(N_3, 74, 50, 12, 16, 13);
glxy(OPENB, 86, 50, 9, 18, 17);
glxy(LESS, 142, 50, 13, 14, 13);
glxy(GREAT, 156, 50, 13, 14, 13);
glxy(OPENSB, 96, 50, 9, 18, 17);
glxy(BSLASH, 234, 50, 9, 18, 17);
glxy(U_J, 244, 50, 10, 17, 14);
glxy(L_G, 44, 52, 10, 17, 8);
glxy(N_8, 186, 52, 13, 14, 12);
glxy(L_T, 0, 54, 11, 16, 13);
glxy(N_9, 54, 54, 11, 16, 14);
glxy(CLOSECB, 106, 54, 9, 18, 17);
glxy(CLOSESB, 116, 54, 9, 17, 16);
glxy(L_A, 170, 54, 14, 12, 9);
glxy(AMP, 24, 56, 11, 15, 13);
glxy(N_7, 200, 56, 11, 15, 13);
glxy(PLING, 66, 54, 8, 18, 16);
glxy(U_I, 126, 58, 10, 15, 14);
glxy(QUOTE, 36, 56, 8, 17, 16);
glxy(L_I, 212, 56, 8, 17, 14);
glxy(CLOSEB, 220, 62, 8, 17, 16);
glxy(L_N, 136, 64, 14, 11, 9);
glxy(L_Q, 150, 64, 11, 14, 8);
glxy(EQUAL, 162, 66, 14, 11, 10);
glxy(N_6, 74, 66, 10, 15, 13);
glxy(U_O, 176, 66, 10, 15, 13);
glxy(L_Z, 186, 66, 13, 12, 9);
glxy(OPENCB, 12, 68, 7, 18, 13);
glxy(L_U, 84, 68, 13, 11, 9);
glxy(L_X, 228, 68, 12, 12, 9);
glxy(N_0, 240, 68, 9, 15, 13);
glxy(BAR, 250, 22, 3, 21, 17);
glxy(L_L, 98, 68, 7, 16, 14);
glxy(N_1, 0, 70, 8, 15, 13);
glxy(TILDE, 44, 70, 15, 8, 7);
glxy(APOST, 250, 68, 5, 17, 16);
glxy(SQUOTE, 60, 70, 5, 17, 16);
glxy(L_E, 166, 20, 10, 12, 9);
glxy(L_C, 20, 72, 9, 12, 9);
glxy(L_O, 106, 72, 9, 11, 9);
glxy(SEMICOLON, 186, 36, 5, 14, 11);
glxy(L_S, 30, 72, 6, 13, 10);
glxy(L_R, 116, 72, 9, 10, 8);
glxy(STOP, 66, 72, 5, 13, 12);
glxy(UNDER, 200, 72, 12, 5, 0);
glxy(COLON, 36, 74, 5, 12, 11);
glxy(MINUS, 126, 74, 8, 8, 7);
glxy(COMMA, 220, 22, 5, 7, 4);
glxy_t *font1[96] =
{
0,
&PLING,
&QUOTE,
&HASH,
&STRING,
&PERCENT,
&AMP,
&SQUOTE,
&OPENB,
&CLOSEB,
&AST,
&PLUS,
&COMMA,
&MINUS,
&STOP,
&FSLASH,
&N_0,
&N_1,
&N_2,
&N_3,
&N_4,
&N_5,
&N_6,
&N_7,
&N_8,
&N_9,
&COLON,
&SEMICOLON,
&LESS,
&EQUAL,
&GREAT,
&QUERY,
&AT,
&U_A,
&U_B,
&U_C,
&U_D,
&U_E,
&U_F,
&U_G,
&U_H,
&U_I,
&U_J,
&U_K,
&U_L,
&U_M,
&U_N,
&U_O,
&U_P,
&U_Q,
&U_R,
&U_S,
&U_T,
&U_U,
&U_V,
&U_W,
&U_X,
&U_Y,
&U_Z,
&OPENSB,
&BSLASH,
&CLOSESB,
&CARET,
&UNDER,
&APOST,
&L_A,
&L_B,
&L_C,
&L_D,
&L_E,
&L_F,
&L_G,
&L_H,
&L_I,
&L_J,
&L_K,
&L_L,
&L_M,
&L_N,
&L_O,
&L_P,
&L_Q,
&L_R,
&L_S,
&L_T,
&L_U,
&L_V,
&L_W,
&L_X,
&L_Y,
&L_Z,
&OPENCB,
&BAR,
&CLOSECB,
&TILDE,
&POUND,
};
// end

View file

@ -0,0 +1,209 @@
// TMix (c) Raven Software (Pagan).
// 96 textures processed.
// 67% of total area consumed
// 0 of textures were unable to be placed.
typedef struct glxy_s
{
float xl, yt, xr, yb;
int w, h, baseline;
} glxy_t;
#define glxy(label, x, y, w, h, b) static glxy_t label = {(x / 256.000000), (y / 128.000000), ((x + w) / 256.000000), ((y + h) / 128.000000), w, h, b };
// Format: xpos,ypos,width,height,baseline
glxy(U_Q, 0, 0, 18, 24, 20);
glxy(U_W, 18, 0, 20, 22, 20);
glxy(U_K, 38, 0, 17, 24, 20);
glxy(U_X, 56, 0, 16, 25, 21);
glxy(U_D, 72, 0, 18, 22, 20);
glxy(U_R, 90, 0, 16, 24, 20);
glxy(N_0, 106, 0, 18, 21, 20);
glxy(U_A, 124, 0, 16, 23, 20);
glxy(U_B, 140, 0, 17, 22, 20);
glxy(U_M, 158, 0, 17, 22, 20);
glxy(U_O, 176, 0, 17, 22, 20);
glxy(U_P, 194, 0, 17, 22, 20);
glxy(U_S, 212, 0, 16, 23, 20);
glxy(N_7, 228, 0, 14, 24, 19);
glxy(U_H, 18, 22, 16, 22, 20);
glxy(U_N, 72, 22, 15, 23, 20);
glxy(U_U, 106, 22, 16, 22, 20);
glxy(N_3, 140, 22, 15, 22, 20);
glxy(N_9, 242, 0, 13, 24, 20);
glxy(AT, 156, 22, 18, 19, 16);
glxy(U_E, 174, 22, 15, 22, 20);
glxy(U_G, 190, 22, 15, 22, 20);
glxy(U_J, 0, 24, 14, 23, 20);
glxy(U_T, 34, 24, 14, 23, 21);
glxy(U_V, 88, 24, 15, 22, 20);
glxy(N_2, 122, 24, 16, 20, 19);
glxy(U_C, 206, 24, 14, 22, 20);
glxy(U_F, 220, 24, 14, 22, 20);
glxy(N_5, 234, 24, 13, 23, 19);
glxy(U_L, 48, 26, 14, 22, 20);
glxy(AST, 156, 42, 15, 21, 20);
glxy(N_8, 14, 44, 15, 21, 20);
glxy(U_Y, 104, 44, 13, 23, 21);
glxy(L_K, 118, 44, 14, 22, 20);
glxy(AMP, 132, 44, 18, 17, 15);
glxy(U_Z, 172, 44, 13, 22, 20);
glxy(L_H, 186, 44, 14, 21, 19);
glxy(N_6, 62, 46, 14, 20, 19);
glxy(L_M, 76, 46, 18, 16, 14);
glxy(L_Y, 200, 46, 14, 20, 14);
glxy(N_4, 214, 46, 13, 20, 19);
glxy(QUERY, 0, 48, 13, 20, 19);
glxy(L_B, 30, 48, 13, 20, 19);
glxy(L_D, 44, 48, 13, 20, 19);
glxy(L_P, 228, 48, 14, 19, 13);
glxy(L_Q, 242, 48, 13, 20, 13);
glxy(L_W, 76, 62, 18, 15, 14);
glxy(L_G, 132, 62, 13, 19, 13);
glxy(STRING, 146, 64, 11, 21, 20);
glxy(PERCENT, 158, 64, 13, 18, 17);
glxy(BSLASH, 94, 46, 10, 21, 19);
glxy(PLUS, 14, 66, 14, 17, 16);
glxy(FSLASH, 58, 66, 10, 21, 19);
glxy(TILDE, 118, 66, 12, 19, 18);
glxy(QUOTE, 172, 66, 9, 21, 20);
glxy(L_F, 62, 26, 10, 20, 19);
glxy(OPENCB, 248, 24, 8, 22, 16);
glxy(CLOSECB, 68, 66, 8, 22, 16);
glxy(L_A, 182, 66, 13, 16, 13);
glxy(U_I, 196, 66, 7, 22, 20);
glxy(L_N, 204, 66, 14, 15, 14);
glxy(L_O, 28, 68, 15, 14, 13);
glxy(L_U, 94, 68, 15, 14, 13);
glxy(L_X, 218, 68, 15, 14, 13);
glxy(BAR, 0, 68, 3, 26, -1);
glxy(L_C, 44, 68, 14, 14, 13);
glxy(L_J, 4, 68, 6, 22, 16);
glxy(L_T, 110, 68, 8, 20, 17);
glxy(L_V, 234, 68, 13, 15, 14);
glxy(L_E, 76, 78, 13, 14, 13);
glxy(HASH, 28, 82, 10, 17, 16);
glxy(L_R, 38, 82, 11, 15, 14);
glxy(L_S, 90, 82, 10, 16, 13);
glxy(OPENSB, 248, 68, 7, 19, -1);
glxy(L_Z, 130, 82, 12, 14, 13);
glxy(SQUOTE, 10, 68, 4, 21, 20);
glxy(L_L, 50, 82, 4, 21, 20);
glxy(CLOSEB, 150, 44, 6, 19, 16);
glxy(STOP, 100, 82, 5, 20, 19);
glxy(PLING, 158, 82, 5, 20, 19);
glxy(N_1, 54, 82, 4, 21, 20);
glxy(OPENB, 164, 82, 6, 19, 16);
glxy(EQUAL, 182, 82, 11, 13, -1);
glxy(CARET, 204, 82, 10, 13, -1);
glxy(GREAT, 214, 82, 8, 15, -1);
glxy(L_I, 222, 82, 5, 17, 16);
glxy(LESS, 14, 84, 7, 15, 14);
glxy(MINUS, 228, 84, 9, 10, 9);
glxy(UNDER, 142, 86, 14, 2, 1);
glxy(SEMICOLON, 22, 84, 5, 11, 9);
glxy(COLON, 14, 24, 4, 9, 8);
glxy(COMMA, 14, 34, 4, 5, 2);
glxy_t *font2[96] =
{
0,
&PLING,
&QUOTE,
&HASH,
&STRING,
&PERCENT,
&AMP,
&SQUOTE,
&OPENB,
&CLOSEB,
&AST,
&PLUS,
&COMMA,
&MINUS,
&STOP,
&FSLASH,
&N_0,
&N_1,
&N_2,
&N_3,
&N_4,
&N_5,
&N_6,
&N_7,
&N_8,
&N_9,
&COLON,
&SEMICOLON,
&LESS,
&EQUAL,
&GREAT,
&QUERY,
&AT,
&U_A,
&U_B,
&U_C,
&U_D,
&U_E,
&U_F,
&U_G,
&U_H,
&U_I,
&U_J,
&U_K,
&U_L,
&U_M,
&U_N,
&U_O,
&U_P,
&U_Q,
&U_R,
&U_S,
&U_T,
&U_U,
&U_V,
&U_W,
&U_X,
&U_Y,
&U_Z,
&OPENSB,
&BSLASH,
0,
&CARET,
&UNDER,
0,
&L_A,
&L_B,
&L_C,
&L_D,
&L_E,
&L_F,
&L_G,
&L_H,
&L_I,
&L_J,
&L_K,
&L_L,
&L_M,
&L_N,
&L_O,
&L_P,
&L_Q,
&L_R,
&L_S,
&L_T,
&L_U,
&L_V,
&L_W,
&L_X,
&L_Y,
&L_Z,
&OPENCB,
&BAR,
&CLOSECB,
&TILDE,
0,
};
// end

View file

@ -7,6 +7,9 @@
#include "Random.h"
#include "ce_Dlight.h"
#include "Utilities.h"
#include "g_playstats.h"
#include "Matrix.h"
#include "Reference.h"
extern void MakeBubble(vec3_t loc, client_entity_t *spawner);
@ -111,7 +114,7 @@ void FXOgleHitPuff(centity_t *owner, int type, int flags, vec3_t origin)
int i, chance ;
float speed;
fxi.GetEffect(owner, flags, "v", dir); // normalized direction vector
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_OGLE_HITPUFF].formatString, dir); // normalized direction vector
speed = VectorNormalize(dir);
if(speed>1.0f)
@ -224,7 +227,7 @@ void FXGenericHitPuff(centity_t *owner, int type, int flags, vec3_t origin)
byte count;
int i;
fxi.GetEffect(owner, flags, "db", dir, &count); // normalized direction vector
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_HITPUFF].formatString, dir, &count); // normalized direction vector
if (count>40)
count=40;
@ -376,6 +379,73 @@ qboolean WaterParticleGeneratorUpdate(client_entity_t *self, centity_t *owner)
return(true);
}
int wake_particle [6] =
{
PART_4x4_WHITE,
PART_8x8_BUBBLE,
PART_16x16_WATERDROP,
PART_32x32_WFALL,
PART_32x32_STEAM,
PART_32x32_BUBBLE
};
void DoWake(client_entity_t *self, centity_t *owner, int refpt)
{
vec3_t org, handpt, right, diff, diff2;
client_particle_t *p;
matrix3_t rotation;
int num_parts, i;
paletteRGBA_t LightColor={200, 255, 255, 140};//RGBA
VectorSubtract(owner->referenceInfo->references[refpt].placement.origin,
owner->referenceInfo->oldReferences[refpt].placement.origin,
diff);
VectorSubtract(owner->origin, self->endpos, diff2);
VectorAdd(diff, diff2, diff);
num_parts = (int)(VectorLength(diff));
if (num_parts > 6)
num_parts = 6;
// Let's take the origin and transform it to the proper coordinate offset from the owner's origin.
VectorCopy(owner->referenceInfo->references[refpt].placement.origin, org);
// Create a rotation matrix
Matrix3FromAngles(owner->lerp_angles, rotation);
Matrix3MultByVec3(rotation, org, handpt);
VectorAdd(handpt, owner->origin, handpt);
AngleVectors(owner->lerp_angles, NULL, right, NULL);
for(i = 0; i < num_parts; i++)
{
if(r_detail->value > DETAIL_LOW)
p = ClientParticle_new(wake_particle[irand(0, 5)], LightColor, irand(1000, 2000));
else
p = ClientParticle_new(wake_particle[irand(0, 5)]|PFL_SOFT_MASK, LightColor, irand(1000, 2000));
VectorSet(p->origin, flrand(-4, 4), flrand(-4, 4), flrand(-4, 4));
VectorAdd(handpt, p->origin, p->origin);
p->scale = flrand(0.75, 1.5);
p->color.a = irand(100, 200);
VectorSet(p->velocity, flrand(-2, 2), flrand(-2, 2), flrand(-2.0, 2.0));
if (irand(0, 1))
VectorMA(p->velocity, flrand(-10, -2), right, p->velocity);
else
VectorMA(p->velocity, flrand(10, 2), right, p->velocity);
p->acceleration[2] = 16;
// p->d_alpha = flrand(-3, -1);
p->d_scale = flrand(-0.15, -0.10);
AddParticleToList(self, p);
}
}
qboolean BubbleSpawner(client_entity_t *self, centity_t *owner)
{
vec3_t org;
@ -388,9 +458,24 @@ qboolean BubbleSpawner(client_entity_t *self, centity_t *owner)
VectorAdd(org, owner->origin, org);
MakeBubble(org, self);
// Create a wake of bubbles!
// ----------------------------------------------------
// This tells if we are wasting our time, because the reference points are culled.
if (r_detail->value < DETAIL_HIGH || !RefPointsValid(owner))
return false; // Remove the effect in this case.
DoWake(self, owner, CORVUS_RIGHTHAND);
DoWake(self, owner, CORVUS_LEFTHAND);
DoWake(self, owner, CORVUS_RIGHTFOOT);
DoWake(self, owner, CORVUS_LEFTFOOT);
VectorCopy(owner->origin, self->endpos);
return(true);
}
void FXWaterParticles(centity_t *owner, int type, int flags, vec3_t origin)
{
client_entity_t *effect;
@ -412,6 +497,7 @@ void FXWaterParticles(centity_t *owner, int type, int flags, vec3_t origin)
effect->AddToView = LinkedEntityUpdatePlacement;
effect->radius = 100.0;
effect->Update = BubbleSpawner;
VectorCopy(owner->origin, effect->endpos);
AddEffect(owner, effect);
}
@ -662,6 +748,131 @@ void FXLeader(centity_t *owner, int type, int flags, vec3_t origin)
}
#define FOOTTRAIL_RADIUS 2.0
#define FOOTTRAIL_SCALE 8.0
#define FOOTTRAIL_ACCEL 20.0
static qboolean FXFeetTrailThink(struct client_entity_s *self,centity_t *owner)
{
client_particle_t *flame;
int i;
vec3_t firestart, origin;
matrix3_t rotation;
int hand_flame_dur;
paletteRGBA_t color;
int count;
vec3_t curpos, diff;
// This tells if we are wasting our time, because the reference points are culled.
if (!RefPointsValid(owner))
return true;
// if we are ghosted, don't do the effect
if ((owner->current.renderfx & RF_TRANS_GHOST) || (owner->current.effects & EF_CLIENT_DEAD))
return(true);
if (!(owner->current.effects & EF_SPEED_ACTIVE))
{
self->Update=RemoveSelfAI;
self->updateTime = fxi.cl->time + 1500;
return true ;
}
// Let's take the origin and transform it to the proper coordinate offset from the owner's origin.
VectorCopy(owner->referenceInfo->references[self->refPoint].placement.origin, firestart);
// Create a rotation matrix
Matrix3FromAngles(owner->lerp_angles, rotation);
Matrix3MultByVec3(rotation, firestart, origin);
VectorAdd(origin, owner->origin, origin);
if (Vec3NotZero(self->origin))
{
// create small particles
count = GetScaledCount(5, 0.5);
VectorSubtract(self->origin, origin, diff);
Vec3ScaleAssign((1.0 / count), diff);
VectorClear(curpos);
if (r_detail->value < DETAIL_NORMAL)
hand_flame_dur = 1500;
else
hand_flame_dur = 2000;
for(i = 0; i < count; i++)
{
color.c = 0xffffff40;
flame = ClientParticle_new(PART_32x32_STEAM, color, hand_flame_dur);
VectorSet( flame->origin,
flrand(-FOOTTRAIL_RADIUS, FOOTTRAIL_RADIUS),
flrand(-FOOTTRAIL_RADIUS, FOOTTRAIL_RADIUS),
flrand(-FOOTTRAIL_RADIUS, FOOTTRAIL_RADIUS));
VectorAdd(flame->origin, self->origin, flame->origin);
VectorAdd(flame->origin, curpos, flame->origin);
flame->scale = FOOTTRAIL_SCALE;
VectorSet(flame->velocity, flrand(-5.0, 5.0), flrand(-5, 5.0), flrand(5.0, 15.0));
flame->acceleration[2] = FOOTTRAIL_ACCEL;
flame->d_scale = flrand(-10.0, -5.0);
flame->d_alpha = flrand(-200.0, -160.0);
flame->duration = (255.0 * 1000.0) / -flame->d_alpha; // time taken to reach zero alpha
AddParticleToList(self, flame);
Vec3SubtractAssign(diff, curpos);
}
}
VectorCopy(origin, self->origin);
return(true);
}
// ************************************************************************************************
// FXFeetTrail
// ------------
// ************************************************************************************************
void FXFeetTrail(centity_t *owner,int type,int flags,vec3_t origin)
{
short refpoints;
client_entity_t *trail;
int i;
int flame_dur;
refpoints=(1 << CORVUS_LEFTFOOT) | (1 << CORVUS_RIGHTFOOT);
VectorClear(origin);
if (r_detail->value > DETAIL_NORMAL)
flame_dur = 50;
else
flame_dur = 75;
// Add a fiery trail effect to the player's hands / feet etc.
for(i=0;i<16;i++)
{
if(!(refpoints & (1 << i)))
continue;
trail=ClientEntity_new(type,flags,origin,0,flame_dur);
VectorClear(trail->origin);
trail->Update=FXFeetTrailThink;
trail->flags|=CEF_NO_DRAW | CEF_OWNERS_ORIGIN | CEF_ABSOLUTE_PARTS;
trail->radius = 40;
trail->AddToView = LinkedEntityUpdatePlacement;
trail->refPoint = i;
trail->color.c = 0xe5007fff;
AddEffect(owner,trail);
}
}
// end

View file

@ -28,7 +28,7 @@ void FXCreateArmorHit(centity_t *owner,int Type,int Flags,vec3_t Origin)
vec3_t dir;
int i;
fxi.GetEffect(owner,Flags,"d", &dir);
fxi.GetEffect(owner,Flags,clientEffectSpawners[FX_ARMOR_HIT].formatString, &dir);
//Spawn a hit explosion of lines
i = GetScaledCount(6, 0.85);

View file

@ -6,9 +6,7 @@
// Heretic II
//
// #include <windows.h>
//#include <windows.h> // Debug only.
#include "Client Effects.h"
#include "FX.h"
@ -23,6 +21,12 @@
#include "Skeletons.h"
#include "q_Physics.h"
#include "g_playstats.h"
#include "qcommon.h"
///// IMPORTANT !!! THIS IS THE STRING THAT DETERMINES IF YOU CAN JOIN A SERVER - IE YOU HAVE THE RIGHT CLIENT EFFECTS DLL
char *client_string = {"Heretic II v1.06"};
client_fx_import_t fxi;
@ -44,8 +48,8 @@ cvar_t *crosshair;
cvar_t *compass;
int ref_soft;
int numprocessedparticles;
int numrenderedparticles;
int numprocessedparticles;
int numrenderedparticles;
qboolean fx_FreezeWorld=false;
@ -64,6 +68,7 @@ int GetLMIMax();
void AddServerEntities(frame_t *frame);
void ParseEffects(centity_t *cent);
void ClientStartClientEffect(centity_t *owner,unsigned short effect,int flags,int index,vec3_t position);
static void RemoveEffectsFromCent(centity_t *cent);
/*
@ -89,14 +94,16 @@ client_fx_export_t GetfxAPI (client_fx_import_t import)
export.RegisterSounds = RegisterSounds;
export.RegisterModels = RegisterModels;
// In the client code in the executable the following functions are called
// First
// In the client code in the executable the following functions are called first.
export.AddPacketEntities = AddServerEntities;
// Second
// Secondly....
export.AddEffects = AddEffects;
// Next (if any independent effects exist)
// Thirdly (if any independent effects exist).
export.ParseClientEffects = ParseEffects;
// Last
// Lastly.
export.UpdateEffects = PostRenderUpdate;
export.SetLightstyle = CL_SetLightstyle;
@ -106,6 +113,8 @@ client_fx_export_t GetfxAPI (client_fx_import_t import)
export.RemoveClientEffects = RemoveEffectsFromCent;
export.client_string = client_string;
return export;
}
@ -229,8 +238,10 @@ void AddEffects(qboolean freeze)
// Add all effects which are attatched to entities, that have no model.
for(i = 0, owner = fxi.server_entities; i < MAX_NETWORKABLE_EDICTS; ++i, ++owner) // gak, think something else need to be done
{ // maybe a list of centities with effects. . .
for(i = 0, owner = fxi.server_entities; i < MAX_NETWORKABLE_EDICTS; ++i, ++owner)
{
// gak, think something else need to be done... maybe a list of centities with effects.
if(owner->effects && (owner->current.effects & EF_ALWAYS_ADD_EFFECTS))
{
num_owned_inview += AddEffectsToView(&owner->effects, owner);
@ -285,13 +296,125 @@ void PostRenderUpdate(void)
}
}
int DummyEffectParams(centity_t *ent, int flags, int effect)
{
char current;
int count = 0;
vec3_t v;
sizebuf_t *msg_read;
sizebuf_t tempBuf;
EffectsBuffer_t *fxBuf;
char *format;
format=clientEffectSpawners[effect].formatString;
if(!format)
return(0);
//#if _DEVEL
#if 0
if(strcmp(format, fxi.Cvar_VariableString("cfxpl")))
{
Com_DPrintf("Parameter mismatch !!!!!!!!!\n");
assert(0);
}
#endif
if(ent && !(flags&(CEF_BROADCAST|CEF_MULTICAST)))
{
if(!(*fxi.cl_effectpredict))
fxBuf = &ent->current.clientEffects;
else
fxBuf = fxi.clientPredEffects;
msg_read = &tempBuf;
memset (msg_read, 0, sizeof(*msg_read));
msg_read->data = fxBuf->buf;
msg_read->cursize = msg_read->maxsize = fxBuf->bufSize;
msg_read->readcount = fxBuf->freeBlock;
}
else
{
msg_read = fxi.net_message;
}
assert(format);
assert(format[0]);
if(!format)
{
Com_Error(ERR_DROP, "CL_ReadEffect: null format string");
return 0;
}
while(current = format[count])
{
switch(current)
{
case 'b':
MSG_ReadByte(msg_read);
break;
case 's':
MSG_ReadShort(msg_read);
break;
case 'i':
MSG_ReadLong(msg_read);
break;
case 'f':
MSG_ReadFloat(msg_read);
break;
case 'p':
case 'v':
MSG_ReadPos(msg_read, v);
break;
case 'u':
MSG_ReadDirMag(msg_read, v);
break;
case 'd':
MSG_ReadDir(msg_read, v);
break;
case 'x':
MSG_ReadYawPitch(msg_read, v);
break;
case 't':
MSG_ReadShortYawPitch(msg_read, v);
break;
default:
assert(0);
return 0;
}
++count;
}
if(ent && !(flags&(CEF_BROADCAST|CEF_MULTICAST)))
{
fxBuf->freeBlock = msg_read->readcount;
}
return count;
}
/*
==============
ParseClientEffects
==============
*/
// Insert the logic in this could use a good cleaning. . .
void ParseEffects(centity_t *owner)
{
int i, index;
@ -303,19 +426,37 @@ void ParseEffects(centity_t *owner)
EffectsBuffer_t *fxBuf;
centity_t *tempOwner;
int last_effect = -1;
int eventId;
qboolean EffectIsFromServer;
tempOwner = owner;
if(owner)
{
fxBuf = &owner->current.clientEffects;
// Where do we pull the effect from?
if(!(*fxi.cl_effectpredict))
{
// Effects received as part of entity_state_t from server.
fxBuf = &owner->current.clientEffects;
}
else
{
// Predicted effects are pulled from here...
fxBuf=fxi.clientPredEffects;
// We are dealing with preicted effects, so reset freeblock for reading, as writing
// will have left it at the end of the written data.
fxBuf->freeBlock=0;
}
num = fxBuf->numEffects;
msg_read = &tempBuf;
memset (msg_read, 0, sizeof(*msg_read));
msg_read->data = fxBuf->buf;
msg_read->cursize = msg_read->maxsize = fxBuf->bufSize;
}
@ -336,13 +477,28 @@ void ParseEffects(centity_t *owner)
for(i = 0; i < num; ++i)
{
EffectIsFromServer=false;
if(owner)
{
msg_read->readcount = fxBuf->freeBlock;
}
effect = MSG_ReadShort(msg_read);
#if _DEVEL
if(effect&EFFECT_PRED_INFO)
{
// EFFECT_PRED_INFO bit if set (only on effects sent by server, never on predicted
// effects) indicates we should read a byte that uniquely identifies the client effect
// int the player code.
eventId=MSG_ReadByte(msg_read);
effect&=~EFFECT_PRED_INFO;
EffectIsFromServer=true;
}
//#if _DEVEL
#if 0
Cvar_Set("cfxpl", MSG_ReadString(msg_read));
#endif
if(effect & 0x8000)
@ -407,15 +563,32 @@ void ParseEffects(centity_t *owner)
return;
}
// Com_Printf("Client Effect %d unbuffered\n", effect);
if(owner && !(flags & (CEF_BROADCAST|CEF_MULTICAST)))
{
fxBuf->freeBlock = msg_read->readcount;
}
// Do we want to start this client-effect if client-prediction has already started it?
if((!(*fxi.cl_effectpredict))&&fxi.cl_predict->value&&EffectIsFromServer&&
(fxi.EffectEventIdTimeArray[eventId]<=*fxi.leveltime)&&(fxi.EffectEventIdTimeArray[eventId]!=0.0))
{
// The client-effect has already been started by client-prediction, so just skip it.
DummyEffectParams(owner,flags,effect);
goto SkipEffect;
}
// Start the client-effect.
clientEffectSpawners[effect].SpawnCFX(tempOwner, effect, flags, position);
SkipEffect:
if((EffectIsFromServer)&&(fxi.EffectEventIdTimeArray[eventId]<=*fxi.leveltime))
fxi.EffectEventIdTimeArray[eventId]=0.0;
if(flags & (CEF_BROADCAST|CEF_MULTICAST))
{
tempOwner = NULL;
@ -463,8 +636,12 @@ void AddServerEntities(frame_t *frame)
int numEntsToAdd;
vec3_t dist;
int maxclients = atoi(fxi.cl->configstrings[CS_MAXCLIENTS]);
clientinfo_t *ci;
int clientnum;
qboolean isPredictedPlayer;
// Have to do this here, since the init is loaded once, and the graphics dll might be reloaded.
// have to do this here, since the init is loaded once, and the graphics dll might be reloaded.
ref_soft = (strcmp("soft", vid_ref->string)) ? 0 : 1;
fxi.cl->PIV = 0;
@ -473,10 +650,12 @@ void AddServerEntities(frame_t *frame)
num_owned_inview = 0;
// Bonus items rotate at a fixed rate.
autorotate = anglemod(fxi.cl->time / 10.0);
macerotate = anglemod(fxi.cl->time / 700.0);
// Brush models can auto animate their frames.
autoanim = 2*fxi.cl->time/1000;
memset (sv_ents, 0, sizeof(sv_ents));
@ -495,23 +674,36 @@ void AddServerEntities(frame_t *frame)
cent = fxi.server_entities + s1->number;
// Setup skin and stuff.
cent->s1=s1;
if((fxi.cl_predict->value)&&(s1->number==fxi.cl->playernum+1))
{
// Prediction is active...
// We are dealing with the client's model under prediction.
effects = cent->Effects;
renderfx = cent->renderfx;
ent->skinnum = cent->skinnum;
isPredictedPlayer=true;
}
else
{
// Prediction is not active...
// We are dealing with a non predicted model (i.e. everything except the client's model).
isPredictedPlayer=false;
}
// Setup effects, renderfx, skinnum and clientnum stuff.
if(isPredictedPlayer)
{
cent->current.effects = effects = fxi.predictinfo->effects;
cent->current.renderfx = renderfx = fxi.predictinfo->renderfx;
ent->skinnum = fxi.predictinfo->skinnum;
clientnum = fxi.predictinfo->clientnum;
}
else
{
effects = s1->effects;
renderfx = s1->renderfx;
ent->skinnum = s1->skinnum;
clientnum = s1->clientnum;
}
// Set frame.
@ -527,28 +719,23 @@ void AddServerEntities(frame_t *frame)
ent->fmnodeinfo = sv_ents_fmnodeinfos[pnum];
if((fxi.cl_predict->value)&&(s1->number==fxi.cl->playernum+1))
if(isPredictedPlayer)
{
// Prediction is active.
memcpy(ent->fmnodeinfo,fxi.predictinfo->fmnodeinfo,sizeof(s1->fmnodeinfo));
}
else
{
// Prediction is not active.
memcpy(ent->fmnodeinfo,s1->fmnodeinfo,sizeof(s1->fmnodeinfo));
}
// What's going on here?
if((fxi.cl_predict->value)&&(s1->number==fxi.cl->playernum+1))
if(isPredictedPlayer)
{
// Deal with predicted origin.
ent->backlerp = 1.0 - cent->playerlerp;
ent->backlerp = 1.0 - fxi.predictinfo->playerLerp;
VectorCopy(cent->origin, ent->origin);
}
else
{
@ -563,6 +750,7 @@ void AddServerEntities(frame_t *frame)
VectorMA(cent->prev.origin, 1.0f - ent->backlerp, dist, ent->origin);
else
VectorCopy(cent->current.origin, ent->origin);
VectorCopy(ent->origin, cent->origin);
}
@ -571,12 +759,36 @@ void AddServerEntities(frame_t *frame)
// Set model.
ent->skin = NULL;
if (s1->modelindex == 255)
ent->model = fxi.cl->baseclientinfo.model;
{
// Use custom model and skin for player.
ci = &fxi.cl->clientinfo[clientnum];
ent->model = ci->model;
if (ent->skinnum < SKIN_MAX)
ent->skin = ci->skin[ent->skinnum];
else
ent->skin = ci->skin[0];
// To allow for mutliple skins on various parts, I'm going to send across a pointer to the whole skin array.
ent->skins = &ci->skin[0];
if (!ent->skin || !ent->model)
{
ent->model = fxi.cl->baseclientinfo.model;
if (ent->skinnum < SKIN_MAX)
ent->skin = fxi.cl->baseclientinfo.skin[ent->skinnum];
else
ent->skin = fxi.cl->baseclientinfo.skin[0];
}
}
else
{
ent->model = &fxi.cl->model_draw[s1->modelindex];
ent->skin = NULL; // No custom skin.
}
ent->scale = s1->scale;
@ -593,7 +805,7 @@ void AddServerEntities(frame_t *frame)
ent->absLight.g = s1->absLight.g;
ent->absLight.b = s1->absLight.b;
// Render effects (fullbright, translucent, etc).
// Set render effects (fullbright, translucent, etc).
ent->flags = renderfx;
@ -607,8 +819,7 @@ void AddServerEntities(frame_t *frame)
ent->angles[1] = macerotate;
ent->angles[2] = 0;
}
else
if (effects & EF_ROTATE)
else if (effects & EF_ROTATE)
{
// Some bonus items auto-rotate.
@ -622,22 +833,24 @@ void AddServerEntities(frame_t *frame)
float a1, a2;
if((fxi.cl_predict->value)&&(s1->number==fxi.cl->playernum+1))
if(isPredictedPlayer)
{
// Prediction is active and we are dealing with the player's entity. The corect angle
// values have already been generated by prediction and written into the player's centity_t.
// The corect angle values have already been generated by prediction and written
// into the client's predictinfo_t structure.
for (i=0 ; i<3 ; i++)
{
cent->current.angles[i] = fxi.predictinfo->currAngles[i];
cent->prev.angles[i] = fxi.predictinfo->prevAngles[i];
a1 = cent->current.angles[i];
a2 = cent->prev.angles[i];
ent->angles[i] = LerpAngle (a2, a1, cent->playerlerp);
ent->angles[i] = LerpAngle (a2, a1, fxi.predictinfo->playerLerp);
}
}
else
{
// Prediction is not active, so always get the angle values from the usual source, for
// all entities, including the player.
// Get the angle values from the usual source, for all entities, including the player.
for (i=0 ; i<3 ; i++)
{
@ -660,14 +873,18 @@ void AddServerEntities(frame_t *frame)
ent->rootJoint = NULL_ROOT_JOINT;
}
if((fxi.cl_predict->value)&&(s1->number==fxi.cl->playernum+1))
if(isPredictedPlayer)
{
// Prediction is active and we are dealing with the player's entity. The corect frame
// swapframe values have already been generated by prediction and written into the
// player's centity_t.
// The corect frame and swapframe values have already been generated by prediction
// and written into the client's predictinfo_t structure.
cent->prev.frame = fxi.predictinfo->prevFrame;
cent->current.frame = fxi.predictinfo->currFrame;
cent->prev.swapFrame = fxi.predictinfo->prevSwapFrame;
cent->current.swapFrame = fxi.predictinfo->currSwapFrame;
ent->oldframe = cent->prev.frame;
ent->frame=cent->current.frame;
ent->frame = cent->current.frame;
if((effects & EF_SWAPFRAME)&&(cent->current.swapFrame!=cent->current.frame))
{
@ -686,8 +903,8 @@ void AddServerEntities(frame_t *frame)
}
else
{
// Prediction is not active, so always get the frame and swapframe values from the usual
// source, for all entities, including the player.
// Always get the frame and swapframe values from the usual source, for all entities,
// including the player.
if((effects & EF_SWAPFRAME) && (s1->swapFrame != s1->frame))
{
@ -710,6 +927,7 @@ void AddServerEntities(frame_t *frame)
if(cent->current.clientEffects.numEffects)
{
*(fxi.cl_effectpredict)=0;
ParseEffects(cent);
}
@ -724,13 +942,36 @@ void AddServerEntities(frame_t *frame)
if(s1->number==fxi.cl->playernum+1)
{
if((fxi.cl_predict->value)&&(fxi.clientPredEffects->numEffects))
{
*(fxi.cl_effectpredict)=1;
ParseEffects(cent);
*(fxi.cl_effectpredict)=0;
}
// This is the player.
if (*(fxi.PlayerAlpha) < 1.0)
{
ent->color.a = (byte)(*(fxi.PlayerAlpha) * (float)(ent->color.a));
ent->flags |= RF_TRANSLUCENT;
}
else
{
// Color has already been copied from s1
// ent->color.a = 255;
ent->flags &= ~RF_TRANSLUCENT;
}
if(s1->modelindex)
{
AddEntityToView(ent);
}
*(fxi.PlayerEntPtr) = ent;
// So client effects can play with owners entity.
cent->entity = ent;
if(cent->effects && !(effects&(EF_DISABLE_ALL_CFX|EF_ALWAYS_ADD_EFFECTS)))

View file

@ -101,6 +101,7 @@ int AddParticlesToView(client_entity_t *ce)
int part_info;
float maxdepth2, mindepth2, depth;
int numparticles;
float yaw, pitch, radius;
assert(ce->p_root);
@ -117,7 +118,7 @@ int AddParticlesToView(client_entity_t *ce)
d_time = d_msec * 0.001f;
alpha = (int)current->color.a + Q_ftol(d_time * current->d_alpha);
if (alpha > 255 && (ce->flags & CEF_PULSE_ALPHA))
if (alpha > 255 && ((current->type & PFL_PULSE_ALPHA) || (ce->flags & CEF_PULSE_ALPHA)))
{ // PULSE ALPHA means that once alpha is at max, reverse and head back down.
alpha = 255 - (alpha - 255); // A weird thing to do, but necessary because the alpha is
// based off a dtime from the CREATION of the particle
@ -165,9 +166,44 @@ int AddParticlesToView(client_entity_t *ce)
}
else
{
r->origin[0] = ce->r.origin[0] + current->origin[0] + (current->velocity[0] * d_time) + (current->acceleration[0] * d_time2);
r->origin[1] = ce->r.origin[1] + current->origin[1] + (current->velocity[1] * d_time) + (current->acceleration[1] * d_time2);
r->origin[2] = ce->r.origin[2] + current->origin[2] + (current->velocity[2] * d_time) + (current->acceleration[2] * d_time2);
switch(current->type & PFL_MOVE_MASK)
{
case PFL_MOVE_SPHERE:
yaw = current->origin[SPH_YAW] + (current->velocity[SPH_YAW] * d_time) + (current->acceleration[SPH_YAW] * d_time2);
pitch = current->origin[SPH_PITCH] + (current->velocity[SPH_PITCH] * d_time) + (current->acceleration[SPH_YAW] * d_time2);
radius = current->origin[SPH_RADIUS] + (current->velocity[SPH_RADIUS] * d_time) + (current->acceleration[SPH_RADIUS] * d_time2);
r->origin[0] = ce->r.origin[0] + cos(yaw) * cos(pitch) * radius;
r->origin[1] = ce->r.origin[1] + sin(yaw) * cos(pitch) * radius;
r->origin[2] = ce->r.origin[2] + sin(pitch) * radius;
break;
case PFL_MOVE_CYL_X:
yaw = current->origin[CYL_YAW] + (current->velocity[CYL_YAW] * d_time) + (current->acceleration[CYL_YAW] * d_time2);
radius = current->origin[CYL_RADIUS] + (current->velocity[CYL_RADIUS] * d_time) + (current->acceleration[CYL_RADIUS] * d_time2);
r->origin[0] = ce->r.origin[0] + current->origin[CYL_Z] + (current->velocity[CYL_Z] * d_time) + (current->acceleration[CYL_Z] * d_time2);
r->origin[1] = ce->r.origin[1] + cos(yaw) * radius;
r->origin[2] = ce->r.origin[2] + sin(yaw) * radius;
break;
case PFL_MOVE_CYL_Y:
yaw = current->origin[CYL_YAW] + (current->velocity[CYL_YAW] * d_time) + (current->acceleration[CYL_YAW] * d_time2);
radius = current->origin[CYL_RADIUS] + (current->velocity[CYL_RADIUS] * d_time) + (current->acceleration[CYL_RADIUS] * d_time2);
r->origin[0] = ce->r.origin[0] + cos(yaw) * radius;
r->origin[1] = ce->r.origin[1] + current->origin[CYL_Z] + (current->velocity[CYL_Z] * d_time) + (current->acceleration[CYL_Z] * d_time2);
r->origin[2] = ce->r.origin[2] + sin(yaw) * radius;
break;
case PFL_MOVE_CYL_Z:
yaw = current->origin[CYL_YAW] + (current->velocity[CYL_YAW] * d_time) + (current->acceleration[CYL_YAW] * d_time2);
radius = current->origin[CYL_RADIUS] + (current->velocity[CYL_RADIUS] * d_time) + (current->acceleration[CYL_RADIUS] * d_time2);
r->origin[0] = ce->r.origin[0] + cos(yaw) * radius;
r->origin[1] = ce->r.origin[1] + sin(yaw) * radius;
r->origin[2] = ce->r.origin[2] + current->origin[CYL_Z] + (current->velocity[CYL_Z] * d_time) + (current->acceleration[CYL_Z] * d_time2);
break;
case PFL_MOVE_NORM:
default:
r->origin[0] = ce->r.origin[0] + current->origin[0] + (current->velocity[0] * d_time) + (current->acceleration[0] * d_time2);
r->origin[1] = ce->r.origin[1] + current->origin[1] + (current->velocity[1] * d_time) + (current->acceleration[1] * d_time2);
r->origin[2] = ce->r.origin[2] + current->origin[2] + (current->velocity[2] * d_time) + (current->acceleration[2] * d_time2);
break;
}
}
if(cull_parts || (current->type & PFL_NEARCULL))
@ -233,7 +269,7 @@ int UpdateParticles(client_entity_t *ce)
alpha = (int)current->color.a + Q_ftol(d_time * current->d_alpha);
if (alpha > 255 && (ce->flags & CEF_PULSE_ALPHA))
if (alpha > 255 && ((ce->flags & CEF_PULSE_ALPHA) || (current->type & PFL_PULSE_ALPHA)))
{ // PULSE ALPHA means that once alpha is at max, reverse and head back down.
alpha = 255 - (alpha - 255); // A weird thing to do, but necessary because the alpha is
// based off a dtime from the CREATION of the particle

View file

@ -128,11 +128,33 @@ typedef struct client_particle_s
//particle render flags, <127 is the type
#define PFL_FLAG_MASK 0x0000007f // Mask out any flags
// Move flags... Note, these are pretty much mutually exclusive.
#define PFL_MOVE_MASK 0x0f000000 // Check how the particles move
#define PFL_MOVE_CYL_X 0x01000000 // Cylindrical on the X axis Yaw, Radius, Z
#define PFL_MOVE_CYL_Y 0x02000000 // Cylindrical on the Y axis
#define PFL_MOVE_CYL_Z 0x04000000 // Cylindrical on the Z axis
#define PFL_MOVE_SPHERE 0x08000000 // Move using spherical coordinates. Pitch, Yaw, Radius
#define PFL_MOVE_NORM 0x00000000 // Move using normal cartesian coordinates. X, Y, Z
// Additional particle flags
#define PFL_PULSE_ALPHA 0x10000000 // If the alpha delta's to above 255, it "bounces" back down towards zero.
#define PFL_SOFT_MASK 0x20000000 // For defining single point particles in software (unused in gl - here to stop
// people using this bit)
#define PFL_ADDITIVE 0x40000000 // Particle is added to additive particle list
#define PFL_NEARCULL 0x80000000 // Force near culling
#define CYL_RADIUS 0 // These are used in the vectors for origin, velocity and acceleration in particles
#define CYL_YAW 1 // that use Cylindrical coordinates.
#define CYL_Z 2
#define SPH_RADIUS 0 // These are used in the vectors for origin, velocity and acceleration in particles
#define SPH_YAW 1 // that use Spherical coordinates.
#define SPH_PITCH 2
void InitParticleMngrMngr();
void ReleaseParticleMngrMngr();

View file

@ -41,7 +41,7 @@ qboolean PlayerFirstSeenInit(struct client_entity_s *self, centity_t *owner)
//if(compass->value)
// FXCompass(owner, FX_WATER_PARTICLES, 0, owner->origin);
FXCrosshair(owner, -1, 0, owner->origin);
FXCrosshair(owner, FX_CROSSHAIR, 0, owner->origin);
return(true);
}
@ -51,7 +51,6 @@ void FXPlayerPersistant(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *self;
vec_t gravity;
// FIXME : Comment this in when I can alter p_client.c
// I believe that gravity is contained somewhere in the player/client sturcture already -JKH
gravity = 675.0;

View file

@ -15,7 +15,7 @@ void FXTestBBox(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t loc[8];
int i, partid, max;
fxi.GetEffect(owner, flags, "fff", &radius, &bottom, &top);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_TEST_BBOX].formatString, &radius, &bottom, &top);
cent = ClientEntity_new(type, CEF_NO_DRAW | CEF_ADDITIVE_PARTS, origin, NULL, 15000);

View file

@ -557,7 +557,7 @@ float GetGravity()
qboolean RefPointsValid(centity_t *owner)
{
if (owner->referenceInfo==NULL ||
owner->renderfx & RF_IGNORE_REFS || // This one is necessary in case we're a chicken.
owner->current.renderfx & RF_IGNORE_REFS || // This one is necessary in case we're a chicken.
owner->referenceInfo->lastUpdate - fxi.cl->time > REF_MINCULLTIME)
return false;
else

View file

@ -0,0 +1,8 @@
// cl_fx.c -- entity effects parsing and management
#include "client.h"

View file

@ -104,7 +104,7 @@ void FXAmmoPickup(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *ce;
byte tag;
fxi.GetEffect(owner, flags, "b", &tag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_PICKUP_AMMO].formatString, &tag);
flags &= ~CEF_OWNERS_ORIGIN;
ce = ClientEntity_new(type, flags | CEF_DONT_LINK | CEF_CHECK_OWNER | CEF_VIEWSTATUSCHANGED, origin, NULL, 50);

View file

@ -24,8 +24,8 @@
#define NUM_DEF_PICKUP_SPARKS 4
#define EGG_TRAIL_DELAY 100
#define EGG_RADIUS 10.0
#define NUM_ITEMDEFENSE 10
#define SPARK_OFFSET 5
#define NUM_ITEMDEFENSE 12
#define SPARK_OFFSET 6
#define EGG_INTENSITY 255
static struct model_s *defense_models[NUM_ITEMDEFENSE];
@ -36,20 +36,19 @@ void PreCacheItemDefense()
defense_models[2] = fxi.RegisterModel("models/items/defense/polymorph/tris.fm"); // ITEM_DEFENSE_POLYMORPH
defense_models[3] = fxi.RegisterModel("models/items/defense/teleport/tris.fm"); // ITEM_DEFENSE_TELEPORT
defense_models[4] = fxi.RegisterModel("models/items/defense/lightshield/tris.fm"); // ITEM_DEFENSE_SHIELD
defense_models[5] = fxi.RegisterModel("sprites/spells/spark_cyan.sp2"); // cyan spark
defense_models[6] = fxi.RegisterModel("sprites/spells/meteorbarrier.sp2"); // Meteor cloud
defense_models[7] = fxi.RegisterModel("sprites/spells/spark_green.sp2"); // green spark
defense_models[8] = fxi.RegisterModel("sprites/spells/spark_red.sp2"); // red spark
defense_models[9] = fxi.RegisterModel("sprites/spells/spark_blue.sp2"); // blue spark
defense_models[5] = fxi.RegisterModel("models/items/defense/tornado/tris.fm"); // ITEM_DEFENSE_TORNADO
defense_models[6] = fxi.RegisterModel("sprites/spells/spark_cyan.sp2"); // cyan spark
defense_models[7] = fxi.RegisterModel("sprites/spells/meteorbarrier.sp2"); // Meteor cloud
defense_models[8] = fxi.RegisterModel("sprites/spells/spark_green.sp2"); // green spark
defense_models[9] = fxi.RegisterModel("sprites/spells/spark_red.sp2"); // red spark
defense_models[10] = fxi.RegisterModel("sprites/spells/spark_blue.sp2"); // blue spark
defense_models[11] = fxi.RegisterModel("sprites/spells/spark_blue.sp2"); // blue spark
}
static qboolean FXEggSparkThink(struct client_entity_s *shield,centity_t *owner)
{
vec3_t angvect;
// client_particle_t *spark;
// int part;
// paletteRGBA_t color;
vec3_t origin = {0,0,0};
VectorCopy(shield->origin, origin);
@ -87,7 +86,7 @@ void FXDefensePickup(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *ce;
byte tag;
fxi.GetEffect(owner, flags, "b", &tag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_PICKUP_DEFENSE].formatString, &tag);
flags &= ~CEF_OWNERS_ORIGIN;
ce = ClientEntity_new(type, flags | CEF_DONT_LINK | CEF_CHECK_OWNER | CEF_VIEWSTATUSCHANGED, origin, NULL, 50);
@ -108,7 +107,7 @@ void FXDefensePickup(centity_t *owner, int type, int flags, vec3_t origin)
// if we are looking at the polymorph egg, put a special effect around it
// stolen wholesale from Pats Shield Effect. Cheers Pat.
if (tag < 5)
if (tag < SPARK_OFFSET)
{
client_entity_t *shield;
int i;
@ -159,7 +158,6 @@ void FXDefensePickup(centity_t *owner, int type, int flags, vec3_t origin)
shield->lastThinkTime = fxi.cl->time;
AngleVectors(shield->direction, angvect, NULL, NULL);
// VectorMA(shield->origin, shield->radius, angvect, shield->r.origin);
AddEffect(owner, shield);
}

View file

@ -168,7 +168,7 @@ void FXDripper(centity_t *Owner, int Type, int Flags, vec3_t Origin)
byte dripspermin, frame;
trace_t trace;
fxi.GetEffect(Owner, Flags, "bb", &dripspermin, &frame);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_DRIPPER].formatString, &dripspermin, &frame);
Flags |= CEF_NO_DRAW | CEF_NOMOVE | CEF_VIEWSTATUSCHANGED;
dripper = ClientEntity_new(Type, Flags, Origin, NULL, 1000);

View file

@ -69,7 +69,7 @@ void FXWaterfallBase(centity_t *owner, int type, int flags, vec3_t origin)
byte xs, ys, yaw;
client_entity_t *wfb;
fxi.GetEffect(owner, flags, "bbb", &xs, &ys, &yaw);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WATERFALLBASE].formatString, &xs, &ys, &yaw);
flags |= CEF_NO_DRAW | CEF_NOMOVE | CEF_VIEWSTATUSCHANGED;
wfb = ClientEntity_new(type, flags, origin, NULL, 100);
@ -152,7 +152,7 @@ void FXFountain(centity_t *Owner, int Type, int Flags, vec3_t Origin)
else
fountain = ClientEntity_new(Type, Flags, Origin, NULL, 90);
fxi.GetEffect(Owner, Flags, "vsb", &fountain->direction, &drop, &frame);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_FOUNTAIN].formatString, &fountain->direction, &drop, &frame);
fountain->r.frame = frame;

View file

@ -40,7 +40,7 @@ void FXHellbolt(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *hellbolt;
paletteRGBA_t lightcolor = {255, 128, 64, 255};
fxi.GetEffect(owner, flags, "t", vel);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_HELLBOLT].formatString, vel);
if (flags & CEF_FLAG6)
Vec3ScaleAssign(HELLBOLT_SPEED/2,vel);
@ -102,7 +102,7 @@ void FXHellboltExplode(centity_t *owner, int type, int flags, vec3_t origin)
{
vec3_t Dir;
fxi.GetEffect(owner, flags, "d", Dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_HELLBOLTEXPLODE].formatString, Dir);
Vec3ScaleAssign(32.0, Dir);
@ -160,7 +160,7 @@ void FXHellstaffPowerBurn(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t angles, fwd, right, up, dir;
VectorClear(angles);
fxi.GetEffect(owner, flags, "t", &dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_HELLSTAFF_POWER_BURN].formatString, &dir);
vectoangles(dir, angles);
angles[PITCH] *= -1;// something's broken with angle signs somewhere ;(
@ -184,7 +184,7 @@ void FXHellstaffPower(centity_t *owner,int type,int flags, vec3_t origin)
byte blen;
VectorClear(angles);
fxi.GetEffect(owner,flags,"tb", &dir, &blen);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_WEAPON_HELLSTAFF_POWER].formatString, &dir, &blen);
vectoangles(dir, angles);
angles[PITCH] *= -1;// something's broken with angle signs somewhere ;(
len = (float)blen * 8.0;

View file

@ -88,7 +88,7 @@ void FXMaceballBounce(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t norm, up, right, lastvel;
float curyaw;
fxi.GetEffect(owner, flags, "d", norm);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_MACEBALLBOUNCE].formatString, norm);
color.c = 0xffffffff;
@ -189,7 +189,7 @@ void FXMaceballExplode(centity_t *owner,int type,int flags,vec3_t origin)
int i;
vec3_t mins={BALL_RADIUS, BALL_RADIUS, BALL_RADIUS};
fxi.GetEffect(owner,flags,"d",dir);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_WEAPON_MACEBALLEXPLODE].formatString,dir);
// Create an expanding ball of gre.
@ -304,7 +304,7 @@ void FXRipperExplode(centity_t *owner, int type, int flags, vec3_t origin)
client_particle_t *spark;
fxi.GetEffect(owner, flags, "vbssssssss",
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_RIPPEREXPLODE].formatString,
casterpos,
&byaw,
&ballarray[0],

View file

@ -116,7 +116,7 @@ void FXMorphMissile(centity_t *owner, int type, int flags, vec3_t origin)
byte blah,pitch;
// get the initial Yaw
fxi.GetEffect(owner, flags, "bb", &blah,&pitch);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_SPELL_MORPHMISSILE].formatString, &blah,&pitch);
// create the client effect with the light on it
missile = ClientEntity_new(type, flags | CEF_DONT_LINK, origin, NULL, 100);
@ -153,7 +153,7 @@ void FXMorphMissile_initial(centity_t *owner, int type, int flags, vec3_t origin
int i;
// get the initial Yaw
fxi.GetEffect(owner, flags, "bssssss",
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_SPELL_MORPHMISSILE_INITIAL].formatString,
&yaw,
&morpharray[0],
&morpharray[1],
@ -219,7 +219,7 @@ void FXMorphExplode(centity_t *owner, int type, int flags, vec3_t origin)
int i, count, dur;
float max_rand;
fxi.GetEffect(owner,flags,"d",Dir);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_SPELL_MORPHEXPLODE].formatString,Dir);
// make a bunch of small particles explode out the wall / object
VectorScale(Dir,SMOKE_SPEED,Dir);

View file

@ -193,7 +193,7 @@ void FXPhoenixMissile(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t temp;
missile = ClientEntity_new(type, flags | CEF_DONT_LINK, origin, NULL, 25);
fxi.GetEffect(owner, flags, "t", missile->velocity);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_PHOENIXMISSILE].formatString, missile->velocity);
if (flags & CEF_FLAG8)
Vec3ScaleAssign(PHOENIX_ARROW_SPEED/2,missile->velocity);
@ -346,7 +346,7 @@ void FXPhoenixExplode(centity_t *owner, int type, int flags, vec3_t origin)
float ballnum;
int count, dur;
fxi.GetEffect(owner,flags,"td",dir,sdir);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_WEAPON_PHOENIXEXPLODE].formatString,dir,sdir);
// make the scorch mark if we should
if(flags & CEF_FLAG8)

View file

@ -90,7 +90,7 @@ void FXPlagueMist(centity_t *Owner, int Type, int Flags, vec3_t Origin)
mist_think_time = 150;
pm = ClientEntity_new(Type, Flags, Origin, NULL, mist_think_time);
fxi.GetEffect(Owner, Flags, "vb", pm->direction, &lifetime);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_PLAGUEMIST].formatString, pm->direction, &lifetime);
pm->LifeTime = lifetime * 50;
pm->Update = FXPlagueMistParticleSpawner;

View file

@ -101,7 +101,7 @@ void FXPlagueMistExplode(centity_t *Owner, int Type, int Flags, vec3_t Origin)
Flags = (Flags & ~CEF_OWNERS_ORIGIN) | CEF_NOMOVE | CEF_NO_DRAW;
spawner = ClientEntity_new(Type, Flags, Origin, NULL, mist_think_time);
fxi.GetEffect(Owner, Flags, "b", &lifetime);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_PLAGUEMISTEXPLODE].formatString, &lifetime);
spawner->LifeTime = lifetime * mist_life;
spawner->radius = 20.0F;
spawner->Update = FXPlagueMistExplodeSpawn;

View file

@ -292,7 +292,7 @@ void FXRedRainMissile(centity_t *Owner, int Type, int Flags, vec3_t Origin)
dur = 100;
missile = ClientEntity_new(Type, Flags | CEF_DONT_LINK, Origin, NULL, dur);
fxi.GetEffect(Owner, Flags, "t", missile->velocity);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_WEAPON_REDRAINMISSILE].formatString, missile->velocity);
if (Flags & CEF_FLAG7)
{

View file

@ -442,9 +442,15 @@ static qboolean FXFireWaveThink(client_entity_t *wall, centity_t *owner)
void FXFireWave(centity_t *owner, int type, int flags, vec3_t origin)
{
client_entity_t *wall;
short shortyaw,shortpitch;
wall = ClientEntity_new(type, flags | CEF_NO_DRAW | CEF_DONT_LINK, origin, NULL, 150);
fxi.GetEffect(owner, flags, "ff", &wall->r.angles[YAW], &wall->r.angles[PITCH]);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_WEAPON_FIREWAVE].formatString, &shortyaw, &shortpitch);
wall->r.angles[YAW]=(float)shortyaw * (360.0/65536.0);
wall->r.angles[PITCH]=(float)shortpitch * (360.0/65536.0);
wall->r.angles[ROLL]=0.0;
AngleVectors(wall->r.angles, wall->direction, wall->right, NULL);
if (flags & CEF_FLAG8) // Since we're in deathmatch, throw it faster.
@ -499,7 +505,7 @@ void FXFireWaveWorm(centity_t *owner, int type, int flags, vec3_t origin)
break;
}
fxi.GetEffect(owner, flags, "t", fwd); // Gets the movedir of the wall.
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_FIREWAVEWORM].formatString, fwd); // Gets the movedir of the wall.
// Trace back half a second and get the proper spawn location.
VectorMA(origin, -0.5*FIREWORM_LIFETIME*FIREWAVE_SPEED, fwd, spawnpt);
@ -716,9 +722,14 @@ void FXFireBurst(centity_t *owner, int type, int flags, vec3_t origin)
client_particle_t *spark;
vec3_t fwd;
int i;
short shortyaw,shortpitch;
wall = ClientEntity_new(type, flags | CEF_NO_DRAW | CEF_ADDITIVE_PARTS | CEF_ABSOLUTE_PARTS | CEF_DONT_LINK, origin, NULL, 150);
fxi.GetEffect(owner, flags, "ff", &wall->r.angles[YAW], &wall->r.angles[PITCH]);
fxi.GetEffect(owner,flags,clientEffectSpawners[FX_WEAPON_FIREBURST].formatString, &shortyaw, &shortpitch);
wall->r.angles[YAW]=(float)shortyaw * (360.0/65536.0);
wall->r.angles[PITCH]=(float)shortpitch * (360.0/65536.0);
wall->r.angles[ROLL]=0.0;
// The Build the velocity out of the fwd vector constructed from the two angles given.
AngleVectors(wall->r.angles, fwd, wall->right, NULL);

View file

@ -59,7 +59,7 @@ static qboolean FXWeaponPickupThink(struct client_entity_s *self, centity_t *own
color.c = 0xff0000ff;
break;
case 1: // Magic Missile
part = PART_16x16_SPARK_G;
part = PART_16x16_SPARK_I;
color.c = 0xff00ff00;
break;
case 2: // Red rain bow
@ -108,7 +108,7 @@ void FXWeaponPickup(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *ce;
byte tag;
fxi.GetEffect(owner, flags, "b", &tag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_PICKUP_WEAPON].formatString, &tag);
flags &= ~CEF_OWNERS_ORIGIN;
ce = ClientEntity_new(type, flags | CEF_DONT_LINK | CEF_CHECK_OWNER | CEF_ADDITIVE_PARTS | CEF_VIEWSTATUSCHANGED, origin, NULL, 50);

View file

@ -90,7 +90,7 @@ void FXAnimate(centity_t *owner, int type, int flags, vec3_t origin)
self = ClientEntity_new(type, flags, origin, 0, 100);
fxi.GetEffect(owner, flags, "bbbv", &anim, &scale, &skinnum, self->r.angles);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_ANIMATE].formatString, &anim, &scale, &skinnum, self->r.angles);
VectorDegreesToRadians(self->r.angles, self->r.angles);
atype = anim & 0x7f;

View file

@ -464,7 +464,7 @@ void FXBloodTrail(centity_t *owner, int type, int flags, vec3_t origin)
{
vec3_t normal;
fxi.GetEffect(owner, flags, "d", &normal);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_BLOOD_TRAIL].formatString, &normal);
VectorMA(origin, 0.25, normal, origin);
ThrowBlood(origin, normal, flags&CEF_FLAG7, flags&CEF_FLAG6, true);
@ -478,7 +478,7 @@ void FXBlood(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t velocity;
qboolean yellow_blood = false;
fxi.GetEffect(owner, flags, "ub", &velocity, &amount);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_BLOOD].formatString, &velocity, &amount);
if(flags&CEF_FLAG8)
yellow_blood = true;
@ -570,7 +570,7 @@ void FXLinkedBlood(centity_t *owner, int type, int flags, vec3_t origin)
int count, i;
int lifetime = 0;
fxi.GetEffect(owner, flags, "bb", &life, &refpointidx);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_LINKEDBLOOD].formatString, &life, &refpointidx);
lifetime = life * 50;
count = 1;
if(life > 1600)

View file

@ -105,7 +105,7 @@ void FXBubbler(centity_t *Owner, int Type, int Flags, vec3_t Origin)
time = GetTimeToReachDistance(0, 100, abs(dist));
fxi.GetEffect(Owner, Flags, "b", &bubblespermin );
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_BUBBLER].formatString, &bubblespermin );
Flags |= CEF_NO_DRAW | CEF_NOMOVE | CEF_CULLED | CEF_VIEWSTATUSCHANGED |CEF_CHECK_OWNER;
self = ClientEntity_new(Type, Flags, Origin, NULL, 1000);

View file

@ -140,7 +140,7 @@ void FXCWatcherEffects(centity_t *owner, int type, int flags, vec3_t origin)
byte fxID;
int i;
fxi.GetEffect(owner, flags, "bv", &fxID, &vel);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_CWATCHER].formatString, &fxID, &vel);
switch (fxID)
{

View file

@ -276,7 +276,7 @@ void FXBodyPart(centity_t *owner,int type, int flags, vec3_t origin)
float ke;
//increase count on owner so that can have multiple effects?
fxi.GetEffect(owner, flags, "ssbbb", &frame, &BodyPart, &damage, &modelindex, &OwnerEntnum);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_BODYPART].formatString, &frame, &BodyPart, &damage, &modelindex, &OwnerEntnum);
realowner = &fxi.server_entities[OwnerEntnum];
@ -329,9 +329,15 @@ static void FXBodyPart_Throw(centity_t *owner, int BodyPart, vec3_t origin, floa
debris->classID = CID_DEBRIS;
debris->msgHandler = CE_DefaultMsgHandler;
if(modelindex == 255)//FIXME: these will tilt up and down with the player's torso!!!
debris->r.model = fxi.cl->baseclientinfo.model;
{ // Player special model.
debris->r.model = fxi.cl->clientinfo[owner->baseline.number-1].model;
if (!debris->r.model)
debris->r.model = fxi.cl->baseclientinfo.model;
}
else
{
debris->r.model = &fxi.cl->model_draw[modelindex];
}
debris->r.fmnodeinfo = FMNodeInfo_new();
debris->r.frame = frame;//first frame should be parts frame of a flexmodel
//need to copy base skin also
@ -670,7 +676,7 @@ void FXDebris(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t dir, mins;
float ke, scale;
fxi.GetEffect(owner, flags, "bbdb", &size, &material, mins, &mag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_DEBRIS].formatString, &size, &material, mins, &mag);
scale = size * 10;
VectorSet(dir, 0.0, 0.0, 1.0);
@ -712,7 +718,7 @@ void FXFleshDebris(centity_t *owner, int type, int flags, vec3_t origin)
else
material = MAT_FLESH;
fxi.GetEffect(owner, flags, "bdb", &size, mins, &mag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_FLESH_DEBRIS].formatString, &size, mins, &mag);
VectorSet(dir, 0.0, 0.0, 1.0);
Vec3ScaleAssign(mag, mins);

View file

@ -100,7 +100,7 @@ void FXDust(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t size;
client_entity_t *ce;
fxi.GetEffect(owner, flags, "bdb", &num, size, &mag);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_DUST].formatString, &num, size, &mag);
ce = ClientEntity_new(-1, CEF_NOMOVE | CEF_NO_DRAW, origin, NULL, 100);
VectorScale(size, mag, ce->startpos);

View file

@ -149,7 +149,7 @@ void FXFire(centity_t *owner, int type, int flags, vec3_t origin)
spawner = ClientEntity_new(type, flags, origin, NULL, 17);
fxi.GetEffect(owner, flags, "b", &scale);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_FIRE].formatString, &scale);
spawner->r.scale = scale / 32.0;
spawner->r.flags |= RF_FULLBRIGHT|RF_TRANSLUCENT|RF_TRANS_ADD|RF_TRANS_ADD_ALPHA;
@ -178,7 +178,7 @@ qboolean FXFireOnEntityThink(client_entity_t *spawner, centity_t *owner)
VectorCopy(owner->origin, spawner->origin);
VectorCopy(owner->origin, spawner->r.origin);
if ((owner->current.effects & EF_MARCUS_FLAG1) && (spawner->nextEventTime - fxi.cl->time >= 1000))
if (!(owner->current.effects & EF_ON_FIRE) && (spawner->nextEventTime - fxi.cl->time >= 1000))
{ // Set up the fire to finish early.
spawner->nextEventTime = fxi.cl->time + 999;
spawner->dlight->d_intensity = -200;
@ -262,7 +262,7 @@ qboolean FXFireOnEntity2Think(client_entity_t *spawner, centity_t *owner)
else if (spawner->nextEventTime - fxi.cl->time < 1000)
return (true); // Let the flames finish.
if (owner->current.effects & EF_MARCUS_FLAG1 && spawner->nextEventTime-fxi.cl->time >= 1000)
if (!(owner->current.effects & EF_ON_FIRE) && spawner->nextEventTime-fxi.cl->time >= 1000)
{
spawner->nextEventTime = fxi.cl->time + 999;
spawner->dlight->d_intensity = -200;
@ -279,7 +279,7 @@ qboolean FXFireOnEntity2Think(client_entity_t *spawner, centity_t *owner)
flame = ClientParticle_new(irand(PART_32x32_FIRE0, PART_32x32_FIRE2) | PFL_NEARCULL, spawner->color, 1000);
radius = spawner->r.scale * FIRE_SPAWN_RADIUS;
VectorSet(flame->origin, flrand(-radius, radius), flrand(-radius, radius), flrand(-16.0F, -8.0F) * spawner->r.scale);
VectorSet(flame->origin, flrand(-radius, radius), flrand(-radius, radius), flrand(-8.0F, 0.0F) * spawner->r.scale);
// If dead, then move the flame down a tad.
if(owner->current.effects&EF_DISABLE_EXTRA_FX)
{
@ -309,7 +309,7 @@ void FXFireOnEntity(centity_t *owner, int type, int flags, vec3_t origin)
byte lifetime;
byte style;
fxi.GetEffect(owner, flags, "bbb", &scale, &lifetime, &style);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_FIRE_ON_ENTITY].formatString, &scale, &lifetime, &style);
spawner = ClientEntity_new(type, flags, origin, NULL, 17);

View file

@ -35,18 +35,30 @@ static qboolean FXFireHandsThink(struct client_entity_s *self,centity_t *owner)
matrix3_t rotation;
int hand_flame_dur;
// If we've timed out, stop the effect (allow for fading)
if (self->LifeTime > 0)
{
if (self->LifeTime < fxi.cl->time)
{ // Lifetime is up
self->Update=RemoveSelfAI;
self->updateTime = fxi.cl->time + 500;
return true;
}
}
else
{ // If we're not on a time limit, check the EF flag
if (!(owner->current.effects & EF_TRAILS_ENABLED))
{
self->Update=RemoveSelfAI;
self->updateTime = fxi.cl->time + 500;
return true;
}
}
// This tells if we are wasting our time, because the reference points are culled.
if (!RefPointsValid(owner))
return false; // Remove the effect in this case.
// If we've timed out, stop the effect (allow for fading)
if ( (self->LifeTime > 0) && (self->LifeTime < fxi.cl->time) )
{
self->Update=RemoveSelfAI;
self->updateTime = fxi.cl->time + 500;
return true;
}
VectorCopy(owner->origin, self->r.origin);
// Let's take the origin and transform it to the proper coordinate offset from the owner's origin.
@ -97,7 +109,7 @@ void FXFireHands(centity_t *owner,int type,int flags,vec3_t origin)
refpoints=0;
fxi.GetEffect(owner, flags, "b", &lifetime);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_FIREHANDS].formatString, &lifetime);
if (flags & CEF_FLAG6)
refpoints=(1 << CORVUS_LEFTHAND) | (1 << CORVUS_RIGHTHAND);

View file

@ -146,7 +146,7 @@ void FXFlamethrower(centity_t *owner, int type, int flags, vec3_t origin)
vec3_t dir;
client_entity_t *glow;
fxi.GetEffect(owner, flags, "df", &dir, &distance);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_FLAMETHROWER].formatString, &dir, &distance);
// create the dummy entity, so particles can be attached
glow = ClientEntity_new(type, (flags | CEF_NO_DRAW | CEF_ADDITIVE_PARTS) , origin, 0, 17);

View file

@ -114,7 +114,7 @@ void FXFlyingFist(centity_t *owner, int type, int flags, vec3_t origin)
paletteRGBA_t LightColor;
float lightsize;
fxi.GetEffect(owner, flags, "t", vel);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_FLYINGFIST].formatString, vel);
if (flags & CEF_FLAG6)
Vec3ScaleAssign(FLYING_FIST_SPEED/2,vel);
else
@ -174,7 +174,7 @@ void FXFlyingFistExplode(centity_t *owner,int type,int flags,vec3_t origin)
float blastvel;
float volume=1.0;
fxi.GetEffect(owner, flags, "d", dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_FLYINGFISTEXPLODE].formatString, dir);
if(flags & CEF_FLAG6)
{

View file

@ -42,7 +42,7 @@ void FXLightningHit(centity_t *owner, int type, int flags, vec3_t origin)
client_particle_t *spark;
int i;
fxi.GetEffect(owner, flags, "t", dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_LIGHTNING_HIT].formatString, dir);
Vec3ScaleAssign(LIGHTNING_VEL*0.25, dir);
@ -67,9 +67,9 @@ void FXLightningHit(centity_t *owner, int type, int flags, vec3_t origin)
blast->r.flags |= RF_TRANS_ADD | RF_TRANS_ADD_ALPHA | RF_TRANSLUCENT; // |
blast->r.frame = 1;
blast->radius = 64.0;
blast->r.scale=1.5;
blast->r.scale=1.0;
blast->d_alpha=-4.0;
blast->d_scale=-4.0;
blast->d_scale=-2.0;
fxi.S_StartSound(blast->r.origin, -1, CHAN_WEAPON, fxi.S_RegisterSound("weapons/HellHit.wav"), 1, ATTN_NORM, 0);
blast->dlight = CE_DLight_new(color, 75.0f, 0.0f);
VectorClear(blast->velocity);

View file

@ -648,7 +648,7 @@ void FXHPMissile(centity_t *Owner,int Type,int Flags,vec3_t Origin)
int bends, i, bolts, j;
fxi.GetEffect(Owner, Flags, "vb", &vel, &effectType);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_HP_MISSILE].formatString, &vel, &effectType);
switch ( effectType )
{
@ -1156,7 +1156,7 @@ void FXHPStaff(centity_t *Owner,int Type,int Flags,vec3_t Origin)
short entID;
byte type;
fxi.GetEffect(Owner, Flags, "bs", &type, &entID);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_HP_STAFF].formatString, &type, &entID);
switch (type)
{

View file

@ -950,7 +950,7 @@ void FXIEffects(centity_t *owner,int type,int flags, vec3_t origin)
vec3_t vel;
byte fx_index;
fxi.GetEffect(owner, flags, "bv", &fx_index, &vel);//fixme- make this 1 dir and 1 float
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_I_EFFECTS].formatString, &fx_index, &vel);//fixme- make this 1 dir and 1 float
switch (fx_index)
{

View file

@ -305,15 +305,15 @@ float flare_scale[] = {2, 1.75, 1.5, 1.25, 1.5, 1.75, 2, 2 };
void FXLensFlare(centity_t *owner,int Type,int Flags,vec3_t Origin)
{
int Count,I;
int Count, I;
client_entity_t *Explosion;
int useOther, lifeTime;
int useOther;
float alpha;
paletteRGBA_t tint;
Count = 7;
fxi.GetEffect(owner, Flags, "ibbbf", &lifeTime, &tint.r, &tint.g, &tint.b, &alpha);
fxi.GetEffect(owner, Flags, clientEffectSpawners[FX_LENSFLARE].formatString, &tint.r, &tint.g, &tint.b, &alpha);
// no lens flares in low detail
if(r_detail->value <= DETAIL_NORMAL)
@ -372,8 +372,9 @@ void FXLensFlare(centity_t *owner,int Type,int Flags,vec3_t Origin)
break;
}
if (lifeTime > 0)
Explosion->LifeTime = (lifeTime*1000)+fxi.cl->time;
if (Flags & CEF_FLAG8)
Explosion->LifeTime = 4000 + fxi.cl->time;
Explosion->r.flags|=RF_FULLBRIGHT|RF_TRANSLUCENT|RF_TRANS_ADD|RF_TRANS_ADD_ALPHA|RF_NODEPTHTEST;
Explosion->Scale=flare_scale[I];

View file

@ -194,7 +194,7 @@ void FXLightning(centity_t *Owner, int Type, int Flags, vec3_t Origin)
byte width, duration;
client_entity_t *lightning;
fxi.GetEffect(Owner, Flags, "vbb", target, &width, &duration);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_LIGHTNING].formatString, target, &width, &duration);
if (duration > 1) // duration is in 1/10 of a second
{ // Create a client effect to zap over time.
@ -237,7 +237,7 @@ void FXPowerLightning(centity_t *Owner, int Type, int Flags, vec3_t Origin)
float curang, degreeinc;
vec3_t lastvel, upvel;
fxi.GetEffect(Owner, Flags, "vb", target, &width);
fxi.GetEffect(Owner, Flags, clientEffectSpawners[FX_POWER_LIGHTNING].formatString, target, &width);
VectorSubtract(target, Origin, diffpos);
length = VectorLength(diffpos);

View file

@ -151,7 +151,7 @@ void FXMagicMissile(centity_t *Owner,int Type,int Flags,vec3_t Origin)
vec3_t fwd, up, right;
short shortyaw, shortpitch;
fxi.GetEffect(Owner,Flags,"ss", &shortyaw, &shortpitch);
fxi.GetEffect(Owner,Flags,clientEffectSpawners[FX_WEAPON_MAGICMISSILE].formatString, &shortyaw, &shortpitch);
ang[YAW]=(float)shortyaw * (360.0/65536.0);
ang[PITCH]=(float)shortpitch * (360.0/65536.0);
@ -201,7 +201,7 @@ void FXMagicMissileExplode(centity_t *owner, int type, int flags, vec3_t origin)
int i;
paletteRGBA_t lightcolor = {0, 128, 128, 255};
fxi.GetEffect(owner, flags, "d", dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_MAGICMISSILEEXPLODE].formatString, dir);
if(flags & CEF_FLAG6)
{
FXClientScorchmark(origin, dir);
@ -269,7 +269,7 @@ void FXBlast(centity_t *owner, int type, int flags, vec3_t origin)
// Sends over the network 7 shorts and an origin.
// Note that this is a vast improvement over five seperate effects with a vector each (60 bytes+origins)
fxi.GetEffect(owner, flags, "sssssss", &syaw, &spitch, &slength[0], &slength[1], &slength[2], &slength[3], &slength[4]);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_WEAPON_BLAST].formatString, &syaw, &spitch, &slength[0], &slength[1], &slength[2], &slength[3], &slength[4]);
// Compress the angles into two shorts.
angles[YAW] = (float)syaw*(360.0/65536.0);

View file

@ -163,7 +163,7 @@ void FXMeteorBarrierExplode(centity_t *owner, int type, int flags, vec3_t origin
int count;
client_particle_t *ce;
fxi.GetEffect(owner, flags, "d", dir);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_SPELL_METEORBARRIEREXPLODE].formatString, dir);
Vec3ScaleAssign(32.0, dir);
if(flags&CEF_FLAG6)

View file

@ -57,7 +57,7 @@ void FXMist(centity_t *owner, int type, int flags, vec3_t origin)
client_entity_t *mist;
byte scale;
fxi.GetEffect(owner, flags, "b", &scale);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_MIST].formatString, &scale);
mist = ClientEntity_new(type, flags, origin, NULL, 100);
mist->SpawnData = scale * 0.1;

View file

@ -2667,15 +2667,15 @@ qboolean FXUnderWaterWakeUpdate (struct client_entity_s *self, centity_t *owner)
for(i = 0; i < num_parts; i++)
{
if(r_detail->value > DETAIL_LOW)
p = ClientParticle_new(water_particle[irand(0, 5)], LightColor, 1000);
p = ClientParticle_new(water_particle[irand(0, 5)], LightColor, irand(1000, 1500));
else
p = ClientParticle_new(water_particle[irand(0, 5)]|PFL_SOFT_MASK, LightColor, 1000);
p = ClientParticle_new(water_particle[irand(0, 5)]|PFL_SOFT_MASK, LightColor, irand(1000, 1500));
VectorSet(p->origin, flrand(-8, 8), flrand(-8, 8), flrand(-4, 4));
VectorAdd(self->r.origin, p->origin, p->origin);
p->scale = flrand(0.75, 1.5);
p->color.a = irand(60, 120);
p->color.a = irand(100, 200);
VectorSet(p->velocity, flrand(-2, 2), flrand(-2, 2), flrand(-2.0, 2.0));
@ -2685,7 +2685,7 @@ qboolean FXUnderWaterWakeUpdate (struct client_entity_s *self, centity_t *owner)
VectorMA(p->velocity, flrand(10, 2), right, p->velocity);
p->acceleration[2] = 2;
p->d_alpha = flrand(-3, -1);
p->d_alpha = flrand(-300, -200);
p->d_scale = flrand(-0.15, -0.10);
AddParticleToList(self, p);
@ -3501,7 +3501,7 @@ void FXMEffects(centity_t *owner,int type,int flags, vec3_t org)
byte fx_index;
int i;
fxi.GetEffect(owner, flags, "bv", &fx_index, &vel);//fixme- make this 1 dir and 1 float
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_M_EFFECTS].formatString, &fx_index, &vel);//fixme- make this 1 dir and 1 float
switch (fx_index)
{

View file

@ -510,7 +510,7 @@ void FXPESpell(centity_t *owner, int type, int flags, vec3_t origin)
byte whicheffect = 0;
vec3_t vel;
fxi.GetEffect(owner, flags, "bv", &whicheffect, vel);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_PE_SPELL].formatString, &whicheffect, vel);
switch(whicheffect)
{

View file

@ -80,7 +80,7 @@ void FXPuzzlePickup(centity_t *owner, int type, int flags, vec3_t origin)
byte tag;
vec3_t angles;
fxi.GetEffect(owner, flags, "bv", &tag,&angles);
fxi.GetEffect(owner, flags, clientEffectSpawners[FX_PICKUP_PUZZLE].formatString, &tag,&angles);
flags &= ~CEF_OWNERS_ORIGIN;
ce = ClientEntity_new(type, flags | CEF_DONT_LINK, origin, NULL, 50);

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