2019-09-19 22:42:45 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 Nuke . YKT
This file is part of NBlood .
NBlood is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
//-------------------------------------------------------------------------
2019-09-21 18:59:54 +00:00
//#include <iostream>
# include "ns.h" // Must come before everything else!
2019-09-19 22:42:45 +00:00
# include "build.h"
2020-09-06 10:44:58 +00:00
# include "automap.h"
2020-11-21 20:31:50 +00:00
# include "savegamehelp.h"
2019-09-19 22:42:45 +00:00
# include "blood.h"
2019-09-22 06:39:22 +00:00
BEGIN_BLD_NS
2020-02-11 22:15:25 +00:00
VECTORDATA gVectorData [ ] = { // this is constant EXCEPT for [VECTOR_TYPE_20].maxDist. What were they thinking...
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Tine
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
17 ,
174762 ,
1152 ,
10240 ,
0 ,
1 ,
20480 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_43 , FX_6 , FX_NONE , 502 ,
FX_43 , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_7 , 502 ,
FX_43 , FX_6 , FX_7 , 502 ,
FX_NONE , FX_NONE , FX_NONE , 503 ,
FX_43 , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 503 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Shell
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
4 ,
65536 ,
0 ,
8192 ,
0 ,
1 ,
12288 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_43 , FX_6 , FX_NONE , - 1 ,
FX_43 , FX_0 , FX_NONE , - 1 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_43 , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Bullet
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
7 ,
21845 ,
0 ,
32768 ,
0 ,
1 ,
12288 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_7 , 510 ,
FX_NONE , FX_5 , FX_7 , 511 ,
FX_43 , FX_6 , FX_NONE , 512 ,
FX_43 , FX_0 , FX_NONE , 513 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_7 , 512 ,
FX_43 , FX_6 , FX_7 , 512 ,
FX_NONE , FX_NONE , FX_NONE , 513 ,
FX_43 , FX_NONE , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Tommy AP
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
20 ,
65536 ,
0 ,
16384 ,
0 ,
1 ,
20480 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_7 , 510 ,
FX_NONE , FX_5 , FX_7 , 511 ,
FX_43 , FX_6 , FX_NONE , 512 ,
FX_43 , FX_0 , FX_NONE , 513 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_7 , 512 ,
FX_43 , FX_6 , FX_7 , 512 ,
FX_NONE , FX_NONE , FX_NONE , 513 ,
FX_43 , FX_NONE , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Shell AP
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
6 ,
87381 ,
0 ,
12288 ,
0 ,
1 ,
6144 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_43 , FX_6 , FX_NONE , - 1 ,
FX_43 , FX_0 , FX_NONE , - 1 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_43 , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Tommy regular
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
12 ,
65536 ,
0 ,
16384 ,
0 ,
1 ,
12288 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_43 , FX_5 , FX_7 , 510 ,
FX_NONE , FX_5 , FX_7 , 511 ,
FX_43 , FX_6 , FX_NONE , 512 ,
FX_43 , FX_0 , FX_NONE , 513 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_7 , 512 ,
FX_43 , FX_6 , FX_7 , 512 ,
FX_NONE , FX_NONE , FX_NONE , 513 ,
FX_43 , FX_NONE , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_6 , FX_NONE , 513 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Bat bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
4 ,
0 ,
921 ,
0 ,
0 ,
1 ,
4096 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Eel bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
12 ,
0 ,
1177 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Gill bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
9 ,
0 ,
1177 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Beast slash
{
2021-06-16 19:13:04 +00:00
kDamageExplode ,
2020-12-02 19:05:53 +00:00
50 ,
43690 ,
1024 ,
8192 ,
0 ,
4 ,
32768 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Axe
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
18 ,
436906 ,
1024 ,
16384 ,
0 ,
2 ,
20480 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Cleaver
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
9 ,
218453 ,
1024 ,
0 ,
0 ,
1 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
// Phantasm slash
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
20 ,
436906 ,
1024 ,
16384 ,
0 ,
3 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Gargoyle Slash
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
16 ,
218453 ,
1024 ,
8192 ,
0 ,
4 ,
20480 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Cerberus bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
19 ,
218453 ,
614 ,
8192 ,
0 ,
2 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Hound bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
10 ,
218453 ,
614 ,
8192 ,
0 ,
2 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Rat bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
4 ,
0 ,
921 ,
0 ,
0 ,
1 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Spider bite
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
8 ,
0 ,
614 ,
0 ,
0 ,
1 ,
24576 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Unk
{
2021-06-16 19:13:04 +00:00
kDamageBullet ,
2020-12-02 19:05:53 +00:00
9 ,
0 ,
512 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_5 , FX_NONE , 500 ,
FX_NONE , FX_5 , FX_NONE , 501 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_0 , FX_NONE , 503 ,
FX_NONE , FX_4 , FX_NONE , - 1 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_6 , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 502 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2021-12-30 09:30:21 +00:00
2020-12-02 19:05:53 +00:00
{
( DAMAGE_TYPE ) - 1 ,
0 ,
0 ,
2560 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_34 , FX_35 , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Tchernobog burn vector
{
2021-06-16 19:13:04 +00:00
kDamageBurn ,
2020-12-02 19:05:53 +00:00
2 ,
0 ,
0 ,
0 ,
15 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// Vodoo 1.0 vector
{
2021-06-16 19:13:04 +00:00
kDamageSpirit ,
2020-12-02 19:05:53 +00:00
25 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
} ,
2020-01-26 11:19:01 +00:00
2020-12-02 19:05:53 +00:00
// 22 kVectorGenDudePunch
{
2021-06-16 19:13:04 +00:00
kDamageFall ,
2020-12-02 19:05:53 +00:00
37 ,
874762 ,
620 ,
0 ,
0 ,
0 ,
0 ,
FX_NONE , FX_NONE , FX_NONE , - 1 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
FX_NONE , FX_NONE , FX_NONE , 357 ,
} ,
2019-09-19 22:42:45 +00:00
} ;
2020-02-11 22:15:25 +00:00
const ITEMDATA gItemData [ ] = {
2020-12-02 19:05:53 +00:00
{
0 ,
2552 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2553 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2554 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2555 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2556 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2557 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
- 1 ,
} ,
{
0 ,
2021-04-17 10:05:37 +00:00
2558 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
2021-04-17 10:05:37 +00:00
32 ,
32 ,
2020-12-02 19:05:53 +00:00
- 1 ,
} ,
{
0 ,
519 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
0 ,
} ,
{
0 ,
822 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
2169 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
2433 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
517 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
783 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
896 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
825 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
827 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
4 ,
} ,
{
0 ,
828 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
829 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
830 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
80 ,
64 ,
1 ,
} ,
{
0 ,
831 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
863 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
760 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
2 ,
} ,
{
0 ,
836 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
851 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
2428 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
839 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
3 ,
} ,
{
0 ,
768 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
840 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
- 1 ,
} ,
{
0 ,
841 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
- 1 ,
} ,
{
0 ,
842 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
- 1 ,
} ,
{
0 ,
843 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
- 1 ,
} ,
{
0 ,
683 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
521 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
604 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
520 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
803 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
518 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
522 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
523 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
- 1 ,
} ,
{
0 ,
837 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
80 ,
64 ,
- 1 ,
} ,
{
0 ,
2628 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
2586 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
2578 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
2602 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
2594 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
753 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
753 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
7 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
3558 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
64 ,
64 ,
- 1 ,
} ,
{
0 ,
3558 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
7 ,
64 ,
64 ,
- 1 ,
}
2019-09-19 22:42:45 +00:00
} ;
2020-02-11 22:15:25 +00:00
const AMMOITEMDATA gAmmoItemData [ ] = {
2020-12-02 19:05:53 +00:00
{
0 ,
618 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
480 ,
6 ,
7
} ,
{
0 ,
589 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
1 ,
5 ,
6
} ,
{
0 ,
589 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
1 ,
5 ,
6
} ,
{
0 ,
809 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
5 ,
5 ,
6
} ,
{
0 ,
811 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
1 ,
10 ,
11
} ,
{
0 ,
810 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
1 ,
11 ,
12
} ,
{
0 ,
820 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
24 ,
24 ,
10 ,
8 ,
0
} ,
{
0 ,
619 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
4 ,
2 ,
0
} ,
{
0 ,
812 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
15 ,
2 ,
0
} ,
{
0 ,
813 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
15 ,
3 ,
0
} ,
{
0 ,
525 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
100 ,
9 ,
10
} ,
{
0 ,
814 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
15 ,
255 ,
0
} ,
{
0 ,
817 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
100 ,
3 ,
0
} ,
{
0 ,
548 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
24 ,
24 ,
32 ,
7 ,
0
} ,
{
0 ,
0 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
6 ,
255 ,
0
} ,
{
0 ,
0 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
6 ,
255 ,
0
} ,
{
0 ,
816 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
8 ,
1 ,
0
} ,
{
0 ,
818 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
8 ,
255 ,
0
} ,
{
0 ,
819 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
8 ,
255 ,
0
} ,
{
0 ,
801 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
6 ,
4 ,
0
} ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
2019-09-19 22:42:45 +00:00
} ;
2020-02-11 22:15:25 +00:00
const WEAPONITEMDATA gWeaponItemData [ ] = {
2020-12-02 19:05:53 +00:00
{
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 ,
- 1 ,
0
} ,
{
0 ,
559 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
3 ,
2 ,
8
} ,
{
0 ,
558 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
4 ,
3 ,
50
} ,
{
0 ,
524 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
2 ,
1 ,
9
} ,
{
0 ,
525 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
10 ,
9 ,
100
} ,
{
0 ,
539 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
8 ,
7 ,
64
} ,
{
0 ,
526 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
5 ,
4 ,
6
} ,
{
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
1 ,
- 1 ,
0
} ,
{
0 ,
618 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
7 ,
6 ,
480
} ,
{
0 ,
589 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
6 ,
5 ,
1
} ,
{
0 ,
800 ,
2021-04-17 08:22:00 +00:00
- 8 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
9 ,
8 ,
35
}
2019-09-19 22:42:45 +00:00
} ;
2020-02-11 22:15:25 +00:00
const MissileType missileInfo [ ] = {
2020-12-02 19:05:53 +00:00
// Cleaver
{
2138 ,
978670 ,
512 ,
40 ,
40 ,
2021-04-17 08:22:00 +00:00
- 16 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Regular flare
{
2424 ,
3145728 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
32 ,
} ,
// Tesla alt
{
3056 ,
2796202 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
32 ,
} ,
// Flare alt
{
2424 ,
2446677 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
4 ,
} ,
// Spray flame
{
0 ,
1118481 ,
0 ,
24 ,
24 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Fireball
{
0 ,
1118481 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
32 ,
} ,
// Tesla regular
{
2130 ,
2796202 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// EctoSkull
{
870 ,
699050 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 24 ,
2020-12-02 19:05:53 +00:00
32 ,
} ,
// Hellhound flame
{
0 ,
1118481 ,
0 ,
24 ,
24 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Puke
{
0 ,
838860 ,
0 ,
16 ,
16 ,
2021-04-17 08:22:00 +00:00
- 16 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Reserved
{
0 ,
838860 ,
0 ,
8 ,
8 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Stone gargoyle projectile
{
3056 ,
2097152 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Napalm launcher
{
0 ,
2446677 ,
0 ,
30 ,
30 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
24 ,
} ,
// Cerberus fireball
{
0 ,
2446677 ,
0 ,
30 ,
30 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
24 ,
} ,
// Tchernobog fireball
{
0 ,
1398101 ,
0 ,
24 ,
24 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Regular life leech
{
2446 ,
2796202 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Dropped life leech (enough ammo)
{
3056 ,
2446677 ,
0 ,
16 ,
16 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
} ,
// Dropped life leech (no ammo)
{
3056 ,
1747626 ,
0 ,
32 ,
32 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
16 ,
}
2019-09-19 22:42:45 +00:00
} ;
2019-12-06 23:07:02 +00:00
const THINGINFO thingInfo [ ] = {
2020-12-02 19:05:53 +00:00
//TNT Barrel
{
25 ,
250 ,
32 ,
11 ,
4096 ,
80 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_YCENTER | CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
907 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 256 , 128 , 64 , 0 , 0 , 128 ,
} ,
2021-09-16 19:59:39 +00:00
2020-12-02 19:05:53 +00:00
// Armed Proxy Dynamite
{
5 ,
5 ,
16 ,
3 ,
24576 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3444 ,
2021-04-17 08:22:00 +00:00
- 16 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
256 , 256 , 256 , 64 , 0 , 0 , 512 ,
} ,
// Armed Remote Dynamite
{
5 ,
5 ,
16 ,
3 ,
24576 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3457 ,
2021-04-17 08:22:00 +00:00
- 16 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
256 , 256 , 256 , 64 , 0 , 0 , 512 ,
} ,
// Vase1
{
1 ,
20 ,
32 ,
3 ,
32768 ,
80 ,
0 ,
739 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 128 , 0 , 0 , 0 ,
} ,
// Vase2
{
1 ,
150 ,
32 ,
3 ,
32768 ,
80 ,
0 ,
642 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 256 , 256 , 128 , 0 , 0 , 0 ,
} ,
// Crate face
{
10 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
462 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 0 , 256 , 0 , 0 , 0 ,
} ,
// Glass window
{
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
266 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 256 , 0 , 0 , 0 ,
} ,
// Flourescent Light
{
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
796 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 256 , 0 , 0 , 512 ,
} ,
// Wall Crack
{
50 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
1127 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 0 , 256 , 0 , 0 , 0 ,
} ,
// Wood Beam
{
8 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
1142 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 128 , 0 , 0 , 0 ,
} ,
// Spider's Web
{
4 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
1069 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 256 , 64 , 256 , 0 , 0 , 128 ,
} ,
// Metal Grate
{
40 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
483 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
64 , 0 , 128 , 256 , 0 , 0 , 0 ,
} ,
// Flammable Tree
{
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 256 , 0 , 256 , 0 , 0 , 128 ,
} ,
// MachineGun Trap
{
1000 ,
0 ,
0 ,
8 ,
0 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 128 , 256 , 0 , 0 , 512 ,
} ,
// Falling Rock
{
0 ,
15 ,
8 ,
3 ,
32768 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// Kickable Pail
{
0 ,
8 ,
48 ,
3 ,
49152 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// Gib Object
{
10 ,
2 ,
0 ,
0 ,
32768 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 256 , 0 , 0 , 128 ,
} ,
// Explode Object
{
20 ,
2 ,
0 ,
0 ,
32768 ,
0 ,
0 ,
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
0 , 0 , 0 , 256 , 0 , 0 , 128 ,
} ,
// Armed stick Of TNT
{
5 ,
14 ,
16 ,
3 ,
24576 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3422 ,
2021-04-17 08:22:00 +00:00
- 32 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
64 , 256 , 128 , 64 , 0 , 0 , 256 ,
} ,
// Armed bundle Of TNT
{
5 ,
14 ,
16 ,
3 ,
24576 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3433 ,
2021-04-17 08:22:00 +00:00
- 32 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
64 , 256 , 128 , 64 , 0 , 0 , 256 ,
} ,
// Armed aerosol
{
5 ,
14 ,
16 ,
3 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3467 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
64 , 256 , 128 , 64 , 0 , 0 , 256 ,
} ,
// Bone (Flesh Garg.)
{
5 ,
6 ,
16 ,
3 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
1462 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// Some alpha stuff
{
8 ,
3 ,
16 ,
11 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
256 , 0 , 256 , 256 , 0 , 0 , 0 ,
} ,
// WaterDrip
{
0 ,
1 ,
1 ,
2 ,
0 ,
0 ,
0 ,
1147 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
10 ,
0 ,
0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// BloodDrip
{
0 ,
1 ,
1 ,
2 ,
0 ,
0 ,
0 ,
1160 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
2 ,
0 ,
0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// Blood chucks1
{
15 ,
4 ,
4 ,
3 ,
24576 ,
0 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_ALL ,
2020-12-02 19:05:53 +00:00
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
128 , 64 , 256 , 256 , 0 , 0 , 256 ,
} ,
// Blood chucks2
{
30 ,
30 ,
8 ,
3 ,
8192 ,
0 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_ALL ,
2020-12-02 19:05:53 +00:00
- 1 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
0 ,
0 ,
128 , 64 , 256 , 256 , 0 , 0 , 64 ,
} ,
// Axe Zombie Head
{
60 ,
5 ,
32 ,
3 ,
40960 ,
1280 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_ALL ,
2020-12-02 19:05:53 +00:00
3405 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
40 ,
40 ,
128 , 64 , 256 , 256 , 0 , 0 , 64 ,
} ,
// Napalm's Alt Fire explosion
{
80 ,
30 ,
32 ,
3 ,
57344 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3281 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// Fire Pod Explosion
{
80 ,
30 ,
32 ,
3 ,
57344 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
2020 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
256 , 0 , 256 , 256 , 0 , 0 , 0 ,
} ,
// Green Pod Explosion
{
80 ,
30 ,
32 ,
3 ,
57344 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
1860 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
256 , 0 , 256 , 256 , 0 , 0 , 0 ,
} ,
// Life Leech
{
150 ,
30 ,
48 ,
3 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_ALL ,
2020-12-02 19:05:53 +00:00
800 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
48 ,
48 ,
64 , 64 , 112 , 64 , 0 , 96 , 96 ,
} ,
// Voodoo Head
{
1 ,
30 ,
48 ,
3 ,
32768 ,
1600 ,
0 ,
2443 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
16 ,
16 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// 433 - kModernThingTNTProx
{
5 ,
5 ,
16 ,
3 ,
24576 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
3444 ,
2021-04-17 08:22:00 +00:00
- 16 ,
2020-12-02 19:05:53 +00:00
7 ,
32 ,
32 ,
256 , 256 , 256 , 64 , 0 , 0 , 512 ,
} ,
// 434 - kModernThingThrowableRock
{
5 ,
6 ,
16 ,
3 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_HITSCAN ,
2020-12-02 19:05:53 +00:00
1462 ,
2021-04-17 08:22:00 +00:00
0 ,
2020-12-02 19:05:53 +00:00
0 ,
32 ,
32 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ,
// 435 - kModernThingEnemyLifeLeech
{
150 ,
30 ,
48 ,
3 ,
32768 ,
1600 ,
2021-12-18 18:19:28 +00:00
CSTAT_SPRITE_BLOCK_ALL ,
2020-12-02 19:05:53 +00:00
800 ,
2021-04-17 08:22:00 +00:00
- 128 ,
2020-12-02 19:05:53 +00:00
0 ,
44 ,
44 ,
0 , 1024 , 512 , 1024 , 0 , 64 , 512 ,
} ,
2019-09-19 22:42:45 +00:00
} ;
2020-02-11 22:15:25 +00:00
const EXPLOSION explodeInfo [ ] = {
2020-12-02 19:05:53 +00:00
{
40 ,
10 ,
10 ,
75 ,
450 ,
0 ,
60 ,
80 ,
40
} ,
{
80 ,
20 ,
10 ,
150 ,
900 ,
0 ,
60 ,
160 ,
60
} ,
{
120 ,
40 ,
15 ,
225 ,
1350 ,
0 ,
60 ,
240 ,
80
} ,
{
80 ,
5 ,
10 ,
120 ,
20 ,
10 ,
60 ,
0 ,
40
} ,
{
120 ,
10 ,
10 ,
180 ,
40 ,
10 ,
60 ,
0 ,
80
} ,
{
160 ,
15 ,
10 ,
240 ,
60 ,
10 ,
60 ,
0 ,
120
} ,
{
40 ,
20 ,
10 ,
120 ,
0 ,
10 ,
30 ,
60 ,
40
} ,
{
80 ,
20 ,
10 ,
150 ,
800 ,
5 ,
60 ,
160 ,
60
} ,
2019-09-19 22:42:45 +00:00
} ;
2021-11-19 19:50:02 +00:00
static const int16_t gPlayerGibThingComments [ ] = {
2020-12-02 19:05:53 +00:00
734 , 735 , 736 , 737 , 738 , 739 , 740 , 741 , 3038 , 3049
2019-09-19 22:42:45 +00:00
} ;
2021-11-19 19:50:02 +00:00
const int16_t DudeDifficulty [ 5 ] = {
2020-12-02 19:22:13 +00:00
512 , 384 , 256 , 208 , 160
} ;
2019-09-19 22:42:45 +00:00
2021-09-16 19:59:39 +00:00
struct POSTPONE
2021-08-30 18:12:19 +00:00
{
DBloodActor * sprite ;
int status ;
2019-09-19 22:42:45 +00:00
} ;
2021-08-30 18:12:19 +00:00
TArray < POSTPONE > gPost ;
2019-09-19 22:42:45 +00:00
2020-12-02 19:22:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-19 17:08:05 +00:00
bool IsUnderwaterSector ( sectortype * pSector )
2019-09-19 22:42:45 +00:00
{
2021-11-19 17:08:05 +00:00
return ! ! pSector - > hasX ( ) & & pSector - > xs ( ) . Underwater ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 19:22:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2020-12-02 19:55:08 +00:00
static void actInitTraps ( )
2020-12-02 16:10:00 +00:00
{
2020-12-02 19:22:13 +00:00
BloodStatIterator it ( kStatTraps ) ;
while ( auto act = it . Next ( ) )
{
2021-12-22 14:33:13 +00:00
if ( act - > spr . type = = kTrapExploder )
2020-12-02 19:22:13 +00:00
{
2021-12-22 14:33:13 +00:00
act - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK ;
act - > spr . cstat | = CSTAT_SPRITE_INVISIBLE ;
2020-12-02 19:22:13 +00:00
if ( ! act - > hasX ( ) ) continue ;
2021-12-22 16:57:58 +00:00
act - > xspr . waitTime = ClipLow ( act - > xspr . waitTime , 1 ) ;
act - > xspr . state = 0 ;
2020-12-02 19:22:13 +00:00
}
}
}
2019-10-12 20:45:46 +00:00
2020-12-02 19:22:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-10-12 20:45:46 +00:00
2020-12-02 19:55:08 +00:00
static void actInitThings ( )
2020-12-02 19:22:13 +00:00
{
BloodStatIterator it ( kStatThing ) ;
while ( auto act = it . Next ( ) )
{
if ( ! act - > hasX ( ) ) continue ;
2019-09-21 11:02:17 +00:00
2021-12-22 14:33:13 +00:00
int nType = act - > spr . type - kThingBase ;
2021-12-22 16:57:58 +00:00
act - > xspr . health = thingInfo [ nType ] . startHealth < < 4 ;
2020-12-02 19:22:13 +00:00
# ifdef NOONE_EXTENSIONS
// allow level designer to set custom clipdist.
// this is especially useful for various Gib and Explode objects which have clipdist 1 for some reason predefined,
// but what if it have voxel model...?
if ( ! gModernMap )
# endif
2021-12-22 14:33:13 +00:00
act - > spr . clipdist = thingInfo [ nType ] . clipdist ;
2019-09-21 11:02:17 +00:00
2021-12-22 14:33:13 +00:00
act - > spr . flags = thingInfo [ nType ] . flags ;
if ( act - > spr . flags & kPhysGravity ) act - > spr . flags | = kPhysFalling ;
2022-08-23 19:25:05 +00:00
act - > ZeroVelocity ( ) ;
2020-12-02 16:10:00 +00:00
2021-12-22 14:33:13 +00:00
switch ( act - > spr . type )
2021-09-15 22:52:54 +00:00
{
2020-12-02 19:22:13 +00:00
case kThingArmedProxBomb :
case kTrapMachinegun :
# ifdef NOONE_EXTENSIONS
case kModernThingTNTProx :
# endif
2021-12-22 16:57:58 +00:00
act - > xspr . state = 0 ;
2020-12-02 19:22:13 +00:00
break ;
2021-08-25 06:46:31 +00:00
case kThingBloodChunks :
2020-12-03 19:30:30 +00:00
{
2021-09-05 07:59:10 +00:00
SEQINST * pInst = GetInstance ( act ) ;
2020-12-02 19:22:13 +00:00
if ( pInst )
{
auto seq = getSequence ( pInst - > nSeqID ) ;
if ( ! seq ) break ;
2020-12-03 19:30:30 +00:00
seqSpawn ( pInst - > nSeqID , act ) ;
2020-12-02 19:22:13 +00:00
}
break ;
}
default :
2021-12-22 16:57:58 +00:00
act - > xspr . state = 1 ;
2020-12-02 19:22:13 +00:00
break ;
}
}
}
2019-09-19 22:42:45 +00:00
2020-12-02 19:22:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-02 16:10:00 +00:00
2020-12-02 19:55:08 +00:00
static void actInitDudes ( )
2020-12-02 19:22:13 +00:00
{
if ( gGameOptions . nMonsterSettings = = 0 )
{
gKillMgr . SetCount ( 0 ) ;
BloodStatIterator it ( kStatDude ) ;
while ( auto act = it . Next ( ) )
{
2021-12-22 15:49:41 +00:00
if ( act - > hasX ( ) & & act - > xspr . key > 0 ) // Drop Key
actDropObject ( act , kItemKeyBase + ( act - > xspr . key - 1 ) ) ;
2020-12-02 19:22:13 +00:00
DeleteSprite ( act ) ;
}
}
else
{
// by NoOne: WTF is this?
///////////////
BloodStatIterator it ( kStatDude ) ;
while ( auto act = it . Next ( ) )
{
2021-12-22 14:33:13 +00:00
if ( act - > spr . type < kDudeBase | | act - > spr . type > = kDudeMax )
2021-09-06 20:47:10 +00:00
I_Error ( " Non-enemy sprite (%d) in the enemy sprite list. \n " , act - > GetIndex ( ) ) ;
2020-12-02 19:22:13 +00:00
}
2019-09-21 11:02:17 +00:00
2020-12-02 19:22:13 +00:00
gKillMgr . CountTotalKills ( ) ;
///////////////
for ( int i = 0 ; i < kDudeMax - kDudeBase ; i + + )
for ( int j = 0 ; j < 7 ; j + + )
2020-12-02 23:30:19 +00:00
dudeInfo [ i ] . damageVal [ j ] = MulScale ( DudeDifficulty [ gGameOptions . nDifficulty ] , dudeInfo [ i ] . startDamage [ j ] , 8 ) ;
2020-12-02 19:22:13 +00:00
it . Reset ( kStatDude ) ;
while ( auto act = it . Next ( ) )
{
if ( ! act - > hasX ( ) ) continue ;
2021-12-22 14:33:13 +00:00
int nType = act - > spr . type - kDudeBase ;
2020-12-02 19:22:13 +00:00
int seqStartId = dudeInfo [ nType ] . seqStartID ;
if ( ! act - > IsPlayerActor ( ) )
{
# ifdef NOONE_EXTENSIONS
2021-12-22 14:33:13 +00:00
switch ( act - > spr . type )
2020-12-02 19:22:13 +00:00
{
case kDudeModernCustom :
case kDudeModernCustomBurning :
2021-12-22 14:33:13 +00:00
act - > spr . cstat | = CSTAT_SPRITE_BLOOD_BIT1 | CSTAT_SPRITE_BLOCK_ALL ;
2022-05-06 16:27:44 +00:00
if ( act - > xspr . data2 > 0 & & getSequence ( act - > xspr . data2 ) )
seqStartId = act - > xspr . data2 ; // Custom Dude stores it's SEQ in data2
2021-05-06 08:51:39 +00:00
seqStartId = genDudeSeqStartId ( act ) ; // Custom Dude stores its SEQ in data2
2021-12-22 16:57:58 +00:00
act - > xspr . sysData1 = act - > xspr . data3 ; // move sndStartId to sysData1, because data3 used by the game;
act - > xspr . data3 = 0 ;
2020-12-02 19:22:13 +00:00
break ;
case kDudePodMother : // FakeDude type (no seq, custom flags, clipdist and cstat)
if ( gModernMap ) break ;
[[fallthrough]] ;
default :
2021-12-22 14:33:13 +00:00
act - > spr . clipdist = dudeInfo [ nType ] . clipdist ;
act - > spr . cstat | = CSTAT_SPRITE_BLOOD_BIT1 | CSTAT_SPRITE_BLOCK_ALL ;
2020-12-02 19:22:13 +00:00
break ;
}
# else
2021-12-22 14:33:13 +00:00
act - > spr . clipdist = dudeInfo [ nType ] . clipdist ;
act - > spr . cstat | = CSTAT_SPRITE_BLOOD_BIT1 | CSTAT_SPRITE_BLOCK_ALL ;
2020-12-02 19:22:13 +00:00
# endif
2022-08-23 19:25:05 +00:00
act - > ZeroVelocity ( ) ;
2020-12-02 19:22:13 +00:00
# ifdef NOONE_EXTENSIONS
// add a way to set custom hp for every enemy - should work only if map just started and not loaded.
2021-12-22 16:57:58 +00:00
if ( ! gModernMap | | act - > xspr . sysData2 < = 0 ) act - > xspr . health = dudeInfo [ nType ] . startHealth < < 4 ;
else act - > xspr . health = ClipRange ( act - > xspr . sysData2 < < 4 , 1 , 65535 ) ;
2020-12-02 19:22:13 +00:00
# else
2021-12-22 16:57:58 +00:00
act - > xspr . health = dudeInfo [ nType ] . startHealth < < 4 ;
2020-12-02 19:22:13 +00:00
# endif
}
2021-09-04 21:27:21 +00:00
if ( getSequence ( seqStartId ) ) seqSpawn ( seqStartId , act ) ;
2020-12-02 19:22:13 +00:00
}
aiInit ( ) ;
}
2019-09-19 22:42:45 +00:00
}
2020-12-02 19:22:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-12-03 20:36:32 +00:00
void actInit ( TArray < DBloodActor * > & actors )
2020-12-02 19:22:13 +00:00
{
2021-08-25 06:46:31 +00:00
# ifdef NOONE_EXTENSIONS
2020-12-02 19:22:13 +00:00
if ( ! gModernMap ) nnExtResetGlobals ( ) ;
2021-12-03 20:36:32 +00:00
else nnExtInitModernStuff ( actors ) ;
2021-08-25 06:46:31 +00:00
# endif
2020-12-02 19:22:13 +00:00
BloodStatIterator it ( kStatItem ) ;
while ( auto act = it . Next ( ) )
{
2021-12-21 22:18:23 +00:00
if ( act - > spr . type = = kItemWeaponVoodooDoll )
2020-12-02 19:22:13 +00:00
{
2021-12-21 22:18:23 +00:00
act - > spr . type = kItemAmmoVoodooDoll ;
2020-12-02 19:22:13 +00:00
break ;
}
}
actInitTraps ( ) ;
actInitThings ( ) ;
actInitDudes ( ) ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-08-22 16:18:31 +00:00
static void ConcussSprite ( DBloodActor * source , DBloodActor * actor , const DVector3 & pos , double damage )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:18:31 +00:00
auto vect = actor - > spr . pos - pos ;
double dist2 = vect . LengthSquared ( ) + 0x4000 ;
damage * = 0x4000 / dist2 ;
2020-12-02 19:55:08 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & kPhysMove )
2020-12-02 19:55:08 +00:00
{
int mass = 0 ;
if ( actor - > IsDudeActor ( ) )
{
2021-12-22 15:43:59 +00:00
mass = getDudeInfo ( actor - > spr . type ) - > mass ;
2020-12-02 19:55:08 +00:00
# ifdef NOONE_EXTENSIONS
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kDudeModernCustom | | actor - > spr . type = = kDudeModernCustomBurning )
2020-12-02 19:55:08 +00:00
{
2021-08-27 17:12:22 +00:00
mass = getSpriteMassBySize ( actor ) ;
2020-12-02 19:55:08 +00:00
}
# endif
}
2021-12-22 15:43:59 +00:00
else if ( actor - > spr . type > = kThingBase & & actor - > spr . type < kThingMax )
2020-12-02 19:55:08 +00:00
{
2021-12-22 15:43:59 +00:00
mass = thingInfo [ actor - > spr . type - kThingBase ] . mass ;
2020-12-02 19:55:08 +00:00
}
else
{
2021-12-22 15:43:59 +00:00
Printf ( PRINT_HIGH , " Unexpected type in ConcussSprite(): Sprite: %d Type: %d Stat: %d " , actor - > GetIndex ( ) , ( int ) actor - > spr . type , ( int ) actor - > spr . statnum ) ;
2020-12-02 19:55:08 +00:00
return ;
}
2019-10-12 20:45:46 +00:00
2020-12-02 19:55:08 +00:00
if ( mass > 0 )
{
2021-12-22 15:43:59 +00:00
int size = ( tileWidth ( actor - > spr . picnum ) * actor - > spr . xrepeat * tileHeight ( actor - > spr . picnum ) * actor - > spr . yrepeat ) > > 1 ;
2021-12-30 07:32:06 +00:00
int t = Scale ( damage , size , mass ) ;
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( ( int ) MulScaleF ( t , vect . X , 12 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( ( int ) MulScaleF ( t , vect . Y , 12 ) ) ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( ( int ) MulScaleF ( t , vect . Z , 12 ) ) ;
2020-12-02 19:55:08 +00:00
}
}
2021-06-16 19:13:04 +00:00
actDamageSprite ( source , actor , kDamageExplode , damage ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 19:55:08 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-03 07:37:52 +00:00
void actWallBounceVector ( DBloodActor * actor , walltype * pWall , double factor )
2019-09-19 22:42:45 +00:00
{
2022-09-03 07:37:52 +00:00
auto delta = pWall - > delta ( ) . Unit ( ) ;
2022-09-03 07:45:23 +00:00
auto vel = actor - > vel . XY ( ) ;
2022-09-03 07:37:52 +00:00
double t = vel . X * - delta . Y + vel . Y * delta . X ;
double t2 = t * ( factor + 1 ) ;
2022-09-03 07:45:23 +00:00
actor - > vel . XY ( ) = ( vel - DVector2 ( - delta . Y * t2 , delta . X * t2 ) ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 20:39:37 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-02 21:56:03 +00:00
DVector4 actFloorBounceVector ( DBloodActor * actor , double oldz , sectortype * pSector , double factor )
2019-09-19 22:42:45 +00:00
{
2022-09-02 21:56:03 +00:00
DVector4 retval ;
double t = 1. - factor ;
2021-11-19 19:35:33 +00:00
if ( pSector - > floorheinum = = 0 )
2020-12-02 20:39:37 +00:00
{
2022-09-02 21:56:03 +00:00
double t2 = oldz * t ;
2022-09-03 07:45:23 +00:00
return { actor - > vel . X , actor - > vel . Y , oldz - t2 , t2 } ;
2020-12-02 20:39:37 +00:00
}
2022-08-22 16:31:23 +00:00
2021-11-19 19:35:33 +00:00
walltype * pWall = pSector - > firstWall ( ) ;
2022-09-02 21:56:03 +00:00
auto p = actor - > int_vel ( ) ;
2022-08-30 21:05:03 +00:00
int angle = getangle ( pWall - > delta ( ) ) + 512 ;
2021-11-19 19:35:33 +00:00
int t2 = pSector - > floorheinum < < 4 ;
2020-12-02 20:39:37 +00:00
int t3 = approxDist ( - 0x10000 , t2 ) ;
int t4 = DivScale ( - 0x10000 , t3 , 16 ) ;
int t5 = DivScale ( t2 , t3 , 16 ) ;
int t6 = MulScale ( t5 , Cos ( angle ) , 30 ) ;
int t7 = MulScale ( t5 , Sin ( angle ) , 30 ) ;
2022-09-02 21:56:03 +00:00
int t8 = TMulScale ( p . X , t6 , p . Y , t7 , oldz , t4 , 16 ) ;
int t9 = MulScale ( t8 , 0x10000 + FloatToFixed ( factor ) , 16 ) ;
retval . X = FixedToFloat ( p . X - MulScale ( t6 , t9 , 16 ) ) ;
retval . Y = FixedToFloat ( p . Y - MulScale ( t7 , t9 , 16 ) ) ;
retval . Z = FixedToFloat ( oldz - MulScale ( t4 , t9 , 16 ) ) ;
retval . W = FixedToFloat ( t8 * t ) ;
return retval ;
2022-09-02 21:56:03 +00:00
}
2020-12-02 20:39:37 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-08-22 16:18:54 +00:00
void actRadiusDamage ( DBloodActor * source , const DVector3 & pos , sectortype * pSector , int nDist , int baseDmg , int distDmg , DAMAGE_TYPE dmgType , int flags , int burn )
2019-09-19 22:42:45 +00:00
{
2020-12-02 20:39:37 +00:00
auto pOwner = source - > GetOwner ( ) ;
2021-08-21 10:16:48 +00:00
const bool newSectCheckMethod = ! cl_bloodvanillaexplosions & & pOwner & & pOwner - > IsDudeActor ( ) & & ! VanillaMode ( ) ; // use new sector checking logic
2022-08-22 16:20:16 +00:00
auto sectorMap = GetClosestSpriteSectors ( pSector , pos . XY ( ) , nDist , nullptr , newSectCheckMethod ) ;
2020-12-02 20:39:37 +00:00
nDist < < = 4 ;
if ( flags & 2 )
{
BloodStatIterator it ( kStatDude ) ;
while ( auto act2 = it . Next ( ) )
{
if ( act2 ! = source | | ( flags & 1 ) )
{
if ( act2 - > hasX ( ) )
{
2021-12-22 14:33:13 +00:00
if ( act2 - > spr . flags & 0x20 ) continue ;
2021-12-22 14:40:15 +00:00
if ( ! CheckSector ( sectorMap , act2 ) ) continue ;
2022-08-22 16:23:36 +00:00
if ( ! CheckProximity ( act2 , pos , pSector , nDist ) ) continue ;
2020-12-02 20:39:37 +00:00
2022-08-22 16:20:47 +00:00
int dist = int ( ( pos - act2 - > spr . pos ) . Length ( ) * worldtoint ) ;
2020-12-02 20:39:37 +00:00
if ( dist > nDist ) continue ;
int totaldmg ;
if ( dist ! = 0 ) totaldmg = baseDmg + ( ( nDist - dist ) * distDmg ) / nDist ;
else totaldmg = baseDmg + distDmg ;
actDamageSprite ( source , act2 , dmgType , totaldmg < < 4 ) ;
if ( burn ) actBurnSprite ( pOwner , act2 , burn ) ;
}
}
}
}
if ( flags & 4 )
{
BloodStatIterator it ( kStatDude ) ;
while ( auto act2 = it . Next ( ) )
{
2021-12-22 14:33:13 +00:00
if ( act2 - > spr . flags & 0x20 ) continue ;
2021-12-22 14:40:15 +00:00
if ( ! CheckSector ( sectorMap , act2 ) ) continue ;
2022-08-22 16:23:36 +00:00
if ( ! CheckProximity ( act2 , pos , pSector , nDist ) ) continue ;
2020-12-02 20:39:37 +00:00
2021-12-22 16:57:58 +00:00
if ( act2 - > xspr . locked ) continue ;
2020-12-02 20:39:37 +00:00
2022-08-22 16:20:47 +00:00
int dist = int ( ( pos . XY ( ) - act2 - > spr . pos . XY ( ) ) . Length ( ) * worldtoint ) ;
2020-12-02 20:39:37 +00:00
if ( dist > nDist ) continue ;
int totaldmg ;
if ( dist ! = 0 ) totaldmg = baseDmg + ( ( nDist - dist ) * distDmg ) / nDist ;
else totaldmg = baseDmg + distDmg ;
actDamageSprite ( source , act2 , dmgType , totaldmg < < 4 ) ;
if ( burn ) actBurnSprite ( pOwner , act2 , burn ) ;
}
}
2019-09-19 22:42:45 +00:00
}
2020-12-02 21:33:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actNapalmMove ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2020-12-02 21:33:14 +00:00
auto pOwner = actor - > GetOwner ( ) ;
actPostSprite ( actor , kStatDecoration ) ;
seqSpawn ( 9 , actor ) ;
2021-12-22 15:43:59 +00:00
if ( Chance ( 0x8000 ) ) actor - > spr . cstat | = CSTAT_SPRITE_XFLIP ;
2020-12-02 21:33:14 +00:00
2021-12-22 15:43:59 +00:00
sfxPlay3DSound ( actor , 303 , 24 + ( actor - > spr . flags & 3 ) , 1 ) ;
2022-08-22 16:18:54 +00:00
actRadiusDamage ( pOwner , actor - > spr . pos , actor - > sector ( ) , 128 , 0 , 60 , kDamageExplode , 15 , 120 ) ;
2020-12-02 21:33:14 +00:00
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . data4 > 1 )
2020-12-02 21:33:14 +00:00
{
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2020-12-02 21:33:14 +00:00
int spawnparam [ 2 ] ;
2021-12-22 17:12:55 +00:00
spawnparam [ 0 ] = actor - > xspr . data4 > > 1 ;
spawnparam [ 1 ] = actor - > xspr . data4 - spawnparam [ 0 ] ;
2022-09-02 21:52:58 +00:00
auto ang = actor - > spr . angle ;
2022-08-23 19:25:05 +00:00
actor - > ZeroVelocity ( ) ;
2020-12-02 21:33:14 +00:00
for ( int i = 0 ; i < 2 ; i + + )
{
int t1 = Random ( 0x33333 ) + 0x33333 ;
2022-09-02 21:52:58 +00:00
auto rndang = DAngle : : fromBuild ( Random2 ( 0x71 ) ) ;
actor - > spr . angle = ( ang + rndang ) . Normalized360 ( ) ;
2020-12-02 21:33:14 +00:00
auto spawned = actFireThing ( actor , 0 , 0 , - 0x93d0 , kThingNapalmBall , t1 ) ;
spawned - > SetOwner ( actor - > GetOwner ( ) ) ;
seqSpawn ( 61 , spawned , nNapalmClient ) ;
2021-12-22 15:49:41 +00:00
spawned - > xspr . data4 = spawnparam [ i ] ;
2020-12-02 21:33:14 +00:00
}
}
2019-09-19 22:42:45 +00:00
}
2020-12-02 21:33:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-05-04 16:41:59 +00:00
static DBloodActor * actSpawnFloor ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2022-08-22 16:24:09 +00:00
auto pos = actor - > spr . pos ;
updatesector ( pos , & pSector ) ;
double zFloor = getflorzofslopeptrf ( pSector , pos . X , pos . Y ) ;
auto spawned = actSpawnSprite ( pSector , DVector3 ( pos . XY ( ) , zFloor ) , 3 , 0 ) ;
2021-12-21 22:18:23 +00:00
if ( spawned ) spawned - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2020-12-02 22:39:38 +00:00
return spawned ;
2019-09-19 22:42:45 +00:00
}
2021-05-04 16:41:59 +00:00
static DBloodActor * actDropAmmo ( DBloodActor * actor , int nType )
2019-09-19 22:42:45 +00:00
{
2020-12-02 22:39:38 +00:00
if ( ! actor ) return nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum < kMaxStatus & & nType > = kItemAmmoBase & & nType < kItemAmmoMax )
2020-12-02 22:39:38 +00:00
{
auto act2 = actSpawnFloor ( actor ) ;
2021-05-04 16:41:59 +00:00
const AMMOITEMDATA * pAmmo = & gAmmoItemData [ nType - kItemAmmoBase ] ;
2021-12-22 14:33:13 +00:00
act2 - > spr . type = nType ;
act2 - > spr . picnum = pAmmo - > picnum ;
act2 - > spr . shade = pAmmo - > shade ;
act2 - > spr . xrepeat = pAmmo - > xrepeat ;
act2 - > spr . yrepeat = pAmmo - > yrepeat ;
2020-12-02 22:39:38 +00:00
return act2 ;
}
return nullptr ;
2019-09-19 22:42:45 +00:00
}
2021-05-04 16:41:59 +00:00
static DBloodActor * actDropWeapon ( DBloodActor * actor , int nType )
2019-09-19 22:42:45 +00:00
{
2020-12-02 22:39:38 +00:00
if ( ! actor ) return nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum < kMaxStatus & & nType > = kItemWeaponBase & & nType < kItemWeaponMax )
2020-12-02 22:39:38 +00:00
{
auto act2 = actSpawnFloor ( actor ) ;
2021-05-04 16:41:59 +00:00
const WEAPONITEMDATA * pWeapon = & gWeaponItemData [ nType - kItemWeaponBase ] ;
2021-12-22 14:33:13 +00:00
act2 - > spr . type = nType ;
act2 - > spr . picnum = pWeapon - > picnum ;
act2 - > spr . shade = pWeapon - > shade ;
act2 - > spr . xrepeat = pWeapon - > xrepeat ;
act2 - > spr . yrepeat = pWeapon - > yrepeat ;
2020-12-02 22:39:38 +00:00
return act2 ;
}
return nullptr ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 22:39:38 +00:00
static DBloodActor * actDropItem ( DBloodActor * actor , int nType )
2019-09-19 22:42:45 +00:00
{
2020-12-02 22:39:38 +00:00
if ( ! actor ) return nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum < kMaxStatus & & nType > = kItemBase & & nType < kItemMax )
2020-12-02 22:39:38 +00:00
{
auto act2 = actSpawnFloor ( actor ) ;
2021-05-04 16:41:59 +00:00
const ITEMDATA * pItem = & gItemData [ nType - kItemBase ] ;
2021-12-22 14:33:13 +00:00
act2 - > spr . type = nType ;
act2 - > spr . picnum = pItem - > picnum ;
act2 - > spr . shade = pItem - > shade ;
act2 - > spr . xrepeat = pItem - > xrepeat ;
act2 - > spr . yrepeat = pItem - > yrepeat ;
2020-12-02 22:39:38 +00:00
return act2 ;
}
return nullptr ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 22:39:38 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-05-04 16:41:59 +00:00
static DBloodActor * actDropKey ( DBloodActor * actor , int nType )
2019-09-19 22:42:45 +00:00
{
2020-12-02 22:39:38 +00:00
if ( ! actor ) return nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum < kMaxStatus & & nType > = kItemKeyBase & & nType < kItemKeyMax )
2020-12-02 22:39:38 +00:00
{
auto act2 = actDropItem ( actor , nType ) ;
if ( act2 & & gGameOptions . nGameType = = 1 )
{
act2 - > addX ( ) ;
2021-12-22 15:49:41 +00:00
act2 - > xspr . respawn = 3 ;
2021-11-26 13:03:21 +00:00
act2 - > hit . florhit . setNone ( ) ;
act2 - > hit . ceilhit . setNone ( ) ;
2020-12-02 22:39:38 +00:00
}
return act2 ;
}
return nullptr ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 22:39:38 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-05-04 16:41:59 +00:00
static DBloodActor * actDropFlag ( DBloodActor * actor , int nType )
2019-09-19 22:42:45 +00:00
{
2020-12-02 22:39:38 +00:00
if ( ! actor ) return nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum < kMaxStatus & & ( nType = = 147 | | nType = = 148 ) )
2020-12-02 22:39:38 +00:00
{
auto act2 = actDropItem ( actor , nType ) ;
if ( act2 & & gGameOptions . nGameType = = 3 )
{
2021-08-27 07:44:47 +00:00
evPostActor ( act2 , 1800 , kCallbackReturnFlag ) ;
2020-12-02 22:39:38 +00:00
}
return act2 ;
}
return nullptr ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 22:39:38 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-10-11 21:59:39 +00:00
2020-12-05 22:49:51 +00:00
DBloodActor * actDropObject ( DBloodActor * actor , int nType )
2020-12-02 22:39:38 +00:00
{
2021-05-04 16:41:59 +00:00
DBloodActor * act2 = nullptr ;
2020-12-02 23:30:19 +00:00
if ( nType > = kItemKeyBase & & nType < kItemKeyMax ) act2 = actDropKey ( actor , nType ) ;
else if ( nType = = kItemFlagA | | nType = = kItemFlagB ) act2 = actDropFlag ( actor , nType ) ;
else if ( nType > = kItemBase & & nType < kItemMax ) act2 = actDropItem ( actor , nType ) ;
else if ( nType > = kItemAmmoBase & & nType < kItemAmmoMax ) act2 = actDropAmmo ( actor , nType ) ;
else if ( nType > = kItemWeaponBase & & nType < kItemWeaponMax ) act2 = actDropWeapon ( actor , nType ) ;
2021-05-04 16:41:59 +00:00
if ( act2 )
2020-12-02 22:39:38 +00:00
{
2022-08-22 16:26:13 +00:00
double top , bottom ;
2020-12-02 22:39:38 +00:00
GetActorExtents ( act2 , & top , & bottom ) ;
2022-08-22 16:26:13 +00:00
if ( bottom > = act2 - > spr . pos . Z )
act2 - > spr . pos . Z - = ( bottom - act2 - > spr . pos . Z ) ;
2020-12-02 22:39:38 +00:00
}
return act2 ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 22:39:38 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-05-04 16:41:59 +00:00
bool actHealDude ( DBloodActor * actor , int add , int threshold )
2019-09-19 22:42:45 +00:00
{
2020-12-02 23:00:03 +00:00
if ( ! actor ) return false ;
add < < = 4 ;
threshold < < = 4 ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . health < ( unsigned ) threshold )
2021-05-04 16:41:59 +00:00
{
2022-08-20 15:11:15 +00:00
if ( actor - > IsPlayerActor ( ) ) sfxPlay3DSound ( actor - > spr . pos , 780 , actor - > sector ( ) ) ;
2021-12-22 17:12:55 +00:00
actor - > xspr . health = min < uint32_t > ( actor - > xspr . health + add , threshold ) ;
2020-12-02 23:00:03 +00:00
return true ;
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
return false ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-02 23:20:14 +00:00
2020-12-02 23:00:03 +00:00
# ifdef NOONE_EXTENSIONS
static bool actKillModernDude ( DBloodActor * actor , DAMAGE_TYPE damageType )
{
2021-08-29 07:27:03 +00:00
GENDUDEEXTRA * pExtra = & actor - > genDudeExtra ;
2021-05-05 19:18:09 +00:00
removeDudeStuff ( actor ) ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . txID < = 0 | | getNextIncarnation ( actor ) = = nullptr )
2020-12-02 23:00:03 +00:00
{
2021-06-16 19:13:04 +00:00
if ( pExtra - > weaponType = = kGenDudeWeaponKamikaze & & Chance ( 0x4000 ) & & damageType ! = kDamageSpirit & & damageType ! = kDamageDrown )
2020-12-02 23:00:03 +00:00
{
2021-12-22 17:12:55 +00:00
doExplosion ( actor , actor - > xspr . data1 - kTrapExploder ) ;
2021-09-16 19:10:23 +00:00
if ( Chance ( 0x9000 ) ) damageType = kDamageExplode ;
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
2021-06-16 19:13:04 +00:00
if ( damageType = = kDamageBurn )
2020-12-02 23:00:03 +00:00
{
2021-05-05 18:40:31 +00:00
if ( pExtra - > availDeaths [ kDamageBurn ] & & ! spriteIsUnderwater ( actor ) )
2020-12-02 23:00:03 +00:00
{
2021-05-04 16:41:59 +00:00
if ( pExtra - > canBurn )
2020-12-02 23:00:03 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeModernCustomBurning ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . data2 = = kGenDudeDefaultSeq ) // don't inherit palette for burning if using default animation
2021-12-22 15:43:59 +00:00
actor - > spr . pal = 0 ;
2021-05-04 16:41:59 +00:00
2021-08-31 19:52:26 +00:00
aiGenDudeNewState ( actor , & genDudeBurnGoto ) ;
2020-12-05 22:49:51 +00:00
actHealDude ( actor , dudeInfo [ 55 ] . startHealth , dudeInfo [ 55 ] . startHealth ) ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . burnTime < = 0 ) actor - > xspr . burnTime = 1200 ;
2020-12-04 22:21:42 +00:00
actor - > dudeExtra . time = PlayClock + 360 ;
2020-12-02 23:00:03 +00:00
return true ;
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
}
2021-05-04 16:41:59 +00:00
else
2020-12-02 23:00:03 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-29 17:22:51 +00:00
actor - > SetBurnSource ( nullptr ) ;
2021-06-16 19:13:04 +00:00
damageType = kDamageFall ;
2020-12-02 23:00:03 +00:00
}
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
}
2021-05-04 16:41:59 +00:00
else
2020-12-02 23:00:03 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . locked = 1 ; // lock while transforming
2020-12-02 23:00:03 +00:00
2021-08-28 07:50:01 +00:00
aiSetGenIdleState ( actor ) ; // set idle state
2020-12-02 23:00:03 +00:00
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . key > 0 ) // drop keys
actDropObject ( actor , kItemKeyBase + actor - > xspr . key - 1 ) ;
2020-12-02 23:00:03 +00:00
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . dropMsg > 0 ) // drop items
actDropObject ( actor , actor - > xspr . dropMsg ) ;
2020-12-02 23:00:03 +00:00
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ kPhysMove ;
2022-09-03 07:45:23 +00:00
actor - > ZeroVelocityXY ( ) ;
2020-12-02 23:00:03 +00:00
2021-05-05 17:15:25 +00:00
playGenDudeSound ( actor , kGenDudeSndTransforming ) ;
2021-12-22 17:12:55 +00:00
int seqId = actor - > xspr . data2 + kGenDudeSeqTransform ;
2020-12-02 23:00:03 +00:00
if ( getSequence ( seqId ) ) seqSpawn ( seqId , actor , - 1 ) ;
2021-05-04 16:41:59 +00:00
else
2020-12-02 23:00:03 +00:00
{
seqKill ( actor ) ;
2022-08-22 16:31:03 +00:00
DBloodActor * pEffect = gFX . fxSpawnActor ( ( FX_ID ) 52 , actor - > sector ( ) , actor - > spr . pos , actor - > int_ang ( ) ) ;
2021-12-22 15:33:03 +00:00
if ( pEffect ! = nullptr )
2020-12-02 23:00:03 +00:00
{
2021-12-22 15:33:03 +00:00
pEffect - > spr . cstat = CSTAT_SPRITE_ALIGNMENT_FACING ;
pEffect - > spr . pal = 6 ;
2021-12-22 15:43:59 +00:00
pEffect - > spr . xrepeat = actor - > spr . xrepeat ;
pEffect - > spr . yrepeat = actor - > spr . yrepeat ;
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
2021-05-04 16:41:59 +00:00
GIBTYPE nGibType ;
for ( int i = 0 ; i < 3 ; i + + )
2020-12-02 23:00:03 +00:00
{
2021-05-04 16:41:59 +00:00
if ( Chance ( 0x3000 ) ) nGibType = GIBTYPE_6 ;
else if ( Chance ( 0x2000 ) ) nGibType = GIBTYPE_5 ;
else nGibType = GIBTYPE_17 ;
2020-12-02 23:00:03 +00:00
2022-08-23 20:43:06 +00:00
double top , bottom ;
2020-12-02 23:00:03 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2022-08-23 20:43:06 +00:00
DVector3 gibPos ( actor - > spr . pos . XY ( ) , top ) ;
2022-09-01 18:43:35 +00:00
CGibVelocity gibVel ( actor - > int_vel ( ) . X > > 1 , actor - > int_vel ( ) . Y > > 1 , - 0xccccc ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , nGibType , & gibPos , & gibVel ) ;
2020-12-02 23:00:03 +00:00
}
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
2021-12-22 17:12:55 +00:00
actor - > xspr . sysData1 = kGenDudeTransformStatus ; // in transform
2020-12-02 23:00:03 +00:00
return true ;
2021-05-04 16:41:59 +00:00
}
2020-12-02 23:00:03 +00:00
return false ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 23:00:03 +00:00
# endif
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-05-04 16:41:59 +00:00
static bool actKillDudeStage1 ( DBloodActor * actor , DAMAGE_TYPE damageType )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
# ifdef NOONE_EXTENSIONS
case kDudeModernCustom :
if ( actKillModernDude ( actor , damageType ) ) return true ;
break ;
# endif
case kDudeCerberusTwoHead : // Cerberus
2021-12-22 15:43:59 +00:00
seqSpawn ( dudeInfo [ actor - > spr . type - kDudeBase ] . seqStartID + 1 , actor , - 1 ) ;
2020-12-02 23:20:14 +00:00
return true ;
2019-10-11 21:59:39 +00:00
2020-12-02 23:20:14 +00:00
case kDudeCultistTommy :
case kDudeCultistShotgun :
case kDudeCultistTesla :
case kDudeCultistTNT :
2021-12-22 17:12:55 +00:00
if ( damageType = = kDamageBurn & & actor - > xspr . medium = = kMediumNormal )
2020-12-02 23:20:14 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeBurningCultist ;
2020-12-02 23:20:14 +00:00
aiNewState ( actor , & cultistBurnGoto ) ;
actHealDude ( actor , dudeInfo [ 40 ] . startHealth , dudeInfo [ 40 ] . startHealth ) ;
return true ;
}
break ;
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
case kDudeBeast :
2021-12-22 17:12:55 +00:00
if ( damageType = = kDamageBurn & & actor - > xspr . medium = = kMediumNormal )
2020-12-02 23:20:14 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeBurningBeast ;
2020-12-02 23:20:14 +00:00
aiNewState ( actor , & beastBurnGoto ) ;
actHealDude ( actor , dudeInfo [ 53 ] . startHealth , dudeInfo [ 53 ] . startHealth ) ;
return true ;
}
break ;
2019-10-11 21:59:39 +00:00
2020-12-02 23:20:14 +00:00
case kDudeInnocent :
2021-12-22 17:12:55 +00:00
if ( damageType = = kDamageBurn & & actor - > xspr . medium = = kMediumNormal )
2020-12-02 23:20:14 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeBurningInnocent ;
2020-12-02 23:20:14 +00:00
aiNewState ( actor , & innocentBurnGoto ) ;
actHealDude ( actor , dudeInfo [ 39 ] . startHealth , dudeInfo [ 39 ] . startHealth ) ;
return true ;
}
break ;
2021-08-15 07:12:33 +00:00
case kDudeTinyCaleb :
2021-08-21 10:16:48 +00:00
if ( cl_bloodvanillaenemies | | VanillaMode ( ) )
2021-08-15 07:12:33 +00:00
break ;
2021-12-22 17:12:55 +00:00
if ( damageType = = kDamageBurn & & actor - > xspr . medium = = kMediumNormal )
2021-08-15 07:12:33 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeBurningTinyCaleb ;
2021-08-15 07:32:00 +00:00
aiNewState ( actor , & tinycalebBurnGoto ) ;
2021-08-15 07:12:33 +00:00
actHealDude ( actor , dudeInfo [ 39 ] . startHealth , dudeInfo [ 39 ] . startHealth ) ;
return true ;
}
break ;
2020-12-02 23:20:14 +00:00
}
return false ;
}
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
static void checkAddFrag ( DBloodActor * killerActor , DBloodActor * actor )
{
if ( VanillaMode ( ) )
{
if ( killerActor - > IsPlayerActor ( ) )
{
2021-12-22 15:33:03 +00:00
PLAYER * pPlayer = & gPlayer [ killerActor - > spr . type - kDudePlayer1 ] ;
2020-12-02 23:20:14 +00:00
if ( gGameOptions . nGameType = = 1 )
pPlayer - > fragCount + + ;
}
}
2021-12-22 15:43:59 +00:00
else if ( gGameOptions . nGameType = = 1 & & killerActor - > IsPlayerActor ( ) & & actor - > spr . statnum = = kStatDude )
2020-12-02 23:20:14 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
case kDudeBat :
case kDudeRat :
case kDudeInnocent :
case kDudeBurningInnocent :
break ;
default :
2021-12-22 15:33:03 +00:00
PLAYER * pKillerPlayer = & gPlayer [ killerActor - > spr . type - kDudePlayer1 ] ;
2020-12-02 23:20:14 +00:00
pKillerPlayer - > fragCount + + ;
break ;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void checkDropObjects ( DBloodActor * actor )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . key > 0 ) actDropObject ( actor , kItemKeyBase + actor - > xspr . key - 1 ) ;
if ( actor - > xspr . dropMsg > 0 ) actDropObject ( actor , actor - > xspr . dropMsg ) ;
2020-12-02 23:20:14 +00:00
2021-12-21 22:18:23 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
case kDudeCultistTommy :
{
int nRand = Random ( 100 ) ;
if ( nRand < 10 ) actDropObject ( actor , kItemWeaponTommygun ) ;
else if ( nRand < 50 ) actDropObject ( actor , kItemAmmoTommygunFew ) ;
break ;
}
case kDudeCultistShotgun :
{
int nRand = Random ( 100 ) ;
if ( nRand < = 10 ) actDropObject ( actor , kItemWeaponSawedoff ) ;
else if ( nRand < = 50 ) actDropObject ( actor , kItemAmmoSawedoffFew ) ;
break ;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int checkDamageType ( DBloodActor * actor , DAMAGE_TYPE damageType )
{
int nSeq ;
switch ( damageType )
{
2021-06-16 19:13:04 +00:00
case kDamageExplode :
2020-12-02 23:20:14 +00:00
nSeq = 2 ;
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
2020-01-26 11:19:01 +00:00
# ifdef NOONE_EXTENSIONS
2020-12-02 23:20:14 +00:00
case kDudeModernCustom :
2021-05-04 16:41:59 +00:00
case kDudeModernCustomBurning :
2020-12-02 23:20:14 +00:00
{
2021-05-05 17:15:25 +00:00
playGenDudeSound ( actor , kGenDudeSndDeathExplode ) ;
2021-08-29 07:27:03 +00:00
GENDUDEEXTRA * pExtra = & actor - > genDudeExtra ;
2021-05-04 16:41:59 +00:00
if ( ! pExtra - > availDeaths [ damageType ] )
2020-12-02 23:20:14 +00:00
{
nSeq = 1 ;
2021-06-16 19:13:04 +00:00
damageType = kDamageFall ;
2020-12-02 23:20:14 +00:00
}
break ;
}
# endif
case kDudeCultistTommy :
case kDudeCultistShotgun :
case kDudeCultistTommyProne :
case kDudeBurningInnocent :
case kDudeBurningCultist :
case kDudeInnocent :
case kDudeCultistShotgunProne :
case kDudeCultistTesla :
case kDudeCultistTNT :
case kDudeCultistBeast :
case kDudeTinyCaleb :
case kDudeBurningTinyCaleb :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 717 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
break ;
}
break ;
2021-06-16 19:13:04 +00:00
case kDamageBurn :
2020-12-02 23:20:14 +00:00
nSeq = 3 ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 351 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
break ;
2021-06-16 19:13:04 +00:00
case kDamageSpirit :
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type ) {
2020-12-02 23:20:14 +00:00
case kDudeZombieAxeNormal :
case kDudeZombieAxeBuried :
nSeq = 14 ;
break ;
case kDudeZombieButcher :
nSeq = 11 ;
break ;
default :
nSeq = 1 ;
break ;
}
break ;
2021-06-16 19:13:04 +00:00
case kDamageFall :
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
case kDudeCultistTommy :
case kDudeCultistShotgun :
nSeq = 1 ;
break ;
default :
nSeq = 1 ;
break ;
}
break ;
default :
nSeq = 1 ;
break ;
}
return nSeq ;
}
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
static void spawnGibs ( DBloodActor * actor , int type , int velz )
{
2022-08-23 20:43:06 +00:00
double top , bottom ;
2020-12-02 23:20:14 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2022-08-23 20:43:06 +00:00
DVector3 gibPos ( actor - > spr . pos . XY ( ) , top ) ;
2022-09-01 18:43:35 +00:00
CGibVelocity gibVel ( actor - > int_vel ( ) . X > > 1 , actor - > int_vel ( ) . Y > > 1 , velz ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_27 , & gibPos , & gibVel ) ;
2020-12-02 23:20:14 +00:00
}
2019-09-19 22:42:45 +00:00
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void zombieAxeNormalDeath ( DBloodActor * actor , int nSeq )
{
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:20:14 +00:00
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1107 + Random ( 2 ) , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
if ( nSeq = = 2 )
{
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , nDudeToGibClient1 ) ;
2021-05-04 16:41:59 +00:00
spawnGibs ( actor , GIBTYPE_27 , - 0xccccc ) ;
2020-12-02 23:20:14 +00:00
}
else if ( nSeq = = 1 & & Chance ( 0x4000 ) )
{
seqSpawn ( dudeInfo [ nType ] . seqStartID + 7 , actor , nDudeToGibClient1 ) ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXZombieSpurt ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 362 , - 1 , 0 ) ;
2021-12-22 15:49:41 +00:00
actor - > xspr . data1 = 35 ;
actor - > xspr . data2 = 5 ;
2020-12-02 23:20:14 +00:00
2021-05-04 16:41:59 +00:00
spawnGibs ( actor , GIBTYPE_27 , - 0x111111 ) ;
2020-12-02 23:20:14 +00:00
}
else if ( nSeq = = 14 ) seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
else if ( nSeq = = 3 ) seqSpawn ( dudeInfo [ nType ] . seqStartID + 13 , actor , nDudeToGibClient2 ) ;
else seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , nDudeToGibClient1 ) ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void burningCultistDeath ( DBloodActor * actor , int nSeq )
{
2021-09-16 19:34:16 +00:00
if ( Chance ( 0x4000 ) & & nSeq = = 3 ) sfxPlay3DSound ( actor , 718 , - 1 , 0 ) ;
else sfxPlay3DSound ( actor , 1018 + Random ( 2 ) , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:20:14 +00:00
if ( Chance ( 0x8000 ) )
{
for ( int i = 0 ; i < 3 ; i + + )
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_7 , nullptr , nullptr ) ;
2020-12-02 23:20:14 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + 16 - Random ( 1 ) , actor , nDudeToGibClient1 ) ;
}
else
seqSpawn ( dudeInfo [ nType ] . seqStartID + 15 , actor , nDudeToGibClient2 ) ;
}
# ifdef NOONE_EXTENSIONS
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void modernCustomDudeDeath ( DBloodActor * actor , int nSeq , int damageType )
{
2021-05-05 17:15:25 +00:00
playGenDudeSound ( actor , kGenDudeSndDeathNormal ) ;
2021-08-30 18:21:49 +00:00
int dudeToGib = ( actCheckRespawn ( actor ) ) ? - 1 : ( ( nSeq = = 3 ) ? nDudeToGibClient2 : nDudeToGibClient1 ) ;
2021-05-04 16:41:59 +00:00
if ( nSeq = = 3 )
2020-12-02 23:20:14 +00:00
{
2021-08-29 07:27:03 +00:00
GENDUDEEXTRA * pExtra = & actor - > genDudeExtra ;
2021-12-22 17:12:55 +00:00
if ( pExtra - > availDeaths [ kDmgBurn ] = = 3 ) seqSpawn ( ( 15 + Random ( 2 ) ) + actor - > xspr . data2 , actor , dudeToGib ) ;
else if ( pExtra - > availDeaths [ kDmgBurn ] = = 2 ) seqSpawn ( 16 + actor - > xspr . data2 , actor , dudeToGib ) ;
else if ( pExtra - > availDeaths [ kDmgBurn ] = = 1 ) seqSpawn ( 15 + actor - > xspr . data2 , actor , dudeToGib ) ;
else if ( getSequence ( actor - > xspr . data2 + nSeq ) ) seqSpawn ( nSeq + actor - > xspr . data2 , actor , dudeToGib ) ;
else seqSpawn ( 1 + actor - > xspr . data2 , actor , dudeToGib ) ;
2020-12-02 23:20:14 +00:00
}
2021-05-04 16:41:59 +00:00
else
2020-12-02 23:20:14 +00:00
{
2021-12-22 17:12:55 +00:00
seqSpawn ( nSeq + actor - > xspr . data2 , actor , dudeToGib ) ;
2020-12-02 23:20:14 +00:00
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void modernCustomDudeBurningDeath ( DBloodActor * actor , int nSeq )
{
2021-05-05 17:15:25 +00:00
playGenDudeSound ( actor , kGenDudeSndDeathExplode ) ;
2021-08-30 18:21:49 +00:00
int dudeToGib = ( actCheckRespawn ( actor ) ) ? - 1 : nDudeToGibClient1 ;
2020-12-02 23:20:14 +00:00
if ( Chance ( 0x4000 ) ) spawnGibs ( actor , GIBTYPE_27 , - 0xccccc ) ;
2021-08-29 07:27:03 +00:00
GENDUDEEXTRA * pExtra = & actor - > genDudeExtra ;
2021-12-22 15:49:41 +00:00
int seqofs = actor - > xspr . data2 ;
2020-12-02 23:20:14 +00:00
if ( pExtra - > availDeaths [ kDmgBurn ] = = 3 ) seqSpawn ( ( 15 + Random ( 2 ) ) + seqofs , actor , dudeToGib ) ;
else if ( pExtra - > availDeaths [ kDmgBurn ] = = 2 ) seqSpawn ( 16 + seqofs , actor , dudeToGib ) ;
else if ( pExtra - > availDeaths [ kDmgBurn ] = = 1 ) seqSpawn ( 15 + seqofs , actor , dudeToGib ) ;
else seqSpawn ( 1 + seqofs , actor , dudeToGib ) ;
}
2020-01-26 11:19:01 +00:00
# endif
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void zombieAxeBurningDeath ( DBloodActor * actor , int nSeq )
{
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:20:14 +00:00
if ( Chance ( 0x8000 ) & & nSeq = = 3 )
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1109 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
else
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1107 + Random ( 2 ) , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
if ( Chance ( 0x8000 ) )
{
seqSpawn ( dudeInfo [ nType ] . seqStartID + 13 , actor , nDudeToGibClient1 ) ;
spawnGibs ( actor , GIBTYPE_27 , - 0xccccc ) ;
}
else
seqSpawn ( dudeInfo [ nType ] . seqStartID + 13 , actor , nDudeToGibClient2 ) ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void zombieButcherDeath ( DBloodActor * actor , int nSeq )
{
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:20:14 +00:00
if ( nSeq = = 14 )
{
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1206 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + 11 , actor , - 1 ) ;
return ;
}
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1204 + Random ( 2 ) , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
if ( nSeq = = 3 )
seqSpawn ( dudeInfo [ nType ] . seqStartID + 10 , actor , - 1 ) ;
else
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 23:20:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void genericDeath ( DBloodActor * actor , int nSeq , int sound1 , int seqnum )
{
2021-09-16 19:34:16 +00:00
if ( Chance ( 0x4000 ) & & nSeq = = 3 ) sfxPlay3DSound ( actor , sound1 + 2 , - 1 , 0 ) ;
else sfxPlay3DSound ( actor , sound1 + Random ( 2 ) , - 1 , 0 ) ;
2021-05-04 16:41:59 +00:00
seqSpawn ( seqnum , actor , - 1 ) ;
2020-12-02 23:20:14 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actKillDude ( DBloodActor * killerActor , DBloodActor * actor , DAMAGE_TYPE damageType , int damage )
{
2021-12-22 15:43:59 +00:00
assert ( actor - > spr . type > = kDudeBase & & actor - > spr . type < kDudeMax & & actor - > hasX ( ) ) ;
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:20:14 +00:00
if ( actKillDudeStage1 ( actor , damageType ) ) return ;
for ( int p = connecthead ; p > = 0 ; p = connectpoint2 [ p ] )
{
2021-09-04 19:59:34 +00:00
if ( gPlayer [ p ] . fragger = = actor & & gPlayer [ p ] . deathTime > 0 )
gPlayer [ p ] . fragger = nullptr ;
2020-12-02 23:20:14 +00:00
}
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type ! = kDudeCultistBeast )
2022-08-10 21:45:29 +00:00
trTriggerSprite ( actor , kCmdOff , killerActor ) ;
2020-12-02 23:20:14 +00:00
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = 7 ;
2020-12-02 23:20:14 +00:00
checkAddFrag ( killerActor , actor ) ;
checkDropObjects ( actor ) ;
int nSeq = checkDamageType ( actor , damageType ) ;
2021-05-04 16:41:59 +00:00
if ( ! getSequence ( getDudeInfo ( nType + kDudeBase ) - > seqStartID + nSeq ) )
2020-12-02 23:20:14 +00:00
{
seqKill ( actor ) ;
2021-12-22 15:43:59 +00:00
gKillMgr . AddKill ( actor ) ;
2020-12-02 23:20:14 +00:00
actPostSprite ( actor , kStatFree ) ;
return ;
}
2020-12-04 22:21:42 +00:00
auto Owner = actor - > GetOwner ( ) ;
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
case kDudeZombieAxeNormal :
zombieAxeNormalDeath ( actor , nSeq ) ;
break ;
case kDudeCultistTommy :
case kDudeCultistShotgun :
case kDudeCultistTesla :
case kDudeCultistTNT :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1018 + Random ( 2 ) , - 1 , 0 ) ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , nSeq = = 3 ? nDudeToGibClient2 : nDudeToGibClient1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeBurningCultist :
burningCultistDeath ( actor , nSeq ) ;
2021-06-16 19:13:04 +00:00
damageType = kDamageExplode ;
2020-12-02 23:20:14 +00:00
break ;
# ifdef NOONE_EXTENSIONS
case kDudeModernCustom :
modernCustomDudeDeath ( actor , nSeq , damageType ) ;
2021-05-06 08:55:56 +00:00
genDudePostDeath ( actor , damageType , damage ) ;
2020-12-02 23:20:14 +00:00
return ;
case kDudeModernCustomBurning :
modernCustomDudeBurningDeath ( actor , nSeq ) ;
2021-05-06 08:55:56 +00:00
genDudePostDeath ( actor , kDamageExplode , damage ) ;
2020-12-02 23:20:14 +00:00
return ;
# endif
case kDudeBurningZombieAxe :
zombieAxeBurningDeath ( actor , nSeq ) ;
2021-06-16 19:13:04 +00:00
damageType = kDamageExplode ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeBurningZombieButcher :
genericDeath ( actor , nSeq , 1204 , dudeInfo [ 4 ] . seqStartID + 10 ) ;
break ;
case kDudeBurningInnocent :
2021-06-16 19:13:04 +00:00
damageType = kDamageExplode ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + 7 , actor , nDudeToGibClient1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeZombieButcher :
zombieButcherDeath ( actor , nSeq ) ;
break ;
case kDudeGargoyleFlesh :
genericDeath ( actor , nSeq , 1403 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeGargoyleStone :
genericDeath ( actor , nSeq , 1453 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudePhantasm :
genericDeath ( actor , nSeq , 1603 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeHellHound :
genericDeath ( actor , nSeq , 1303 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeHand :
genericDeath ( actor , nSeq , 1903 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeSpiderBrown :
2021-10-06 20:20:57 +00:00
if ( Owner ) Owner - > dudeExtra . stats . birthCounter - - ;
2020-12-02 23:20:14 +00:00
genericDeath ( actor , nSeq , 1803 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeSpiderRed :
2021-10-06 20:20:57 +00:00
if ( Owner ) Owner - > dudeExtra . stats . birthCounter - - ;
2020-12-02 23:20:14 +00:00
genericDeath ( actor , nSeq , 1803 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeSpiderBlack :
2021-10-06 20:20:57 +00:00
if ( Owner ) Owner - > dudeExtra . stats . birthCounter - - ;
2020-12-02 23:20:14 +00:00
genericDeath ( actor , nSeq , 1803 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeSpiderMother :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 1850 , - 1 , 0 ) ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeGillBeast :
genericDeath ( actor , nSeq , 1703 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeBoneEel :
genericDeath ( actor , nSeq , 1503 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeBat :
genericDeath ( actor , nSeq , 2003 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeRat :
genericDeath ( actor , nSeq , 2103 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudePodGreen :
case kDudeTentacleGreen :
case kDudePodFire :
case kDudeTentacleFire :
2021-12-22 15:43:59 +00:00
if ( ( actor - > spr . cstat & CSTAT_SPRITE_YFLIP ) ) actor - > spr . cstat & = ~ CSTAT_SPRITE_YFLIP ;
switch ( actor - > spr . type )
2020-12-02 23:20:14 +00:00
{
case kDudePodGreen :
genericDeath ( actor , nSeq , 2203 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeTentacleGreen :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , damage = = 5 ? 2471 : 2472 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
break ;
case kDudePodFire :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , damage = = 5 ? 2451 : 2452 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
break ;
case kDudeTentacleFire :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 2501 , - 1 , 0 ) ;
2020-12-02 23:20:14 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
break ;
}
break ;
case kDudePodMother :
case kDudeTentacleMother :
genericDeath ( actor , nSeq , 2203 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeCerberusTwoHead :
case kDudeCerberusOneHead :
genericDeath ( actor , nSeq , 2303 , dudeInfo [ nType ] . seqStartID + nSeq ) ;
break ;
case kDudeTchernobog :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 2380 , - 1 , 0 ) ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , - 1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeBurningTinyCaleb :
2021-06-16 19:13:04 +00:00
damageType = kDamageExplode ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + 11 , actor , nDudeToGibClient1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeBeast :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 9000 + Random ( 2 ) , - 1 , 0 ) ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + nSeq , actor , nSeq = = 3 ? nDudeToGibClient2 : nDudeToGibClient1 ) ;
2020-12-02 23:20:14 +00:00
break ;
case kDudeBurningBeast :
2021-06-16 19:13:04 +00:00
damageType = kDamageExplode ;
2021-05-04 16:41:59 +00:00
seqSpawn ( dudeInfo [ nType ] . seqStartID + 12 , actor , nDudeToGibClient1 ) ;
2020-12-02 23:20:14 +00:00
break ;
default :
2021-05-04 16:41:59 +00:00
seqSpawn ( getDudeInfo ( nType + kDudeBase ) - > seqStartID + nSeq , actor , - 1 ) ;
2020-12-02 23:20:14 +00:00
break ;
}
2021-05-04 16:41:59 +00:00
2021-06-16 19:13:04 +00:00
if ( damageType = = kDamageExplode )
2020-12-02 23:20:14 +00:00
{
2021-12-22 15:43:59 +00:00
DUDEINFO * pDudeInfo = getDudeInfo ( actor - > spr . type ) ;
2020-12-02 23:20:14 +00:00
for ( int i = 0 ; i < 3 ; i + + )
if ( pDudeInfo - > nGibType [ i ] > - 1 )
2021-08-29 20:22:16 +00:00
GibSprite ( actor , ( GIBTYPE ) pDudeInfo - > nGibType [ i ] , nullptr , nullptr ) ;
2020-12-02 23:20:14 +00:00
for ( int i = 0 ; i < 4 ; i + + )
2021-08-26 22:07:33 +00:00
fxSpawnBlood ( actor , damage ) ;
2020-12-02 23:20:14 +00:00
}
2021-12-22 15:43:59 +00:00
gKillMgr . AddKill ( actor ) ;
2021-08-30 18:21:49 +00:00
actCheckRespawn ( actor ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . type = kThingBloodChunks ;
2020-12-02 23:20:14 +00:00
actPostSprite ( actor , kStatThing ) ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-02 23:30:19 +00:00
static int actDamageDude ( DBloodActor * source , DBloodActor * actor , int damage , DAMAGE_TYPE damageType )
{
if ( ! actor - > IsDudeActor ( ) )
{
2021-12-22 15:43:59 +00:00
Printf ( PRINT_HIGH , " Bad Dude Failed: initial=%d type=%d %s \n " , ( int ) actor - > spr . inittype , ( int ) actor - > spr . type , ( int ) ( actor - > spr . flags & kHitagRespawn ) ? " RESPAWN " : " NORMAL " ) ;
2020-12-02 23:30:19 +00:00
return damage > > 4 ;
2021-12-22 15:43:59 +00:00
//I_Error("Bad Dude Failed: initial=%d type=%d %s\n", (int)actor->spr.inittype, (int)actor->spr.type, (int)(actor->spr.flags & 16) ? "RESPAWN" : "NORMAL");
2020-12-02 23:30:19 +00:00
}
2019-10-12 20:45:46 +00:00
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kDudeBase ;
2020-12-02 23:30:19 +00:00
int nDamageFactor = getDudeInfo ( nType + kDudeBase ) - > damageVal [ damageType ] ;
# ifdef NOONE_EXTENSIONS
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kDudeModernCustom )
2021-08-29 07:27:03 +00:00
nDamageFactor = actor - > genDudeExtra . dmgControl [ damageType ] ;
2020-12-02 23:30:19 +00:00
# endif
2019-10-20 14:50:47 +00:00
2020-12-02 23:30:19 +00:00
if ( ! nDamageFactor ) return 0 ;
else if ( nDamageFactor ! = 256 ) damage = MulScale ( damage , nDamageFactor , 8 ) ;
2019-11-08 19:57:01 +00:00
2021-08-29 07:44:08 +00:00
if ( ! actor - > IsPlayerActor ( ) )
2020-12-02 23:30:19 +00:00
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . health < = 0 ) return 0 ;
2020-12-02 23:30:19 +00:00
damage = aiDamageSprite ( source , actor , damageType , damage ) ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . health < = 0 )
2021-06-16 19:13:04 +00:00
actKillDude ( source , actor , ( ( damageType = = kDamageExplode & & damage < 160 ) ? kDamageFall : damageType ) , damage ) ;
2020-12-02 23:30:19 +00:00
}
else
{
2021-12-22 15:43:59 +00:00
PLAYER * pPlayer = & gPlayer [ actor - > spr . type - kDudePlayer1 ] ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . health > 0 | | playerSeqPlaying ( pPlayer , 16 ) )
2020-12-02 23:30:19 +00:00
damage = playerDamageSprite ( source , pPlayer , damageType , damage ) ;
2019-10-12 20:45:46 +00:00
2020-12-02 23:30:19 +00:00
}
return damage ;
}
2019-10-12 20:45:46 +00:00
2020-12-02 23:30:19 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-10-12 20:45:46 +00:00
2020-12-02 23:30:19 +00:00
static int actDamageThing ( DBloodActor * source , DBloodActor * actor , int damage , DAMAGE_TYPE damageType , PLAYER * pSourcePlayer )
{
2021-12-22 15:43:59 +00:00
assert ( actor - > spr . type > = kThingBase & & actor - > spr . type < kThingMax ) ;
int nType = actor - > spr . type - kThingBase ;
2020-12-02 23:30:19 +00:00
int nDamageFactor = thingInfo [ nType ] . dmgControl [ damageType ] ;
2020-01-26 11:19:01 +00:00
2020-12-02 23:30:19 +00:00
if ( ! nDamageFactor ) return 0 ;
else if ( nDamageFactor ! = 256 ) damage = MulScale ( damage , nDamageFactor , 8 ) ;
2019-10-11 21:59:39 +00:00
2021-12-22 17:12:55 +00:00
actor - > xspr . health = ClipLow ( actor - > xspr . health - damage , 0 ) ;
if ( actor - > xspr . health < = 0 )
2020-12-02 23:30:19 +00:00
{
auto Owner = actor - > GetOwner ( ) ;
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:30:19 +00:00
{
case kThingDroppedLifeLeech :
# ifdef NOONE_EXTENSIONS
case kModernThingEnemyLifeLeech :
# endif
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_14 , nullptr , nullptr ) ;
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = actor - > xspr . data2 = actor - > xspr . data3 = actor - > xspr . DudeLockout = 0 ;
actor - > xspr . stateTimer = actor - > xspr . data4 = actor - > xspr . isTriggered = 0 ;
2020-12-02 23:30:19 +00:00
# ifdef NOONE_EXTENSIONS
2021-12-21 22:18:23 +00:00
if ( Owner & & Owner - > spr . type = = kDudeModernCustom )
2020-12-02 23:30:19 +00:00
Owner - > SetSpecialOwner ( ) ; // indicates if custom dude had life leech.
# endif
break ;
default :
2021-12-22 15:43:59 +00:00
if ( ! ( actor - > spr . flags & kHitagRespawn ) )
2020-12-02 23:30:19 +00:00
actor - > SetOwner ( source ) ;
break ;
}
2022-08-10 21:45:29 +00:00
trTriggerSprite ( actor , kCmdOff , source ) ;
2020-12-02 23:30:19 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-02 23:30:19 +00:00
{
case kThingObjectGib :
case kThingObjectExplode :
case kThingBloodBits :
case kThingBloodChunks :
case kThingZombieHead :
if ( damageType = = 3 & & pSourcePlayer & & PlayClock > pSourcePlayer - > laughCount & & Chance ( 0x4000 ) )
{
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( pSourcePlayer - > actor , gPlayerGibThingComments [ Random ( 10 ) ] , 0 , 2 ) ;
2020-12-02 23:30:19 +00:00
pSourcePlayer - > laughCount = PlayClock + 3600 ;
}
break ;
case kTrapMachinegun :
2021-09-04 21:27:21 +00:00
seqSpawn ( 28 , actor , - 1 ) ;
2020-12-02 23:30:19 +00:00
break ;
case kThingFluorescent :
2021-09-04 21:27:21 +00:00
seqSpawn ( 12 , actor , - 1 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_6 , nullptr , nullptr ) ;
2020-12-02 23:30:19 +00:00
break ;
case kThingSpiderWeb :
2021-09-04 21:27:21 +00:00
seqSpawn ( 15 , actor , - 1 ) ;
2020-12-02 23:30:19 +00:00
break ;
case kThingMetalGrate :
2021-09-04 21:27:21 +00:00
seqSpawn ( 21 , actor , - 1 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_4 , nullptr , nullptr ) ;
2020-12-02 23:30:19 +00:00
break ;
case kThingFlammableTree :
2021-12-22 17:12:55 +00:00
switch ( actor - > xspr . data1 )
2020-12-02 23:30:19 +00:00
{
case - 1 :
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_14 , nullptr , nullptr ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( actor - > spr . pos , 312 , actor - > sector ( ) ) ;
2020-12-02 23:30:19 +00:00
actPostSprite ( actor , kStatFree ) ;
break ;
case 0 :
seqSpawn ( 25 , actor , nTreeToGibClient ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 351 , - 1 , 0 ) ;
2020-12-02 23:30:19 +00:00
break ;
case 1 :
2021-09-04 21:27:21 +00:00
seqSpawn ( 26 , actor , nTreeToGibClient ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 351 , - 1 , 0 ) ;
2020-12-02 23:30:19 +00:00
break ;
}
break ;
}
}
return damage ;
2019-09-19 22:42:45 +00:00
}
2020-12-02 23:30:19 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int actDamageSprite ( DBloodActor * source , DBloodActor * actor , DAMAGE_TYPE damageType , int damage )
2020-12-02 19:55:08 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 | | ! actor - > hasX ( ) )
2020-12-02 23:30:19 +00:00
return 0 ;
2021-12-22 17:12:55 +00:00
if ( ( actor - > xspr . health = = 0 & & actor - > spr . statnum ! = kStatDude ) | | actor - > xspr . locked )
2020-12-02 23:30:19 +00:00
return 0 ;
if ( source = = nullptr ) source = actor ;
2020-12-03 17:00:07 +00:00
PLAYER * pSourcePlayer = nullptr ;
2021-12-21 22:18:23 +00:00
if ( source - > IsPlayerActor ( ) ) pSourcePlayer = & gPlayer [ source - > spr . type - kDudePlayer1 ] ;
2021-12-22 15:43:59 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pSourcePlayer , actor ) ) return 0 ;
2020-12-02 23:30:19 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . statnum )
2020-12-02 23:30:19 +00:00
{
case kStatDude :
damage = actDamageDude ( source , actor , damage , damageType ) ;
break ;
case kStatThing :
damage = actDamageThing ( source , actor , damage , damageType , pSourcePlayer ) ;
break ;
}
return damage > > 4 ;
2020-12-02 19:55:08 +00:00
}
2020-12-02 23:30:19 +00:00
//---------------------------------------------------------------------------
//
2020-12-03 17:00:07 +00:00
// this was condensed to the parts actually in use.
2020-12-02 23:30:19 +00:00
//
//---------------------------------------------------------------------------
2021-11-25 22:28:28 +00:00
void actHitcodeToData ( int a1 , HitInfo * pHitInfo , DBloodActor * * pActor , walltype * * ppWall )
2019-09-19 22:42:45 +00:00
{
2020-12-03 17:00:07 +00:00
assert ( pHitInfo ! = nullptr ) ;
2021-05-05 14:43:42 +00:00
DBloodActor * actor = nullptr ;
2020-12-03 17:00:07 +00:00
walltype * pWall = nullptr ;
switch ( a1 )
{
case 3 :
case 5 :
2021-11-25 22:28:28 +00:00
actor = pHitInfo - > actor ( ) ;
2020-12-03 17:00:07 +00:00
break ;
case 0 :
case 4 :
2021-11-23 16:00:00 +00:00
pWall = pHitInfo - > hitWall ;
2020-12-03 17:00:07 +00:00
break ;
default :
break ;
}
2021-05-05 14:43:42 +00:00
if ( pActor ) * pActor = actor ;
if ( ppWall ) * ppWall = pWall ;
2019-09-19 22:42:45 +00:00
}
2020-12-03 17:00:07 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actImpactMissile ( DBloodActor * missileActor , int hitCode )
2019-09-19 22:42:45 +00:00
{
2020-12-03 17:00:07 +00:00
auto missileOwner = missileActor - > GetOwner ( ) ;
2019-10-11 21:59:39 +00:00
2020-12-03 17:00:07 +00:00
DBloodActor * actorHit = nullptr ;
walltype * pWallHit = nullptr ;
2019-09-21 11:02:17 +00:00
2020-12-03 17:00:07 +00:00
actHitcodeToData ( hitCode , & gHitInfo , & actorHit , & pWallHit ) ;
const THINGINFO * pThingInfo = nullptr ;
DUDEINFO * pDudeInfo = nullptr ;
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:47:58 +00:00
switch ( actorHit - > spr . statnum )
2020-12-03 17:00:07 +00:00
{
case kStatThing :
2021-12-22 15:47:58 +00:00
pThingInfo = & thingInfo [ actorHit - > spr . type - kThingBase ] ;
2020-12-03 17:00:07 +00:00
break ;
case kStatDude :
2021-12-22 15:47:58 +00:00
pDudeInfo = getDudeInfo ( actorHit - > spr . type ) ;
2020-12-03 17:00:07 +00:00
break ;
}
}
2021-12-22 15:33:03 +00:00
switch ( missileActor - > spr . type )
2020-12-03 17:00:07 +00:00
{
case kMissileLifeLeechRegular :
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
DAMAGE_TYPE rand1 = ( DAMAGE_TYPE ) Random ( 7 ) ;
int rand2 = ( 7 + Random ( 7 ) ) < < 4 ;
int nDamage = actDamageSprite ( missileOwner , actorHit , rand1 , rand2 ) ;
2021-06-16 19:13:04 +00:00
if ( ( pThingInfo & & pThingInfo - > dmgControl [ kDamageBurn ] ! = 0 ) | | ( pDudeInfo & & pDudeInfo - > damageVal [ kDamageBurn ] ! = 0 ) )
2020-12-03 17:00:07 +00:00
actBurnSprite ( missileActor - > GetOwner ( ) , actorHit , 360 ) ;
// by NoOne: make Life Leech heal user, just like it was in 1.0x versions
2021-08-21 10:16:48 +00:00
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) & & pDudeInfo ! = nullptr )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:49:41 +00:00
if ( missileOwner - > IsDudeActor ( ) & & missileOwner - > hasX ( ) & & missileOwner - > xspr . health ! = 0 )
2021-12-21 22:18:23 +00:00
actHealDude ( missileOwner , nDamage > > 2 , getDudeInfo ( missileOwner - > spr . type ) - > startHealth ) ;
2020-12-03 17:00:07 +00:00
}
}
2021-09-05 07:59:10 +00:00
if ( missileActor - > hasX ( ) )
2020-12-03 17:00:07 +00:00
{
actPostSprite ( missileActor , kStatDecoration ) ;
2022-09-02 21:52:58 +00:00
if ( missileActor - > spr . angle = = DAngle180 ) sfxPlay3DSound ( missileActor , 307 , - 1 , 0 ) ;
2021-12-22 15:33:03 +00:00
missileActor - > spr . type = kSpriteDecoration ;
2020-12-03 17:00:07 +00:00
seqSpawn ( 9 , missileActor , - 1 ) ;
}
else
{
2021-08-28 11:59:29 +00:00
actPostSprite ( missileActor , kStatFree ) ;
2020-12-03 17:00:07 +00:00
}
break ;
case kMissileTeslaAlt :
2021-09-04 22:10:28 +00:00
teslaHit ( missileActor , hitCode ) ;
2020-12-03 17:00:07 +00:00
switch ( hitCode )
{
case 0 :
case 4 :
if ( pWallHit )
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_52 , missileActor - > sector ( ) , missileActor - > spr . pos , 0 ) ;
2022-08-16 21:20:03 +00:00
if ( pFX ) pFX - > set_int_ang ( ( GetWallAngle ( pWallHit ) + 512 ) & 2047 ) ;
2020-12-03 17:00:07 +00:00
}
break ;
}
2021-08-29 20:22:16 +00:00
GibSprite ( missileActor , GIBTYPE_24 , NULL , NULL ) ;
2020-12-03 17:00:07 +00:00
actPostSprite ( missileActor , kStatFree ) ;
break ;
case kMissilePukeGreen :
seqKill ( missileActor ) ;
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
int nDamage = ( 15 + Random ( 7 ) ) < < 4 ;
2021-09-16 19:10:23 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
actPostSprite ( missileActor , kStatFree ) ;
break ;
case kMissileArcGargoyle :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( missileActor - > spr . pos , 306 , missileActor - > sector ( ) ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( missileActor , GIBTYPE_6 , NULL , NULL ) ;
2020-12-03 17:00:07 +00:00
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
int nDamage = ( 25 + Random ( 20 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageSpirit , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
actPostSprite ( missileActor , kStatFree ) ;
break ;
case kMissileLifeLeechAltNormal :
case kMissileLifeLeechAltSmall :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( missileActor - > spr . pos , 306 , missileActor - > sector ( ) ) ;
2020-12-03 17:00:07 +00:00
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:33:03 +00:00
int nDmgMul = ( missileActor - > spr . type = = kMissileLifeLeechAltSmall ) ? 6 : 3 ;
2020-12-03 17:00:07 +00:00
int nDamage = ( nDmgMul + Random ( nDmgMul ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageSpirit , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
actPostSprite ( missileActor , kStatFree ) ;
break ;
case kMissileFireball :
2021-08-22 07:49:02 +00:00
case kMissileFireballNapalm :
2021-12-22 15:47:58 +00:00
if ( hitCode = = 3 & & actorHit & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:49:41 +00:00
if ( pThingInfo & & actorHit - > spr . type = = kThingTNTBarrel & & actorHit - > xspr . burnTime = = 0 )
2021-08-27 07:44:47 +00:00
evPostActor ( actorHit , 0 , kCallbackFXFlameLick ) ;
2020-12-03 17:00:07 +00:00
int nDamage = ( 50 + Random ( 50 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
break ;
case kMissileFlareAlt :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
break ;
case kMissileFlareRegular :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2021-12-22 15:47:58 +00:00
if ( ( hitCode = = 3 & & actorHit ) & & ( pThingInfo | | pDudeInfo ) )
2020-12-03 17:00:07 +00:00
{
2021-06-16 19:13:04 +00:00
if ( ( pThingInfo & & pThingInfo - > dmgControl [ kDamageBurn ] ! = 0 ) | | ( pDudeInfo & & pDudeInfo - > damageVal [ kDamageBurn ] ! = 0 ) )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:47:58 +00:00
if ( pThingInfo & & actorHit - > spr . type = = kThingTNTBarrel & & actorHit - > xspr . burnTime = = 0 )
2021-08-27 07:44:47 +00:00
evPostActor ( actorHit , 0 , kCallbackFXFlameLick ) ;
2020-12-03 17:00:07 +00:00
actBurnSprite ( missileOwner , actorHit , 480 ) ;
2022-08-22 16:18:54 +00:00
actRadiusDamage ( missileOwner , missileActor - > spr . pos , missileActor - > sector ( ) , 16 , 20 , 10 , kDamageBullet , 6 , 480 ) ;
2020-12-03 17:00:07 +00:00
// by NoOne: allow additional bullet damage for Flare Gun
2021-08-21 10:16:48 +00:00
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) )
2020-12-03 17:00:07 +00:00
{
int nDamage = ( 20 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
}
else
{
int nDamage = ( 20 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
2021-12-22 15:47:58 +00:00
if ( surfType [ actorHit - > spr . picnum ] = = kSurfFlesh )
2020-12-03 17:00:07 +00:00
{
2021-12-22 15:33:03 +00:00
missileActor - > spr . picnum = 2123 ;
2020-12-03 17:00:07 +00:00
missileActor - > SetTarget ( actorHit ) ;
2022-08-22 16:31:45 +00:00
missileActor - > xspr . TargetPos . Z = ( missileActor - > spr . pos . Z - actorHit - > spr . pos . Z ) ;
2022-09-03 22:38:26 +00:00
missileActor - > xspr . goalAng = VecToAngle ( missileActor - > spr . pos . XY ( ) - actorHit - > spr . pos . XY ( ) ) - actorHit - > spr . angle ;
2021-12-22 16:57:58 +00:00
missileActor - > xspr . state = 1 ;
2021-08-28 11:59:29 +00:00
actPostSprite ( missileActor , kStatFlare ) ;
2021-12-22 15:33:03 +00:00
missileActor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2020-12-03 17:00:07 +00:00
break ;
}
}
2021-08-29 20:22:16 +00:00
GibSprite ( missileActor , GIBTYPE_17 , NULL , NULL ) ;
2020-12-03 17:00:07 +00:00
actPostSprite ( missileActor , kStatFree ) ;
break ;
case kMissileFlameSpray :
case kMissileFlameHound :
if ( hitCode = = 3 & & actorHit & & actorHit - > hasX ( ) )
{
2021-12-22 16:57:58 +00:00
if ( ( actorHit - > spr . statnum = = kStatThing | | actorHit - > spr . statnum = = kStatDude ) & & actorHit - > xspr . burnTime = = 0 )
2021-08-27 07:44:47 +00:00
evPostActor ( actorHit , 0 , kCallbackFXFlameLick ) ;
2020-12-03 17:00:07 +00:00
actBurnSprite ( missileOwner , actorHit , ( 4 + gGameOptions . nDifficulty ) < < 2 ) ;
2021-08-19 12:28:00 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBurn , 8 ) ;
2020-12-03 17:00:07 +00:00
}
break ;
case kMissileFireballCerberus :
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
if ( hitCode = = 3 & & actorHit & & actorHit - > hasX ( ) )
{
2021-12-22 16:57:58 +00:00
if ( ( actorHit - > spr . statnum = = kStatThing | | actorHit - > spr . statnum = = kStatDude ) & & actorHit - > xspr . burnTime = = 0 )
2021-08-27 07:44:47 +00:00
evPostActor ( actorHit , 0 , kCallbackFXFlameLick ) ;
2020-12-03 17:00:07 +00:00
actBurnSprite ( missileOwner , actorHit , ( 4 + gGameOptions . nDifficulty ) < < 2 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBurn , 8 ) ;
2020-12-03 17:00:07 +00:00
int nDamage = ( 25 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
break ;
case kMissileFireballTchernobog :
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
if ( hitCode = = 3 & & actorHit & & actorHit - > hasX ( ) )
{
2021-12-22 16:57:58 +00:00
if ( ( actorHit - > spr . statnum = = kStatThing | | actorHit - > spr . statnum = = kStatDude ) & & actorHit - > xspr . burnTime = = 0 )
2021-08-27 07:44:47 +00:00
evPostActor ( actorHit , 0 , kCallbackFXFlameLick ) ;
2020-12-03 17:00:07 +00:00
actBurnSprite ( missileOwner , actorHit , 32 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageSpirit , 12 ) ;
2020-12-03 17:00:07 +00:00
int nDamage = ( 25 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageBullet , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
2020-12-05 11:17:28 +00:00
actExplodeSprite ( missileActor ) ;
2020-12-03 17:00:07 +00:00
break ;
case kMissileEctoSkull :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( missileActor - > spr . pos , 522 , missileActor - > sector ( ) ) ;
2021-08-28 11:59:29 +00:00
actPostSprite ( missileActor , kStatDebris ) ;
2021-09-04 21:27:21 +00:00
seqSpawn ( 20 , missileActor , - 1 ) ;
2020-12-03 17:00:07 +00:00
if ( hitCode = = 3 & & actorHit & & actorHit - > hasX ( ) )
{
2021-12-22 15:47:58 +00:00
if ( actorHit - > spr . statnum = = kStatDude )
2020-12-03 17:00:07 +00:00
{
int nDamage = ( 25 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageSpirit , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
}
break ;
case kMissileButcherKnife :
actPostSprite ( missileActor , kStatDebris ) ;
2021-12-22 15:33:03 +00:00
missileActor - > spr . cstat & = ~ CSTAT_SPRITE_ALIGNMENT_WALL ;
missileActor - > spr . type = kSpriteDecoration ;
2021-09-04 21:27:21 +00:00
seqSpawn ( 20 , missileActor , - 1 ) ;
2020-12-03 17:00:07 +00:00
if ( hitCode = = 3 & & actorHit & & actorHit - > hasX ( ) )
{
2021-12-22 15:47:58 +00:00
if ( actorHit - > spr . statnum = = kStatDude )
2020-12-03 17:00:07 +00:00
{
int nDamage = ( 10 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageSpirit , nDamage ) ;
2021-12-21 22:18:23 +00:00
int nType = missileOwner - > spr . type - kDudeBase ;
2021-12-22 15:49:41 +00:00
if ( missileOwner - > xspr . health > 0 )
2020-12-03 17:00:07 +00:00
actHealDude ( missileOwner , 10 , getDudeInfo ( nType + kDudeBase ) - > startHealth ) ;
}
}
break ;
case kMissileTeslaRegular :
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( missileActor , - 1 , - 1 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( missileActor - > spr . pos , 518 , missileActor - > sector ( ) ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( missileActor , ( hitCode = = 2 ) ? GIBTYPE_23 : GIBTYPE_22 , NULL , NULL ) ;
2021-08-27 07:44:47 +00:00
evKillActor ( missileActor ) ;
2020-12-03 17:00:07 +00:00
seqKill ( missileActor ) ;
actPostSprite ( missileActor , kStatFree ) ;
if ( hitCode = = 3 & & actorHit )
{
int nDamage = ( 15 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageTesla , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
break ;
default :
seqKill ( missileActor ) ;
actPostSprite ( missileActor , kStatFree ) ;
if ( hitCode = = 3 & & actorHit )
{
int nDamage = ( 10 + Random ( 10 ) ) < < 4 ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( missileOwner , actorHit , kDamageFall , nDamage ) ;
2020-12-03 17:00:07 +00:00
}
break ;
}
# ifdef NOONE_EXTENSIONS
2022-01-01 00:38:30 +00:00
if ( gModernMap & & actorHit & & actorHit - > hasX ( ) & & actorHit - > xspr . state ! = actorHit - > xspr . restState & & actorHit - > xspr . Impact )
2022-08-10 21:45:29 +00:00
trTriggerSprite ( actorHit , kCmdSpriteImpact , missileActor ) ;
2020-12-03 17:00:07 +00:00
# endif
2021-12-22 15:33:03 +00:00
missileActor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2019-09-19 22:42:45 +00:00
}
2020-12-03 17:38:30 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actKickObject ( DBloodActor * kicker , DBloodActor * kicked )
2019-09-19 22:42:45 +00:00
{
2022-09-01 18:49:35 +00:00
int nSpeed = ClipLow ( approxDist ( kicker - > int_vel ( ) . X , kicker - > int_vel ( ) . Y ) * 2 , 0xaaaaa ) ;
2022-09-01 19:18:16 +00:00
kicked - > set_int_bvel_x ( MulScale ( nSpeed , Cos ( kicker - > int_ang ( ) + Random2 ( 85 ) ) , 30 ) ) ;
2022-09-01 19:24:29 +00:00
kicked - > set_int_bvel_y ( MulScale ( nSpeed , Sin ( kicker - > int_ang ( ) + Random2 ( 85 ) ) , 30 ) ) ;
2022-09-01 19:40:03 +00:00
kicked - > set_int_bvel_z ( MulScale ( nSpeed , - 0x2000 , 14 ) ) ;
2021-12-21 22:18:23 +00:00
kicked - > spr . flags = 7 ;
2019-09-19 22:42:45 +00:00
}
2020-12-03 17:38:30 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-19 17:08:05 +00:00
static void actTouchFloor ( DBloodActor * actor , sectortype * pSector )
2019-09-19 22:42:45 +00:00
{
2021-12-29 18:41:41 +00:00
XSECTOR * pXSector = pSector - > hasX ( ) ? & pSector - > xs ( ) : nullptr ;
2019-09-19 22:42:45 +00:00
2020-12-06 20:56:09 +00:00
bool doDamage = ( pXSector & & ( pSector - > type = = kSectorDamage | | pXSector - > damageType > 0 ) ) ;
// don't allow damage for damage sectors if they are not enabled
2021-08-25 06:46:31 +00:00
# ifdef NOONE_EXTENSIONS
2020-12-06 20:56:09 +00:00
if ( gModernMap & & doDamage & & pSector - > type = = kSectorDamage & & ! pXSector - > state )
doDamage = false ;
2021-08-25 06:46:31 +00:00
# endif
2020-12-06 20:56:09 +00:00
if ( doDamage ) {
2020-12-03 17:38:30 +00:00
DAMAGE_TYPE nDamageType ;
2021-06-16 19:13:04 +00:00
if ( pSector - > type = = kSectorDamage ) nDamageType = ( DAMAGE_TYPE ) ClipRange ( pXSector - > damageType , kDamageFall , kDamageTesla ) ;
else nDamageType = ( DAMAGE_TYPE ) ClipRange ( pXSector - > damageType - 1 , kDamageFall , kDamageTesla ) ;
2019-10-20 14:50:47 +00:00
2020-12-03 17:38:30 +00:00
int nDamage ;
if ( pXSector - > data ) nDamage = ClipRange ( pXSector - > data , 0 , 1000 ) ;
else nDamage = 1000 ;
2019-10-20 14:50:47 +00:00
2021-12-30 07:32:06 +00:00
actDamageSprite ( actor , actor , nDamageType , Scale ( 4 , nDamage , 120 ) < < 4 ) ;
2020-12-03 17:38:30 +00:00
}
2021-11-19 17:08:05 +00:00
if ( tileGetSurfType ( pSector - > floorpicnum ) = = kSurfLava )
2020-12-03 17:38:30 +00:00
{
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor , actor , kDamageBurn , 16 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 352 , 5 , 2 ) ;
2020-12-03 17:38:30 +00:00
}
2019-09-19 22:42:45 +00:00
}
2020-12-03 17:38:30 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-03 19:30:30 +00:00
static void checkCeilHit ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-05 19:55:19 +00:00
auto & coll = actor - > hit . ceilhit ;
2020-12-03 19:30:30 +00:00
switch ( coll . type )
{
case kHitWall :
break ;
case kHitSprite :
2021-12-05 19:55:19 +00:00
auto actor2 = coll . actor ( ) ;
if ( actor2 & & actor2 - > hasX ( ) )
2020-12-03 19:30:30 +00:00
{
2022-09-03 08:12:09 +00:00
if ( ( actor2 - > spr . statnum = = kStatThing | | actor2 - > spr . statnum = = kStatDude ) & & ( actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 | | actor - > vel . Z ! = 0 ) )
2020-12-03 19:30:30 +00:00
{
2022-08-23 20:23:34 +00:00
auto adelta = actor2 - > spr . pos - actor - > spr . pos ;
2021-12-22 14:33:13 +00:00
if ( actor2 - > spr . statnum = = kStatThing )
2020-12-03 19:30:30 +00:00
{
2021-12-22 14:33:13 +00:00
int nType = actor2 - > spr . type - kThingBase ;
2020-12-03 19:30:30 +00:00
const THINGINFO * pThingInfo = & thingInfo [ nType ] ;
2021-12-22 14:33:13 +00:00
if ( pThingInfo - > flags & 1 ) actor2 - > spr . flags | = 1 ;
if ( pThingInfo - > flags & 2 ) actor2 - > spr . flags | = 4 ;
2020-12-03 19:30:30 +00:00
// Inlined ?
2022-09-01 19:02:20 +00:00
actor2 - > add_int_bvel_x ( int ( adelta . X * 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor2 - > add_int_bvel_y ( int ( adelta . Y * 16 ) ) ;
2020-12-03 19:30:30 +00:00
}
else
{
2021-12-22 14:33:13 +00:00
actor2 - > spr . flags | = 5 ;
2022-09-01 19:02:20 +00:00
actor2 - > add_int_bvel_x ( int ( adelta . X * 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor2 - > add_int_bvel_y ( int ( adelta . Y * 16 ) ) ;
2020-12-03 19:30:30 +00:00
# ifdef NOONE_EXTENSIONS
// add size shroom abilities
2021-08-29 11:44:04 +00:00
if ( ( actor - > IsPlayerActor ( ) & & isShrinked ( actor ) ) | | ( actor2 - > IsPlayerActor ( ) & & isGrown ( actor2 ) ) ) {
2020-12-03 19:30:30 +00:00
2021-12-22 14:33:13 +00:00
int mass1 = getDudeInfo ( actor2 - > spr . type ) - > mass ;
2021-12-22 15:43:59 +00:00
int mass2 = getDudeInfo ( actor - > spr . type ) - > mass ;
switch ( actor - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kDudeModernCustom :
case kDudeModernCustomBurning :
2021-08-27 17:12:22 +00:00
mass2 = getSpriteMassBySize ( actor ) ;
2020-12-03 19:30:30 +00:00
break ;
}
if ( mass1 > mass2 )
{
2021-12-22 15:43:59 +00:00
int dmg = abs ( ( mass1 - mass2 ) * ( actor2 - > spr . clipdist - actor - > spr . clipdist ) ) ;
2020-12-03 19:30:30 +00:00
if ( actor2 - > IsDudeActor ( ) )
{
2021-09-16 19:10:23 +00:00
if ( dmg > 0 ) actDamageSprite ( actor2 , actor , ( Chance ( 0x2000 ) ) ? kDamageFall : ( Chance ( 0x4000 ) ) ? kDamageExplode : kDamageBullet , dmg ) ;
2020-12-03 19:30:30 +00:00
if ( Chance ( 0x0200 ) ) actKickObject ( actor2 , actor ) ;
}
}
}
# endif
2021-12-22 15:43:59 +00:00
if ( ! actor - > IsPlayerActor ( ) | | gPlayer [ actor - > spr . type - kDudePlayer1 ] . godMode = = 0 )
2020-12-03 19:30:30 +00:00
{
2021-12-22 14:33:13 +00:00
switch ( actor2 - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kDudeTchernobog :
2021-12-22 16:57:58 +00:00
actDamageSprite ( actor2 , actor , kDamageExplode , actor - > xspr . health < < 2 ) ;
2020-12-03 19:30:30 +00:00
break ;
# ifdef NOONE_EXTENSIONS
case kDudeModernCustom :
case kDudeModernCustomBurning :
int dmg = 0 ;
2021-08-27 17:12:22 +00:00
if ( ! actor - > IsDudeActor ( ) | | ( dmg = ClipLow ( ( getSpriteMassBySize ( actor2 ) - getSpriteMassBySize ( actor ) ) > > 1 , 0 ) ) = = 0 )
2020-12-03 19:30:30 +00:00
break ;
if ( ! actor - > IsPlayerActor ( ) )
{
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor2 , actor , kDamageFall , dmg ) ;
2021-12-22 16:57:58 +00:00
if ( actor - > hasX ( ) & & ! actor - > isActive ( ) ) aiActivateDude ( actor ) ;
2020-12-03 19:30:30 +00:00
}
2021-12-22 15:43:59 +00:00
else if ( powerupCheck ( & gPlayer [ actor - > spr . type - kDudePlayer1 ] , kPwUpJumpBoots ) > 0 ) actDamageSprite ( actor2 , actor , kDamageExplode , dmg ) ;
2021-06-16 19:13:04 +00:00
else actDamageSprite ( actor2 , actor , kDamageFall , dmg ) ;
2020-12-03 19:30:30 +00:00
break ;
# endif
}
}
}
}
2021-12-22 16:57:58 +00:00
if ( actor2 - > spr . type = = kTrapSawCircular & & actor2 - > hasX ( ) )
2020-12-03 19:30:30 +00:00
{
2021-12-22 16:57:58 +00:00
if ( ! actor2 - > xspr . state ) actDamageSprite ( actor , actor , kDamageBullet , 1 ) ;
2020-12-03 19:30:30 +00:00
else {
2021-12-22 16:57:58 +00:00
actor2 - > xspr . data1 = 1 ;
actor2 - > xspr . data2 = ClipHigh ( actor2 - > xspr . data2 + 8 , 600 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor , actor , kDamageBullet , 16 ) ;
2020-12-03 19:30:30 +00:00
}
}
}
break ;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void checkHit ( DBloodActor * actor )
{
2021-12-11 01:59:46 +00:00
const auto & coll = actor - > hit . hit ;
2020-12-03 19:30:30 +00:00
switch ( coll . type )
{
case kHitWall :
break ;
case kHitSprite :
2021-11-26 13:03:21 +00:00
if ( coll . actor ( ) - > hasX ( ) )
2020-12-03 19:30:30 +00:00
{
2021-11-26 13:03:21 +00:00
auto actor2 = coll . actor ( ) ;
2020-12-03 19:30:30 +00:00
# ifdef NOONE_EXTENSIONS
// add size shroom abilities
2021-08-29 11:44:04 +00:00
if ( ( actor2 - > IsPlayerActor ( ) & & isShrinked ( actor2 ) ) | | ( actor - > IsPlayerActor ( ) & & isGrown ( actor ) ) )
2020-12-03 19:30:30 +00:00
{
2022-09-03 08:12:09 +00:00
if ( actor - > vel . X ! = 0 & & actor2 - > IsDudeActor ( ) )
2020-12-03 19:30:30 +00:00
{
2021-12-22 15:43:59 +00:00
int mass1 = getDudeInfo ( actor - > spr . type ) - > mass ;
2021-12-22 14:33:13 +00:00
int mass2 = getDudeInfo ( actor2 - > spr . type ) - > mass ;
switch ( actor2 - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kDudeModernCustom :
case kDudeModernCustomBurning :
2021-08-27 17:12:22 +00:00
mass2 = getSpriteMassBySize ( actor2 ) ;
2020-12-03 19:30:30 +00:00
break ;
}
if ( mass1 > mass2 )
{
actKickObject ( actor , actor2 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 357 , - 1 , 1 ) ;
2022-09-01 18:49:35 +00:00
int dmg = ( mass1 - mass2 ) + abs ( FixedToInt ( actor - > int_vel ( ) . X ) ) ;
2021-06-16 19:13:04 +00:00
if ( dmg > 0 ) actDamageSprite ( actor , actor2 , ( Chance ( 0x2000 ) ) ? kDamageFall : kDamageBullet , dmg ) ;
2020-12-03 19:30:30 +00:00
}
}
}
# endif
2021-12-22 14:33:13 +00:00
switch ( actor2 - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kThingKickablePail :
actKickObject ( actor , actor2 ) ;
break ;
case kThingZombieHead :
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( actor - > spr . pos , 357 , actor - > sector ( ) ) ;
2020-12-03 19:30:30 +00:00
actKickObject ( actor , actor2 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( nullptr , actor2 , kDamageFall , 80 ) ;
2020-12-03 19:30:30 +00:00
break ;
case kDudeBurningInnocent :
case kDudeBurningCultist :
case kDudeBurningZombieAxe :
case kDudeBurningZombieButcher :
// This does not make sense
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = ClipLow ( actor - > xspr . burnTime - 4 , 0 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor - > GetBurnSource ( ) , actor , kDamageBurn , 8 ) ;
2020-12-03 19:30:30 +00:00
break ;
}
}
break ;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void checkFloorHit ( DBloodActor * actor )
{
2021-12-11 01:59:46 +00:00
const auto & coll = actor - > hit . florhit ;
2020-12-03 19:30:30 +00:00
switch ( coll . type )
{
case kHitWall :
break ;
case kHitSector :
2021-11-26 13:03:21 +00:00
actTouchFloor ( actor , coll . hitSector ) ;
2020-12-03 19:30:30 +00:00
break ;
case kHitSprite :
2021-11-26 13:03:21 +00:00
if ( coll . actor ( ) - > hasX ( ) )
2020-12-03 19:30:30 +00:00
{
2021-11-26 13:03:21 +00:00
auto actor2 = coll . actor ( ) ;
2020-12-03 19:30:30 +00:00
# ifdef NOONE_EXTENSIONS
// add size shroom abilities
2021-08-29 11:44:04 +00:00
if ( ( actor2 - > IsPlayerActor ( ) & & isShrinked ( actor2 ) ) | | ( actor - > IsPlayerActor ( ) & & isGrown ( actor ) ) )
2020-12-03 19:30:30 +00:00
{
2021-12-22 15:43:59 +00:00
int mass1 = getDudeInfo ( actor - > spr . type ) - > mass ;
2021-12-22 14:33:13 +00:00
int mass2 = getDudeInfo ( actor2 - > spr . type ) - > mass ;
switch ( actor2 - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kDudeModernCustom :
case kDudeModernCustomBurning :
2021-08-27 17:12:22 +00:00
mass2 = getSpriteMassBySize ( actor2 ) ;
2020-12-03 19:30:30 +00:00
break ;
}
2021-09-01 19:52:36 +00:00
if ( mass1 > mass2 & & actor2 - > IsDudeActor ( ) )
2020-12-03 19:30:30 +00:00
{
2021-12-22 14:33:13 +00:00
if ( ( actor2 - > IsPlayerActor ( ) & & Chance ( 0x500 ) ) | | ! actor2 - > IsPlayerActor ( ) )
2020-12-03 19:30:30 +00:00
actKickObject ( actor , actor2 ) ;
2021-12-22 15:43:59 +00:00
int dmg = ( mass1 - mass2 ) + actor - > spr . clipdist ;
2021-06-16 19:13:04 +00:00
if ( dmg > 0 ) actDamageSprite ( actor , actor2 , ( Chance ( 0x2000 ) ) ? kDamageFall : kDamageBullet , dmg ) ;
2020-12-03 19:30:30 +00:00
}
}
# endif
PLAYER * pPlayer = nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > IsPlayerActor ( ) ) pPlayer = & gPlayer [ actor - > spr . type - kDudePlayer1 ] ;
2020-12-03 19:30:30 +00:00
2021-12-22 14:33:13 +00:00
switch ( actor2 - > spr . type )
2020-12-03 19:30:30 +00:00
{
case kThingKickablePail :
if ( pPlayer )
{
if ( pPlayer - > kickPower > PlayClock ) return ;
pPlayer - > kickPower = PlayClock + 60 ;
}
actKickObject ( actor , actor2 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( actor - > spr . pos , 357 , actor - > sector ( ) ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 374 , 0 , 0 ) ;
2020-12-03 19:30:30 +00:00
break ;
case kThingZombieHead :
if ( pPlayer )
{
if ( pPlayer - > kickPower > PlayClock ) return ;
pPlayer - > kickPower = PlayClock + 60 ;
}
actKickObject ( actor , actor2 ) ;
2022-08-20 15:11:15 +00:00
sfxPlay3DSound ( actor - > spr . pos , 357 , actor - > sector ( ) ) ;
2021-09-16 19:10:23 +00:00
actDamageSprite ( nullptr , actor2 , kDamageFall , 80 ) ;
2020-12-03 19:30:30 +00:00
break ;
case kTrapSawCircular :
2021-12-22 16:57:58 +00:00
if ( ! actor2 - > xspr . state ) actDamageSprite ( actor , actor , kDamageBullet , 1 ) ;
2020-12-03 19:30:30 +00:00
else
{
2021-12-22 16:57:58 +00:00
actor2 - > xspr . data1 = 1 ;
actor2 - > xspr . data2 = ClipHigh ( actor2 - > xspr . data2 + 8 , 600 ) ;
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor , actor , kDamageBullet , 16 ) ;
2020-12-03 19:30:30 +00:00
}
break ;
case kDudeCultistTommy :
case kDudeCultistShotgun :
case kDudeZombieAxeNormal :
case kDudeZombieButcher :
case kDudeZombieAxeBuried :
case kDudeGargoyleFlesh :
case kDudeGargoyleStone :
case kDudePhantasm :
case kDudeHellHound :
case kDudeHand :
case kDudeSpiderBrown :
case kDudeSpiderRed :
case kDudeSpiderBlack :
case kDudeGillBeast :
case kDudeBat :
case kDudeRat :
case kDudePodGreen :
case kDudeTentacleGreen :
case kDudePodFire :
case kDudeTentacleFire :
case kDudePodMother :
case kDudeTentacleMother :
case kDudeCerberusTwoHead :
case kDudeCerberusOneHead :
case kDudeTchernobog :
case kDudePlayer1 :
case kDudePlayer2 :
case kDudePlayer3 :
case kDudePlayer4 :
case kDudePlayer5 :
case kDudePlayer6 :
case kDudePlayer7 :
case kDudePlayer8 :
# ifdef NOONE_EXTENSIONS
2021-08-29 11:44:04 +00:00
if ( pPlayer & & ! isShrinked ( actor ) )
2020-12-03 19:30:30 +00:00
# else
if ( pPlayer )
# endif
2021-06-16 19:13:04 +00:00
actDamageSprite ( actor , actor2 , kDamageBullet , 8 ) ;
2020-12-03 19:30:30 +00:00
break ;
}
}
break ;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void ProcessTouchObjects ( DBloodActor * actor )
{
checkCeilHit ( actor ) ;
checkHit ( actor ) ;
checkFloorHit ( actor ) ;
# ifdef NOONE_EXTENSIONS
// add more trigger statements for Touch flag
if ( gModernMap & & actor - > IsDudeActor ( ) )
{
DBloodActor * actor2 = nullptr ;
2021-12-29 18:41:41 +00:00
for ( auto * coll : { & actor - > hit . hit , & actor - > hit . florhit , & actor - > hit . ceilhit } )
2020-12-03 19:30:30 +00:00
{
2021-09-02 18:23:51 +00:00
if ( coll - > type = = kHitSprite )
2020-12-03 19:30:30 +00:00
{
2021-11-26 13:03:21 +00:00
actor2 = coll - > actor ( ) ;
2020-12-03 19:30:30 +00:00
break ;
}
}
2021-07-18 06:56:49 +00:00
if ( actor2 & & actor2 - > hasX ( ) )
2020-12-03 17:38:30 +00:00
{
2022-08-10 21:45:29 +00:00
triggerTouchSprite ( actor , actor2 ) ;
2020-12-03 19:30:30 +00:00
}
// Touch walls
2021-12-11 01:59:46 +00:00
const auto & coll = actor - > hit . hit ;
2021-11-19 00:12:05 +00:00
walltype * pHWall = nullptr ;
2020-12-03 19:30:30 +00:00
if ( coll . type = = kHitWall )
{
2021-11-26 13:03:21 +00:00
pHWall = coll . hitWall ;
2021-11-19 00:12:05 +00:00
if ( pHWall & & pHWall - > hasX ( ) )
2020-12-03 17:38:30 +00:00
{
2022-08-10 21:45:29 +00:00
triggerTouchWall ( actor , pHWall ) ;
2020-12-03 19:30:30 +00:00
}
}
}
# endif
2019-09-19 22:42:45 +00:00
}
2020-12-03 19:30:30 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-03 21:04:07 +00:00
void actAirDrag ( DBloodActor * actor , int a2 )
2019-09-19 22:42:45 +00:00
{
2020-12-03 21:04:07 +00:00
int wind_x = 0 ;
int wind_y = 0 ;
2021-12-30 15:51:56 +00:00
assert ( actor - > sector ( ) ) ;
sectortype * pSector = actor - > sector ( ) ;
2021-11-19 17:08:05 +00:00
if ( pSector - > hasX ( ) )
2021-08-23 17:21:41 +00:00
{
2021-11-19 17:08:05 +00:00
XSECTOR * pXSector = & pSector - > xs ( ) ;
2021-08-23 17:21:41 +00:00
if ( pXSector - > windVel & & ( pXSector - > windAlways | | pXSector - > busy ) )
{
2020-12-03 21:04:07 +00:00
int wind = pXSector - > windVel < < 12 ;
if ( ! pXSector - > windAlways & & pXSector - > busy ) wind = MulScale ( wind , pXSector - > busy , 16 ) ;
wind_x = MulScale ( wind , Cos ( pXSector - > windAng ) , 30 ) ;
wind_y = MulScale ( wind , Sin ( pXSector - > windAng ) , 30 ) ;
2021-08-23 17:21:41 +00:00
}
}
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( wind_x - actor - > int_vel ( ) . X , a2 , 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( wind_y - actor - > int_vel ( ) . Y , a2 , 16 ) ) ;
2022-09-01 19:10:35 +00:00
actor - > add_int_bvel_z ( - MulScale ( actor - > int_vel ( ) . Z , a2 , 16 ) ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-03 21:04:07 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-09-02 18:23:51 +00:00
static Collision MoveThing ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2020-12-03 21:04:07 +00:00
assert ( actor - > hasX ( ) ) ;
2021-12-22 15:43:59 +00:00
assert ( actor - > spr . type > = kThingBase & & actor - > spr . type < kThingMax ) ;
const THINGINFO * pThingInfo = & thingInfo [ actor - > spr . type - kThingBase ] ;
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2021-11-23 23:18:14 +00:00
assert ( pSector ) ;
2021-08-23 17:21:41 +00:00
int top , bottom ;
2021-09-02 18:23:51 +00:00
Collision lhit ;
2020-12-03 21:04:07 +00:00
2021-09-02 18:23:51 +00:00
lhit . setNone ( ) ;
2020-12-03 21:04:07 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2021-08-23 17:21:41 +00:00
const int bakCompat = enginecompatibility_mode ;
2022-09-03 16:18:43 +00:00
if ( actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
auto bakCstat = actor - > spr . cstat ;
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2021-08-29 21:10:19 +00:00
if ( ( actor - > GetOwner ( ) ) & & ! cl_bloodvanillaexplosions & & ! VanillaMode ( ) )
2021-08-23 17:21:41 +00:00
enginecompatibility_mode = ENGINECOMPATIBILITY_NONE ; // improved clipmove accuracy
2022-09-01 18:43:35 +00:00
ClipMove ( actor - > spr . pos , & pSector , actor - > int_vel ( ) . X > > 12 , actor - > int_vel ( ) . Y > > 12 , actor - > spr . clipdist < < 2 , ( actor - > int_pos ( ) . Z - top ) / 4 , ( bottom - actor - > int_pos ( ) . Z ) / 4 , CLIPMASK0 , lhit ) ;
2021-11-26 13:03:21 +00:00
actor - > hit . hit = lhit ;
2021-08-23 17:21:41 +00:00
enginecompatibility_mode = bakCompat ; // restore
2021-12-22 15:43:59 +00:00
actor - > spr . cstat = bakCstat ;
2021-11-23 23:18:14 +00:00
assert ( pSector ) ;
2021-12-30 15:51:56 +00:00
if ( actor - > sector ( ) ! = pSector )
2021-08-23 17:21:41 +00:00
{
2021-11-23 23:18:14 +00:00
assert ( pSector ) ;
ChangeActorSect ( actor , pSector ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-03 21:04:07 +00:00
2021-12-29 18:41:41 +00:00
auto & coll = actor - > hit . hit ;
2020-12-03 21:04:07 +00:00
if ( coll . type = = kHitWall )
{
2022-09-03 07:37:52 +00:00
actWallBounceVector ( actor , coll . hitWall , FixedToFloat ( pThingInfo - > elastic ) ) ;
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-03 21:04:07 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingZombieHead :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 607 , 0 , 0 ) ;
2020-12-03 21:04:07 +00:00
actDamageSprite ( nullptr , actor , kDamageFall , 80 ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
2021-08-25 06:46:31 +00:00
case kThingKickablePail :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 374 , 0 , 0 ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
}
}
else
{
2021-11-23 23:18:14 +00:00
assert ( pSector ) ;
2022-08-25 17:15:06 +00:00
auto pSector2 = pSector ;
updatesectorz ( actor - > spr . pos , & pSector2 ) ;
if ( pSector2 ) pSector = pSector2 ;
2021-08-23 17:21:41 +00:00
}
2020-12-03 21:04:07 +00:00
2022-09-03 16:18:43 +00:00
actor - > spr . pos . Z + = actor - > vel . Z ;
2020-12-03 21:04:07 +00:00
2021-09-02 18:23:51 +00:00
int ceilZ , floorZ ;
Collision ceilColl , floorColl ;
2021-12-22 15:43:59 +00:00
GetZRange ( actor , & ceilZ , & ceilColl , & floorZ , & floorColl , actor - > spr . clipdist < < 2 , CLIPMASK0 ) ;
2020-12-03 21:04:07 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2021-12-22 15:43:59 +00:00
if ( ( actor - > spr . flags & 2 ) & & bottom < floorZ )
2021-08-23 17:21:41 +00:00
{
2022-08-20 15:59:15 +00:00
actor - > spr . pos . Z + = 1.777 ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( 58254 ) ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kThingZombieHead )
2021-08-23 17:21:41 +00:00
{
2022-08-22 16:31:03 +00:00
auto * fxActor = gFX . fxSpawnActor ( FX_27 , actor - > sector ( ) , actor - > spr . pos , 0 ) ;
2020-12-03 21:04:07 +00:00
if ( fxActor )
2021-08-23 17:21:41 +00:00
{
2020-12-03 21:04:07 +00:00
int v34 = ( PlayClock * 3 ) & 2047 ;
int v30 = ( PlayClock * 5 ) & 2047 ;
int vbx = ( PlayClock * 11 ) & 2047 ;
2021-08-23 17:21:41 +00:00
int v2c = 0x44444 ;
int v28 = 0 ;
int v24 = 0 ;
2020-12-03 21:04:07 +00:00
RotateVector ( & v2c , & v28 , vbx ) ;
RotateVector ( & v2c , & v24 , v30 ) ;
RotateVector ( & v28 , & v24 , v34 ) ;
2022-09-01 19:18:16 +00:00
fxActor - > set_int_bvel_x ( actor - > int_vel ( ) . X + v2c ) ;
2022-09-01 19:24:29 +00:00
fxActor - > set_int_bvel_y ( actor - > int_vel ( ) . Y + v28 ) ;
2022-09-01 19:40:03 +00:00
fxActor - > set_int_bvel_z ( actor - > int_vel ( ) . Z + v24 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
2021-12-22 15:43:59 +00:00
if ( CheckLink ( actor ) ) GetZRange ( actor , & ceilZ , & ceilColl , & floorZ , & floorColl , actor - > spr . clipdist < < 2 , CLIPMASK0 ) ;
2020-12-03 21:04:07 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2021-08-23 17:21:41 +00:00
if ( bottom > = floorZ )
{
2021-12-30 15:51:56 +00:00
actTouchFloor ( actor , actor - > sector ( ) ) ;
2021-08-29 17:09:29 +00:00
actor - > hit . florhit = floorColl ;
2022-01-30 15:20:11 +00:00
actor - > add_int_z ( floorZ - bottom ) ;
2020-12-03 21:04:07 +00:00
2022-09-03 22:28:30 +00:00
double veldiff = actor - > vel . Z - actor - > sector ( ) - > velFloor ;
if ( veldiff > 0 )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = 4 ;
2022-09-02 21:56:03 +00:00
2022-09-03 22:28:30 +00:00
auto vec4 = actFloorBounceVector ( actor , veldiff , actor - > sector ( ) , FixedToFloat ( pThingInfo - > elastic ) ) ;
2022-09-03 08:02:25 +00:00
actor - > vel . XY ( ) = vec4 . XY ( ) ;
2022-09-02 21:56:03 +00:00
int vax = FloatToFixed ( vec4 . W ) ;
2020-12-03 21:04:07 +00:00
int nDamage = MulScale ( vax , vax , 30 ) - pThingInfo - > dmgResist ;
if ( nDamage > 0 ) actDamageSprite ( actor , actor , kDamageFall , nDamage ) ;
2019-10-20 14:50:47 +00:00
2022-09-02 21:56:03 +00:00
actor - > set_int_bvel_z ( FloatToFixed ( vec4 . Z ) ) ;
2022-09-03 22:28:30 +00:00
if ( actor - > sector ( ) - > velFloor = = 0 & & abs ( actor - > vel . Z ) < 1 )
2021-08-23 17:21:41 +00:00
{
2022-09-03 08:11:05 +00:00
actor - > vel . Z = 0 ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 4 ;
2021-08-23 17:21:41 +00:00
}
2020-12-03 21:04:07 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-03 21:04:07 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingNapalmBall :
2022-09-03 08:12:09 +00:00
if ( actor - > vel . Z = = 0 | | Chance ( 0xA000 ) ) actNapalmMove ( actor ) ;
2021-08-25 06:46:31 +00:00
break ;
2020-12-03 21:04:07 +00:00
2021-08-25 06:46:31 +00:00
case kThingZombieHead :
2022-09-03 08:12:52 +00:00
if ( abs ( actor - > vel . Z ) > 8 )
2020-12-03 21:04:07 +00:00
{
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 607 , 0 , 0 ) ;
2020-12-03 21:04:07 +00:00
actDamageSprite ( nullptr , actor , kDamageFall , 80 ) ;
2021-08-25 06:46:31 +00:00
}
break ;
2020-12-03 21:04:07 +00:00
2021-08-25 06:46:31 +00:00
case kThingKickablePail :
2022-09-03 08:12:52 +00:00
if ( abs ( actor - > vel . Z ) > 8 )
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 374 , 0 , 0 ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
2019-10-11 21:59:39 +00:00
2021-11-23 23:18:14 +00:00
lhit . setSector ( pSector ) ;
2021-08-23 17:21:41 +00:00
}
2022-09-03 08:12:09 +00:00
else if ( actor - > vel . Z = = 0 )
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 4 ;
2021-08-23 17:21:41 +00:00
}
else
{
2021-11-26 13:03:21 +00:00
actor - > hit . florhit . setNone ( ) ;
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 2 )
actor - > spr . flags | = 4 ;
2021-08-23 17:21:41 +00:00
}
2020-12-03 21:04:07 +00:00
2021-08-23 17:21:41 +00:00
if ( top < = ceilZ )
{
2021-08-29 17:09:29 +00:00
actor - > hit . ceilhit = ceilColl ;
2022-01-30 15:20:11 +00:00
actor - > add_int_z ( ClipLow ( ceilZ - top , 0 ) ) ;
2022-09-03 08:12:09 +00:00
if ( actor - > vel . Z < 0 )
2021-08-23 17:21:41 +00:00
{
2022-09-03 16:18:43 +00:00
actor - > vel . XY ( ) * = 0.75 ;
actor - > vel . Z * = - 0.25 ;
2020-12-03 21:04:07 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-03 21:04:07 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingZombieHead :
2022-09-03 08:12:52 +00:00
if ( abs ( actor - > vel . Z ) > 8 )
2020-12-03 21:04:07 +00:00
{
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 607 , 0 , 0 ) ;
2020-12-03 21:04:07 +00:00
actDamageSprite ( nullptr , actor , kDamageFall , 80 ) ;
2021-08-25 06:46:31 +00:00
}
break ;
2020-12-03 21:04:07 +00:00
2021-08-25 06:46:31 +00:00
case kThingKickablePail :
2022-09-03 08:12:52 +00:00
if ( abs ( actor - > vel . Z ) > 8 )
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 374 , 0 , 0 ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
}
}
2021-11-26 13:03:21 +00:00
else actor - > hit . ceilhit . setNone ( ) ;
2020-12-03 21:04:07 +00:00
2021-08-23 17:21:41 +00:00
if ( bottom > = floorZ )
{
2022-09-03 16:18:43 +00:00
double nVel = actor - > vel . XY ( ) . Length ( ) ;
2022-10-09 04:14:48 +00:00
double nVelClipped = min ( nVel , ( 16. / 15. ) ) ;
2021-09-02 18:23:51 +00:00
Collision & coll = floorColl ;
2020-12-04 23:08:51 +00:00
if ( coll . type = = kHitSprite )
2021-08-23 17:21:41 +00:00
{
2021-11-26 13:03:21 +00:00
auto hitActor = coll . actor ( ) ;
2021-12-22 15:33:03 +00:00
if ( ( hitActor - > spr . cstat & CSTAT_SPRITE_ALIGNMENT_MASK ) = = CSTAT_SPRITE_ALIGNMENT_FACING )
2021-08-23 17:21:41 +00:00
{
2022-09-03 16:18:43 +00:00
actor - > vel . XY ( ) + = ( actor - > spr . pos . XY ( ) - hitActor - > spr . pos . XY ( ) ) / 4096. ;
2021-08-29 17:09:29 +00:00
lhit = actor - > hit . hit ;
2021-08-23 17:21:41 +00:00
}
}
if ( nVel > 0 )
{
2022-10-09 04:14:48 +00:00
actor - > vel . XY ( ) - = actor - > vel . XY ( ) * nVelClipped / nVel ;
2021-08-23 17:21:41 +00:00
}
}
2022-09-03 16:18:43 +00:00
if ( actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 )
actor - > spr . angle = VecToAngle ( actor - > vel ) ;
2020-12-03 21:04:07 +00:00
return lhit ;
2019-09-19 22:42:45 +00:00
}
2020-12-03 21:04:07 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-05 09:40:13 +00:00
void MoveDude ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2020-12-05 09:40:13 +00:00
PLAYER * pPlayer = nullptr ;
2021-12-22 15:43:59 +00:00
if ( actor - > IsPlayerActor ( ) ) pPlayer = & gPlayer [ actor - > spr . type - kDudePlayer1 ] ;
if ( ! ( actor - > spr . type > = kDudeBase & & actor - > spr . type < kDudeMax ) )
2020-12-04 13:25:04 +00:00
{
2021-12-22 15:43:59 +00:00
Printf ( PRINT_HIGH , " %d: actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax " , actor - > spr . type ) ;
2021-08-23 17:21:41 +00:00
return ;
}
2020-12-04 13:25:04 +00:00
2021-12-22 15:43:59 +00:00
DUDEINFO * pDudeInfo = getDudeInfo ( actor - > spr . type ) ;
2021-08-23 17:21:41 +00:00
int top , bottom ;
GetActorExtents ( actor , & top , & bottom ) ;
2022-01-30 17:09:26 +00:00
int bz = ( bottom - actor - > int_pos ( ) . Z ) / 4 ;
int tz = ( actor - > int_pos ( ) . Z - top ) / 4 ;
2021-12-22 15:43:59 +00:00
int wd = actor - > spr . clipdist < < 2 ;
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2021-12-22 17:12:55 +00:00
int nAiStateType = ( actor - > xspr . aiState ) ? actor - > xspr . aiState - > stateType : - 1 ;
2021-07-19 21:15:26 +00:00
2021-11-23 23:16:02 +00:00
assert ( pSector ) ;
2020-12-04 13:25:04 +00:00
2022-09-03 08:12:09 +00:00
if ( actor - > vel . X ! = 0 | | actor - > int_vel ( ) . Y )
2021-08-23 17:21:41 +00:00
{
if ( pPlayer & & gNoClip )
{
2022-09-01 18:43:35 +00:00
actor - > add_int_pos ( { actor - > int_vel ( ) . X > > 12 , actor - > int_vel ( ) . Y > > 12 , 0 } ) ;
2022-08-25 17:15:06 +00:00
updatesector ( actor - > spr . pos , & pSector ) ;
if ( ! pSector ) pSector = actor - > sector ( ) ;
2021-08-23 17:21:41 +00:00
}
else
{
2021-12-22 15:43:59 +00:00
auto bakCstat = actor - > spr . cstat ;
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2022-09-01 18:43:35 +00:00
ClipMove ( actor - > spr . pos , & pSector , actor - > int_vel ( ) . X > > 12 , actor - > int_vel ( ) . Y > > 12 , wd , tz , bz , CLIPMASK0 , actor - > hit . hit ) ;
2021-11-23 23:16:02 +00:00
if ( pSector = = nullptr )
2021-08-23 17:21:41 +00:00
{
2021-12-30 15:51:56 +00:00
pSector = actor - > sector ( ) ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum = = kStatDude | | actor - > spr . statnum = = kStatThing )
2021-09-16 19:10:23 +00:00
actDamageSprite ( actor , actor , kDamageFall , 1000 < < 4 ) ;
2021-08-23 17:21:41 +00:00
}
2021-11-23 23:16:02 +00:00
if ( pSector - > type > = kSectorPath & & pSector - > type < = kSectorRotate )
2021-08-23 17:21:41 +00:00
{
2021-11-23 23:16:02 +00:00
auto pSector2 = pSector ;
2022-01-30 16:56:38 +00:00
if ( pushmove ( actor , & pSector2 , wd , tz , bz , CLIPMASK0 ) = = - 1 )
2021-08-23 17:21:41 +00:00
actDamageSprite ( actor , actor , kDamageFall , 1000 < < 4 ) ;
2021-11-23 23:16:02 +00:00
if ( pSector2 ! = nullptr )
pSector = pSector2 ;
2021-08-23 17:21:41 +00:00
}
2021-11-23 23:16:02 +00:00
assert ( pSector ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . cstat = bakCstat ;
2021-08-23 17:21:41 +00:00
}
2021-12-05 19:55:19 +00:00
auto & coll = actor - > hit . hit ;
2021-09-02 18:23:51 +00:00
switch ( coll . type )
2021-08-23 17:21:41 +00:00
{
case kHitSprite :
{
2021-12-22 15:33:03 +00:00
auto hitActor = coll . actor ( ) ;
2021-12-22 16:57:58 +00:00
auto Owner = hitActor - > GetOwner ( ) ;
2020-12-04 13:25:04 +00:00
2021-12-22 15:33:03 +00:00
if ( hitActor - > spr . statnum = = kStatProjectile & & ! ( hitActor - > spr . flags & 32 ) & & actor ! = Owner )
2021-08-23 17:21:41 +00:00
{
2021-11-25 22:28:28 +00:00
auto hitInfo = gHitInfo ;
gHitInfo . hitActor = actor ;
2021-12-22 16:57:58 +00:00
actImpactMissile ( hitActor , 3 ) ;
2021-08-23 17:21:41 +00:00
gHitInfo = hitInfo ;
}
2020-12-05 09:40:13 +00:00
# ifdef NOONE_EXTENSIONS
2021-12-22 16:57:58 +00:00
if ( ! gModernMap & & hitActor - > hasX ( ) & & hitActor - > xspr . Touch & & ! hitActor - > xspr . state & & ! hitActor - > xspr . isTriggered )
2022-08-10 21:45:29 +00:00
trTriggerSprite ( coll . actor ( ) , kCmdSpriteTouch , actor ) ;
2020-12-05 09:40:13 +00:00
# else
2021-12-22 16:57:58 +00:00
if ( hitActor - > hasX ( ) & & hitActor - > xspr . Touch & & ! hitActor - > xspr . state & & ! hitActor - > xspr . isTriggered )
2021-08-25 06:46:31 +00:00
trTriggerSprite ( coll . actor , kCmdSpriteTouch ) ;
2020-12-05 09:40:13 +00:00
# endif
2019-12-23 20:10:28 +00:00
2021-12-22 16:57:58 +00:00
if ( pDudeInfo - > lockOut & & hitActor - > hasX ( ) & & hitActor - > xspr . Push & & ! hitActor - > xspr . key & & ! hitActor - > xspr . DudeLockout & & ! hitActor - > xspr . state & & ! hitActor - > xspr . busy & & ! pPlayer )
2022-08-10 21:45:29 +00:00
trTriggerSprite ( coll . actor ( ) , kCmdSpritePush , actor ) ;
2019-10-11 21:59:39 +00:00
2021-08-23 17:21:41 +00:00
break ;
}
case kHitWall :
{
2021-11-26 13:03:21 +00:00
walltype * pHitWall = coll . hitWall ;
2020-12-05 09:40:13 +00:00
XWALL * pHitXWall = nullptr ;
2021-11-19 18:33:38 +00:00
if ( pHitWall - > hasX ( ) ) pHitXWall = & pHitWall - > xw ( ) ;
2020-12-04 23:08:51 +00:00
2021-08-23 17:21:41 +00:00
if ( pDudeInfo - > lockOut & & pHitXWall & & pHitXWall - > triggerPush & & ! pHitXWall - > key & & ! pHitXWall - > dudeLockout & & ! pHitXWall - > state & & ! pHitXWall - > busy & & ! pPlayer )
2022-08-10 21:45:29 +00:00
trTriggerWall ( pHitWall , kCmdWallPush , actor ) ;
2020-12-04 13:25:04 +00:00
2021-11-23 22:04:21 +00:00
if ( pHitWall - > twoSided ( ) )
2021-08-23 17:21:41 +00:00
{
2021-11-19 17:08:05 +00:00
sectortype * pHitSector = pHitWall - > nextSector ( ) ;
2021-12-29 18:41:41 +00:00
XSECTOR * pHitXSector = pHitSector - > hasX ( ) ? & pHitSector - > xs ( ) : nullptr ;
2021-08-23 17:21:41 +00:00
if ( pDudeInfo - > lockOut & & pHitXSector & & pHitXSector - > Wallpush & & ! pHitXSector - > Key & & ! pHitXSector - > dudeLockout & & ! pHitXSector - > state & & ! pHitXSector - > busy & & ! pPlayer )
2022-08-10 21:45:29 +00:00
trTriggerSector ( pHitSector , kCmdSectorPush , actor ) ;
2021-08-23 17:21:41 +00:00
2022-02-02 23:46:04 +00:00
if ( top < pHitSector - > int_ceilingz ( ) | | bottom > pHitSector - > int_floorz ( ) )
2021-08-23 17:21:41 +00:00
{
// ???
}
}
2022-09-03 07:37:52 +00:00
actWallBounceVector ( actor , pHitWall , 0 ) ;
2021-08-23 17:21:41 +00:00
break ;
}
}
}
else
{
2021-11-23 23:16:02 +00:00
assert ( pSector ) ;
2022-08-25 17:15:06 +00:00
auto pSector2 = pSector ;
updatesectorz ( actor - > spr . pos , & pSector2 ) ;
if ( pSector2 ) pSector = pSector2 ;
2021-08-23 17:21:41 +00:00
}
2021-11-19 17:08:05 +00:00
XSECTOR * pXSector = pSector - > hasX ( ) ? & pSector - > xs ( ) : nullptr ;
2021-12-30 15:51:56 +00:00
if ( actor - > sector ( ) ! = pSector )
2021-08-23 17:21:41 +00:00
{
2021-12-30 15:51:56 +00:00
assert ( actor - > sector ( ) ) ;
auto pOldSector = actor - > sector ( ) ;
2021-12-29 18:41:41 +00:00
XSECTOR * pXOldSector = pOldSector - > hasX ( ) ? & pOldSector - > xs ( ) : nullptr ;
2021-11-19 17:08:05 +00:00
if ( pXOldSector & & pXOldSector - > Exit & & ( pPlayer | | ! pXOldSector - > dudeLockout ) )
2022-08-10 21:45:29 +00:00
trTriggerSector ( pOldSector , kCmdSectorExit , actor ) ;
2021-11-23 23:16:02 +00:00
ChangeActorSect ( actor , pSector ) ;
2021-08-23 17:21:41 +00:00
2020-12-05 09:40:13 +00:00
if ( pXSector & & pXSector - > Enter & & ( pPlayer | | ! pXSector - > dudeLockout ) )
2020-12-04 13:25:04 +00:00
{
2021-11-19 17:08:05 +00:00
if ( pSector - > type = = kSectorTeleport )
2021-09-05 06:41:44 +00:00
pXSector - > actordata = actor ;
2022-08-10 21:45:29 +00:00
trTriggerSector ( pSector , kCmdSectorEnter , actor ) ;
2021-08-23 17:21:41 +00:00
}
2021-12-30 15:51:56 +00:00
pSector = actor - > sector ( ) ;
2021-08-23 17:21:41 +00:00
}
int bUnderwater = 0 ;
int bDepth = 0 ;
2021-11-19 17:08:05 +00:00
if ( pXSector )
2021-08-23 17:21:41 +00:00
{
if ( pXSector - > Underwater ) bUnderwater = 1 ;
if ( pXSector - > Depth ) bDepth = 1 ;
}
2021-12-05 23:50:33 +00:00
DCoreActor * pUpperLink = pSector - > upperLink ;
DCoreActor * pLowerLink = pSector - > lowerLink ;
2021-12-21 22:18:23 +00:00
if ( pUpperLink & & ( pUpperLink - > spr . type = = kMarkerUpWater | | pUpperLink - > spr . type = = kMarkerUpGoo ) ) bDepth = 1 ;
if ( pLowerLink & & ( pLowerLink - > spr . type = = kMarkerLowWater | | pLowerLink - > spr . type = = kMarkerLowGoo ) ) bDepth = 1 ;
2021-08-23 17:21:41 +00:00
if ( pPlayer ) wd + = 16 ;
2022-09-01 18:43:35 +00:00
if ( actor - > int_vel ( ) . Z ) actor - > add_int_z ( actor - > int_vel ( ) . Z > > 8 ) ;
2020-12-04 23:08:51 +00:00
2021-09-02 18:23:51 +00:00
int ceilZ , floorZ ;
Collision ceilColl , floorColl ;
2021-09-04 18:19:38 +00:00
GetZRange ( actor , & ceilZ , & ceilColl , & floorZ , & floorColl , wd , CLIPMASK0 , PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR ) ;
2021-08-23 17:21:41 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 2 )
2021-08-23 17:21:41 +00:00
{
int vc = 58254 ;
if ( bDepth )
{
if ( bUnderwater )
{
2022-08-23 20:24:01 +00:00
int cz = getceilzofslopeptr ( pSector , actor - > spr . pos ) ;
2021-08-23 17:21:41 +00:00
if ( cz > top )
2020-12-05 09:40:13 +00:00
vc + = ( ( bottom - cz ) * - 80099 ) / ( bottom - top ) ;
2021-08-23 17:21:41 +00:00
else
vc = 0 ;
}
else
{
2022-08-23 20:24:01 +00:00
int fz = getflorzofslopeptr ( pSector , actor - > spr . pos ) ;
2021-08-23 17:21:41 +00:00
if ( fz < bottom )
2020-12-05 09:40:13 +00:00
vc + = ( ( bottom - fz ) * - 80099 ) / ( bottom - top ) ;
2021-08-23 17:21:41 +00:00
}
}
else
{
if ( bUnderwater )
vc = 0 ;
else if ( bottom > = floorZ )
2021-08-25 06:46:31 +00:00
vc = 0 ;
2021-08-23 17:21:41 +00:00
}
if ( vc )
{
2022-01-30 15:20:11 +00:00
actor - > add_int_z ( ( ( vc * 4 ) / 2 ) > > 8 ) ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( vc ) ;
2021-08-23 17:21:41 +00:00
}
}
2022-09-03 08:12:09 +00:00
if ( pPlayer & & actor - > vel . Z > 0x155555 & & ! pPlayer - > fallScream & & actor - > xspr . height > 0 )
2021-08-23 17:21:41 +00:00
{
2021-12-22 17:12:55 +00:00
const bool playerAlive = ( actor - > xspr . health > 0 ) | | VanillaMode ( ) ; // only trigger falling scream if player is alive or vanilla mode
2021-08-23 17:21:41 +00:00
if ( playerAlive )
{
pPlayer - > fallScream = 1 ;
2021-09-16 19:59:39 +00:00
sfxPlay3DSound ( actor , 719 , 0 , 0 ) ;
2021-08-23 17:21:41 +00:00
}
}
2022-01-30 17:09:26 +00:00
vec3_t const oldpos = actor - > int_pos ( ) ;
2021-09-04 07:37:17 +00:00
int nLink = CheckLink ( actor ) ;
2021-08-23 17:21:41 +00:00
if ( nLink )
{
2021-09-04 18:19:38 +00:00
GetZRange ( actor , & ceilZ , & ceilColl , & floorZ , & floorColl , wd , CLIPMASK0 , PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR ) ;
2021-08-23 17:21:41 +00:00
if ( pPlayer )
playerCorrectInertia ( pPlayer , & oldpos ) ;
2020-12-05 09:40:13 +00:00
switch ( nLink )
2020-12-04 13:25:04 +00:00
{
2021-08-23 17:21:41 +00:00
case kMarkerLowStack :
if ( pPlayer = = gView )
2021-12-30 15:51:56 +00:00
gotpic . Set ( actor - > sector ( ) - > floorpicnum ) ;
2021-08-23 17:21:41 +00:00
break ;
case kMarkerUpStack :
if ( pPlayer = = gView )
2021-12-30 15:51:56 +00:00
gotpic . Set ( actor - > sector ( ) - > ceilingpicnum ) ;
2021-08-23 17:21:41 +00:00
break ;
case kMarkerLowWater :
case kMarkerLowGoo :
2021-12-22 17:12:55 +00:00
actor - > xspr . medium = kMediumNormal ;
2020-12-05 09:40:13 +00:00
if ( pPlayer )
2020-12-04 13:25:04 +00:00
{
2021-08-23 17:21:41 +00:00
pPlayer - > posture = 0 ;
pPlayer - > bubbleTime = 0 ;
2020-12-05 09:40:13 +00:00
if ( ! pPlayer - > cantJump & & ( pPlayer - > input . actions & SB_JUMP ) )
2020-12-04 13:25:04 +00:00
{
2022-09-03 09:58:35 +00:00
actor - > vel . Z = FixedToFloat ( - 0x6aaaa ) ;
2021-08-23 17:21:41 +00:00
pPlayer - > cantJump = 1 ;
}
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 721 , - 1 , 0 ) ;
2020-12-05 09:40:13 +00:00
}
else
2020-12-04 13:25:04 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-04 13:25:04 +00:00
{
2020-12-05 09:40:13 +00:00
case kDudeCultistTommy :
case kDudeCultistShotgun :
2021-09-16 19:59:39 +00:00
aiNewState ( actor , & cultistGoto ) ;
2020-12-05 09:40:13 +00:00
break ;
case kDudeGillBeast :
2021-09-16 19:59:39 +00:00
aiNewState ( actor , & gillBeastGoto ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = 6 ;
2020-12-05 09:40:13 +00:00
break ;
case kDudeBoneEel :
2021-09-16 19:59:39 +00:00
actKillDude ( actor , actor , kDamageFall , 1000 < < 4 ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
2021-08-25 06:46:31 +00:00
# ifdef NOONE_EXTENSIONS
2021-12-22 17:12:55 +00:00
if ( actor - > IsDudeActor ( ) & & actor - > xspr . health > 0 & & aiInPatrolState ( nAiStateType ) )
2021-08-29 12:36:40 +00:00
aiPatrolState ( actor , kAiStatePatrolMoveL ) ; // continue patrol when going from water
2021-08-25 06:46:31 +00:00
# endif
2021-08-23 17:21:41 +00:00
}
break ;
case kMarkerUpWater :
case kMarkerUpGoo :
{
int chance = 0xa00 ; int medium = kMediumWater ;
2020-12-05 09:40:13 +00:00
if ( nLink = = kMarkerUpGoo ) {
2021-08-23 17:21:41 +00:00
medium = kMediumGoo ;
chance = 0x400 ;
}
2020-01-26 11:19:01 +00:00
2021-12-22 17:12:55 +00:00
actor - > xspr . medium = medium ;
2019-09-19 22:42:45 +00:00
2021-08-23 17:21:41 +00:00
if ( pPlayer )
{
2020-12-05 09:40:13 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// look for palette in data2 of marker. If value <= 0, use default ones.
2021-08-25 06:46:31 +00:00
if ( gModernMap )
2020-12-05 09:40:13 +00:00
{
2021-08-23 17:21:41 +00:00
pPlayer - > nWaterPal = 0 ;
2021-12-05 23:50:33 +00:00
auto pUpper = barrier_cast < DBloodActor * > ( pSector - > upperLink ) ;
2021-12-22 15:49:41 +00:00
if ( pUpper & & pUpper - > hasX ( ) ) pPlayer - > nWaterPal = pUpper - > xspr . data2 ;
2021-08-23 17:21:41 +00:00
}
2021-08-25 06:46:31 +00:00
# endif
2021-08-23 17:21:41 +00:00
pPlayer - > posture = 1 ;
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2022-09-01 18:43:35 +00:00
pPlayer - > bubbleTime = abs ( actor - > int_vel ( ) . Z ) > > 12 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackPlayerBubble ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-23 17:21:41 +00:00
}
else
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-04 13:25:04 +00:00
{
2021-08-23 17:21:41 +00:00
case kDudeCultistTommy :
case kDudeCultistShotgun :
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-23 17:21:41 +00:00
aiNewState ( actor , & cultistSwimGoto ) ;
break ;
case kDudeBurningCultist :
{
2022-05-05 23:21:48 +00:00
const bool fixRandomCultist = ! cl_bloodvanillaenemies & & ( actor - > spr . inittype > = kDudeBase ) & & ( actor - > spr . inittype < kDudeMax ) & & ( actor - > spr . inittype ! = actor - > spr . type ) & & ! VanillaMode ( ) ; // fix burning cultists randomly switching types underwater
2021-08-23 17:21:41 +00:00
if ( Chance ( chance ) )
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeCultistTommy ;
2021-08-23 17:21:41 +00:00
else
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeCultistShotgun ;
2021-08-23 17:21:41 +00:00
if ( fixRandomCultist ) // fix burning cultists randomly switching types underwater
2021-12-22 15:43:59 +00:00
actor - > spr . type = actor - > spr . inittype ; // restore back to spawned cultist type
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-09-16 19:59:39 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-25 06:46:31 +00:00
aiNewState ( actor , & cultistSwimGoto ) ;
2021-08-23 17:21:41 +00:00
break ;
}
case kDudeZombieAxeNormal :
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-23 17:21:41 +00:00
aiNewState ( actor , & zombieAGoto ) ;
break ;
case kDudeZombieButcher :
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-23 17:21:41 +00:00
aiNewState ( actor , & zombieFGoto ) ;
break ;
case kDudeGillBeast :
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = 0 ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 720 , - 1 , 0 ) ;
2021-08-23 17:21:41 +00:00
aiNewState ( actor , & gillBeastSwimGoto ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 6 ;
2021-08-23 17:21:41 +00:00
break ;
case kDudeGargoyleFlesh :
case kDudeHellHound :
case kDudeSpiderBrown :
case kDudeSpiderRed :
case kDudeSpiderBlack :
case kDudeBat :
case kDudeRat :
case kDudeBurningInnocent :
2020-12-05 22:49:51 +00:00
actKillDude ( actor , actor , kDamageFall , 1000 < < 4 ) ;
2021-08-23 17:21:41 +00:00
break ;
}
2021-08-25 06:46:31 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
if ( gModernMap ) {
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kDudeModernCustom ) {
2021-07-19 21:15:26 +00:00
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackEnemeyBubble ) ;
2021-12-29 18:41:41 +00:00
if ( ! canSwim ( actor ) ) actKillDude ( actor , actor , kDamageFall , 1000 < < 4 ) ;
2020-12-04 13:25:04 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
// continue patrol when fall into water
2021-12-22 17:12:55 +00:00
if ( actor - > IsDudeActor ( ) & & actor - > xspr . health > 0 & & aiInPatrolState ( nAiStateType ) )
2021-08-29 12:36:40 +00:00
aiPatrolState ( actor , kAiStatePatrolMoveW ) ;
2021-08-23 17:21:41 +00:00
}
2021-08-25 06:46:31 +00:00
# endif
2021-08-23 17:21:41 +00:00
}
break ;
}
2021-08-25 06:46:31 +00:00
}
}
2021-08-23 17:21:41 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
if ( pPlayer & & bottom > = floorZ )
{
int floorZ2 = floorZ ;
2021-09-02 18:23:51 +00:00
auto floorColl2 = floorColl ;
2021-12-22 15:43:59 +00:00
GetZRange ( actor , & ceilZ , & ceilColl , & floorZ , & floorColl , actor - > spr . clipdist < < 2 , CLIPMASK0 , PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR ) ;
2022-01-30 17:09:26 +00:00
if ( bottom < = floorZ & & actor - > int_pos ( ) . Z - floorZ2 < bz )
2021-08-23 17:21:41 +00:00
{
floorZ = floorZ2 ;
2021-09-02 18:23:51 +00:00
floorColl = floorColl2 ;
2021-08-23 17:21:41 +00:00
}
}
if ( floorZ < = bottom )
{
2021-08-29 17:09:29 +00:00
actor - > hit . florhit = floorColl ;
2022-01-30 15:20:11 +00:00
actor - > add_int_z ( floorZ - bottom ) ;
2022-09-03 22:28:30 +00:00
double veldiff = actor - > vel . Z - actor - > sector ( ) - > velFloor ;
if ( veldiff > 0 )
2021-08-23 17:21:41 +00:00
{
2022-09-03 22:28:30 +00:00
auto vec4 = actFloorBounceVector ( actor , veldiff , actor - > sector ( ) , 0 ) ;
2022-09-03 07:45:23 +00:00
actor - > vel . XY ( ) = vec4 . XY ( ) ;
2022-09-02 21:56:03 +00:00
int vax = FloatToFixed ( vec4 . W ) ;
2021-08-23 17:21:41 +00:00
int nDamage = MulScale ( vax , vax , 30 ) ;
if ( pPlayer )
{
pPlayer - > fallScream = 0 ;
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
if ( nDamage > ( 15 < < 4 ) & & ( actor - > spr . flags & 4 ) )
2021-08-23 17:21:41 +00:00
playerLandingSound ( pPlayer ) ;
2020-12-05 09:40:13 +00:00
if ( nDamage > ( 30 < < 4 ) )
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 701 , 0 , 0 ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 09:40:13 +00:00
nDamage - = 100 < < 4 ;
2021-08-23 17:21:41 +00:00
if ( nDamage > 0 )
actDamageSprite ( actor , actor , kDamageFall , nDamage ) ;
2022-09-02 21:56:03 +00:00
actor - > set_int_bvel_z ( FloatToFixed ( vec4 . Z ) ) ;
2022-09-03 22:28:30 +00:00
if ( abs ( actor - > vel . Z ) < 1 )
2021-08-23 17:21:41 +00:00
{
2022-09-03 22:28:30 +00:00
actor - > vel . Z = actor - > sector ( ) - > velFloor ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 4 ;
2021-08-23 17:21:41 +00:00
}
else
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = 4 ;
2021-08-27 17:12:22 +00:00
2022-08-22 16:31:03 +00:00
double ffloorZ = floorZ * zinttoworld ;
2021-08-27 19:49:18 +00:00
switch ( tileGetSurfType ( floorColl ) )
2021-08-23 17:21:41 +00:00
{
case kSurfWater :
2022-08-22 16:31:03 +00:00
gFX . fxSpawnActor ( FX_9 , actor - > sector ( ) , DVector3 ( actor - > spr . pos , ffloorZ ) , 0 ) ;
2021-08-23 17:21:41 +00:00
break ;
case kSurfLava :
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_10 , actor - > sector ( ) , DVector3 ( actor - > spr . pos , ffloorZ ) , 0 ) ;
2021-08-23 17:21:41 +00:00
if ( pFX )
{
for ( int i = 0 ; i < 7 ; i + + )
{
2022-08-22 16:31:03 +00:00
auto pFX2 = gFX . fxSpawnActor ( FX_14 , pFX - > sector ( ) , pFX - > spr . pos , 0 ) ;
2021-08-23 17:21:41 +00:00
if ( pFX2 )
{
2022-09-03 08:07:06 +00:00
pFX2 - > vel . X = Random2F ( 0x6aaaa ) ;
pFX2 - > vel . Y = Random2F ( 0x6aaaa ) ;
pFX2 - > vel . Z = - Random2F ( 0xd5555 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
break ;
}
}
}
2022-09-03 08:12:09 +00:00
else if ( actor - > vel . Z = = 0 )
2021-08-23 17:21:41 +00:00
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 4 ;
2021-08-23 17:21:41 +00:00
}
else
{
2021-11-26 13:03:21 +00:00
actor - > hit . florhit . setNone ( ) ;
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 2 )
actor - > spr . flags | = 4 ;
2021-08-23 17:21:41 +00:00
}
if ( top < = ceilZ )
{
2021-08-29 17:09:29 +00:00
actor - > hit . ceilhit = ceilColl ;
2022-01-30 15:20:11 +00:00
actor - > add_int_z ( ClipLow ( ceilZ - top , 0 ) ) ;
2019-10-20 14:50:47 +00:00
2022-09-01 19:54:07 +00:00
if ( actor - > int_vel ( ) . Z < = 0 & & ( actor - > spr . flags & 4 ) )
2022-09-01 19:40:03 +00:00
actor - > set_int_bvel_z ( MulScale ( - actor - > int_vel ( ) . Z , 0x2000 , 16 ) ) ;
2021-08-23 17:21:41 +00:00
}
else
2021-11-26 13:03:21 +00:00
actor - > hit . ceilhit . setNone ( ) ;
2020-12-04 23:08:51 +00:00
2020-12-05 09:40:13 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2019-09-19 22:42:45 +00:00
2021-12-22 17:12:55 +00:00
actor - > xspr . height = ClipLow ( floorZ - bottom , 0 ) > > 8 ;
2022-09-03 08:12:09 +00:00
if ( actor - > vel . X ! = 0 | | actor - > int_vel ( ) . Y )
2021-08-23 17:21:41 +00:00
{
2021-09-02 18:23:51 +00:00
if ( floorColl . type = = kHitSprite )
2021-08-23 17:21:41 +00:00
{
2021-11-26 13:03:21 +00:00
auto hitAct = floorColl . actor ( ) ;
2021-12-21 22:18:23 +00:00
if ( ( hitAct - > spr . cstat & CSTAT_SPRITE_ALIGNMENT_MASK ) = = CSTAT_SPRITE_ALIGNMENT_FACING )
2021-08-23 17:21:41 +00:00
{
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( 4 , actor - > int_pos ( ) . X - hitAct - > int_pos ( ) . X , 2 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( 4 , actor - > int_pos ( ) . Y - hitAct - > int_pos ( ) . Y , 2 ) ) ;
2021-08-23 17:21:41 +00:00
return ;
}
}
2021-12-30 15:51:56 +00:00
if ( IsUnderwaterSector ( actor - > sector ( ) ) )
2021-08-23 17:21:41 +00:00
return ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . height > = 0x100 )
2021-08-23 17:21:41 +00:00
return ;
int nDrag = gDudeDrag ;
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . height > 0 )
2021-12-30 07:32:06 +00:00
nDrag - = Scale ( gDudeDrag , actor - > xspr . height , 0x100 ) ;
2022-09-01 19:10:35 +00:00
actor - > add_int_bvel_x ( - mulscale16r ( actor - > int_vel ( ) . X , nDrag ) ) ;
actor - > add_int_bvel_y ( - mulscale16r ( actor - > int_vel ( ) . Y , nDrag ) ) ;
2021-08-23 17:21:41 +00:00
2022-09-01 18:49:35 +00:00
if ( approxDist ( actor - > int_vel ( ) . X , actor - > int_vel ( ) . Y ) < 0x1000 )
2022-09-03 07:45:23 +00:00
actor - > ZeroVelocityXY ( ) ;
2021-08-23 17:21:41 +00:00
}
2019-09-19 22:42:45 +00:00
}
2020-12-05 09:40:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-05 11:17:28 +00:00
int MoveMissile ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2020-12-05 11:17:28 +00:00
auto Owner = actor - > GetOwner ( ) ;
int cliptype = - 1 ;
2021-12-18 18:19:28 +00:00
ESpriteFlags bakCstat = 0 ;
2022-01-01 08:31:57 +00:00
if ( Owner )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:33:03 +00:00
bakCstat = Owner - > spr . cstat ;
2022-01-01 08:31:57 +00:00
if ( Owner - > IsDudeActor ( ) )
{
Owner - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
}
2021-08-25 06:46:31 +00:00
}
2021-05-05 14:43:42 +00:00
gHitInfo . clearObj ( ) ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kMissileFlameSpray ) actAirDrag ( actor , 0x1000 ) ;
2020-12-05 11:17:28 +00:00
2022-09-03 08:12:09 +00:00
if ( actor - > GetTarget ( ) ! = nullptr & & ( actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 | | actor - > int_vel ( ) . Z ) )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:17:28 +00:00
auto target = actor - > GetTarget ( ) ;
2021-12-22 17:12:55 +00:00
if ( target - > spr . statnum = = kStatDude & & target - > hasX ( ) & & target - > xspr . health > 0 )
2021-08-23 17:21:41 +00:00
{
2022-08-22 16:31:23 +00:00
int nTargetAngle = getangle ( - ( target - > int_pos ( ) . Y - actor - > int_pos ( ) . Y ) , target - > int_pos ( ) . X - actor - > int_pos ( ) . X ) ; // X and Y are swapped here!
2021-12-22 15:43:59 +00:00
int vx = missileInfo [ actor - > spr . type - kMissileBase ] . velocity ;
2021-08-23 17:21:41 +00:00
int vy = 0 ;
2022-09-02 21:53:50 +00:00
auto rpt = rotatepoint ( DVector2 ( 0 , 0 ) , DVector2 ( vx , 0 ) , DAngle : : fromBuild ( nTargetAngle + 1536 ) ) ;
actor - > set_int_bvel_x ( rpt . X ) ; // we were rotating an int vector here so scale matches.
actor - > set_int_bvel_y ( rpt . Y ) ;
2022-01-30 17:09:26 +00:00
int dz = target - > int_pos ( ) . Z - actor - > int_pos ( ) . Z ;
2020-12-05 11:17:28 +00:00
int deltaz = dz / 10 ;
2022-01-30 17:09:26 +00:00
if ( target - > int_pos ( ) . Z < actor - > int_pos ( ) . Z ) deltaz = - deltaz ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( deltaz ) ;
2021-08-23 17:21:41 +00:00
}
}
2022-09-03 07:45:23 +00:00
auto vel = actor - > vel ;
2022-08-30 17:08:16 +00:00
double top , bottom ;
2020-12-05 11:17:28 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2021-08-23 17:21:41 +00:00
int i = 1 ;
const int bakCompat = enginecompatibility_mode ;
2021-12-22 15:43:59 +00:00
const bool isFlameSprite = ( actor - > spr . type = = kMissileFlameSpray | | actor - > spr . type = = kMissileFlameHound ) ; // do not use accurate clipmove for flame based sprites (changes damage too much)
2021-08-23 17:21:41 +00:00
while ( 1 )
{
2022-08-30 17:08:16 +00:00
auto ppos = actor - > spr . pos ;
2021-12-30 15:51:56 +00:00
auto pSector2 = actor - > sector ( ) ;
2021-12-22 15:43:59 +00:00
const auto bakSpriteCstat = actor - > spr . cstat ;
2021-12-22 15:33:03 +00:00
if ( Owner & & ! isFlameSprite & & ! cl_bloodvanillaexplosions & & ! VanillaMode ( ) )
2021-08-23 17:21:41 +00:00
{
enginecompatibility_mode = ENGINECOMPATIBILITY_NONE ; // improved clipmove accuracy
2021-12-22 15:43:59 +00:00
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ; // remove self collisions for accurate clipmove
2021-08-23 17:21:41 +00:00
}
2021-11-26 13:03:21 +00:00
Collision clipmoveresult ;
2022-08-30 17:08:16 +00:00
ClipMove ( ppos , & pSector2 , vel . XY ( ) , actor - > spr . clipdist < < 2 , ( ppos . Z - top ) / 4 , ( bottom - ppos . Z ) / 4 , CLIPMASK0 , clipmoveresult , 1 ) ;
2021-08-23 17:21:41 +00:00
enginecompatibility_mode = bakCompat ; // restore
2021-12-22 15:43:59 +00:00
actor - > spr . cstat = bakSpriteCstat ;
2021-11-23 23:21:08 +00:00
auto pSector = pSector2 ;
if ( pSector2 = = nullptr )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:17:28 +00:00
cliptype = - 1 ;
2021-08-23 17:21:41 +00:00
break ;
}
2020-12-05 11:17:28 +00:00
if ( clipmoveresult . type = = kHitSprite )
2021-08-23 17:21:41 +00:00
{
2021-11-26 13:03:21 +00:00
gHitInfo . hitActor = clipmoveresult . actor ( ) ;
2020-12-05 11:17:28 +00:00
cliptype = 3 ;
2021-08-25 06:46:31 +00:00
}
2020-12-05 11:17:28 +00:00
else if ( clipmoveresult . type = = kHitWall )
2021-08-25 06:46:31 +00:00
{
2021-11-26 13:03:21 +00:00
gHitInfo . hitWall = clipmoveresult . hitWall ;
2021-11-23 16:00:00 +00:00
if ( ! gHitInfo . hitWall - > twoSided ( ) ) cliptype = 0 ;
2021-08-25 06:46:31 +00:00
else
{
2022-08-30 17:08:16 +00:00
double fz , cz ;
getzsofslopeptr ( clipmoveresult . hitWall - > nextSector ( ) , ppos , & cz , & fz ) ;
if ( ppos . Z < = cz | | ppos . Z > = fz ) cliptype = 0 ;
2020-12-05 11:17:28 +00:00
else cliptype = 4 ;
2021-08-23 17:21:41 +00:00
}
2021-08-25 06:46:31 +00:00
}
2020-12-05 11:17:28 +00:00
if ( cliptype = = 4 )
2021-08-23 17:21:41 +00:00
{
2021-11-26 13:03:21 +00:00
walltype * pWall = clipmoveresult . hitWall ;
2021-11-19 14:46:20 +00:00
if ( pWall - > hasX ( ) )
2021-08-23 17:21:41 +00:00
{
2021-11-19 00:13:33 +00:00
XWALL * pXWall = & pWall - > xw ( ) ;
2021-08-23 17:21:41 +00:00
if ( pXWall - > triggerVector )
{
2022-08-10 21:45:29 +00:00
trTriggerWall ( pWall , kCmdWallImpact , Owner ? Owner : actor ) ;
2021-12-18 14:36:50 +00:00
if ( ! ( pWall - > cstat & CSTAT_WALL_BLOCK_HITSCAN ) )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:17:28 +00:00
cliptype = - 1 ;
2021-08-23 17:21:41 +00:00
if ( i - - > 0 )
continue ;
2020-12-05 11:17:28 +00:00
cliptype = 0 ;
2021-08-23 17:21:41 +00:00
break ;
}
}
}
}
2020-12-05 11:17:28 +00:00
if ( cliptype > = 0 & & cliptype ! = 3 )
2021-08-23 17:21:41 +00:00
{
2022-09-03 07:45:23 +00:00
double nVel = actor - > vel . XY ( ) . Length ( ) ;
ppos . XY ( ) - = actor - > vel . XY ( ) / nVel ;
vel . Z - = actor - > vel . Z / nVel ;
2022-08-30 17:08:16 +00:00
updatesector ( ppos , & pSector ) ;
2021-11-23 23:21:08 +00:00
pSector2 = pSector ;
2021-08-23 17:21:41 +00:00
}
2022-08-30 17:08:16 +00:00
double ceilZ , floorZ ;
2021-09-02 18:23:51 +00:00
Collision ceilColl , floorColl ;
2022-08-30 17:08:16 +00:00
GetZRangeAtXYZ ( ppos , pSector2 , & ceilZ , & ceilColl , & floorZ , & floorColl , actor - > spr . clipdist < < 2 , CLIPMASK0 ) ;
2020-12-05 11:17:28 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2022-08-30 17:08:16 +00:00
top + = vel . Z ;
bottom + = vel . Z ;
2021-08-23 17:21:41 +00:00
if ( bottom > = floorZ )
{
2021-08-29 17:09:29 +00:00
actor - > hit . florhit = floorColl ;
2022-08-30 17:08:16 +00:00
vel . Z + = floorZ - bottom ;
2020-12-05 11:17:28 +00:00
cliptype = 2 ;
2021-08-23 17:21:41 +00:00
}
if ( top < = ceilZ )
{
2021-08-29 17:09:29 +00:00
actor - > hit . ceilhit = ceilColl ;
2022-08-30 17:08:16 +00:00
vel . Z + = std : : max ( ceilZ - top , 0. ) ;
2020-12-05 11:17:28 +00:00
cliptype = 1 ;
2021-08-23 17:21:41 +00:00
}
2022-08-30 17:08:16 +00:00
actor - > spr . pos = ppos . plusZ ( vel . Z ) ;
updatesector ( ppos , & pSector ) ;
2021-12-30 15:51:56 +00:00
if ( pSector ! = nullptr & & pSector ! = actor - > sector ( ) )
2021-08-23 17:21:41 +00:00
{
2021-11-23 23:21:08 +00:00
assert ( pSector ) ;
ChangeActorSect ( actor , pSector ) ;
2021-08-23 17:21:41 +00:00
}
2021-09-04 07:37:17 +00:00
CheckLink ( actor ) ;
2021-12-30 15:51:56 +00:00
gHitInfo . hitSector = actor - > sector ( ) ;
2022-08-17 16:53:45 +00:00
gHitInfo . hitpos = actor - > spr . pos ;
2021-08-23 17:21:41 +00:00
break ;
}
2021-12-22 15:33:03 +00:00
if ( Owner ) Owner - > spr . cstat = bakCstat ;
2020-12-05 11:17:28 +00:00
return cliptype ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 11:17:28 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actExplodeSprite ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2020-12-05 11:17:28 +00:00
if ( ! actor - > hasX ( ) ) return ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum = = kStatExplosion ) return ;
2021-11-28 09:24:42 +00:00
sfxKill3DSound ( actor , - 1 , - 1 ) ;
2021-08-27 07:44:47 +00:00
evKillActor ( actor ) ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
int nType = kExplosionStandard ;
2020-05-22 16:28:03 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-23 17:21:41 +00:00
{
case kMissileFireballNapalm :
nType = kExplosionNapalm ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 4 , actor , - 1 ) ;
2021-12-22 15:43:59 +00:00
if ( Chance ( 0x8000 ) ) actor - > spr . cstat | = CSTAT_SPRITE_XFLIP ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 303 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kMissileFlareAlt :
nType = kExplosionFireball ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 9 , actor , - 1 ) ;
2021-12-22 15:43:59 +00:00
if ( Chance ( 0x8000 ) ) actor - > spr . cstat | = CSTAT_SPRITE_XFLIP ;
2021-11-10 23:32:15 +00:00
sfxPlay3DSound ( actor , 306 , 24 + ( actor - > GetIndex ( ) & 3 ) , FX_GlobalChannel ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kMissileFireballCerberus :
case kMissileFireballTchernobog :
nType = kExplosionFireball ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 5 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 304 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kThingArmedTNTStick :
nType = kExplosionSmall ;
2021-08-29 17:09:29 +00:00
if ( actor - > hit . florhit . type = = kHitNone ) seqSpawn ( 4 , actor , - 1 ) ;
2020-12-05 11:17:28 +00:00
else seqSpawn ( 3 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 303 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kThingArmedProxBomb :
case kThingArmedRemoteBomb :
case kThingArmedTNTBundle :
2020-12-05 11:17:28 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
case kModernThingTNTProx :
2020-12-05 11:17:28 +00:00
# endif
2021-08-23 17:21:41 +00:00
nType = kExplosionStandard ;
2021-08-29 17:09:29 +00:00
if ( actor - > hit . florhit . type = = kHitNone ) seqSpawn ( 4 , actor , - 1 ) ;
2021-08-23 17:21:41 +00:00
else
2020-12-05 11:17:28 +00:00
seqSpawn ( 3 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 304 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kThingArmedSpray :
nType = kExplosionSpray ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 5 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 307 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
case kThingTNTBarrel :
{
2022-08-22 16:24:09 +00:00
auto spawned = actSpawnSprite ( actor - > sector ( ) , actor - > spr . pos , 0 , 1 ) ;
2020-12-05 11:17:28 +00:00
spawned - > SetOwner ( actor - > GetOwner ( ) ) ;
2021-08-30 18:21:49 +00:00
if ( actCheckRespawn ( actor ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . state = 1 ;
actor - > xspr . health = thingInfo [ 0 ] . startHealth < < 4 ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 11:17:28 +00:00
else actPostSprite ( actor , kStatFree ) ;
2021-08-23 17:21:41 +00:00
nType = kExplosionLarge ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 4 , spawned , - 1 ) ;
actor = spawned ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 305 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_14 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
}
2020-12-05 11:17:28 +00:00
case kTrapExploder :
2019-09-19 22:42:45 +00:00
{
// Defaults for exploder
2020-12-05 11:17:28 +00:00
nType = 1 ;
int nSnd = 304 ;
int nSeq = 4 ;
2019-09-19 22:42:45 +00:00
2020-12-05 11:17:28 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// allow to customize hidden exploder trap
2020-12-05 11:17:28 +00:00
if ( gModernMap )
{
2021-12-22 17:12:55 +00:00
nType = actor - > xspr . data1 ; // Explosion type
int tSeq = actor - > xspr . data2 ; // SEQ id
int tSnd = actor - > xspr . data3 ; // Sound Id
2019-10-20 14:50:47 +00:00
2021-08-23 17:21:41 +00:00
if ( nType < = 1 | | nType > kExplodeMax ) { nType = 1 ; nSeq = 4 ; nSnd = 304 ; }
else if ( nType = = 2 ) { nSeq = 4 ; nSnd = 305 ; }
else if ( nType = = 3 ) { nSeq = 9 ; nSnd = 307 ; }
else if ( nType = = 4 ) { nSeq = 5 ; nSnd = 307 ; }
else if ( nType < = 6 ) { nSeq = 4 ; nSnd = 303 ; }
else if ( nType = = 7 ) { nSeq = 4 ; nSnd = 303 ; }
else if ( nType = = 8 ) { nType = 0 ; nSeq = 3 ; nSnd = 303 ; }
// Override previous sound and seq assigns
if ( tSeq > 0 ) nSeq = tSeq ;
if ( tSnd > 0 ) nSnd = tSnd ;
}
2020-12-05 11:17:28 +00:00
# endif
2019-09-19 22:42:45 +00:00
2020-12-05 11:17:28 +00:00
if ( getSequence ( nSeq ) ) seqSpawn ( nSeq , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , nSnd , - 1 , 0 ) ;
2020-12-05 11:17:28 +00:00
break ;
2019-09-19 22:42:45 +00:00
}
2021-08-23 17:21:41 +00:00
case kThingPodFireBall :
nType = kExplosionFireball ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 9 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 307 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-26 22:07:33 +00:00
fxSpawnPodStuff ( actor , 240 ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 11:17:28 +00:00
2021-08-23 17:21:41 +00:00
default :
nType = kExplosionStandard ;
2020-12-05 11:17:28 +00:00
seqSpawn ( 4 , actor , - 1 ) ;
2021-12-22 15:43:59 +00:00
if ( Chance ( 0x8000 ) ) actor - > spr . cstat | = CSTAT_SPRITE_XFLIP ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 303 , - 1 , 0 ) ;
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_5 , nullptr , nullptr ) ;
2021-08-23 17:21:41 +00:00
break ;
}
2022-08-23 19:25:05 +00:00
actor - > ZeroVelocity ( ) ;
2020-12-05 11:17:28 +00:00
actPostSprite ( actor , kStatExplosion ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . xrepeat = actor - > spr . yrepeat = explodeInfo [ nType ] . repeat ;
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 3 ;
actor - > spr . type = nType ;
2020-12-05 11:17:28 +00:00
const EXPLOSION * pExplodeInfo = & explodeInfo [ nType ] ;
2021-08-29 12:36:40 +00:00
actor - > SetTarget ( nullptr ) ;
2021-08-29 12:42:05 +00:00
actor - > explosionhackflag = true ;
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = pExplodeInfo - > ticks ;
actor - > xspr . data2 = pExplodeInfo - > quakeEffect ;
actor - > xspr . data3 = pExplodeInfo - > flashEffect ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 11:17:28 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-11-06 21:48:22 +00:00
void actActivateGibObject ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 17:12:55 +00:00
int gib1 = ClipRange ( actor - > xspr . data1 , 0 , 31 ) ;
int gib2 = ClipRange ( actor - > xspr . data2 , 0 , 31 ) ;
int gib3 = ClipRange ( actor - > xspr . data3 , 0 , 31 ) ;
int sound = actor - > xspr . data4 ;
int dropmsg = actor - > xspr . dropMsg ;
2020-12-05 11:17:28 +00:00
2021-08-29 20:22:16 +00:00
if ( gib1 > 0 ) GibSprite ( actor , ( GIBTYPE ) ( gib1 - 1 ) , nullptr , nullptr ) ;
if ( gib2 > 0 ) GibSprite ( actor , ( GIBTYPE ) ( gib2 - 1 ) , nullptr , nullptr ) ;
2021-12-22 17:12:55 +00:00
if ( gib3 > 0 & & actor - > xspr . burnTime > 0 ) GibSprite ( actor , ( GIBTYPE ) ( gib3 - 1 ) , nullptr , nullptr ) ;
2022-08-20 15:11:15 +00:00
if ( sound > 0 ) sfxPlay3DSound ( actor - > spr . pos , sound , actor - > sector ( ) ) ;
2020-12-05 22:49:51 +00:00
if ( dropmsg > 0 ) actDropObject ( actor , dropmsg ) ;
2020-12-05 11:17:28 +00:00
2021-12-22 15:43:59 +00:00
if ( ! ( actor - > spr . cstat & CSTAT_SPRITE_INVISIBLE ) & & ! ( actor - > spr . flags & kHitagRespawn ) )
2020-12-05 11:17:28 +00:00
actPostSprite ( actor , kStatFree ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 11:17:28 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-05 11:54:26 +00:00
static void actCheckProximity ( )
2019-09-19 22:42:45 +00:00
{
2020-12-05 11:54:26 +00:00
BloodStatIterator it ( kStatThing ) ;
while ( auto actor = it . Next ( ) )
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 ) continue ;
2019-09-21 11:02:17 +00:00
2020-12-05 11:54:26 +00:00
if ( actor - > hasX ( ) )
2021-08-25 06:46:31 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-05 11:54:26 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingBloodBits :
case kThingBloodChunks :
case kThingZombieHead :
2022-08-22 16:31:45 +00:00
if ( actor - > xspr . locked & & PlayClock > = actor - > xspr . TargetPos . X ) actor - > xspr . locked = 0 ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . burnTime > 0 )
2021-08-23 17:21:41 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = ClipLow ( actor - > xspr . burnTime - 4 , 0 ) ;
2021-09-18 18:12:15 +00:00
actDamageSprite ( actor - > GetBurnSource ( ) , actor , kDamageBurn , 8 ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 11:54:26 +00:00
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . Proximity )
2020-12-05 11:54:26 +00:00
{
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// don't process locked or 1-shot things for proximity
2021-12-22 17:12:55 +00:00
if ( gModernMap & & ( actor - > xspr . locked | | actor - > xspr . isTriggered ) )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 11:54:26 +00:00
# endif
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kThingDroppedLifeLeech ) actor - > SetTarget ( nullptr ) ;
2020-12-05 11:54:26 +00:00
BloodStatIterator it1 ( kStatDude ) ;
while ( auto dudeactor = it1 . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:54:26 +00:00
auto nextdude = it1 . Peek ( ) ;
2019-10-20 14:50:47 +00:00
2021-12-22 14:33:13 +00:00
if ( dudeactor - > spr . flags & 32 | | ! dudeactor - > hasX ( ) ) continue ;
2020-12-05 11:54:26 +00:00
2021-12-22 16:57:58 +00:00
if ( ( unsigned int ) dudeactor - > xspr . health > 0 )
2020-12-05 11:54:26 +00:00
{
int proxyDist = 96 ;
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// allow dudeLockout for proximity flag
2021-12-22 17:12:55 +00:00
if ( gModernMap & & actor - > spr . type ! = kThingDroppedLifeLeech & & actor - > xspr . DudeLockout & & ! dudeactor - > IsPlayerActor ( ) )
2021-08-23 17:21:41 +00:00
continue ;
2019-09-21 11:02:17 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kModernThingEnemyLifeLeech ) proxyDist = 512 ;
2020-12-05 11:54:26 +00:00
# endif
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kThingDroppedLifeLeech & & actor - > GetTarget ( ) = = nullptr )
2020-12-05 11:54:26 +00:00
{
auto Owner = actor - > GetOwner ( ) ;
if ( ! Owner - > IsPlayerActor ( ) ) continue ;
2021-12-22 15:33:03 +00:00
PLAYER * pPlayer = & gPlayer [ Owner - > spr . type - kDudePlayer1 ] ;
2021-12-22 14:33:13 +00:00
PLAYER * pPlayer2 = dudeactor - > IsPlayerActor ( ) ? & gPlayer [ dudeactor - > spr . type - kDudePlayer1 ] : nullptr ;
2020-12-05 11:54:26 +00:00
2021-12-22 14:33:13 +00:00
if ( dudeactor = = Owner | | dudeactor - > spr . type = = kDudeZombieAxeBuried | | dudeactor - > spr . type = = kDudeRat | | dudeactor - > spr . type = = kDudeBat ) continue ;
2020-12-05 11:54:26 +00:00
if ( gGameOptions . nGameType = = 3 & & pPlayer2 & & pPlayer - > teamId = = pPlayer2 - > teamId ) continue ;
if ( gGameOptions . nGameType = = 1 & & pPlayer2 ) continue ;
2021-08-23 17:21:41 +00:00
proxyDist = 512 ;
}
2019-09-21 11:02:17 +00:00
2022-08-22 16:23:36 +00:00
if ( CheckProximity ( dudeactor , actor - > spr . pos , actor - > sector ( ) , proxyDist ) )
2020-12-05 11:54:26 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2020-12-05 11:54:26 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingDroppedLifeLeech :
2020-12-05 11:54:26 +00:00
if ( ! Chance ( 0x4000 ) & & nextdude ) continue ;
2021-12-22 14:33:13 +00:00
if ( dudeactor - > spr . cstat & CSTAT_SPRITE_BLOCK ) actor - > SetTarget ( dudeactor ) ;
2021-08-25 06:46:31 +00:00
else continue ;
break ;
2020-12-05 11:54:26 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-25 06:46:31 +00:00
case kModernThingTNTProx :
2020-12-05 11:54:26 +00:00
if ( ! dudeactor - > IsPlayerActor ( ) ) continue ;
2021-12-22 15:43:59 +00:00
actor - > spr . pal = 0 ;
2021-08-25 06:46:31 +00:00
break ;
2020-12-05 11:54:26 +00:00
2021-08-25 06:46:31 +00:00
case kModernThingEnemyLifeLeech :
2021-09-15 22:52:54 +00:00
if ( actor - > GetTarget ( ) ! = dudeactor ) continue ;
2021-08-25 06:46:31 +00:00
break ;
2020-12-05 11:54:26 +00:00
# endif
default :
break ;
2021-08-23 17:21:41 +00:00
}
2021-08-29 21:10:19 +00:00
if ( actor - > GetOwner ( ) = = nullptr ) actor - > SetOwner ( dudeactor ) ;
2022-08-10 21:45:29 +00:00
trTriggerSprite ( actor , kCmdSpriteProximity , dudeactor ) ;
2021-08-23 17:21:41 +00:00
}
}
}
}
}
}
2020-12-05 11:54:26 +00:00
}
2020-10-15 15:08:21 +00:00
2020-12-05 11:54:26 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actCheckThings ( )
{
BloodStatIterator it ( kStatThing ) ;
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 ) continue ;
2020-12-05 11:54:26 +00:00
if ( ! actor - > hasX ( ) ) continue ;
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2020-12-05 11:54:26 +00:00
2021-12-29 18:41:41 +00:00
XSECTOR * pXSector = pSector - > hasX ( ) ? & pSector - > xs ( ) : nullptr ;
2021-08-23 17:21:41 +00:00
if ( pXSector & & pXSector - > panVel & & ( pXSector - > panAlways | | pXSector - > state | | pXSector - > busy ) )
{
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type - kThingBase ;
2020-12-05 11:54:26 +00:00
const THINGINFO * pThingInfo = & thingInfo [ nType ] ;
2021-12-22 15:43:59 +00:00
if ( pThingInfo - > flags & 1 ) actor - > spr . flags | = 1 ;
if ( pThingInfo - > flags & 2 ) actor - > spr . flags | = 4 ;
2021-08-23 17:21:41 +00:00
}
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 3 )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:54:26 +00:00
viewBackupSpriteLoc ( actor ) ;
2021-08-23 17:21:41 +00:00
if ( pXSector & & pXSector - > panVel )
{
int top , bottom ;
2020-12-05 11:54:26 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2022-08-23 20:24:01 +00:00
if ( getflorzofslopeptr ( pSector , actor - > spr . pos ) < = bottom )
2021-08-23 17:21:41 +00:00
{
int angle = pXSector - > panAngle ;
int speed = 0 ;
if ( pXSector - > panAlways | | pXSector - > state | | pXSector - > busy )
{
speed = pXSector - > panVel < < 9 ;
2020-12-05 11:54:26 +00:00
if ( ! pXSector - > panAlways & & pXSector - > busy ) speed = MulScale ( speed , pXSector - > busy , 16 ) ;
2021-08-23 17:21:41 +00:00
}
2021-12-18 13:08:57 +00:00
if ( pSector - > floorstat & CSTAT_SECTOR_ALIGN ) angle = ( angle + GetWallAngle ( pSector - > firstWall ( ) ) + 512 ) & 2047 ;
2020-12-05 11:54:26 +00:00
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( speed , Cos ( angle ) , 30 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( speed , Sin ( angle ) , 30 ) ) ;
2021-08-23 17:21:41 +00:00
}
}
2020-12-05 11:54:26 +00:00
actAirDrag ( actor , 128 ) ;
2019-10-20 14:50:47 +00:00
2021-12-22 15:43:59 +00:00
if ( ( ( actor - > GetIndex ( ) > > 8 ) & 15 ) = = ( gFrameCount & 15 ) & & ( actor - > spr . flags & 2 ) ) actor - > spr . flags | = 4 ;
2022-09-03 22:28:30 +00:00
if ( ( actor - > spr . flags & 4 ) | | actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 | | actor - > vel . Z ! = 0 | | actor - > sector ( ) - > velFloor | | actor - > sector ( ) - > velCeil )
2021-08-23 17:21:41 +00:00
{
2020-12-05 11:54:26 +00:00
Collision hit = MoveThing ( actor ) ;
if ( hit . type )
2021-08-23 17:21:41 +00:00
{
2022-08-10 21:45:29 +00:00
if ( actor - > xspr . Impact ) trTriggerSprite ( actor , kCmdOff , hit . type = = kHitSprite ? hit . safeActor ( ) : nullptr ) ;
2020-12-05 11:54:26 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-23 17:21:41 +00:00
{
2021-08-25 06:46:31 +00:00
case kThingDripWater :
case kThingDripBlood :
2021-08-31 23:28:19 +00:00
MakeSplash ( actor ) ;
2021-08-25 06:46:31 +00:00
break ;
2020-12-05 11:54:26 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-25 06:46:31 +00:00
case kModernThingThrowableRock :
2020-12-05 11:54:26 +00:00
seqSpawn ( 24 , actor , - 1 ) ;
2021-08-26 06:16:43 +00:00
if ( hit . type = = kHitSprite )
2021-08-25 06:46:31 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . xrepeat = 32 ;
actor - > spr . yrepeat = 32 ;
2021-12-22 17:12:55 +00:00
actDamageSprite ( actor - > GetOwner ( ) , hit . actor ( ) , kDamageFall , actor - > xspr . data1 ) ;
2021-08-25 06:46:31 +00:00
}
break ;
2020-12-05 11:54:26 +00:00
# endif
2021-08-25 06:46:31 +00:00
case kThingBone :
2020-12-05 11:54:26 +00:00
seqSpawn ( 24 , actor , - 1 ) ;
2021-08-26 06:16:43 +00:00
if ( hit . type = = kHitSprite )
2021-08-25 06:46:31 +00:00
{
2021-11-26 13:03:21 +00:00
actDamageSprite ( actor - > GetOwner ( ) , hit . actor ( ) , kDamageFall , 12 ) ;
2021-08-25 06:46:31 +00:00
}
break ;
2020-12-05 11:54:26 +00:00
2021-08-25 06:46:31 +00:00
case kThingPodGreenBall :
2020-12-05 11:54:26 +00:00
if ( hit . type = = kHitSector )
2021-08-25 06:46:31 +00:00
{
2022-08-22 16:18:54 +00:00
actRadiusDamage ( actor - > GetOwner ( ) , actor - > spr . pos , actor - > sector ( ) , 200 , 1 , 20 , kDamageExplode , 6 , 0 ) ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXPodBloodSplat ) ;
2021-08-25 06:46:31 +00:00
}
2020-12-05 11:54:26 +00:00
else if ( hit . type = = kHitSprite )
2021-08-25 06:46:31 +00:00
{
2021-11-26 13:03:21 +00:00
actDamageSprite ( actor - > GetOwner ( ) , hit . actor ( ) , kDamageFall , 12 ) ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXPodBloodSplat ) ;
2021-08-25 06:46:31 +00:00
}
break ;
2020-12-05 11:54:26 +00:00
2021-08-25 06:46:31 +00:00
case kThingPodFireBall :
2021-08-27 11:25:01 +00:00
actExplodeSprite ( actor ) ;
2021-08-25 06:46:31 +00:00
break ;
2021-08-23 17:21:41 +00:00
}
}
}
2021-08-25 06:46:31 +00:00
}
}
2020-12-05 11:54:26 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-05 15:23:01 +00:00
static void actCheckProjectiles ( )
2020-12-05 11:54:26 +00:00
{
BloodStatIterator it ( kStatProjectile ) ;
2020-12-05 15:23:01 +00:00
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 15:23:01 +00:00
viewBackupSpriteLoc ( actor ) ;
int hit = MoveMissile ( actor ) ;
2021-08-31 23:28:19 +00:00
if ( hit > = 0 ) actImpactMissile ( actor , hit ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-23 16:10:04 +00:00
static TArray < walltype * > affectedXWalls ; // keep this outside the function so that it only needs to be allocated once
2020-12-05 15:23:01 +00:00
static void actCheckExplosion ( )
{
BloodStatIterator it ( kStatExplosion ) ;
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 15:23:01 +00:00
if ( ! actor - > hasX ( ) ) continue ;
auto Owner = actor - > GetOwner ( ) ;
2021-12-22 15:43:59 +00:00
int nType = actor - > spr . type ;
2021-08-23 17:21:41 +00:00
assert ( nType > = 0 & & nType < kExplodeMax ) ;
2020-12-05 15:23:01 +00:00
const EXPLOSION * pExplodeInfo = & explodeInfo [ nType ] ;
2022-08-22 16:18:31 +00:00
const auto apos = actor - > spr . pos ;
const int x = actor - > int_pos ( ) . X ;
const int y = actor - > int_pos ( ) . Y ;
const int z = actor - > int_pos ( ) . Z ;
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2021-08-23 17:21:41 +00:00
int radius = pExplodeInfo - > radius ;
2019-10-11 21:59:39 +00:00
2020-12-05 15:23:01 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// Allow to override explosion radius by data4 field of any sprite which have statnum 2 set in editor
// or of Hidden Exploder.
2021-12-22 17:12:55 +00:00
if ( gModernMap & & actor - > xspr . data4 > 0 )
radius = actor - > xspr . data4 ;
2020-12-05 15:23:01 +00:00
# endif
2021-08-23 17:21:41 +00:00
// GetClosestSpriteSectors() has issues checking some sectors due to optimizations
// the new flag newSectCheckMethod for GetClosestSpriteSectors() does rectify these issues, but this may cause unintended side effects for level scripted explosions
// so only allow this new checking method for dude spawned explosions
2021-11-16 19:20:25 +00:00
affectedXWalls . Clear ( ) ;
2021-08-23 17:24:56 +00:00
const bool newSectCheckMethod = ! cl_bloodvanillaexplosions & & Owner & & Owner - > IsDudeActor ( ) & & ! VanillaMode ( ) ; // use new sector checking logic
2022-08-22 16:20:16 +00:00
auto sectorMap = GetClosestSpriteSectors ( pSector , apos . XY ( ) , radius , & affectedXWalls , newSectCheckMethod ) ;
2021-08-25 06:46:31 +00:00
2021-11-23 16:10:04 +00:00
for ( auto pWall : affectedXWalls )
2021-08-23 17:21:41 +00:00
{
2022-08-10 21:45:29 +00:00
trTriggerWall ( pWall , kCmdWallImpact , Owner ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
BloodStatIterator it1 ( kStatDude ) ;
while ( auto dudeactor = it1 . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:33:03 +00:00
if ( dudeactor - > spr . flags & 32 ) continue ;
2019-10-20 14:50:47 +00:00
2021-12-22 14:40:15 +00:00
if ( CheckSector ( sectorMap , dudeactor ) )
2021-08-23 17:21:41 +00:00
{
2022-08-22 16:23:36 +00:00
if ( actor - > xspr . data1 & & CheckProximity ( dudeactor , apos , pSector , radius ) )
2021-08-23 17:21:41 +00:00
{
2021-08-29 12:42:05 +00:00
if ( pExplodeInfo - > dmg & & actor - > explosionhackflag )
2021-08-23 17:21:41 +00:00
{
2021-08-29 12:42:05 +00:00
actor - > explosionhackflag = false ;
2020-12-05 15:23:01 +00:00
actDamageSprite ( Owner , dudeactor , kDamageFall , ( pExplodeInfo - > dmg + Random ( pExplodeInfo - > dmgRng ) ) < < 4 ) ;
2021-08-23 17:21:41 +00:00
}
2022-08-22 16:18:31 +00:00
if ( pExplodeInfo - > dmgType ) ConcussSprite ( actor , dudeactor , apos , pExplodeInfo - > dmgType ) ;
2020-12-05 15:23:01 +00:00
2021-12-22 16:57:58 +00:00
if ( pExplodeInfo - > burnTime & & dudeactor - > hasX ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 16:57:58 +00:00
if ( ! dudeactor - > xspr . burnTime ) evPostActor ( dudeactor , 0 , kCallbackFXFlameLick ) ;
2020-12-05 15:23:01 +00:00
actBurnSprite ( Owner , dudeactor , pExplodeInfo - > burnTime < < 2 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
}
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
it1 . Reset ( kStatThing ) ;
2020-12-05 15:23:01 +00:00
while ( auto thingactor = it1 . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:33:03 +00:00
if ( thingactor - > spr . flags & 32 ) continue ;
2020-12-05 15:23:01 +00:00
2021-12-22 14:40:15 +00:00
if ( CheckSector ( sectorMap , thingactor ) )
2021-08-23 17:21:41 +00:00
{
2022-08-22 16:23:36 +00:00
if ( actor - > xspr . data1 & & CheckProximity ( thingactor , apos , pSector , radius ) & & thingactor - > hasX ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 16:57:58 +00:00
if ( ! thingactor - > xspr . locked )
2021-08-23 17:21:41 +00:00
{
2022-08-22 16:18:31 +00:00
if ( pExplodeInfo - > dmgType ) ConcussSprite ( Owner , thingactor , apos , pExplodeInfo - > dmgType ) ;
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
if ( pExplodeInfo - > burnTime )
{
2021-12-22 16:57:58 +00:00
if ( thingactor - > spr . type = = kThingTNTBarrel & & ! thingactor - > xspr . burnTime )
2021-08-27 07:44:47 +00:00
evPostActor ( thingactor , 0 , kCallbackFXFlameLick ) ;
2020-12-05 15:23:01 +00:00
actBurnSprite ( Owner , thingactor , pExplodeInfo - > burnTime < < 2 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
}
}
for ( int p = connecthead ; p > = 0 ; p = connectpoint2 [ p ] )
{
2022-01-30 17:09:26 +00:00
auto pos = gPlayer [ p ] . actor - > int_pos ( ) ;
2021-12-22 14:40:15 +00:00
int dx = ( x - pos . X ) > > 4 ;
int dy = ( y - pos . Y ) > > 4 ;
int dz = ( z - pos . Z ) > > 8 ;
2020-12-05 15:23:01 +00:00
int nDist = dx * dx + dy * dy + dz * dz + 0x40000 ;
2021-12-22 17:12:55 +00:00
int t = DivScale ( actor - > xspr . data2 , nDist , 16 ) ;
2021-08-23 17:21:41 +00:00
gPlayer [ p ] . flickerEffect + = t ;
}
2020-03-01 20:36:28 +00:00
2020-12-05 15:23:01 +00:00
# ifdef NOONE_EXTENSIONS
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . data1 ! = 0 )
2020-12-05 15:23:01 +00:00
{
2021-08-25 06:46:31 +00:00
// add impulse for sprites from physics list
2020-12-05 15:23:01 +00:00
if ( gPhysSpritesCount > 0 & & pExplodeInfo - > dmgType ! = 0 )
{
for ( int i = 0 ; i < gPhysSpritesCount ; i + + )
{
2021-09-01 19:52:00 +00:00
if ( gPhysSpritesList [ i ] = = nullptr ) continue ;
2021-12-05 23:20:46 +00:00
DBloodActor * physactor = gPhysSpritesList [ i ] ;
2021-12-30 15:24:51 +00:00
if ( ! physactor - > insector ( ) | | ( physactor - > spr . flags & kHitagFree ) ! = 0 ) continue ;
2019-09-21 11:02:17 +00:00
2022-08-22 16:23:36 +00:00
if ( ! CheckSector ( sectorMap , physactor ) | | ! CheckProximity ( physactor , apos , pSector , radius ) ) continue ;
2021-10-12 22:46:21 +00:00
else debrisConcuss ( Owner , i , x , y , z , pExplodeInfo - > dmgType ) ;
2021-08-25 06:46:31 +00:00
}
2021-08-23 17:21:41 +00:00
}
2020-03-01 20:36:28 +00:00
2021-08-23 17:21:41 +00:00
// trigger sprites from impact list
if ( gImpactSpritesCount > 0 ) {
2020-12-05 15:23:01 +00:00
for ( int i = 0 ; i < gImpactSpritesCount ; i + + )
{
2021-09-01 19:52:00 +00:00
if ( gImpactSpritesList [ i ] = = nullptr ) continue ;
2021-08-30 18:32:14 +00:00
2021-12-05 22:56:35 +00:00
DBloodActor * impactactor = gImpactSpritesList [ i ] ;
2021-12-30 15:24:51 +00:00
if ( ! impactactor - > hasX ( ) | | ! impactactor - > insector ( ) | | ( impactactor - > spr . flags & kHitagFree ) ! = 0 ) continue ;
2020-03-01 20:36:28 +00:00
2022-08-22 16:23:36 +00:00
if ( ! CheckSector ( sectorMap , impactactor ) | | ! CheckProximity ( impactactor , apos , pSector , radius ) )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 15:23:01 +00:00
2022-08-10 21:45:29 +00:00
trTriggerSprite ( impactactor , kCmdSpriteImpact , Owner ) ;
2021-08-25 06:46:31 +00:00
}
2021-08-23 17:21:41 +00:00
}
2020-03-01 20:36:28 +00:00
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
2021-12-22 15:43:59 +00:00
if ( ! gModernMap | | ! ( actor - > spr . flags & kModernTypeFlag1 ) )
2020-12-05 15:23:01 +00:00
{
// if data4 > 0, do not remove explosion. This can be useful when designer wants put explosion generator in map manually via sprite statnum 2.
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = ClipLow ( actor - > xspr . data1 - 4 , 0 ) ;
actor - > xspr . data2 = ClipLow ( actor - > xspr . data2 - 4 , 0 ) ;
actor - > xspr . data3 = ClipLow ( actor - > xspr . data3 - 4 , 0 ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
# else
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = ClipLow ( actor - > xspr . data1 - 4 , 0 ) ;
actor - > xspr . data2 = ClipLow ( actor - > xspr . data2 - 4 , 0 ) ;
actor - > xspr . data3 = ClipLow ( actor - > xspr . data3 - 4 , 0 ) ;
2020-12-05 15:23:01 +00:00
# endif
2019-09-19 22:42:45 +00:00
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . data1 = = 0 & & actor - > xspr . data2 = = 0 & & actor - > xspr . data3 = = 0 & & seqGetStatus ( actor ) < 0 )
2020-12-05 15:23:01 +00:00
actPostSprite ( actor , kStatFree ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actCheckTraps ( )
{
BloodStatIterator it ( kStatTraps ) ;
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( ( actor - > spr . flags & 32 ) | | ! actor - > hasX ( ) )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 15:23:01 +00:00
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type ) {
2021-08-23 17:21:41 +00:00
case kTrapSawCircular :
2021-12-22 17:12:55 +00:00
actor - > xspr . data2 = ClipLow ( actor - > xspr . data2 - 4 , 0 ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
case kTrapFlame :
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . state & & seqGetStatus ( actor ) < 0 )
2020-12-05 15:23:01 +00:00
{
2022-01-30 17:09:26 +00:00
int x = actor - > int_pos ( ) . X ;
int y = actor - > int_pos ( ) . Y ;
int z = actor - > int_pos ( ) . Z ;
2021-12-22 17:12:55 +00:00
int t = ( actor - > xspr . data1 < < 23 ) / 120 ;
2022-08-16 21:17:01 +00:00
int dx = MulScale ( t , Cos ( actor - > int_ang ( ) ) , 30 ) ;
int dy = MulScale ( t , Sin ( actor - > int_ang ( ) ) , 30 ) ;
2021-08-23 17:21:41 +00:00
for ( int i = 0 ; i < 2 ; i + + )
{
2021-12-30 15:51:56 +00:00
auto pFX = gFX . fxSpawnActor ( FX_32 , actor - > sector ( ) , x , y , z , 0 ) ;
2021-08-23 17:21:41 +00:00
if ( pFX )
{
2022-09-01 19:18:16 +00:00
pFX - > set_int_bvel_x ( dx + Random2 ( 0x8888 ) ) ;
2022-09-01 19:24:29 +00:00
pFX - > set_int_bvel_y ( dy + Random2 ( 0x8888 ) ) ;
2022-09-03 08:07:06 +00:00
pFX - > vel . Z = Random2F ( 0x8888 ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
x + = ( dx / 2 ) > > 12 ;
y + = ( dy / 2 ) > > 12 ;
2021-08-23 17:21:41 +00:00
}
2022-08-16 21:15:49 +00:00
dy = bsin ( actor - > int_ang ( ) ) ;
dx = bcos ( actor - > int_ang ( ) ) ;
2021-12-22 17:12:55 +00:00
gVectorData [ kVectorTchernobogBurn ] . maxDist = actor - > xspr . data1 < < 9 ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , 0 , dx , dy , Random2 ( 0x8888 ) , kVectorTchernobogBurn ) ;
2021-08-23 17:21:41 +00:00
}
break ;
}
}
2020-12-05 15:23:01 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void actCheckDudes ( )
{
BloodStatIterator it ( kStatDude ) ;
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 )
2021-08-23 17:21:41 +00:00
continue ;
2020-12-05 15:23:01 +00:00
if ( actor - > hasX ( ) )
2021-08-23 17:21:41 +00:00
{
2021-08-29 11:44:04 +00:00
const bool fixBurnGlitch = ! cl_bloodvanillaenemies & & IsBurningDude ( actor ) & & ! VanillaMode ( ) ; // if enemies are burning, always apply burning damage per tick
2021-12-22 17:12:55 +00:00
if ( ( actor - > xspr . burnTime > 0 ) | | fixBurnGlitch )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-23 17:21:41 +00:00
{
case kDudeBurningInnocent :
case kDudeBurningCultist :
case kDudeBurningZombieAxe :
case kDudeBurningZombieButcher :
2020-12-05 15:23:01 +00:00
actDamageSprite ( actor - > GetBurnSource ( ) , actor , kDamageBurn , 8 ) ;
2021-08-23 17:21:41 +00:00
break ;
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
default :
2021-12-22 17:12:55 +00:00
actor - > xspr . burnTime = ClipLow ( actor - > xspr . burnTime - 4 , 0 ) ;
2020-12-05 15:23:01 +00:00
actDamageSprite ( actor - > GetBurnSource ( ) , actor , kDamageBurn , 8 ) ;
2021-08-23 17:21:41 +00:00
break ;
}
}
2019-09-19 22:42:45 +00:00
2020-12-05 15:23:01 +00:00
# ifdef NOONE_EXTENSIONS
2021-08-23 17:21:41 +00:00
// handle incarnations of custom dude
2021-12-22 17:12:55 +00:00
if ( actor - > spr . type = = kDudeModernCustom & & actor - > xspr . txID > 0 & & actor - > xspr . sysData1 = = kGenDudeTransformStatus )
2020-12-05 15:23:01 +00:00
{
2022-09-03 07:45:23 +00:00
actor - > ZeroVelocityXY ( ) ;
2021-05-06 07:55:56 +00:00
if ( seqGetStatus ( actor ) < 0 ) genDudeTransform ( actor ) ;
2021-08-25 06:46:31 +00:00
}
2020-12-05 15:23:01 +00:00
# endif
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kDudeCerberusTwoHead )
2021-08-23 17:21:41 +00:00
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . health < = 0 & & seqGetStatus ( actor ) < 0 )
2021-08-23 17:21:41 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . health = dudeInfo [ 28 ] . startHealth < < 4 ;
2021-12-22 15:43:59 +00:00
actor - > spr . type = kDudeCerberusOneHead ;
2021-09-15 22:52:54 +00:00
if ( actor - > GetTarget ( ) ! = nullptr ) aiSetTarget ( actor , actor - > GetTarget ( ) ) ;
2020-12-05 15:23:01 +00:00
aiActivateDude ( actor ) ;
2021-08-23 17:21:41 +00:00
}
}
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . Proximity & & ! actor - > xspr . isTriggered )
2021-08-23 17:21:41 +00:00
{
2020-12-05 15:23:01 +00:00
BloodStatIterator it1 ( kStatDude ) ;
while ( auto actor2 = it1 . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 14:40:15 +00:00
if ( actor2 - > spr . flags & 32 ) continue ;
2019-10-20 14:50:47 +00:00
2021-12-22 16:57:58 +00:00
if ( actor2 - > IsPlayerActor ( ) & & ( unsigned int ) actor2 - > xspr . health > 0 )
2020-12-05 15:23:01 +00:00
{
2022-08-22 16:23:36 +00:00
if ( CheckProximity ( actor2 , actor - > spr . pos , actor - > sector ( ) , 128 ) )
2022-08-10 21:45:29 +00:00
trTriggerSprite ( actor , kCmdSpriteProximity , actor2 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
2020-12-05 15:23:01 +00:00
if ( actor - > IsPlayerActor ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
PLAYER * pPlayer = & gPlayer [ actor - > spr . type - kDudePlayer1 ] ;
2020-12-05 15:23:01 +00:00
if ( pPlayer - > voodooTargets ) voodooTarget ( pPlayer ) ;
if ( pPlayer - > hand & & Chance ( 0x8000 ) ) actDamageSprite ( actor , actor , kDamageDrown , 12 ) ;
2021-08-23 17:21:41 +00:00
if ( pPlayer - > isUnderwater )
{
2021-11-16 17:30:23 +00:00
bool bActive = packItemActive ( pPlayer , 1 ) ;
2020-12-05 15:23:01 +00:00
if ( bActive | | pPlayer - > godMode ) pPlayer - > underwaterTime = 1200 ;
else pPlayer - > underwaterTime = ClipLow ( pPlayer - > underwaterTime - 4 , 0 ) ;
2021-08-23 17:21:41 +00:00
if ( pPlayer - > underwaterTime < 1080 & & packCheckItem ( pPlayer , 1 ) & & ! bActive )
packUseItem ( pPlayer , 1 ) ;
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
if ( ! pPlayer - > underwaterTime )
{
pPlayer - > chokeEffect + = 4 ;
if ( Chance ( pPlayer - > chokeEffect ) )
2020-12-05 15:23:01 +00:00
actDamageSprite ( actor , actor , kDamageDrown , 3 < < 4 ) ;
2021-08-23 17:21:41 +00:00
}
else
pPlayer - > chokeEffect = 0 ;
2020-12-05 15:23:01 +00:00
2022-09-03 08:12:09 +00:00
if ( actor - > vel . X ! = 0 | | actor - > int_vel ( ) . Y )
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 709 , 100 , 2 ) ;
2020-12-05 15:23:01 +00:00
pPlayer - > bubbleTime = ClipLow ( pPlayer - > bubbleTime - 4 , 0 ) ;
2021-08-23 17:21:41 +00:00
}
else if ( gGameOptions . nGameType = = 0 )
{
2021-12-22 17:12:55 +00:00
if ( pPlayer - > actor - > xspr . health > 0 & & pPlayer - > restTime > = 1200 & & Chance ( 0x200 ) )
2021-08-23 17:21:41 +00:00
{
pPlayer - > restTime = - 1 ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 3100 + Random ( 11 ) , 0 , 2 ) ;
2021-08-23 17:21:41 +00:00
}
}
}
2020-12-05 15:23:01 +00:00
ProcessTouchObjects ( actor ) ;
2021-08-23 17:21:41 +00:00
}
}
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
it . Reset ( kStatDude ) ;
2020-12-05 15:23:01 +00:00
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 | | ! actor - > hasX ( ) ) continue ;
2019-10-20 14:50:47 +00:00
2021-12-30 15:51:56 +00:00
auto pSector = actor - > sector ( ) ;
2020-12-05 15:23:01 +00:00
viewBackupSpriteLoc ( actor ) ;
2021-12-29 18:41:41 +00:00
XSECTOR * pXSector = pSector - > hasX ( ) ? & pSector - > xs ( ) : nullptr ;
2020-12-05 15:23:01 +00:00
2021-08-23 17:21:41 +00:00
if ( pXSector )
{
int top , bottom ;
2020-12-05 15:23:01 +00:00
GetActorExtents ( actor , & top , & bottom ) ;
2022-08-23 20:24:01 +00:00
if ( getflorzofslopeptr ( pSector , actor - > spr . pos ) < = bottom )
2021-08-23 17:21:41 +00:00
{
int angle = pXSector - > panAngle ;
int speed = 0 ;
if ( pXSector - > panAlways | | pXSector - > state | | pXSector - > busy )
{
speed = pXSector - > panVel < < 9 ;
if ( ! pXSector - > panAlways & & pXSector - > busy )
speed = MulScale ( speed , pXSector - > busy , 16 ) ;
}
2021-12-18 13:08:57 +00:00
if ( pSector - > floorstat & CSTAT_SECTOR_ALIGN )
2021-11-21 08:45:50 +00:00
angle = ( angle + GetWallAngle ( pSector - > firstWall ( ) ) + 512 ) & 2047 ;
2021-08-23 17:21:41 +00:00
int dx = MulScale ( speed , Cos ( angle ) , 30 ) ;
int dy = MulScale ( speed , Sin ( angle ) , 30 ) ;
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( dx ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( dy ) ;
2021-08-23 17:21:41 +00:00
}
}
2020-12-05 15:23:01 +00:00
if ( pXSector & & pXSector - > Underwater ) actAirDrag ( actor , 5376 ) ;
else actAirDrag ( actor , 128 ) ;
2019-10-20 14:50:47 +00:00
2022-09-03 22:28:30 +00:00
if ( ( actor - > spr . flags & 4 ) | | actor - > vel . X ! = 0 | | actor - > vel . Y ! = 0 | | actor - > vel . Z ! = 0 | | actor - > sector ( ) - > velFloor | | actor - > sector ( ) - > velCeil )
2020-12-05 15:23:01 +00:00
MoveDude ( actor ) ;
2021-08-23 17:21:41 +00:00
}
2020-12-05 15:23:01 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actCheckFlares ( )
{
BloodStatIterator it ( kStatFlare ) ;
while ( auto actor = it . Next ( ) )
2021-08-23 17:21:41 +00:00
{
2021-12-22 15:43:59 +00:00
if ( ( actor - > spr . flags & 32 ) | | ! actor - > hasX ( ) ) continue ;
2019-10-20 14:50:47 +00:00
2020-12-05 15:23:01 +00:00
auto target = actor - > GetTarget ( ) ;
if ( ! target ) continue ;
viewBackupSpriteLoc ( actor ) ;
2021-12-22 15:33:03 +00:00
if ( target - > spr . statnum = = kMaxStatus )
2021-08-23 17:21:41 +00:00
{
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_17 , NULL , NULL ) ;
2020-12-05 15:23:01 +00:00
actPostSprite ( actor , kStatFree ) ;
2021-08-23 17:21:41 +00:00
}
2021-12-22 16:57:58 +00:00
if ( target - > hasX ( ) & & target - > xspr . health > 0 )
2021-08-23 17:21:41 +00:00
{
2022-08-22 21:57:39 +00:00
DVector3 pos = target - > spr . pos ;
2022-10-09 23:51:05 +00:00
pos . XY ( ) + = ( actor - > xspr . goalAng + target - > spr . angle ) . ToVector ( ) * target - > spr . clipdist * 2 * inttoworld ;
2022-08-22 21:57:39 +00:00
pos . Z + = actor - > xspr . TargetPos . Z ;
SetActor ( actor , pos ) ;
2022-09-03 08:57:32 +00:00
actor - > vel = target - > vel ;
2021-08-23 17:21:41 +00:00
}
else
{
2021-08-29 20:22:16 +00:00
GibSprite ( actor , GIBTYPE_17 , NULL , NULL ) ;
2020-12-05 15:23:01 +00:00
actPostSprite ( actor , kStatFree ) ;
2021-08-23 17:21:41 +00:00
}
}
2020-12-05 15:23:01 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actProcessSprites ( void )
{
# ifdef NOONE_EXTENSIONS
if ( gModernMap ) nnExtProcessSuperSprites ( ) ;
# endif
actCheckProximity ( ) ;
actCheckThings ( ) ;
actCheckProjectiles ( ) ;
actCheckExplosion ( ) ;
actCheckTraps ( ) ;
actCheckDudes ( ) ;
actCheckFlares ( ) ;
2021-08-25 06:46:31 +00:00
aiProcessDudes ( ) ;
gFX . fxProcess ( ) ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 15:23:01 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-08-22 16:24:09 +00:00
DBloodActor * actSpawnSprite ( sectortype * pSector , const DVector3 & pos , int nStat , bool setextra )
2019-09-19 22:42:45 +00:00
{
2021-11-23 23:55:57 +00:00
DBloodActor * actor = InsertSprite ( pSector , nStat ) ;
2020-12-05 16:24:27 +00:00
2022-08-22 16:24:09 +00:00
SetActor ( actor , pos ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . type = kSpriteDecoration ;
2020-12-05 16:24:27 +00:00
if ( setextra & & ! actor - > hasX ( ) )
2021-08-25 06:46:31 +00:00
{
2021-08-27 20:13:17 +00:00
actor - > addX ( ) ;
2021-11-26 13:03:21 +00:00
actor - > hit . florhit . setNone ( ) ;
actor - > hit . ceilhit . setNone ( ) ;
2020-12-05 16:24:27 +00:00
if ( ! VanillaMode ( ) ) actor - > SetTarget ( nullptr ) ;
2021-08-25 06:46:31 +00:00
}
2020-12-05 16:24:27 +00:00
return actor ;
2020-12-02 22:39:38 +00:00
}
2020-12-05 16:24:27 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2020-12-05 17:32:49 +00:00
DBloodActor * actSpawnSprite ( DBloodActor * source , int nStat )
2019-09-19 22:42:45 +00:00
{
2021-12-30 15:51:56 +00:00
DBloodActor * actor = InsertSprite ( source - > sector ( ) , nStat ) ;
2020-12-05 17:32:49 +00:00
2022-08-10 22:13:36 +00:00
actor - > spr . pos = source - > spr . pos ;
2022-09-03 08:57:32 +00:00
actor - > vel = source - > vel ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags = 0 ;
2020-12-05 17:32:49 +00:00
actor - > addX ( ) ;
2021-11-26 13:03:21 +00:00
actor - > hit . florhit . setNone ( ) ;
actor - > hit . ceilhit . setNone ( ) ;
2020-12-05 17:32:49 +00:00
if ( ! VanillaMode ( ) ) actor - > SetTarget ( nullptr ) ;
return actor ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-16 17:24:01 +00:00
DBloodActor * actSpawnDude ( DBloodActor * source , int nType , int a3 , int a4 )
2020-12-05 17:32:49 +00:00
{
auto spawned = actSpawnSprite ( source , kStatDude ) ;
2021-12-22 15:33:03 +00:00
if ( ! spawned ) return nullptr ;
2022-08-16 21:17:01 +00:00
int angle = source - > int_ang ( ) ;
2020-12-05 17:32:49 +00:00
int nDude = nType - kDudeBase ;
2022-08-22 21:57:39 +00:00
auto pos = source - > spr . pos ;
pos . Z + = a4 * zinttoworld ;
if ( a3 > = 0 )
2021-09-16 19:59:39 +00:00
{
2022-08-22 21:57:39 +00:00
pos . X + = mulscale30r ( Cos ( angle ) , a3 ) * inttoworld ;
pos . Y + = mulscale30r ( Sin ( angle ) , a3 ) * inttoworld ;
2021-09-16 19:59:39 +00:00
}
2021-12-22 14:40:15 +00:00
spawned - > spr . type = nType ;
2022-05-05 23:10:22 +00:00
if ( ! VanillaMode ( ) )
spawned - > spr . inittype = nType ;
2022-08-16 21:20:03 +00:00
spawned - > set_int_ang ( angle ) ;
2022-08-22 21:57:39 +00:00
SetActor ( spawned , pos ) ;
2021-12-22 14:40:15 +00:00
spawned - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL | CSTAT_SPRITE_BLOOD_BIT1 ;
spawned - > spr . clipdist = getDudeInfo ( nDude + kDudeBase ) - > clipdist ;
2021-12-22 16:57:58 +00:00
spawned - > xspr . health = getDudeInfo ( nDude + kDudeBase ) - > startHealth < < 4 ;
spawned - > xspr . respawn = 1 ;
2020-12-05 17:32:49 +00:00
if ( getSequence ( getDudeInfo ( nDude + kDudeBase ) - > seqStartID ) )
seqSpawn ( getDudeInfo ( nDude + kDudeBase ) - > seqStartID , spawned , - 1 ) ;
# ifdef NOONE_EXTENSIONS
2021-09-16 19:59:39 +00:00
// add a way to inherit some values of spawner type 18 by dude.
// This way designer can count enemies via switches and do many other interesting things.
2021-12-22 15:33:03 +00:00
if ( gModernMap & & source - > spr . flags & kModernTypeFlag1 )
2020-12-05 17:32:49 +00:00
{
// allow inheriting only for selected source types
2021-12-22 15:33:03 +00:00
switch ( source - > spr . type )
2020-12-05 17:32:49 +00:00
{
2021-09-16 19:59:39 +00:00
case kMarkerDudeSpawn :
//inherit pal?
2021-12-22 15:33:03 +00:00
if ( spawned - > spr . pal < = 0 ) spawned - > spr . pal = source - > spr . pal ;
2021-09-16 19:59:39 +00:00
// inherit spawn sprite trigger settings, so designer can count monsters.
2021-12-22 16:57:58 +00:00
spawned - > xspr . txID = source - > xspr . txID ;
spawned - > xspr . command = source - > xspr . command ;
spawned - > xspr . triggerOn = source - > xspr . triggerOn ;
spawned - > xspr . triggerOff = source - > xspr . triggerOff ;
2021-09-16 19:59:39 +00:00
// inherit drop items
2021-12-22 16:57:58 +00:00
spawned - > xspr . dropMsg = source - > xspr . dropMsg ;
2021-09-16 19:59:39 +00:00
// inherit dude flags
2021-12-22 16:57:58 +00:00
spawned - > xspr . dudeDeaf = source - > xspr . dudeDeaf ;
spawned - > xspr . dudeGuard = source - > xspr . dudeGuard ;
spawned - > xspr . dudeAmbush = source - > xspr . dudeAmbush ;
spawned - > xspr . dudeFlag4 = source - > xspr . dudeFlag4 ;
spawned - > xspr . unused1 = source - > xspr . unused1 ;
2021-09-16 19:59:39 +00:00
break ;
}
}
2020-12-05 17:32:49 +00:00
# endif
2019-09-19 22:42:45 +00:00
2021-05-05 10:55:52 +00:00
aiInitSprite ( spawned ) ;
2020-12-05 17:32:49 +00:00
return spawned ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 17:32:49 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2021-11-23 23:58:43 +00:00
DBloodActor * actSpawnThing ( sectortype * pSector , int x , int y , int z , int nThingType )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:24:09 +00:00
DVector3 pos ( x * inttoworld , y * inttoworld , z * zinttoworld ) ;
2021-09-16 19:59:39 +00:00
assert ( nThingType > = kThingBase & & nThingType < kThingMax ) ;
2022-08-22 16:24:09 +00:00
auto actor = actSpawnSprite ( pSector , pos , 4 , 1 ) ;
2020-12-05 19:22:29 +00:00
int nType = nThingType - kThingBase ;
2021-12-22 15:43:59 +00:00
actor - > spr . type = nThingType ;
2021-05-05 15:25:37 +00:00
assert ( actor - > hasX ( ) ) ;
2020-12-05 19:22:29 +00:00
const THINGINFO * pThingInfo = & thingInfo [ nType ] ;
2021-12-22 17:12:55 +00:00
actor - > xspr . health = pThingInfo - > startHealth < < 4 ;
2021-12-22 15:43:59 +00:00
actor - > spr . clipdist = pThingInfo - > clipdist ;
actor - > spr . flags = pThingInfo - > flags ;
if ( actor - > spr . flags & 2 ) actor - > spr . flags | = 4 ;
actor - > spr . cstat | = pThingInfo - > cstat ;
actor - > spr . picnum = pThingInfo - > picnum ;
actor - > spr . shade = pThingInfo - > shade ;
actor - > spr . pal = pThingInfo - > pal ;
if ( pThingInfo - > xrepeat ) actor - > spr . xrepeat = pThingInfo - > xrepeat ;
if ( pThingInfo - > yrepeat ) actor - > spr . yrepeat = pThingInfo - > yrepeat ;
actor - > spr . cstat2 | = CSTAT2_SPRITE_MAPPED ;
2020-12-05 19:22:29 +00:00
switch ( nThingType )
{
2021-09-16 19:59:39 +00:00
case kThingVoodooHead :
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = 0 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . data4 = 0 ;
actor - > xspr . state = 1 ;
actor - > xspr . triggerOnce = 1 ;
actor - > xspr . isTriggered = 0 ;
2021-09-16 19:59:39 +00:00
break ;
case kThingDroppedLifeLeech :
2020-12-05 19:22:29 +00:00
# ifdef NOONE_EXTENSIONS
2021-09-16 19:59:39 +00:00
case kModernThingEnemyLifeLeech :
2020-12-05 19:22:29 +00:00
# endif
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = 0 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . data4 = 0 ;
actor - > xspr . state = 1 ;
actor - > xspr . triggerOnce = 0 ;
actor - > xspr . isTriggered = 0 ;
2021-09-16 19:59:39 +00:00
break ;
case kThingZombieHead :
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = 8 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . data4 = 318 ;
2022-08-22 16:31:45 +00:00
actor - > xspr . TargetPos . X = PlayClock + 180 ;
2021-12-22 17:12:55 +00:00
actor - > xspr . locked = 1 ;
actor - > xspr . state = 1 ;
actor - > xspr . triggerOnce = 0 ;
actor - > xspr . isTriggered = 0 ;
2021-09-16 19:59:39 +00:00
break ;
case kThingBloodBits :
case kThingBloodChunks :
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = ( nThingType = = kThingBloodBits ) ? 19 : 8 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
2022-05-05 23:40:27 +00:00
actor - > xspr . data4 = 319 ;
2022-08-22 16:31:45 +00:00
actor - > xspr . TargetPos . X = PlayClock + 180 ;
2021-12-22 17:12:55 +00:00
actor - > xspr . locked = 1 ;
actor - > xspr . state = 1 ;
actor - > xspr . triggerOnce = 0 ;
actor - > xspr . isTriggered = 0 ;
2021-09-16 19:59:39 +00:00
break ;
case kThingArmedTNTStick :
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXDynPuff ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 450 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
2020-12-05 19:22:29 +00:00
2021-09-16 19:59:39 +00:00
case kThingArmedTNTBundle :
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 450 , 0 , 0 ) ;
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXDynPuff ) ;
2021-09-16 19:59:39 +00:00
break ;
2020-12-05 19:22:29 +00:00
2021-09-16 19:59:39 +00:00
case kThingArmedSpray :
2021-08-27 07:44:47 +00:00
evPostActor ( actor , 0 , kCallbackFXDynPuff ) ;
2021-09-16 19:59:39 +00:00
break ;
}
2020-12-05 19:22:29 +00:00
return actor ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 19:22:29 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
DBloodActor * actFireThing ( DBloodActor * actor , int a2 , int a3 , int a4 , int thingType , int a6 )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:59:39 +00:00
assert ( thingType > = kThingBase & & thingType < kThingMax ) ;
2022-08-16 21:15:49 +00:00
int x = actor - > int_pos ( ) . X + MulScale ( a2 , Cos ( actor - > int_ang ( ) + 512 ) , 30 ) ;
int y = actor - > int_pos ( ) . Y + MulScale ( a2 , Sin ( actor - > int_ang ( ) + 512 ) , 30 ) ;
2022-01-30 17:09:26 +00:00
int z = actor - > int_pos ( ) . Z + a3 ;
2022-08-16 21:17:01 +00:00
x + = MulScale ( actor - > spr . clipdist , Cos ( actor - > int_ang ( ) ) , 28 ) ;
y + = MulScale ( actor - > spr . clipdist , Sin ( actor - > int_ang ( ) ) , 28 ) ;
2022-01-30 17:09:26 +00:00
if ( HitScan ( actor , z , x - actor - > int_pos ( ) . X , y - actor - > int_pos ( ) . Y , 0 , CLIPMASK0 , actor - > spr . clipdist ) ! = - 1 )
2021-12-22 15:43:59 +00:00
{
2022-08-16 22:59:32 +00:00
x = gHitInfo . int_hitpos ( ) . X - MulScale ( actor - > spr . clipdist < < 1 , Cos ( actor - > int_ang ( ) ) , 28 ) ;
y = gHitInfo . int_hitpos ( ) . Y - MulScale ( actor - > spr . clipdist < < 1 , Sin ( actor - > int_ang ( ) ) , 28 ) ;
2021-09-16 19:59:39 +00:00
}
2021-12-30 15:51:56 +00:00
auto fired = actSpawnThing ( actor - > sector ( ) , x , y , z , thingType ) ;
2021-08-29 21:10:19 +00:00
fired - > SetOwner ( actor ) ;
2022-08-28 03:15:31 +00:00
fired - > spr . angle = actor - > spr . angle ;
2022-09-01 19:18:16 +00:00
fired - > set_int_bvel_x ( MulScale ( a6 , Cos ( fired - > int_ang ( ) ) , 30 ) ) ;
2022-09-01 19:24:29 +00:00
fired - > set_int_bvel_y ( MulScale ( a6 , Sin ( fired - > int_ang ( ) ) , 30 ) ) ;
2022-09-01 19:40:03 +00:00
fired - > set_int_bvel_z ( MulScale ( a6 , a4 , 14 ) ) ;
2022-09-03 08:12:52 +00:00
fired - > vel + = actor - > vel * 0.5 ;
2020-12-05 19:22:29 +00:00
return fired ;
2019-09-19 22:42:45 +00:00
}
2020-12-05 19:22:29 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-12-02 21:33:14 +00:00
2020-12-05 20:23:53 +00:00
void actBuildMissile ( DBloodActor * spawned , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:33:03 +00:00
switch ( spawned - > spr . type )
2021-09-16 19:59:39 +00:00
{
case kMissileLifeLeechRegular :
2021-12-29 18:41:41 +00:00
evPostActor ( spawned , 0 , kCallbackFXFlameLick ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileTeslaAlt :
2021-12-29 18:41:41 +00:00
evPostActor ( spawned , 0 , kCallbackFXTeslaAlt ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissilePukeGreen :
2020-12-05 20:23:53 +00:00
seqSpawn ( 29 , spawned , - 1 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileButcherKnife :
2021-12-22 15:33:03 +00:00
spawned - > spr . cstat | = CSTAT_SPRITE_ALIGNMENT_WALL ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileTeslaRegular :
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 251 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileEctoSkull :
2020-12-05 20:23:53 +00:00
seqSpawn ( 2 , spawned , - 1 ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 493 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFireballNapalm :
2020-12-05 20:23:53 +00:00
seqSpawn ( 61 , spawned , nNapalmClient ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 441 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFireball :
2020-12-05 20:23:53 +00:00
seqSpawn ( 22 , spawned , nFireballClient ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 441 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFlameHound :
2020-12-05 20:23:53 +00:00
seqSpawn ( 27 , spawned , - 1 ) ;
2022-09-03 08:12:52 +00:00
spawned - > vel + = actor - > vel * 0.5 ;
spawned - > vel . X + = Random2F ( 0x11111 ) ;
spawned - > vel . Y + = Random2F ( 0x11111 ) ;
spawned - > vel . Z + = Random2F ( 0x11111 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFireballCerberus :
2020-12-05 20:23:53 +00:00
seqSpawn ( 61 , spawned , dword_2192E0 ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 441 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFireballTchernobog :
2020-12-05 20:23:53 +00:00
seqSpawn ( 23 , spawned , dword_2192D8 ) ;
2022-09-03 08:12:52 +00:00
spawned - > vel + = actor - > vel * 0.5 ;
spawned - > vel . X + = Random2F ( 0x11111 ) ;
spawned - > vel . Y + = Random2F ( 0x11111 ) ;
spawned - > vel . Z + = Random2F ( 0x11111 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFlameSpray :
2020-12-05 20:23:53 +00:00
if ( Chance ( 0x8000 ) ) seqSpawn ( 0 , spawned , - 1 ) ;
else seqSpawn ( 1 , spawned , - 1 ) ;
2022-09-03 08:12:52 +00:00
spawned - > vel + = actor - > vel * 0.5 ;
spawned - > vel . X + = Random2F ( 0x11111 ) ;
spawned - > vel . Y + = Random2F ( 0x11111 ) ;
spawned - > vel . Z + = Random2F ( 0x11111 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFlareAlt :
2021-08-27 07:44:47 +00:00
evPostActor ( spawned , 30 , kCallbackFXFlareBurst ) ;
evPostActor ( spawned , 0 , kCallbackFXFlareSpark ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 422 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileFlareRegular :
2021-08-27 07:44:47 +00:00
evPostActor ( spawned , 0 , kCallbackFXFlareSpark ) ;
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 422 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileLifeLeechAltSmall :
2021-08-27 07:44:47 +00:00
evPostActor ( spawned , 0 , kCallbackFXArcSpark ) ;
2021-09-16 19:59:39 +00:00
break ;
case kMissileArcGargoyle :
2021-11-28 09:24:42 +00:00
sfxPlay3DSound ( spawned , 252 , 0 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
}
2019-09-19 22:42:45 +00:00
}
2020-12-05 20:23:53 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
DBloodActor * actFireMissile ( DBloodActor * actor , int a2 , int a3 , int a4 , int a5 , int a6 , int nType )
{
assert ( nType > = kMissileBase & & nType < kMissileMax ) ;
2021-11-16 17:30:23 +00:00
bool impact = false ;
2020-12-05 20:23:53 +00:00
const MissileType * pMissileInfo = & missileInfo [ nType - kMissileBase ] ;
2022-08-16 21:15:49 +00:00
int x = actor - > int_pos ( ) . X + MulScale ( a2 , Cos ( actor - > int_ang ( ) + 512 ) , 30 ) ;
int y = actor - > int_pos ( ) . Y + MulScale ( a2 , Sin ( actor - > int_ang ( ) + 512 ) , 30 ) ;
2022-01-30 17:09:26 +00:00
int z = actor - > int_pos ( ) . Z + a3 ;
2021-12-22 15:43:59 +00:00
int clipdist = pMissileInfo - > clipDist + actor - > spr . clipdist ;
2022-08-16 21:17:01 +00:00
x + = MulScale ( clipdist , Cos ( actor - > int_ang ( ) ) , 28 ) ;
y + = MulScale ( clipdist , Sin ( actor - > int_ang ( ) ) , 28 ) ;
2022-01-30 17:09:26 +00:00
int hit = HitScan ( actor , z , x - actor - > int_pos ( ) . X , y - actor - > int_pos ( ) . Y , 0 , CLIPMASK0 , clipdist ) ;
2020-12-05 20:23:53 +00:00
if ( hit ! = - 1 )
{
if ( hit = = 3 | | hit = = 0 )
{
2021-11-16 17:30:23 +00:00
impact = true ;
2022-08-16 22:59:32 +00:00
x = gHitInfo . int_hitpos ( ) . X - MulScale ( Cos ( actor - > int_ang ( ) ) , 16 , 30 ) ;
y = gHitInfo . int_hitpos ( ) . Y - MulScale ( Sin ( actor - > int_ang ( ) ) , 16 , 30 ) ;
2020-12-05 20:23:53 +00:00
}
else
{
2022-08-16 22:59:32 +00:00
x = gHitInfo . int_hitpos ( ) . X - MulScale ( pMissileInfo - > clipDist < < 1 , Cos ( actor - > int_ang ( ) ) , 28 ) ;
y = gHitInfo . int_hitpos ( ) . Y - MulScale ( pMissileInfo - > clipDist < < 1 , Sin ( actor - > int_ang ( ) ) , 28 ) ;
2020-12-05 20:23:53 +00:00
}
}
2022-08-22 16:24:09 +00:00
DVector3 pos ( x * inttoworld , y * inttoworld , z * zinttoworld ) ;
auto spawned = actSpawnSprite ( actor - > sector ( ) , pos , 5 , 1 ) ;
2021-12-22 15:33:03 +00:00
spawned - > spr . cstat2 | = CSTAT2_SPRITE_MAPPED ;
spawned - > spr . type = nType ;
spawned - > spr . shade = pMissileInfo - > shade ;
spawned - > spr . pal = 0 ;
spawned - > spr . clipdist = pMissileInfo - > clipDist ;
spawned - > spr . flags = 1 ;
spawned - > spr . xrepeat = pMissileInfo - > xrepeat ;
spawned - > spr . yrepeat = pMissileInfo - > yrepeat ;
spawned - > spr . picnum = pMissileInfo - > picnum ;
2022-08-16 21:20:03 +00:00
spawned - > set_int_ang ( ( actor - > int_ang ( ) + pMissileInfo - > angleOfs ) & 2047 ) ;
2022-09-01 19:18:16 +00:00
spawned - > set_int_bvel_x ( MulScale ( pMissileInfo - > velocity , a4 , 14 ) ) ;
2022-09-01 19:24:29 +00:00
spawned - > set_int_bvel_y ( MulScale ( pMissileInfo - > velocity , a5 , 14 ) ) ;
2022-09-01 19:40:03 +00:00
spawned - > set_int_bvel_z ( MulScale ( pMissileInfo - > velocity , a6 , 14 ) ) ;
2021-08-29 21:10:19 +00:00
spawned - > SetOwner ( actor ) ;
2021-12-22 15:33:03 +00:00
spawned - > spr . cstat | = CSTAT_SPRITE_BLOCK ;
2020-12-05 20:23:53 +00:00
spawned - > SetTarget ( nullptr ) ;
2021-08-27 07:44:47 +00:00
evPostActor ( spawned , 600 , kCallbackRemove ) ;
2020-12-05 20:23:53 +00:00
actBuildMissile ( spawned , actor ) ;
2021-11-16 17:30:23 +00:00
if ( impact )
2020-12-05 20:23:53 +00:00
{
actImpactMissile ( spawned , hit ) ;
return nullptr ;
}
return spawned ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-08-30 18:21:49 +00:00
int actGetRespawnTime ( DBloodActor * actor )
{
if ( ! actor - > hasX ( ) ) return - 1 ;
if ( actor - > IsDudeActor ( ) & & ! actor - > IsPlayerActor ( ) )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . respawn = = 2 | | ( actor - > xspr . respawn ! = 1 & & gGameOptions . nMonsterSettings = = 2 ) )
2021-09-16 19:59:39 +00:00
return gGameOptions . nMonsterRespawnTime ;
return - 1 ;
}
2019-10-13 22:29:19 +00:00
2021-08-30 18:21:49 +00:00
if ( actor - > IsWeaponActor ( ) )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . respawn = = 3 | | gGameOptions . nWeaponSettings = = 1 ) return 0 ;
else if ( actor - > xspr . respawn ! = 1 & & gGameOptions . nWeaponSettings ! = 0 )
2021-09-16 19:59:39 +00:00
return gGameOptions . nWeaponRespawnTime ;
return - 1 ;
}
2019-10-13 22:29:19 +00:00
2021-08-30 18:21:49 +00:00
if ( actor - > IsAmmoActor ( ) )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . respawn = = 2 | | ( actor - > xspr . respawn ! = 1 & & gGameOptions . nWeaponSettings ! = 0 ) )
2021-09-16 19:59:39 +00:00
return gGameOptions . nWeaponRespawnTime ;
return - 1 ;
}
2019-10-13 22:29:19 +00:00
2021-08-30 18:21:49 +00:00
if ( actor - > IsItemActor ( ) )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . respawn = = 3 & & gGameOptions . nGameType = = 1 ) return 0 ;
else if ( actor - > xspr . respawn = = 2 | | ( actor - > xspr . respawn ! = 1 & & gGameOptions . nItemSettings ! = 0 ) )
2021-08-30 18:21:49 +00:00
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-30 18:21:49 +00:00
{
2021-09-16 19:59:39 +00:00
case kItemShadowCloak :
case kItemTwoGuns :
case kItemReflectShots :
return gGameOptions . nSpecialRespawnTime ;
case kItemDeathMask :
2021-08-30 18:21:49 +00:00
return gGameOptions . nSpecialRespawnTime < < 1 ;
2021-09-16 19:59:39 +00:00
default :
return gGameOptions . nItemRespawnTime ;
}
}
return - 1 ;
}
return - 1 ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:21:49 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool actCheckRespawn ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-08-30 18:21:49 +00:00
if ( actor - > hasX ( ) )
2021-09-16 19:59:39 +00:00
{
2021-08-30 18:21:49 +00:00
int nRespawnTime = actGetRespawnTime ( actor ) ;
if ( nRespawnTime < 0 ) return 0 ;
2021-12-22 17:12:55 +00:00
actor - > xspr . respawnPending = 1 ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type > = kThingBase & & actor - > spr . type < kThingMax )
2021-09-16 19:59:39 +00:00
{
2021-12-22 17:12:55 +00:00
actor - > xspr . respawnPending = 3 ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type = = kThingTNTBarrel ) actor - > spr . cstat | = CSTAT_SPRITE_INVISIBLE ;
2021-09-16 19:59:39 +00:00
}
if ( nRespawnTime > 0 )
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . respawnPending = = 1 ) nRespawnTime = MulScale ( nRespawnTime , 0xa000 , 16 ) ;
2022-05-23 22:30:41 +00:00
actor - > spr . intowner = actor - > spr . statnum ;
2021-08-30 18:21:49 +00:00
actPostSprite ( actor , kStatRespawn ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = kHitagRespawn ;
2021-08-30 18:21:49 +00:00
2021-12-22 15:43:59 +00:00
if ( ! ( actor - > spr . type > = kDudeBase & & actor - > spr . type < kDudeMax ) )
2021-09-16 19:59:39 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2022-08-10 22:13:36 +00:00
actor - > spr . pos = actor - > basePoint ;
2021-09-16 19:59:39 +00:00
}
2021-08-27 07:44:47 +00:00
evPostActor ( actor , nRespawnTime , kCallbackRespawn ) ;
2021-09-16 19:59:39 +00:00
}
return 1 ;
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:28:24 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-21 08:51:51 +00:00
bool actCanSplatWall ( walltype * pWall )
2019-09-19 22:42:45 +00:00
{
2021-12-18 14:36:50 +00:00
if ( pWall - > cstat & ( CSTAT_WALL_MOVE_MASK ) ) return 0 ;
2021-08-30 18:28:24 +00:00
2021-11-21 08:51:51 +00:00
int nType = pWall - > type ;
2021-08-30 18:28:24 +00:00
if ( nType > = kWallBase & & nType < kWallMax ) return 0 ;
2021-11-23 22:04:21 +00:00
if ( pWall - > twoSided ( ) )
2021-09-16 19:59:39 +00:00
{
2021-11-19 19:08:50 +00:00
sectortype * pSector = pWall - > nextSector ( ) ;
2021-08-30 18:28:24 +00:00
if ( pSector - > type > = kSectorBase & & pSector - > type < kSectorMax ) return 0 ;
2021-09-16 19:59:39 +00:00
}
return 1 ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:28:24 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actFireVector ( DBloodActor * shooter , int a2 , int a3 , int a4 , int a5 , int a6 , VECTOR_TYPE vectorType )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:59:39 +00:00
assert ( vectorType > = 0 & & vectorType < kVectorMax ) ;
2021-08-30 18:28:24 +00:00
const VECTORDATA * pVectorData = & gVectorData [ vectorType ] ;
2021-09-16 19:59:39 +00:00
int nRange = pVectorData - > maxDist ;
2021-12-29 18:41:41 +00:00
int hit = VectorScan ( shooter , a2 , a3 , a4 , a5 , a6 , nRange , 1 ) ;
2021-09-16 19:59:39 +00:00
if ( hit = = 3 )
{
2021-11-25 22:28:28 +00:00
auto hitactor = gHitInfo . actor ( ) ;
2021-05-05 14:43:42 +00:00
assert ( hitactor ! = nullptr ) ;
2021-12-22 15:33:03 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( shooter , hitactor ) ) return ;
if ( hitactor - > IsPlayerActor ( ) )
2021-08-30 18:28:24 +00:00
{
2021-12-22 15:33:03 +00:00
PLAYER * pPlayer = & gPlayer [ hitactor - > spr . type - kDudePlayer1 ] ;
2021-09-16 19:59:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpReflectShots ) )
{
2021-11-25 22:28:28 +00:00
gHitInfo . hitActor = shooter ;
2022-08-17 16:53:45 +00:00
gHitInfo . hitpos = shooter - > spr . pos ;
2021-09-16 19:59:39 +00:00
}
}
}
2022-08-16 22:59:32 +00:00
int x = gHitInfo . int_hitpos ( ) . X - MulScale ( a4 , 16 , 14 ) ;
int y = gHitInfo . int_hitpos ( ) . Y - MulScale ( a5 , 16 , 14 ) ;
int z = gHitInfo . int_hitpos ( ) . Z - MulScale ( a6 , 256 , 14 ) ;
2021-11-25 22:28:28 +00:00
auto pSector = gHitInfo . hitSector ;
2021-09-16 19:59:39 +00:00
uint8_t nSurf = kSurfNone ;
2022-08-23 20:32:14 +00:00
if ( nRange = = 0 | | approxDist ( gHitInfo . hitpos . XY ( ) - shooter - > spr . pos . XY ( ) ) < nRange )
2021-09-16 19:59:39 +00:00
{
switch ( hit )
{
case 1 :
{
2021-12-18 12:14:56 +00:00
if ( pSector - > ceilingstat & CSTAT_SECTOR_SKY )
2021-09-16 19:59:39 +00:00
nSurf = kSurfNone ;
else
2021-11-23 16:00:00 +00:00
nSurf = surfType [ pSector - > ceilingpicnum ] ;
2021-09-16 19:59:39 +00:00
break ;
}
case 2 :
{
2021-12-18 12:14:56 +00:00
if ( pSector - > floorstat & CSTAT_SECTOR_SKY )
2021-09-16 19:59:39 +00:00
nSurf = kSurfNone ;
else
2021-11-23 16:00:00 +00:00
nSurf = surfType [ pSector - > floorpicnum ] ;
2021-09-16 19:59:39 +00:00
break ;
}
case 0 :
{
2021-11-23 16:00:00 +00:00
auto pWall = gHitInfo . hitWall ;
2021-11-19 19:35:33 +00:00
nSurf = surfType [ pWall - > picnum ] ;
2021-11-21 08:51:51 +00:00
if ( actCanSplatWall ( pWall ) )
2021-09-16 19:59:39 +00:00
{
2022-08-16 22:59:32 +00:00
int xx = gHitInfo . int_hitpos ( ) . X - MulScale ( a4 , 16 , 14 ) ;
int yy = gHitInfo . int_hitpos ( ) . Y - MulScale ( a5 , 16 , 14 ) ;
int zz = gHitInfo . int_hitpos ( ) . Z - MulScale ( a6 , 256 , 14 ) ;
2022-01-02 16:23:01 +00:00
int nnSurf = surfType [ pWall - > picnum ] ;
assert ( nnSurf < kSurfMax ) ;
if ( pVectorData - > surfHit [ nnSurf ] . fx1 > = 0 )
2021-09-16 19:59:39 +00:00
{
2022-01-02 16:23:01 +00:00
auto pFX = gFX . fxSpawnActor ( pVectorData - > surfHit [ nnSurf ] . fx1 , pSector , xx , yy , zz , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-08-16 21:20:03 +00:00
pFX - > set_int_ang ( ( GetWallAngle ( pWall ) + 512 ) & 2047 ) ;
2021-12-21 22:18:23 +00:00
pFX - > spr . cstat | = CSTAT_SPRITE_ALIGNMENT_WALL ;
2021-09-16 19:59:39 +00:00
}
}
}
break ;
}
case 4 :
{
2021-11-23 16:00:00 +00:00
auto pWall = gHitInfo . hitWall ;
2021-11-19 14:46:20 +00:00
nSurf = surfType [ pWall - > overpicnum ] ;
if ( pWall - > hasX ( ) )
2021-09-16 19:59:39 +00:00
{
2021-11-19 14:46:20 +00:00
if ( pWall - > xw ( ) . triggerVector )
2022-08-10 21:45:29 +00:00
trTriggerWall ( pWall , kCmdWallImpact , shooter ) ;
2021-09-16 19:59:39 +00:00
}
break ;
}
case 3 :
{
2021-11-25 22:28:28 +00:00
auto actor = gHitInfo . actor ( ) ;
2021-12-22 15:43:59 +00:00
nSurf = surfType [ actor - > spr . picnum ] ;
2021-09-16 19:59:39 +00:00
x - = MulScale ( a4 , 112 , 14 ) ;
y - = MulScale ( a5 , 112 , 14 ) ;
2021-08-30 18:28:24 +00:00
z - = MulScale ( a6 , 112 < < 4 , 14 ) ;
2021-09-16 19:59:39 +00:00
int shift = 4 ;
2021-08-30 18:28:24 +00:00
if ( vectorType = = kVectorTine & & ! actor - > IsPlayerActor ( ) ) shift = 3 ;
actDamageSprite ( shooter , actor , pVectorData - > dmgType , pVectorData - > dmg < < shift ) ;
2022-08-10 21:45:29 +00:00
if ( actor - > hasX ( ) & & actor - > xspr . Vector ) trTriggerSprite ( actor , kCmdSpriteImpact , shooter ) ;
2021-08-30 18:28:24 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum = = kStatThing )
2021-09-16 19:59:39 +00:00
{
2021-12-22 15:43:59 +00:00
int t = thingInfo [ actor - > spr . type - kThingBase ] . mass ;
2021-09-16 19:59:39 +00:00
if ( t > 0 & & pVectorData - > impulse )
{
int t2 = DivScale ( pVectorData - > impulse , t , 8 ) ;
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( a4 , t2 , 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( a5 , t2 , 16 ) ) ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( MulScale ( a6 , t2 , 16 ) ) ;
2021-09-16 19:59:39 +00:00
}
if ( pVectorData - > burnTime )
{
2021-12-22 15:49:41 +00:00
if ( ! actor - > xspr . burnTime ) evPostActor ( actor , 0 , kCallbackFXFlameLick ) ;
2021-08-30 18:28:24 +00:00
actBurnSprite ( shooter - > GetOwner ( ) , actor , pVectorData - > burnTime ) ;
2021-09-16 19:59:39 +00:00
}
}
2021-12-22 15:43:59 +00:00
if ( actor - > spr . statnum = = kStatDude & & actor - > hasX ( ) )
2021-09-16 19:59:39 +00:00
{
2021-12-22 15:43:59 +00:00
int t = getDudeInfo ( actor - > spr . type ) - > mass ;
2021-08-30 18:28:24 +00:00
# ifdef NOONE_EXTENSIONS
if ( actor - > IsDudeActor ( ) )
{
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-30 18:28:24 +00:00
{
2021-09-16 19:59:39 +00:00
case kDudeModernCustom :
case kDudeModernCustomBurning :
2021-12-29 18:41:41 +00:00
t = getSpriteMassBySize ( actor ) ;
2021-09-16 19:59:39 +00:00
break ;
}
}
2021-08-30 18:28:24 +00:00
# endif
2019-09-19 22:42:45 +00:00
2021-09-16 19:59:39 +00:00
if ( t > 0 & & pVectorData - > impulse )
{
int t2 = DivScale ( pVectorData - > impulse , t , 8 ) ;
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( a4 , t2 , 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( a5 , t2 , 16 ) ) ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( MulScale ( a6 , t2 , 16 ) ) ;
2021-09-16 19:59:39 +00:00
}
if ( pVectorData - > burnTime )
{
2021-12-22 15:49:41 +00:00
if ( ! actor - > xspr . burnTime ) evPostActor ( actor , 0 , kCallbackFXFlameLick ) ;
2021-08-30 18:28:24 +00:00
actBurnSprite ( shooter - > GetOwner ( ) , actor , pVectorData - > burnTime ) ;
2021-09-16 19:59:39 +00:00
}
if ( Chance ( pVectorData - > fxChance ) )
{
2022-01-02 16:23:01 +00:00
int tt = gVectorData [ 19 ] . maxDist ;
2021-09-16 19:59:39 +00:00
a4 + = Random3 ( 4000 ) ;
a5 + = Random3 ( 4000 ) ;
a6 + = Random3 ( 4000 ) ;
2022-08-23 20:45:42 +00:00
if ( HitScan ( actor , gHitInfo . hitpos . Z , a4 , a5 , a6 , CLIPMASK1 , tt ) = = 0 )
2021-09-16 19:59:39 +00:00
{
2022-08-23 20:32:14 +00:00
if ( approxDist ( gHitInfo . hitpos . XY ( ) - actor - > spr . pos . XY ( ) ) < = tt )
2021-09-16 19:59:39 +00:00
{
2021-11-23 16:00:00 +00:00
auto pWall = gHitInfo . hitWall ;
2022-01-02 16:23:01 +00:00
auto pSector1 = gHitInfo . hitSector ;
2021-11-23 16:00:00 +00:00
if ( actCanSplatWall ( pWall ) )
2021-09-16 19:59:39 +00:00
{
2022-08-16 22:59:32 +00:00
int xx = gHitInfo . int_hitpos ( ) . X - MulScale ( a4 , 16 , 14 ) ;
int yy = gHitInfo . int_hitpos ( ) . Y - MulScale ( a5 , 16 , 14 ) ;
int zz = gHitInfo . int_hitpos ( ) . Z - MulScale ( a6 , 16 < < 4 , 14 ) ;
2022-01-02 16:23:01 +00:00
int nnSurf = surfType [ pWall - > picnum ] ;
const VECTORDATA * pVectorData1 = & gVectorData [ 19 ] ;
FX_ID t2 = pVectorData1 - > surfHit [ nnSurf ] . fx2 ;
FX_ID t3 = pVectorData1 - > surfHit [ nnSurf ] . fx3 ;
2021-08-30 18:28:24 +00:00
DBloodActor * pFX = nullptr ;
2022-01-02 16:23:01 +00:00
if ( t2 > FX_NONE & & ( t3 = = FX_NONE | | Chance ( 0x4000 ) ) ) pFX = gFX . fxSpawnActor ( t2 , pSector1 , xx , yy , zz , 0 ) ;
else if ( t3 > FX_NONE ) pFX = gFX . fxSpawnActor ( t3 , pSector1 , xx , yy , zz , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-09-03 09:58:35 +00:00
pFX - > vel . Z = FixedToFloat ( 0x2222 ) ;
2022-08-16 21:20:03 +00:00
pFX - > set_int_ang ( ( GetWallAngle ( pWall ) + 512 ) & 2047 ) ;
2021-12-21 22:18:23 +00:00
pFX - > spr . cstat | = CSTAT_SPRITE_ALIGNMENT_WALL ;
2021-09-16 19:59:39 +00:00
}
}
}
}
}
for ( int i = 0 ; i < pVectorData - > bloodSplats ; i + + )
if ( Chance ( pVectorData - > splatChance ) )
2021-08-26 22:07:33 +00:00
fxSpawnBlood ( actor , pVectorData - > dmg < < 4 ) ;
2021-09-16 19:59:39 +00:00
}
2021-08-30 18:28:24 +00:00
# ifdef NOONE_EXTENSIONS
2021-09-16 19:59:39 +00:00
// add impulse for sprites from physics list
2021-08-30 18:28:24 +00:00
if ( gPhysSpritesCount > 0 & & pVectorData - > impulse )
{
2021-09-16 19:59:39 +00:00
if ( actor - > hasX ( ) )
2021-08-30 18:28:24 +00:00
{
2021-12-22 17:12:55 +00:00
if ( actor - > xspr . physAttr & kPhysDebrisVector ) {
2021-09-16 19:59:39 +00:00
2021-12-29 18:41:41 +00:00
int impulse = DivScale ( pVectorData - > impulse , ClipLow ( actor - > spriteMass . mass , 10 ) , 6 ) ;
2022-09-01 19:02:20 +00:00
actor - > add_int_bvel_x ( MulScale ( a4 , impulse , 16 ) ) ;
2022-09-01 19:05:25 +00:00
actor - > add_int_bvel_y ( MulScale ( a5 , impulse , 16 ) ) ;
2022-09-01 19:08:05 +00:00
actor - > add_int_bvel_z ( MulScale ( a6 , impulse , 16 ) ) ;
2021-07-19 21:15:26 +00:00
2021-09-16 19:59:39 +00:00
if ( pVectorData - > burnTime ! = 0 ) {
2021-12-29 18:41:41 +00:00
if ( ! actor - > xspr . burnTime ) evPostActor ( actor , 0 , kCallbackFXFlameLick ) ;
2021-09-16 19:59:39 +00:00
actBurnSprite ( shooter - > GetOwner ( ) , actor , pVectorData - > burnTime ) ;
}
2021-07-19 21:15:26 +00:00
2021-12-22 15:43:59 +00:00
if ( actor - > spr . type > = kThingBase & & actor - > spr . type < kThingMax ) {
actor - > spr . statnum = kStatThing ; // temporary change statnum property
2021-09-16 19:59:39 +00:00
actDamageSprite ( shooter , actor , pVectorData - > dmgType , pVectorData - > dmg < < 4 ) ;
2021-12-22 15:43:59 +00:00
actor - > spr . statnum = kStatDecoration ; // return statnum property back
2021-09-16 19:59:39 +00:00
}
2021-07-19 21:15:26 +00:00
2021-09-16 19:59:39 +00:00
}
2019-09-21 11:02:17 +00:00
2021-07-19 21:15:26 +00:00
2021-09-16 19:59:39 +00:00
}
2021-07-19 21:15:26 +00:00
2021-09-16 19:59:39 +00:00
}
# endif
break ;
}
}
}
assert ( nSurf < kSurfMax ) ;
2021-07-19 21:15:26 +00:00
# ifdef NOONE_EXTENSIONS
2021-09-16 19:59:39 +00:00
// let the patrol enemies hear surface hit sounds!
if ( pVectorData - > surfHit [ nSurf ] . fx2 > = 0 ) {
2021-12-29 18:41:41 +00:00
auto pFX2 = gFX . fxSpawnActor ( pVectorData - > surfHit [ nSurf ] . fx2 , pSector , x , y , z , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX2 & & gModernMap )
2021-08-29 21:10:19 +00:00
pFX2 - > SetOwner ( shooter ) ;
2021-09-16 19:59:39 +00:00
}
if ( pVectorData - > surfHit [ nSurf ] . fx3 > = 0 ) {
2021-12-29 18:41:41 +00:00
auto pFX3 = gFX . fxSpawnActor ( pVectorData - > surfHit [ nSurf ] . fx3 , pSector , x , y , z , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX3 & & gModernMap )
2021-08-29 21:10:19 +00:00
pFX3 - > SetOwner ( shooter ) ;
2021-07-19 21:15:26 +00:00
2021-09-16 19:59:39 +00:00
}
2021-07-19 21:15:26 +00:00
# else
2021-09-16 19:59:39 +00:00
if ( pVectorData - > surfHit [ nSurf ] . fx2 > = 0 )
2021-12-29 18:41:41 +00:00
gFX . fxSpawnActor ( pVectorData - > surfHit [ nSurf ] . fx2 , pSector , x , y , z , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pVectorData - > surfHit [ nSurf ] . fx3 > = 0 )
2021-12-29 18:41:41 +00:00
gFX . fxSpawnActor ( pVectorData - > surfHit [ nSurf ] . fx3 , pSector , x , y , z , 0 ) ;
2021-07-19 21:15:26 +00:00
# endif
2021-09-16 19:59:39 +00:00
if ( pVectorData - > surfHit [ nSurf ] . fxSnd > = 0 )
2021-11-23 16:00:00 +00:00
sfxPlay3DSound ( x , y , z , pVectorData - > surfHit [ nSurf ] . fxSnd , pSector ) ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:28:24 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-08-30 18:32:14 +00:00
2020-11-07 14:16:12 +00:00
void FireballSeqCallback ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_11 , actor - > sector ( ) , actor - > spr . pos , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-09-03 08:05:20 +00:00
pFX - > vel = actor - > vel ;
2021-09-16 19:59:39 +00:00
}
2019-09-19 22:42:45 +00:00
}
2020-11-07 14:16:12 +00:00
void NapalmSeqCallback ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_12 , actor - > sector ( ) , actor - > spr . pos , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-09-03 08:05:20 +00:00
pFX - > vel = actor - > vel ;
2021-09-16 19:59:39 +00:00
}
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:32:14 +00:00
void Fx32Callback ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_32 , actor - > sector ( ) , actor - > spr . pos , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-09-03 08:05:20 +00:00
pFX - > vel = actor - > vel ;
2021-09-16 19:59:39 +00:00
}
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:32:14 +00:00
void Fx33Callback ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2022-08-22 16:31:03 +00:00
auto pFX = gFX . fxSpawnActor ( FX_33 , actor - > sector ( ) , actor - > spr . pos , 0 ) ;
2021-09-16 19:59:39 +00:00
if ( pFX )
{
2022-09-03 08:05:20 +00:00
pFX - > vel = actor - > vel ;
2021-09-16 19:59:39 +00:00
}
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:32:14 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-11-07 14:16:12 +00:00
void TreeToGibCallback ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kThingObjectExplode ;
2021-12-22 17:12:55 +00:00
actor - > xspr . state = 1 ;
actor - > xspr . data1 = 15 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . health = thingInfo [ 17 ] . startHealth ;
actor - > xspr . data4 = 312 ;
2021-12-22 15:43:59 +00:00
actor - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
2019-09-19 22:42:45 +00:00
}
2020-11-07 14:16:12 +00:00
void DudeToGibCallback1 ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kThingBloodChunks ;
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = 8 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . health = thingInfo [ 26 ] . startHealth ;
actor - > xspr . data4 = 319 ;
actor - > xspr . triggerOnce = 0 ;
actor - > xspr . isTriggered = 0 ;
actor - > xspr . locked = 0 ;
2022-08-22 16:31:45 +00:00
actor - > xspr . TargetPos . X = PlayClock ;
2021-12-22 17:12:55 +00:00
actor - > xspr . state = 1 ;
2019-09-19 22:42:45 +00:00
}
2020-11-07 14:16:12 +00:00
void DudeToGibCallback2 ( int , DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . type = kThingBloodChunks ;
2021-12-22 17:12:55 +00:00
actor - > xspr . data1 = 3 ;
actor - > xspr . data2 = 0 ;
actor - > xspr . data3 = 0 ;
actor - > xspr . health = thingInfo [ 26 ] . startHealth ;
actor - > xspr . data4 = 319 ;
actor - > xspr . triggerOnce = 0 ;
actor - > xspr . isTriggered = 0 ;
actor - > xspr . locked = 0 ;
2022-08-22 16:31:45 +00:00
actor - > xspr . TargetPos . X = PlayClock ;
2021-12-22 17:12:55 +00:00
actor - > xspr . state = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:12:19 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actPostSprite ( DBloodActor * actor , int nStatus )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:59:39 +00:00
assert ( nStatus > = 0 & & nStatus < = kStatFree ) ;
2021-12-22 15:43:59 +00:00
if ( actor - > spr . flags & 32 )
2021-09-16 19:59:39 +00:00
{
2021-08-30 18:12:19 +00:00
for ( auto & post : gPost )
if ( post . sprite = = actor )
{
post . status = nStatus ;
return ;
2021-09-16 19:59:39 +00:00
}
2021-08-30 18:12:19 +00:00
}
2021-09-16 19:59:39 +00:00
else
{
2021-12-22 15:43:59 +00:00
actor - > spr . flags | = 32 ;
2021-08-30 18:12:19 +00:00
gPost . Push ( { actor , nStatus } ) ;
2021-09-16 19:59:39 +00:00
}
2020-12-02 21:33:14 +00:00
}
2019-09-19 22:42:45 +00:00
void actPostProcess ( void )
{
2021-08-30 18:12:19 +00:00
for ( auto & p : gPost )
2021-09-16 19:59:39 +00:00
{
2021-12-21 22:18:23 +00:00
p . sprite - > spr . flags & = ~ 32 ;
2021-08-30 18:12:19 +00:00
int nStatus = p . status ;
2021-09-16 19:59:39 +00:00
if ( nStatus = = kStatFree )
{
2021-12-21 22:18:23 +00:00
if ( p . sprite - > spr . statnum ! = kStatFree )
2021-08-26 06:10:18 +00:00
{
2021-08-27 07:44:47 +00:00
evKillActor ( p . sprite ) ;
2021-08-30 18:12:19 +00:00
if ( p . sprite - > hasX ( ) ) seqKill ( p . sprite ) ;
2021-08-29 20:04:35 +00:00
DeleteSprite ( p . sprite ) ;
2021-08-26 06:10:18 +00:00
}
2021-09-16 19:59:39 +00:00
}
else
2021-09-04 07:37:17 +00:00
ChangeActorStat ( p . sprite , nStatus ) ;
2021-09-16 19:59:39 +00:00
}
2021-08-30 18:12:19 +00:00
gPost . Clear ( ) ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:12:19 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-11-06 21:48:22 +00:00
void MakeSplash ( DBloodActor * actor )
2019-09-19 22:42:45 +00:00
{
2021-12-22 15:43:59 +00:00
actor - > spr . flags & = ~ 2 ;
2022-02-07 07:47:18 +00:00
actor - > spr . pos . Z - = 4 ;
2021-08-29 17:09:29 +00:00
int nSurface = tileGetSurfType ( actor - > hit . florhit ) ;
2021-12-22 15:43:59 +00:00
switch ( actor - > spr . type )
2021-08-30 18:32:14 +00:00
{
2021-09-16 19:59:39 +00:00
case kThingDripWater :
2021-08-30 18:32:14 +00:00
switch ( nSurface )
{
2021-09-16 19:59:39 +00:00
case kSurfWater :
2021-08-30 18:32:14 +00:00
seqSpawn ( 6 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 356 , - 1 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
default :
2021-08-30 18:32:14 +00:00
seqSpawn ( 7 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 354 , - 1 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
}
break ;
case kThingDripBlood :
2021-08-30 18:32:14 +00:00
seqSpawn ( 8 , actor , - 1 ) ;
2021-09-16 19:34:16 +00:00
sfxPlay3DSound ( actor , 354 , - 1 , 0 ) ;
2021-09-16 19:59:39 +00:00
break ;
}
2019-09-19 22:42:45 +00:00
}
2021-08-29 17:22:51 +00:00
void actBurnSprite ( DBloodActor * pSource , DBloodActor * pTarget , int nTime )
{
2021-12-22 17:12:55 +00:00
pTarget - > xspr . burnTime = ClipHigh ( pTarget - > xspr . burnTime + nTime , pTarget - > spr . statnum = = kStatDude ? 2400 : 1200 ) ;
2021-08-29 17:22:51 +00:00
pTarget - > SetBurnSource ( pSource ) ;
}
2020-11-21 20:31:50 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
2020-11-21 22:40:33 +00:00
FSerializer & Serialize ( FSerializer & arc , const char * keyname , SPRITEHIT & w , SPRITEHIT * def )
{
2021-09-02 18:23:51 +00:00
if ( arc . BeginObject ( keyname ) )
{
2021-12-29 18:41:41 +00:00
arc ( " hit " , w . hit )
( " ceilhit " , w . ceilhit )
( " florhit " , w . florhit )
2021-09-16 19:59:39 +00:00
. EndObject ( ) ;
}
return arc ;
2020-11-21 22:40:33 +00:00
}
2020-11-21 20:31:50 +00:00
void SerializeActor ( FSerializer & arc )
2019-09-19 22:42:45 +00:00
{
2020-11-21 20:31:50 +00:00
if ( arc . BeginObject ( " actor " ) )
{
2021-06-16 19:13:04 +00:00
arc ( " maxdist20 " , gVectorData [ kVectorTchernobogBurn ] . maxDist ) // The code messes around with this field so better save it.
2020-11-21 20:31:50 +00:00
. EndObject ( ) ;
2021-08-30 18:12:19 +00:00
if ( arc . isReading ( ) & & gGameOptions . nMonsterSettings ! = 0 )
2020-11-21 20:31:50 +00:00
{
for ( int i = 0 ; i < kDudeMax - kDudeBase ; i + + )
for ( int j = 0 ; j < 7 ; j + + )
2020-12-02 23:30:19 +00:00
dudeInfo [ i ] . damageVal [ j ] = MulScale ( DudeDifficulty [ gGameOptions . nDifficulty ] , dudeInfo [ i ] . startDamage [ j ] , 8 ) ;
2020-11-21 20:31:50 +00:00
}
}
2019-09-19 22:42:45 +00:00
}
2019-09-22 06:39:22 +00:00
END_BLD_NS