1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010-2019 EDuke32 developers and contributors
4 Copyright (C) 2019 Nuke.YKT
5 Copyright (C) NoOne
6 
7 This file is part of NBlood.
8 
9 NBlood is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License version 2
11 as published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 */
23 //-------------------------------------------------------------------------
24 #ifdef NOONE_EXTENSIONS
25 #pragma once
26 #include "nnexts.h"
27 #include "ai.h"
28 #include "eventq.h"
29 
30 #define kGenDudeDefaultSeq 11520
31 #define kGenDudeMaxSlaves 7
32 #define kGenDudeTransformStatus -222
33 #define kGenDudeUpdTimeRate 10
34 #define kGenDudeMaxMeleeDist 2048
35 #define kGenDudeMinDispesion 200
36 #define kGenDudeMaxDispersion 3500
37 #define kGenDudeKlabsAng 56
38 
39 enum {
40 kGenDudeSeqIdleL            = 0,
41 kGenDudeSeqDeathDefault     = 1,
42 kGenDudeSeqDeathExplode     = 2,
43 kGenDudeSeqBurning          = 3,
44 kGenDudeSeqElectocuted      = 4,
45 kGenDudeSeqRecoil           = 5,
46 kGenDudeSeqAttackNormalL    = 6,
47 kGenDudeSeqAttackThrow      = 7,
48 kGenDudeSeqAttackNormalDW   = 8,
49 kGenDudeSeqMoveL            = 9,
50 kGenDudeSeqAttackPunch      = 10,
51 kGenDudeSeqReserved1        = 11,
52 kGenDudeSeqReserved2        = 12,
53 kGenDudeSeqMoveW            = 13,
54 kGenDudeSeqMoveD            = 14,
55 kGenDudeSeqDeathBurn1       = 15,
56 kGenDudeSeqDeathBurn2       = 16,
57 kGenDudeSeqIdleW            = 17,
58 kGenDudeSeqTransform        = 18,
59 kGenDudeSeqReserved3        = 19,
60 kGenDudeSeqReserved4        = 20,
61 kGenDudeSeqReserved5        = 21,
62 kGenDudeSeqReserved6        = 22,
63 kGenDudeSeqReserved7        = 23,
64 kGenDudeSeqReserved8        = 24,
65 kGenDudeSeqMax                  ,
66 };
67 
68 enum {
69 kGenDudeSndTargetSpot       = 0,
70 kGenDudeSndGotHit           = 1,
71 kGenDudeSndDeathNormal      = 2,
72 kGenDudeSndBurning          = 3,
73 kGenDudeSndDeathExplode     = 4,
74 kGenDudeSndTargetDead       = 5,
75 kGenDudeSndChasing          = 6,
76 kGenDudeSndAttackNormal     = 7,
77 kGenDudeSndAttackThrow      = 8,
78 kGenDudeSndAttackMelee      = 9,
79 kGenDudeSndTransforming     = 10,
80 kGenDudeSndMax                  ,
81 };
82 
83 enum {
84 kGenDudePropertyAll         = 0,
85 kGenDudePropertyWeapon      = 1,
86 kGenDudePropertyDmgScale    = 2,
87 kGenDudePropertyMass        = 3,
88 kGenDudePropertyAttack      = 4,
89 kGenDudePropertyStates      = 5,
90 kGenDudePropertyLeech       = 6,
91 kGenDudePropertySlaves      = 7,
92 kGenDudePropertySpriteSize  = 8,
93 kGenDudePropertyInitVals    = 9,
94 kGenDudePropertyMax            ,
95 };
96 
97 enum {
98 kGenDudeWeaponNone          = -1,
99 kGenDudeWeaponHitscan       = 0,
100 kGenDudeWeaponMissile       = 1,
101 kGenDudeWeaponThrow         = 2,
102 kGenDudeWeaponSummon        = 3,
103 kGenDudeWeaponKamikaze      = 4,
104 kGenDudeWeaponMax              ,
105 };
106 
107 extern AISTATE genDudeIdleL;
108 extern AISTATE genDudeIdleW;
109 extern AISTATE genDudeSearchL;
110 extern AISTATE genDudeSearchW;
111 extern AISTATE genDudeGotoL;
112 extern AISTATE genDudeGotoW;
113 extern AISTATE genDudeDodgeL;
114 extern AISTATE genDudeDodgeD;
115 extern AISTATE genDudeDodgeW;
116 extern AISTATE genDudeDodgeShortL;
117 extern AISTATE genDudeDodgeShortD;
118 extern AISTATE genDudeDodgeShortW;
119 extern AISTATE genDudeDodgeShorterL;
120 extern AISTATE genDudeDodgeShorterD;
121 extern AISTATE genDudeDodgeShorterW;
122 extern AISTATE genDudeChaseL;
123 extern AISTATE genDudeChaseD;
124 extern AISTATE genDudeChaseW;
125 extern AISTATE genDudeFireL;
126 extern AISTATE genDudeFireD;
127 extern AISTATE genDudeFireW;
128 extern AISTATE genDudeRecoilL;
129 extern AISTATE genDudeRecoilD;
130 extern AISTATE genDudeRecoilW;
131 extern AISTATE genDudeThrow;
132 extern AISTATE genDudeThrow2;
133 extern AISTATE genDudePunch;
134 extern AISTATE genDudeRecoilTesla;
135 extern AISTATE genDudeSearchNoWalkL;
136 extern AISTATE genDudeSearchNoWalkW;
137 extern AISTATE genDudeChaseNoWalkL;
138 extern AISTATE genDudeChaseNoWalkD;
139 extern AISTATE genDudeChaseNoWalkW;
140 
141 struct GENDUDESND
142 {
143     int defaultSndId;
144     int randomRange;
145     int sndIdOffset;  // relative to data3
146     bool aiPlaySound; // false = sfxStart3DSound();
147     bool interruptable;
148 };
149 
150 extern GENDUDESND gCustomDudeSnd[];
151 
152 // temporary, until normal DUDEEXTRA gets refactored
153 struct GENDUDEEXTRA {
154     unsigned short initVals[3];             // xrepeat, yrepeat, clipdist
155     unsigned short availDeaths[kDamageMax]; // list of seqs with deaths for each damage type
156     unsigned int moveSpeed;
157     unsigned int fireDist;                  // counts from sprite size
158     unsigned int throwDist;                 // counts from sprite size
159     unsigned short curWeapon;               // data1 duplicate to avoid potential problems when changing data dynamically
160     unsigned short weaponType;
161     unsigned short baseDispersion;
162     unsigned short slaveCount;              // how many dudes is summoned
163     signed short nLifeLeech;                // spritenum of dropped dude's leech
164     signed short slave[kGenDudeMaxSlaves];  // index of the ones dude is summon
165     signed short dmgControl[kDamageMax];    // depends of current weapon, drop armor item, sprite yrepeat and surface type
166     bool updReq[kGenDudePropertyMax];       // update requests
167     bool sndPlaying;                        // indicate if sound of AISTATE currently playing
168     bool forcePunch;                        // indicate if there is no fire trigger in punch state seq
169     bool isMelee;
170     bool canBurn;                           // can turn in Burning dude or not
171     bool canElectrocute;
172     bool canAttack;
173     bool canRecoil;
174     bool canWalk;
175     bool canDuck;
176     bool canSwim;
177     bool canFly;
178 };
179 
180 extern GENDUDEEXTRA gGenDudeExtra[kMaxSprites];
181 
182 GENDUDEEXTRA* genDudeExtra(spritetype* pGenDude);
183 XSPRITE* getNextIncarnation(XSPRITE* pXSprite);
184 void killDudeLeech(spritetype* pLeech);
185 void removeLeech(spritetype* pLeech, bool delSprite = true);
186 void removeDudeStuff(spritetype* pSprite);
187 spritetype* leechIsDropped(spritetype* pSprite);
188 bool spriteIsUnderwater(spritetype* pSprite, bool oldWay = false);
189 bool playGenDudeSound(spritetype* pSprite, int mode);
190 void aiGenDudeMoveForward(spritetype* pSprite, XSPRITE* pXSprite);
191 void aiGenDudeChooseDirection(spritetype* pSprite, XSPRITE* pXSprite, int a3, int aXvel = -1, int aYvel = -1);
192 void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState);
193 int getGenDudeMoveSpeed(spritetype* pSprite, int which, bool mul, bool shift);
194 int checkAttackState(spritetype* pSprite, XSPRITE* pXSprite);
195 bool doExplosion(spritetype* pSprite, int nType);
196 spritetype* genDudeSpawn(spritetype* pSprite, int nDist);
197 void genDudeTransform(spritetype* pSprite);
198 void dudeLeechOperate(spritetype* pSprite, XSPRITE* pXSprite, EVENT a3);
199 int getDodgeChance(spritetype* pSprite);
200 int getRecoilChance(spritetype* pSprite);
201 bool dudeIsMelee(XSPRITE* pXSprite);
202 void updateTargetOfSlaves(spritetype* pSprite);
203 void updateTargetOfLeech(spritetype* pSprite);
204 bool canSwim(spritetype* pSprite);
205 bool canDuck(spritetype* pSprite);
206 bool canWalk(spritetype* pSprite);
207 short inDodge(AISTATE* aiState);
208 bool inIdle(AISTATE* aiState);
209 bool inAttack(AISTATE* aiState);
210 short inRecoil(AISTATE* aiState);
211 short inSearch(AISTATE* aiState);
212 short inChase(AISTATE* aiState);
213 short inDuck(AISTATE* aiState);
214 int genDudeSeqStartId(XSPRITE* pXSprite);
215 int getRangeAttackDist(spritetype* pSprite, int minDist = 3000, int maxDist = 80000);
216 int getDispersionModifier(spritetype* pSprite, int minDisp, int maxDisp);
217 void scaleDamage(XSPRITE* pXSprite);
218 bool genDudePrepare(spritetype* pSprite, int propId);
219 void genDudeUpdate(spritetype* pSprite);
220 bool genDudeAdjustSlope(spritetype* pSprite, XSPRITE* pXSprite, int dist, int weaponType, int by = 64);
221 void genDudePostDeath(spritetype* pSprite, DAMAGE_TYPE damageType, int damage);
222 void aiGenDudeInitSprite(spritetype* pSprite, XSPRITE* pXSprite);
223 #endif