Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.82 KB | None | 0 0
  1. 2100
  2. %{
  3. #include "StdH.h"
  4. #include "EntitiesMP/CustomDebris.h"
  5.  
  6. void CCustomEnemy_OnInitClass(void)
  7. {
  8. // init particle effects
  9. InitParticles();
  10. }
  11.  
  12. %}
  13.  
  14. uses "EntitiesMP/EnemyBase";
  15.  
  16. enum AttackType {
  17. 0 AT_SINGLEFIRE "Single Fire",
  18. 1 AT_MULTIFIRE "Dual Fire",
  19. 2 AT_NONE "NONE",
  20. };
  21.  
  22. enum CloseType {
  23. 0 CT_SINGLEHIT "Hit",
  24. 1 CT_KAMIKADZE "Kamikadze",
  25. 2 CT_NONE "NONE",
  26. 3 CT_DOUBLEHIT "Double hit",
  27. 4 CT_JUMP "Jump on enemy"
  28. };
  29.  
  30. %{
  31. // info structure
  32. static EntityInfo eiCustMon = {
  33. EIBT_BONES, 250.0f,
  34. 0.0f, 1.9f, 0.0f, // source (eyes)
  35. 0.0f, 1.9f, 0.0f, // target (body)
  36. };
  37.  
  38. #define BONES_HIT 2.8f
  39. #define FIRE_RIGHT_HAND FLOAT3D( 0.25f, 1.5f, 0.0f)
  40. #define FIRE_LEFT_HAND FLOAT3D(-0.25f, 1.5f, 0.0f)
  41.  
  42. %}
  43.  
  44. class CCustomEnemy : CEnemyBase {
  45. name "CustomEnemy";
  46. thumbnail "Thumbnails\\Boneman.tbn";
  47. features "ImplementsOnInitClass";
  48.  
  49. properties:
  50. 1 CTFileName m_fnModel "&G Model" 'M' =CTFILENAME("Models\\Editor\\Axis.mdl"),
  51. 2 CTFileName m_fnTexture "&G Texture" 'T' =CTFILENAME("Models\\Editor\\Vector.tex"),
  52. 3 CTFileName m_fnReflection "&G Reflection" =CTString(""),
  53. 4 CTFileName m_fnSpecular "&G Specular" =CTString(""),
  54. 5 CTFileName m_fnBump "&G Bump" =CTString(""),
  55. 6 BOOL m_bFistHit = FALSE,
  56. 7 BOOL m_bRunSoundPlaying "Play runnning sound" = TRUE,
  57. 8 CSoundObject m_soFeet,
  58.  
  59. 10 ANIMATION m_iStandAnim "&A Standing animation" = 0,
  60. 11 ANIMATION m_iRotateAnim "&A Rotating animation" = 0,
  61. 12 ANIMATION m_iWalkAnim "&A Walking animation" = 0,
  62. 13 ANIMATION m_iRunAnim "&A Running animation" = 0,
  63. 14 ANIMATION m_iFireAnim "&A Fireing animation" = 0,
  64. 15 ANIMATION m_iDieAnim "&A Dieing animation" = 0,
  65. 16 ANIMATION m_iDamAnim "&A Damaging animation" = 0,
  66. 17 ANIMATION m_iCloseAnim "&A CloseFireing animation" = 0,
  67. 18 ANIMATION m_iCloseDoubleAnim "&A CloseDoublehit animation" = 0,
  68. 188 ANIMATION m_iJumpAnim "&A Jumping animation" = 0,
  69.  
  70. 20 enum SprayParticlesType m_sptPartType "&G Particle Type" = SPT_NONE,
  71.  
  72. 21 FLOAT m_fHealth "&G Health" = 125.0f,
  73. 22 FLOAT m_fWlkSp "&S Walk Speed" = 2.5f,
  74. 23 FLOAT m_fWlkRotSp "&S Walk Rot. Speed" = 45.0f,
  75. 24 FLOAT m_fAttSp "&S Attack Speed" = 10.0f,
  76. 25 FLOAT m_fAttRotSp "&S Attack Rot. Speed" = 600.0f,
  77. 26 FLOAT m_fClsSp "&S Close Speed" = 13.0f,
  78. 27 FLOAT m_fClsRtSp "&S Close Rot. Speed" = 1000.0f,
  79. 228 FLOAT m_fJumpHeight "&S Jump height" = 10.0f,
  80. 28 FLOAT m_fAttDist "&D Attack Distance" = 100.0f,
  81. 29 FLOAT m_fClsDist "&D Close Distance" = 30.0f,
  82. 30 FLOAT m_fStpDist "&D Stop Distance" = 2.0f,
  83. 31 FLOAT m_fIgnRng "&D Ignore Range" = 200.0f,
  84. 32 FLOAT m_fAttFireTime "&F Attack Fire Time" = 3.0f,
  85. 33 FLOAT m_fClsFireTime "&F Close Fire Time" = 2.0f,
  86. 234 BOOL m_bJumpAnytime "&F Jump anytime" = FALSE,
  87. 34 FLOAT m_fScr "&M Score" = 1000.0f,
  88. 35 FLOAT m_fBlwUp "&M Blow Up Ammount" = 70.0f,
  89. 36 FLOAT m_fDensity "&M Density" = 2000.0f,
  90. 77 FLOAT m_fHitTime "&F Wait after hit" = 3.0f,
  91. 147 FLOAT m_fFirAngl "&F Fire angle" = 100.0f,
  92. 167 BOOL m_bAlwaysVisible "Always visible" = FALSE,
  93. 178 FLOAT m_fBeforeHitTime "&F Wait before hit" = 3.0f,
  94. 125 FLOAT m_fBetweenHitTime "&F Wait between hits" = 1.0f,
  95. 71 FLOAT m_fHitStrenght "&F Hit strenght" = 10.0f,
  96. 37 CTFileName m_fnMess "&M Message" = CTString(""), // message
  97. 38 CTString m_str "&M Kill Message" = CTString("%s was killed by a Custom Monster"),
  98.  
  99. 40 enum ProjectileType m_ptType "&F Proj Type" 'T' = PRT_LAVA_COMET,
  100. 41 FLOAT m_FireOX "&FO Fire Offset X" 'X' = 0.25f,
  101. 42 FLOAT m_FireOY "&FO Fire Offset Y" 'Y' = 1.5f,
  102. 43 FLOAT m_FireOZ "&FO Fire Offset Z" 'Z' = 0.0f,
  103. 44 enum AttackType m_atType "&F Attack Type" = AT_SINGLEFIRE,
  104. 45 INDEX m_iPrCount "&F Proj. Count" 'P' = 1,
  105. 46 FLOAT m_fPrTime "&F Pr. Count Time" = 0.1f,
  106. 47 enum CloseType m_ctType "&F Close Attack Type" = CT_SINGLEHIT,
  107. 48 FLOAT m_fKamDist "&FK Kamikazi Dist." = 2.0f,
  108. 49 FLOAT m_fKamDam "&FK Kamikazi Damage" = 30.0f,
  109.  
  110. 50 CTFileName m_fnSIdle "&S Sound Idle" = CTFILENAME("Sounds\\Default.wav"), // sound
  111. 51 CTFileName m_fnSWound "&S Sound Wound" = CTFILENAME("Sounds\\Default.wav"), // sound
  112. 52 CTFileName m_fnSAttack "&S Sound Attack" = CTFILENAME("Sounds\\Default.wav"), // sound
  113. 53 CTFileName m_fnSRun "&S Sound Run" = CTFILENAME("Sounds\\Default.wav"), // sound
  114. 54 CTFileName m_fnSSight "&S Sound Sight" = CTFILENAME("Sounds\\Default.wav"), // sound
  115. 55 CTFileName m_fnSDeath "&S Sound Death" = CTFILENAME("Sounds\\Default.wav"), // sound
  116.  
  117. 56 FLOAT m_fDamageWoundedCustom "&F Damage for wound" = 80.0f,
  118.  
  119. 60 BOOL m_bLS "&P Leave Stain" = TRUE,
  120. 61 CEntityPointer m_penCustomDestruction "&P Custom Debris" COLOR(C_GREEN|0xFF), // targeted when destroyed
  121. 62 BOOL m_bAD "&P Always Debris" = FALSE,
  122. 100 INDEX m_iLoopCounter = 0,
  123. 88 BOOL m_bJumpAllowed "&F Allow jumping" = FALSE,
  124.  
  125. components:
  126. 0 class CLASS_BASE "Classes\\EnemyBase.ecl",
  127. 1 class CLASS_PROJECTILE "Classes\\Projectile.ecl",
  128. 2 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl",
  129. functions:
  130. void Precache(void) {
  131. CEnemyBase::Precache();
  132. //PrecacheModel(m_fnModel);
  133. PrecacheClass(CLASS_PROJECTILE,m_ptType);
  134. };
  135.  
  136. void AdjustMipFactor(FLOAT &fMipFactor)
  137. {
  138. if(m_bAlwaysVisible==TRUE)
  139. {
  140. fMipFactor=0;
  141. }
  142. };
  143.  
  144. // describe how this enemy killed player
  145. virtual CTString GetPlayerKillDescription(const CTString &strPlayerName, const EDeath &eDeath)
  146. {
  147. CTString str;
  148. str.PrintF(TranslateConst(m_str), strPlayerName);
  149. return str;
  150. }
  151.  
  152. SLONG GetUsedMemory(void)
  153. {
  154. // initial
  155. SLONG slUsedMemory = sizeof(CCustomEnemy) - sizeof(CEnemyBase) + CEnemyBase::GetUsedMemory();
  156. // add some more
  157. slUsedMemory += m_strName.Length();
  158. slUsedMemory += m_fnModel.Length();
  159. slUsedMemory += m_fnMess.Length();
  160. slUsedMemory += m_fnSIdle.Length();
  161. slUsedMemory += m_fnSWound.Length();
  162. slUsedMemory += m_fnSAttack.Length();
  163. slUsedMemory += m_fnSRun.Length();
  164. slUsedMemory += m_fnSSight.Length();
  165. slUsedMemory += m_fnSDeath.Length();
  166. slUsedMemory += m_str.Length();
  167. slUsedMemory += m_fnSpecular.Length();
  168. slUsedMemory += m_fnTexture.Length();
  169. slUsedMemory += m_fnReflection.Length();
  170. slUsedMemory += m_fnBump.Length();
  171. return slUsedMemory;
  172. }
  173.  
  174. virtual const CTFileName &GetComputerMessageName(void) const {
  175. return m_fnMess;
  176. };
  177.  
  178. void RenderParticles(void)
  179. {
  180. return;
  181. }
  182.  
  183. /* Entity info */
  184. void *GetEntityInfo(void) {
  185. return &eiCustMon;
  186. };
  187.  
  188. CAnimData *GetAnimData(SLONG slPropertyOffset)
  189. {
  190. if (slPropertyOffset==offsetof(CCustomEnemy, m_iStandAnim)) {
  191. return GetModelObject()->GetData();
  192. } else if (slPropertyOffset==offsetof(CCustomEnemy, m_iRotateAnim)) {
  193. return GetModelObject()->GetData();
  194. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iWalkAnim)) {
  195. return GetModelObject()->GetData();
  196. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iRunAnim)) {
  197. return GetModelObject()->GetData();
  198. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iFireAnim)) {
  199. return GetModelObject()->GetData();
  200. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iCloseDoubleAnim)) {
  201. return GetModelObject()->GetData();
  202. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iDieAnim)) {
  203. return GetModelObject()->GetData();
  204. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iDamAnim)) {
  205. return GetModelObject()->GetData();
  206. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iCloseAnim)) {
  207. return GetModelObject()->GetData();
  208. } else if (slPropertyOffset==offsetof(CCustomEnemy,m_iJumpAnim)) {
  209. return GetModelObject()->GetData();
  210. } else {
  211. return CEntity::GetAnimData(slPropertyOffset);
  212. }
  213. };
  214.  
  215. /* Receive damage */
  216. void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
  217. FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
  218. {
  219. //if (!IsOfClass(penInflictor, "CustomEnemy") && m_iGroup!=((CEnemyBase *)penInflictor)->m_iGroup) {
  220. CEnemyBase::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection);
  221. //};
  222. };
  223.  
  224. void LeaveStain(BOOL bGrow)
  225. {
  226. if(m_bLS){
  227. ESpawnEffect ese;
  228. FLOAT3D vPoint;
  229. FLOATplane3D vPlaneNormal;
  230. FLOAT fDistanceToEdge;
  231. // get your size
  232. FLOATaabbox3D box;
  233. GetBoundingBox(box);
  234.  
  235. // on plane
  236. if( GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
  237. // if near to polygon and away from last stain point
  238. if( (vPoint-GetPlacement().pl_PositionVector).Length()<0.5f
  239. && (m_vLastStain-vPoint).Length()>1.0f ) {
  240. m_vLastStain = vPoint;
  241. FLOAT fStretch = box.Size().Length();
  242. ese.colMuliplier = C_WHITE|CT_OPAQUE;
  243. // stain
  244. if (bGrow) {
  245. ese.betType = BET_BLOODSTAINGROW;
  246. ese.vStretch = FLOAT3D( fStretch*1.5f, fStretch*1.5f, 1.0f);
  247. } else {
  248. ese.betType = BET_BLOODSTAIN;
  249. ese.vStretch = FLOAT3D( fStretch*0.75f, fStretch*0.75f, 1.0f);
  250. }
  251. ese.vNormal = FLOAT3D( vPlaneNormal);
  252. ese.vDirection = FLOAT3D( 0, 0, 0);
  253. FLOAT3D vPos = vPoint+ese.vNormal/50.0f*(FRnd()+0.5f);
  254. CEntityPointer penEffect = CreateEntity( CPlacement3D(vPos, ANGLE3D(0,0,0)), CLASS_BASIC_EFFECT);
  255. penEffect->Initialize(ese);
  256. }
  257. }
  258. }
  259. }
  260.  
  261. // damage anim
  262. INDEX AnimForDamage(FLOAT fDamage) {
  263.  
  264. StartModelAnim(m_iDamAnim, 0);
  265. //DeactivateRunningSound();
  266. return m_iDamAnim;
  267. };
  268.  
  269. // death
  270. INDEX AnimForDeath(void) {
  271. if (m_ctType==CT_KAMIKADZE && CalcDist(m_penEnemy) < m_fKamDist) {
  272. // explode
  273. SetHealth(-10000.0f);
  274. m_vDamage = FLOAT3D(0,10000,0);
  275. Explode();
  276. SendEvent(EDeath());
  277. }
  278. if(m_bAD){
  279. SetHealth(-10000.0f);
  280. m_vDamage = FLOAT3D(0,10000,0);
  281. Explode();
  282. SendEvent(EDeath());
  283. }
  284. StartModelAnim(m_iDieAnim, 0);
  285. //DeactivateRunningSound();
  286. return m_iDieAnim;
  287. };
  288.  
  289. FLOAT WaitForDust(FLOAT3D &vStretch) {
  290. vStretch=FLOAT3D(1,1,2)*0.75f;
  291. return 0.48f;
  292. };
  293.  
  294. void DeathNotify(void) {
  295. };
  296.  
  297. // virtual anim functions
  298. void StandingAnim(void) {
  299. StartModelAnim(m_iStandAnim, AOF_LOOPING|AOF_NORESTART);
  300. DeactivateRunningSound();
  301. };
  302. void WalkingAnim(void) {
  303. StartModelAnim(m_iWalkAnim, AOF_LOOPING|AOF_NORESTART);
  304. DeactivateRunningSound();
  305. };
  306. void RunningAnim(void) {
  307. StartModelAnim(m_iRunAnim, AOF_LOOPING|AOF_NORESTART);
  308. ActivateRunningSound();
  309. };
  310. void RotatingAnim(void) {
  311. StartModelAnim(m_iRotateAnim, AOF_LOOPING|AOF_NORESTART);
  312. DeactivateRunningSound();
  313. };
  314. void MortalJumpAnim(void) {
  315. StartModelAnim(m_iJumpAnim, AOF_LOOPING|AOF_NORESTART);
  316. DeactivateRunningSound();
  317. };
  318.  
  319. // virtual sound functions
  320. void IdleSound(void) {
  321. PlaySound(m_soSound, m_fnSIdle, SOF_3D);
  322. };
  323. void SightSound(void) {
  324. PlaySound(m_soSound, m_fnSSight, SOF_3D);
  325. };
  326. void WoundSound(void) {
  327. PlaySound(m_soSound, m_fnSWound, SOF_3D);
  328. };
  329. void DeathSound(void) {
  330. PlaySound(m_soSound, m_fnSDeath, SOF_3D);
  331. /*m_soSound.Stop();
  332. m_soFeet.Stop();*/
  333. };
  334.  
  335.  
  336. void ActivateRunningSound(void)
  337. {
  338. if (!m_bRunSoundPlaying) {
  339. PlaySound(m_soFeet, m_fnSRun, SOF_3D|SOF_LOOP);
  340. m_bRunSoundPlaying = TRUE;
  341. }
  342. }
  343.  
  344. void DeactivateRunningSound(void)
  345. {
  346. m_soFeet.Stop();
  347. m_bRunSoundPlaying = FALSE;
  348. }
  349.  
  350. /************************************************************
  351. * BLOW UP FUNCTIONS *
  352. ************************************************************/
  353. // spawn body parts
  354. void BlowUp(void) {
  355. SwitchToEditorModel();
  356. SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
  357. SetCollisionFlags(ECF_IMMATERIAL);
  358. if(m_ctType==CT_KAMIKADZE){
  359. Explode();
  360. }
  361. if(!(m_penCustomDestruction==NULL)){
  362. CCustomDebris *pmd;
  363. pmd=(CCustomDebris*)&*m_penCustomDestruction;
  364. pmd->SpawnDebris(this);
  365. }
  366. };
  367.  
  368. BOOL ShouldBlowUp(void)
  369. {
  370. if ((m_ctType==CT_KAMIKADZE && GetHealth()<=0) || m_bAD) {
  371. return TRUE;
  372. } else {
  373. return CEnemyBase::ShouldBlowUp();
  374. }
  375. }
  376.  
  377.  
  378. void Explode(void) {
  379.  
  380. if(m_bAD && !(m_ctType==CT_KAMIKADZE)){
  381. FLOAT3D vSource;
  382. GetEntityInfoPosition(this, eiCustMon.vTargetCenter, vSource);
  383. InflictDirectDamage(this, this, DMT_CLOSERANGE, 100.0f, vSource,
  384. -en_vGravityDir);
  385. }
  386. if(m_ctType==CT_KAMIKADZE){
  387. // inflict damage
  388. FLOAT3D vSource;
  389. GetEntityInfoPosition(this, eiCustMon.vTargetCenter, vSource);
  390. InflictDirectDamage(this, this, DMT_CLOSERANGE, 100.0f, vSource,
  391. -en_vGravityDir);
  392. InflictRangeDamage(this, DMT_EXPLOSION, m_fKamDam, vSource, 2.75f, 8.0f);
  393.  
  394. // spawn explosion
  395. CPlacement3D plExplosion = GetPlacement();
  396. CEntityPointer penExplosion = CreateEntity(plExplosion, CLASS_BASIC_EFFECT);
  397. ESpawnEffect eSpawnEffect;
  398. eSpawnEffect.colMuliplier = C_WHITE|CT_OPAQUE;
  399. eSpawnEffect.betType = BET_BOMB;
  400. eSpawnEffect.vStretch = FLOAT3D(1.0f,1.0f,1.0f);
  401. penExplosion->Initialize(eSpawnEffect);
  402.  
  403. // explosion debris
  404. eSpawnEffect.betType = BET_EXPLOSION_DEBRIS;
  405. CEntityPointer penExplosionDebris = CreateEntity(plExplosion, CLASS_BASIC_EFFECT);
  406. penExplosionDebris->Initialize(eSpawnEffect);
  407.  
  408. // explosion smoke
  409. eSpawnEffect.betType = BET_EXPLOSION_SMOKE;
  410. CEntityPointer penExplosionSmoke = CreateEntity(plExplosion, CLASS_BASIC_EFFECT);
  411. penExplosionSmoke->Initialize(eSpawnEffect);
  412. }
  413. };
  414.  
  415. void SetSpeedsToDesiredPosition(const FLOAT3D &vPosDelta, FLOAT fPosDistance, BOOL bGoingToPlayer)
  416. {
  417. // if very close to player
  418. if (m_ctType==CT_KAMIKADZE && CalcDist(m_penEnemy) < m_fKamDist) {
  419. // explode
  420. SetHealth(-10000.0f);
  421. m_vDamage = FLOAT3D(0,10000,0);
  422. Explode();
  423. SendEvent(EDeath());
  424. // if not close
  425. } else {
  426. // behave as usual
  427. CEnemyBase::SetSpeedsToDesiredPosition(vPosDelta, fPosDistance, bGoingToPlayer);
  428. }
  429. }
  430.  
  431.  
  432. procedures:
  433. /************************************************************
  434. * A T T A C K E N E M Y *
  435. ************************************************************/
  436. Fire(EVoid) : CEnemyBase::Fire {
  437. if(m_atType==AT_SINGLEFIRE || m_atType==AT_MULTIFIRE){
  438. StartModelAnim(m_iFireAnim, AOF_LOOPING);
  439. m_iLoopCounter = m_iPrCount;
  440. while(m_iLoopCounter>0) {
  441. if (m_iLoopCounter%2 && m_atType==AT_MULTIFIRE) {
  442. ShootProjectile(m_ptType, FLOAT3D(-m_FireOX,m_FireOY,m_FireOZ), ANGLE3D(0, 0, 0));
  443. } else {
  444. ShootProjectile(m_ptType, FLOAT3D(m_FireOX,m_FireOY,m_FireOZ), ANGLE3D(0, 0, 0));
  445. }
  446. PlaySound(m_soSound, m_fnSAttack, SOF_3D);
  447. if (m_iLoopCounter>1) {
  448. m_fLockOnEnemyTime = m_fPrTime;
  449. autocall CEnemyBase::LockOnEnemy() EReturn;
  450. }
  451. m_iLoopCounter--;
  452. }
  453. autowait(GetModelObject()->GetAnimLength(m_iFireAnim));
  454. }
  455.  
  456. if(m_atType==AT_NONE){
  457.  
  458. }
  459.  
  460. //m_ptType*/
  461. return EReturn();
  462. };
  463.  
  464. Hit(EVoid) : CEnemyBase::Hit {
  465. if(m_ctType==CT_SINGLEHIT){
  466. StartModelAnim(m_iCloseAnim, AOF_LOOPING);
  467. autowait(m_fBeforeHitTime);
  468. FLOAT3D vDirection = m_penEnemy->GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector;
  469. vDirection.Normalize();
  470. FLOAT3D vSpeed;
  471. GetHeadingDirection(AngleDeg(0.0f), vSpeed);
  472. vSpeed = vSpeed * 5.0f;
  473. if (CalcDist(m_penEnemy)<m_fClsDist) {
  474. InflictDirectDamage(m_penEnemy, this, DMT_CLOSERANGE, m_fHitStrenght, FLOAT3D(0, 0, 0), vDirection);
  475. KickEntity(m_penEnemy, vSpeed);
  476. autowait(m_fHitTime);
  477. };
  478. };
  479. if(m_ctType==CT_DOUBLEHIT){
  480. StartModelAnim(m_iCloseDoubleAnim, AOF_LOOPING);
  481. autowait(m_fBeforeHitTime);
  482. FLOAT3D vDirection = m_penEnemy->GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector;
  483. vDirection.Normalize();
  484. FLOAT3D vSpeed;
  485. GetHeadingDirection(AngleDeg(0.0f), vSpeed);
  486. vSpeed = vSpeed * 5.0f;
  487. if (CalcDist(m_penEnemy)<m_fClsDist) {
  488. InflictDirectDamage(m_penEnemy, this, DMT_CLOSERANGE, m_fHitStrenght, FLOAT3D(0, 0, 0), vDirection);
  489. KickEntity(m_penEnemy, vSpeed);
  490. };
  491. autowait(m_fBetweenHitTime);
  492. FLOAT3D vDirection = m_penEnemy->GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector;
  493. vDirection.Normalize();
  494. FLOAT3D vSpeed;
  495. GetHeadingDirection(AngleDeg(0.0f), vSpeed);
  496. if (CalcDist(m_penEnemy)<m_fClsDist) {
  497. InflictDirectDamage(m_penEnemy, this, DMT_CLOSERANGE, m_fHitStrenght, FLOAT3D(0, 0, 0), vDirection);
  498. KickEntity(m_penEnemy, vSpeed);
  499. };
  500. autowait(m_fHitTime);
  501. };
  502. if(m_ctType==CT_KAMIKADZE){
  503.  
  504. };
  505. if(m_ctType==CT_JUMP){
  506. StartModelAnim(m_iCloseAnim, AOF_LOOPING);
  507. autowait(m_fBeforeHitTime);
  508. FLOAT3D vDirection = m_penEnemy->GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector;
  509. vDirection.Normalize();
  510. FLOAT3D vSpeed;
  511. GetHeadingDirection(AngleDeg(0.0f), vSpeed);
  512. vSpeed = vSpeed * 5.0f;
  513. if (CalcDist(m_penEnemy)<m_fClsDist) {
  514. KickEntity(m_penEnemy, vSpeed);
  515. autocall JumpOnce() EReturn;
  516. autowait(m_fHitTime);
  517. };
  518. };
  519. return EReturn();
  520. };
  521.  
  522. JumpOnce(EVoid)
  523. {
  524. // ------------ Jump either in slightly randomized direction or mortal, streight and fast toward enemy
  525. // we are always going for enemy
  526. m_vDesiredPosition = m_penEnemy->GetPlacement().pl_PositionVector;
  527. m_fMoveFrequency = 0.1f;
  528. // if we are close enough for mortal jump
  529. if( CalcPlaneDist(m_penEnemy) < 10.0f)
  530. {
  531. // set mortal jump parameters (no random)
  532. m_fMoveSpeed = m_fCloseRunSpeed*1.5f;
  533. m_aRotateSpeed = m_aCloseRotateSpeed*0.5f;
  534. FLOAT fSpeedX = 0.0f;
  535. FLOAT fSpeedY = m_fJumpHeight;
  536. FLOAT fSpeedZ = -m_fMoveSpeed;
  537. // if can't see enemy
  538. if( !IsInFrustum(m_penEnemy, CosFast(30.0f)))
  539. {
  540. // rotate a lot
  541. m_aRotateSpeed = m_aCloseRotateSpeed*1.5f;
  542. // but don't jump too much
  543. fSpeedY /= 2.0f;
  544. fSpeedZ /= 4.0f;
  545. PlaySound(m_soSound, m_fnSAttack, SOF_3D);
  546. }
  547. else
  548. {
  549. PlaySound(m_soSound, m_fnSAttack, SOF_3D);
  550. }
  551. FLOAT3D vTranslation(fSpeedX, fSpeedY, fSpeedZ);
  552. SetDesiredTranslation(vTranslation);
  553. MortalJumpAnim();
  554. }
  555. // start slightly randomized jump
  556. else
  557. {
  558. if(m_bJumpAnytime==TRUE) {
  559. m_fMoveSpeed = m_fCloseRunSpeed;
  560. m_aRotateSpeed = m_aCloseRotateSpeed;
  561. // set random jump parameters
  562. FLOAT fSpeedX = (FRnd()-0.5f)*10.0f;
  563. FLOAT fSpeedY = FRnd()*5.0f+5.0f;
  564. FLOAT fSpeedZ = -m_fMoveSpeed-FRnd()*2.5f;
  565. FLOAT3D vTranslation(fSpeedX, fSpeedY, fSpeedZ);
  566. SetDesiredTranslation(vTranslation);
  567. RunningAnim();
  568. PlaySound(m_soSound, m_fnSAttack, SOF_3D);
  569. };
  570. }
  571.  
  572. // ------------ While in air, adjust directions, on touch start new jump or explode
  573. while (TRUE)
  574. {
  575. // adjust direction and speed
  576. m_fMoveSpeed = 0.0f;
  577. m_aRotateSpeed = m_aCloseRotateSpeed;
  578. FLOAT3D vTranslation = GetDesiredTranslation();
  579. SetDesiredMovement();
  580. SetDesiredTranslation(vTranslation);
  581.  
  582. wait(m_fBeforeHitTime)
  583. {
  584. on (EBegin) : { resume; };
  585. on (ESound) : { resume; } // ignore all sounds
  586. on (EWatch) : { resume; } // ignore watch
  587. on (ETimer) : { stop; } // timer tick expire
  588. on (ETouch etouch) :
  589. {
  590. // if we touched ground
  591. if( etouch.penOther->GetRenderType() & RT_BRUSH)
  592. {
  593. return EReturn();
  594. }
  595. // we touched player, explode
  596. else if ( IsDerivedFromClass( etouch.penOther, "Player"))
  597. {
  598. FLOAT3D vDirection = m_penEnemy->GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector;
  599. vDirection.Normalize();
  600. InflictDirectDamage(m_penEnemy, this, DMT_CLOSERANGE, m_fHitStrenght, FLOAT3D(0, 0, 0), vDirection);
  601. }
  602. // we didn't touch ground nor player, ignore
  603. resume;
  604. }
  605. }
  606. }
  607. };
  608.  
  609. /************************************************************
  610. * M A I N *
  611. ************************************************************/
  612. Main(EVoid) {
  613. // declare yourself as a model
  614. InitAsModel();
  615. SetPhysicsFlags(EPF_MODEL_WALKING);
  616. SetCollisionFlags(ECF_MODEL);
  617. SetFlags(GetFlags()|ENF_ALIVE);
  618. SetHealth(m_fHealth);
  619. m_fMaxHealth = m_fHealth;
  620. en_fDensity = m_fDensity;
  621.  
  622. // set your appearance
  623. SetModel(m_fnModel);
  624. GetModelObject()->AutoSetTextures();
  625. GetModelObject()->AutoSetAttachments();
  626. try
  627. {
  628. GetModelObject()->mo_toTexture.SetData_t(m_fnTexture);
  629. GetModelObject()->mo_toReflection.SetData_t(m_fnReflection);
  630. GetModelObject()->mo_toSpecular.SetData_t(m_fnSpecular);
  631. GetModelObject()->mo_toBump.SetData_t(m_fnBump);
  632. } catch (char *strError) {
  633. WarningMessage(strError);
  634. }
  635. m_fnTexture = GetModelObject()->mo_toTexture.GetName();
  636. m_fnReflection = GetModelObject()->mo_toReflection.GetName();
  637. m_fnSpecular = GetModelObject()->mo_toSpecular.GetName();
  638. m_fnBump = GetModelObject()->mo_toBump.GetName();
  639.  
  640. StandingAnim();
  641. m_sptType = m_sptPartType;
  642. // setup moving speed
  643. m_fWalkSpeed = FRnd() + m_fWlkSp;
  644. m_aWalkRotateSpeed = FRnd()*m_fWlkRotSp/3 + m_fWlkRotSp;
  645. m_fAttackRunSpeed = FRnd() + m_fAttSp;
  646. m_aAttackRotateSpeed = FRnd()*m_fAttRotSp/3 + m_fAttRotSp;
  647. m_fCloseRunSpeed = FRnd() + m_fClsSp;
  648. m_aCloseRotateSpeed = FRnd()*m_fClsRtSp/3 + m_fClsRtSp;
  649. // setup attack distances
  650. m_fAttackDistance = m_fAttDist;
  651. m_fCloseDistance = m_fClsDist;
  652. m_fStopDistance = m_fStpDist;
  653. m_fAttackFireTime = m_fAttFireTime;
  654. m_fCloseFireTime = m_fClsFireTime;
  655. m_fIgnoreRange = m_fIgnRng;
  656. // damage/explode properties
  657. // m_fFireAngle = m_fFirAngl;
  658. m_fBlowUpAmount = m_fBlwUp;
  659. m_fBodyParts = 4;
  660. m_fDamageWounded = m_fDamageWoundedCustom;
  661. m_iScore = m_fScr;
  662. if (m_fStepHeight==-1) {
  663. m_fStepHeight = 4.0f;
  664. }
  665. GetModelObject()->AutoSetAttachments();
  666. // set stretch factors for height and width
  667. CEnemyBase::SizeModel();
  668. m_soFeet.Set3DParameters(80.0f, 5.0f, 1.0f, 1.0f);
  669. m_bRunSoundPlaying = FALSE;
  670.  
  671. // continue behavior in base class
  672. jump CEnemyBase::MainLoop();
  673. };
  674. };
  675. //need some code for attachments && other fire types
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement