330 %{ #include "Entities/StdH/StdH.h" #include "Models/Enemies/Cyborg/Cyborg.h" %} uses "Entities/EnemyFly"; uses "Entities/Projectile"; uses "Entities/CyborgBike"; enum CyborgType { 0 CBT_GROUND "Ground", 1 CBT_FLY "Fly", 2 CBT_FLYGROUND "Fly-Ground", }; %{ // info structure static EntityInfo eiCyborgStand = { EIBT_ROBOT, 200.0f, 0.0f, 1.55f, 0.0f, 0.0f, 1.0f, 0.0f, }; static EntityInfo eiCyborgFly = { EIBT_ROBOT, 1500.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, }; #define FIRE_BIKE FLOAT3D(-0.35f, 0.1f, -1.2f) #define FIRE_LASER FLOAT3D(-0.5f, 1.7f, -0.75f) #define IGNORE_RANGE 400.0f #define BIKE_ATTACHMENT FLOAT3D(0, 0, -0.271f) %} class CCyborg : CEnemyBase { name "Cyborg"; thumbnail "Thumbnails\\Cyborg.tbn"; properties: 1 enum CyborgType m_EctType "Type" 'T' = CBT_GROUND, // type 2 INDEX m_iCloseHit = 0, // close hit hand (left or right) 3 INDEX m_iFireLaserCount = 0, // fire laser binary divider 4 INDEX m_ctBombsToDrop = 0, // counter of bombs to drop in fly-over 10 FLOAT m_tmLastBombDropped = -1.0f, // when last bomb was dropped 5 FLOAT m_fFlyAboveEnemy = 0.0f, // fly above enemy height 6 FLOAT m_fFlySpeed = 0.0f, 7 FLOAT m_aFlyRotateSpeed = 0.0f, 8 FLOAT m_fFallStartTime = 0.0f, 9 BOOL m_bBombing "Bombing" 'B' = FALSE, // enable bombing { CEntity *penBullet; // bullet } components: 0 class CLASS_BASE "Classes\\EnemyFly.ecl", 1 class CLASS_BULLET "Classes\\Bullet.ecl", 2 class CLASS_CYBORG_BIKE "Classes\\CyborgBike.ecl", 3 class CLASS_PROJECTILE "Classes\\Projectile.ecl", 4 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl", 10 model MODEL_CYBORG "Models\\Enemies\\Cyborg\\Cyborg.mdl", 11 model MODEL_ASS "Models\\Enemies\\Cyborg\\AssHole.mdl", 12 model MODEL_TORSO "Models\\Enemies\\Cyborg\\Torso.mdl", 13 model MODEL_HEAD "Models\\Enemies\\Cyborg\\Head.mdl", 14 model MODEL_RIGHT_UPPER_ARM "Models\\Enemies\\Cyborg\\RightUpperArm.mdl", 15 model MODEL_RIGHT_LOWER_ARM "Models\\Enemies\\Cyborg\\RightLowerArm.mdl", 16 model MODEL_LEFT_UPPER_ARM "Models\\Enemies\\Cyborg\\LeftUpperArm.mdl", 17 model MODEL_LEFT_LOWER_ARM "Models\\Enemies\\Cyborg\\LeftLowerArm.mdl", 18 model MODEL_RIGHT_UPPER_LEG "Models\\Enemies\\Cyborg\\RightUpperLeg.mdl", 19 model MODEL_RIGHT_LOWER_LEG "Models\\Enemies\\Cyborg\\RightLowerLeg.mdl", 20 model MODEL_LEFT_UPPER_LEG "Models\\Enemies\\Cyborg\\LeftUpperLeg.mdl", 21 model MODEL_LEFT_LOWER_LEG "Models\\Enemies\\Cyborg\\LeftLowerLeg.mdl", 22 model MODEL_FOOT "Models\\Enemies\\Cyborg\\Foot.mdl", 23 model MODEL_BIKE "Models\\Enemies\\Cyborg\\Bike.mdl", 30 texture TEXTURE_CYBORG "Models\\Enemies\\Cyborg\\Cyborg.tex", 31 texture TEXTURE_BIKE "Models\\Enemies\\Cyborg\\Bike.tex", // ************** SOUNDS ************** 50 sound SOUND_IDLE "Models\\Enemies\\Cyborg\\Sounds\\Idle.wav", 51 sound SOUND_SIGHT "Models\\Enemies\\Cyborg\\Sounds\\Sight.wav", 52 sound SOUND_WOUND "Models\\Enemies\\Cyborg\\Sounds\\Wound.wav", 53 sound SOUND_FIRE "Models\\Enemies\\Cyborg\\Sounds\\Fire.wav", 54 sound SOUND_KICK "Models\\Enemies\\Cyborg\\Sounds\\Kick.wav", 55 sound SOUND_DEATH "Models\\Enemies\\Cyborg\\Sounds\\Death.wav", // ************** REFLECTIONS ************** 202 texture TEX_REFL_LIGHTMETAL01 "Models\\ReflectionTextures\\LightMetal01.tex", // ************** SPECULAR ************** 211 texture TEX_SPEC_MEDIUM "Models\\SpecularTextures\\Medium.tex", 212 texture TEX_SPEC_STRONG "Models\\SpecularTextures\\Strong.tex", functions: /* Entity info */ void *GetEntityInfo(void) { if (m_EctType!=CBT_GROUND) { return &eiCyborgFly; } else { return &eiCyborgStand; } }; /* Receive damage */ void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection) { // cyborg can't harm cyborg if (!IsOfClass(penInflictor, "Cyborg")) { CEnemyBase::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection); } }; // damage anim INDEX AnimForDamage(FLOAT fDamage) { INDEX iAnim; switch (IRnd()%4) { case 0: iAnim = CYBORG_ANIM_WOUND01; break; case 1: iAnim = CYBORG_ANIM_WOUND02; break; case 2: iAnim = CYBORG_ANIM_WOUND03; break; case 3: iAnim = CYBORG_ANIM_WOUND04; break; default: ASSERTALWAYS("Cyborg unknown damage"); } StartModelAnim(iAnim, 0); return iAnim; }; // death INDEX AnimForDeath(void) { INDEX iAnim; switch (IRnd()%2) { case 0: iAnim = CYBORG_ANIM_DEATH01; break; case 1: iAnim = CYBORG_ANIM_DEATH02; break; default: ASSERTALWAYS("Cyborg unknown death"); } StartModelAnim(iAnim, 0); return iAnim; }; // virtual anim functions void StandingAnim(void) { if (m_EctType!=CBT_GROUND) { StartModelAnim(CYBORG_ANIM_BIKEREST, AOF_LOOPING|AOF_NORESTART); } else { StartModelAnim(CYBORG_ANIM_WAIT01, AOF_LOOPING|AOF_NORESTART); } }; void WalkingAnim(void) { if (m_EctType!=CBT_GROUND) { StartModelAnim(CYBORG_ANIM_BIKEREST, AOF_LOOPING|AOF_NORESTART); } else { StartModelAnim(CYBORG_ANIM_WALK01, AOF_LOOPING|AOF_NORESTART); } }; void RunningAnim(void) { if (m_EctType!=CBT_GROUND) { StartModelAnim(CYBORG_ANIM_BIKEREST, AOF_LOOPING|AOF_NORESTART); } else { StartModelAnim(CYBORG_ANIM_WALK01, AOF_LOOPING|AOF_NORESTART); } }; void RotatingAnim(void) { if (m_EctType!=CBT_GROUND) { StartModelAnim(CYBORG_ANIM_BIKEREST, AOF_LOOPING|AOF_NORESTART); } else { StartModelAnim(CYBORG_ANIM_WALK01, AOF_LOOPING|AOF_NORESTART); } }; void ChangeCollisionToAir() { ChangeCollisionBoxIndexWhenPossible(CYBORG_COLLISION_BOX_BIKE); }; void ChangeCollisionToGround() { ChangeCollisionBoxIndexWhenPossible(CYBORG_COLLISION_BOX_GROUND); }; // virtual sound functions void IdleSound(void) { PlaySound(m_soSound, SOUND_IDLE, SOF_3D); }; void SightSound(void) { PlaySound(m_soSound, SOUND_SIGHT, SOF_3D); }; void WoundSound(void) { PlaySound(m_soSound, SOUND_WOUND, SOF_3D); }; void DeathSound(void) { PlaySound(m_soSound, SOUND_DEATH, SOF_3D); }; /************************************************************ * BLOW UP FUNCTIONS * ************************************************************/ // spawn body parts void BlowUp(void) { // get your size FLOATaabbox3D box; GetBoundingBox(box); FLOAT fEntitySize = box.Size().MaxNorm(); // spawn debris Debris_Begin(EIBT_ROBOT, DPR_SMOKETRAIL, BET_EXPLOSIONSTAIN, fEntitySize, m_vDamage*0.3f, en_vCurrentTranslationAbsolute, 1.0f, 0.0f); Debris_Spawn(this, this, MODEL_ASS, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_TORSO, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_STRONG, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_HEAD, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_RIGHT_UPPER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_RIGHT_LOWER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_LEFT_UPPER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_LEFT_LOWER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_RIGHT_UPPER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_RIGHT_LOWER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_LEFT_UPPER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_LEFT_LOWER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_FOOT, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); Debris_Spawn(this, this, MODEL_FOOT, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0, 0, 0.0f, FLOAT3D(FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f, FRnd()*0.6f+0.2f)); // spawn explosion CPlacement3D plExplosion = GetPlacement(); CEntityPointer penExplosion = CreateEntity(plExplosion, CLASS_BASIC_EFFECT); ESpawnEffect eSpawnEffect; eSpawnEffect.colMuliplier = C_WHITE|CT_OPAQUE; eSpawnEffect.betType = BET_BOMB; FLOAT fSize = fEntitySize*0.3f; eSpawnEffect.vStretch = FLOAT3D(fSize,fSize,fSize); penExplosion->Initialize(eSpawnEffect); // hide yourself (must do this after spawning debris) SwitchToEditorModel(); SetPhysicsFlags(EPF_MODEL_IMMATERIAL); SetCollisionFlags(ECF_IMMATERIAL); }; /************************************************************ * MOVING FUNCTIONS * ************************************************************/ // fly desired position for attack virtual void FlyDesiredPosition(FLOAT3D &vPos) { FLOAT fDist = (m_penEnemy->GetPlacement().pl_PositionVector - GetPlacement().pl_PositionVector).Length(); vPos = m_penEnemy->GetPlacement().pl_PositionVector; vPos += FLOAT3D(m_penEnemy->en_mRotation(1, 2), m_penEnemy->en_mRotation(2, 2), m_penEnemy->en_mRotation(3, 2)) * m_fFlyAboveEnemy; }; // fly move in direction void FlyInDirection() { /* !!!! RotateToAngle(); // determine translation speed FLOAT3D vTranslation = (m_vDesiredPosition - GetPlacement().pl_PositionVector) * !en_mRotation; vTranslation(1) = 0.0f; vTranslation.Normalize(); vTranslation *= m_fMoveSpeed; // start moving SetDesiredTranslation(vTranslation); */ }; // fly entity to desired position void FlyToPosition() { /* !!!! CalcAngleFromPosition(); FlyInDirection(); */ }; procedures: /************************************************************ * CLASS INTERNAL * ************************************************************/ // fall to floor FallToFloor(EVoid) { // spawn bike CPlacement3D plBike = GetPlacement(); FLOATmatrix3D mRotation; MakeRotationMatrixFast(mRotation, GetPlacement().pl_OrientationAngle); plBike.pl_PositionVector += BIKE_ATTACHMENT*mRotation; ECyborgBike ecb; ecb.fSpeed = m_fFlySpeed*2.0f; CEntityPointer penBike = CreateEntity(plBike, CLASS_CYBORG_BIKE); penBike->Initialize(ecb); // drop to floor m_EctType = CBT_GROUND; SetPhysicsFlags(EPF_MODEL_WALKING); ChangeCollisionToGround(); // remove bike RemoveAttachmentFromModel(*GetModelObject(), CYBORG_ATTACHMENT_BIKE); // anim if (IRnd()&1) { StartModelAnim(CYBORG_ANIM_FALL01, 0); } else { StartModelAnim(CYBORG_ANIM_FALL02, 0); } // wait to touch brush or time limit m_fFallStartTime = _pTimer->CurrentTick(); wait (10.0f) { on (EBegin) : { resume; } // brush touched on (ETouch et) : { if (et.penOther->GetRenderType()&RT_BRUSH) { StopMoving(); stop; } resume; } on (EDamage) : { resume; } on (EWatch) : { resume; } on (ETimer) : { stop; } } // wait fall anim if (_pTimer->CurrentTick() < m_fFallStartTime+1.5f) { wait(m_fFallStartTime+1.5f - _pTimer->CurrentTick()) { on (EBegin) : { resume; } on (EDamage) : { resume; } on (EWatch) : { resume; } on (ETimer) : { stop; } } } return EReturn(); }; // get up GetUp(EVoid) { // get up StartModelAnim(CYBORG_ANIM_GETUP, 0); wait(GetModelObject()->GetAnimLength(CYBORG_ANIM_GETUP)) { on (EBegin) : { resume; } on (EDamage) : { resume; } on (EWatch) : { resume; } on (ETimer) : { stop; } } return EReturn(); }; /************************************************************ * PROCEDURES WHEN NO ANY SPECIAL ACTION * ************************************************************/ // Move to destination /* !!!! MoveToDestination(EVoid) : CEnemyBase::MoveToDestination { // animation if (m_bRunToMarker) { RunningAnim(); } else { WalkingAnim(); } // fly to position if (m_EctType!=CBT_GROUND) { m_fMoveFrequency = 0.25f; m_fMovePrecision = m_fMoveSpeed*m_fMoveFrequency*2.0f; while ((m_vDesiredPosition-GetPlacement().pl_PositionVector).Length()>m_fMovePrecision) { wait (0.25f) { on (EBegin) : { FlyToPosition(); } on (ETimer) : { stop; } } } return EReturn(); // move to position } else { jump CEnemyBase::MoveToDestination(); } }; */ /************************************************************ * PROCEDURES WHEN HARMED * ************************************************************/ // Play wound animation and falling body part BeWounded(EDamage eDamage) : CEnemyBase::BeWounded { // damage only on ground if (m_EctType==CBT_GROUND) { jump CEnemyBase::BeWounded(eDamage); // fall on ground } else if (m_EctType==CBT_FLYGROUND && GetHealth()<=60.0f) { SetHealth(60.0f); m_fMaxHealth = 60.0f; autocall FallToFloor() EReturn; autocall GetUp() EReturn; SendEvent(ERestartAttack()); } return EReturn(); }; /************************************************************ * A T T A C K E N E M Y * ************************************************************/ AttackEnemy(EVoid) : CEnemyBase::AttackEnemy { // air attack if (m_EctType!=CBT_GROUND) { jump FlyAttackEnemy(); // ground attack } else if (TRUE) { jump CEnemyBase::AttackEnemy(); } }; // fly attack enemy FlyAttackEnemy(EVoid) { // initial preparation autocall CEnemyBase::InitializeAttack() EReturn; // while you have some enemy while (m_penEnemy != NULL) { // to far cease attack if (CalcDist(m_penEnemy) > IGNORE_RANGE) { SetTargetNone(); } if (m_penEnemy != NULL) { // attack run if (SeeEntity(m_penEnemy, CosFast(90.0f))) { autocall FlyAttackRun() EReturn; // go away and rotate } else if (TRUE) { autocall GoAwayAndRotate() EReturn; } } } // stop attack autocall CEnemyBase::StopAttack() EReturn; // return to Move() procedure return EBegin(); }; // fly attack run FlyAttackRun(EVoid) { m_iFireLaserCount = 0; if (m_bBombing) { m_ctBombsToDrop = 3; } while (SeeEntity(m_penEnemy, CosFast(90.0f))) { m_fMoveFrequency = 0.1f; wait(m_fMoveFrequency) { on (EBegin) : { if (IsInFrustum(m_penEnemy, CosFast(55.0f))) { // fire laser if (m_iFireLaserCount==0) { ShootProjectile(PRT_CYBORG_LASER, FIRE_BIKE, ANGLE3D(0, 0, 0)); PlaySound(m_soSound, SOUND_FIRE, SOF_3D); } if (m_iFireLaserCount++ == 2) { m_iFireLaserCount = 0; } } // if a bomb may be dropped if (m_ctBombsToDrop>0 && _pTimer->CurrentTick()>=m_tmLastBombDropped+0.3f) { // calculate where it would hit FLOAT fV = en_vCurrentTranslationAbsolute.Length(); FLOAT fD = CalcDist(m_penEnemy); FLOAT fDP = CalcPlaneDist(m_penEnemy); FLOAT fH = Sqrt(fD*fD-fDP*fDP); FLOAT fHitD = fDP-fV*Sqrt(2*fH/en_fGravityA); // if close enough if( Abs(fHitD)<10.0f) { // drop it CPlacement3D pl(FLOAT3D(FRnd()*2.0f-1.0f, -1.0f, 0.0f), ANGLE3D(0, 0, 0)); ; pl.RelativeToAbsoluteSmooth(GetPlacement()); CEntityPointer penProjectile = CreateEntity(pl, CLASS_PROJECTILE); ELaunchProjectile eLaunch; eLaunch.penLauncher = this; eLaunch.prtType = PRT_CYBORG_BOMB; eLaunch.fSpeed = fV; penProjectile->Initialize(eLaunch); m_ctBombsToDrop--; m_tmLastBombDropped = _pTimer->CurrentTick(); } } // inside attack radius if (MayMoveToAttack()) { m_fMoveSpeed = m_fFlySpeed; m_aRotateSpeed = m_aFlyRotateSpeed; FlyDesiredPosition(m_vDesiredPosition); FlyToPosition(); RunningAnim(); // outside attack radius } else { StopMoving(); StandingAnim(); } } on (ETimer) : { stop; } } } return EReturn(); }; GoAwayAndRotate(EVoid) { // go away SetDesiredTranslation(FLOAT3D(0, 1.25f, -m_fFlySpeed)); StopRotating(); autowait(1.0f); // rotate side if (IRnd()&1) { SetDesiredRotation(ANGLE3D( 100.0f, 0, 0)); } else { SetDesiredRotation(ANGLE3D(-100.0f, 0, 0)); } // rotate to enemy SetDesiredTranslation(FLOAT3D(0, 0, -m_fFlySpeed)); while (!SeeEntityInPlane(m_penEnemy, CosFast(5.0f))) { autowait(_pTimer->TickQuantum); } return EReturn(); }; Fire(EVoid) : CEnemyBase::Fire { // to fire StartModelAnim(CYBORG_ANIM_TOFIRE, 0); m_fLockOnEnemyTime = GetModelObject()->GetAnimLength(CYBORG_ANIM_TOFIRE) + FRnd()/3; autocall CEnemyBase::LockOnEnemy() EReturn; StartModelAnim(CYBORG_ANIM_FIRE02, 0); ShootProjectile(PRT_CYBORG_LASER, FIRE_LASER, ANGLE3D(0, 0, 0)); PlaySound(m_soSound, SOUND_FIRE, SOF_3D); m_fLockOnEnemyTime = 0.5f; autocall CEnemyBase::LockOnEnemy() EReturn; StartModelAnim(CYBORG_ANIM_FIRE02, 0); ShootProjectile(PRT_CYBORG_LASER, FIRE_LASER, ANGLE3D(0, 0, 0)); PlaySound(m_soSound, SOUND_FIRE, SOF_3D); m_fLockOnEnemyTime = 0.5f; autocall CEnemyBase::LockOnEnemy() EReturn; StartModelAnim(CYBORG_ANIM_FIRE02, 0); ShootProjectile(PRT_CYBORG_LASER, FIRE_LASER, ANGLE3D(0, 0, 0)); PlaySound(m_soSound, SOUND_FIRE, SOF_3D); autowait(0.1f + FRnd()/3); m_fShootTime = _pTimer->CurrentTick() + m_fAttackFireTime*(1.0f + FRnd()/3.0f); // from fire StartModelAnim(CYBORG_ANIM_FROMFIRE, 0); autowait(GetModelObject()->GetAnimLength(CYBORG_ANIM_FROMFIRE)); return EReturn(); }; Hit(EVoid) : CEnemyBase::Hit { // animation m_iCloseHit = IRnd()&1; if (m_iCloseHit==0) { StartModelAnim(CYBORG_ANIM_ATTACKCLOSE01, 0); } else { StartModelAnim(CYBORG_ANIM_ATTACKCLOSE02, 0); } autowait(0.9f); PlaySound(m_soSound, SOUND_KICK, SOF_3D); if (CalcDist(m_penEnemy)GetPlacement().pl_PositionVector-GetPlacement().pl_PositionVector; vDirection.Normalize(); InflictDirectDamage(m_penEnemy, this, DMT_CLOSERANGE, 15.0f, FLOAT3D(0, 0, 0), vDirection); // push target left/right FLOAT3D vSpeed; if (m_iCloseHit==0) { GetHeadingDirection(AngleDeg(90.0f), vSpeed); } else { GetHeadingDirection(AngleDeg(-90.0f), vSpeed); } vSpeed = vSpeed * 5.0f; KickEntity(m_penEnemy, vSpeed); } return EReturn(); }; /************************************************************ * D E A T H * ************************************************************/ Death(EVoid) : CEnemyBase::Death { StopMoving(); // stop moving DeathSound(); // death sound // death notify (usually change collision box and change body density) ChangeCollisionBoxIndexWhenPossible(CYBORG_COLLISION_BOX_DEATH); // set physic flags SetPhysicsFlags(EPF_MODEL_CORPSE); SetCollisionFlags(ECF_CORPSE); if (m_EctType==CBT_FLY || m_EctType==CBT_FLYGROUND) { autocall FallToFloor() EReturn; } else if (TRUE) { // start death anim INDEX iAnim = AnimForDeath(); autowait(GetModelObject()->GetAnimLength(iAnim)); } // death twist StartModelAnim(CYBORG_ANIM_DEATHTWIST, AOF_LOOPING); autowait(FRnd()*5.0f + 1.0f); StartModelAnim(CYBORG_ANIM_DEATHREST, 0); // explode SetHealth(-45.0f); ReceiveDamage(NULL, DMT_EXPLOSION, 10.0f, FLOAT3D(0,0,0), FLOAT3D(0,1,0)); return EEnd(); }; /************************************************************ * M A I N * ************************************************************/ Main(EVoid) { // declare yourself as a model InitAsModel(); SetCollisionFlags(ECF_MODEL); SetFlags(GetFlags()|ENF_ALIVE); en_fDensity = 5000.0f; // set your appearance SetModel(MODEL_CYBORG); SetModelMainTexture(TEXTURE_CYBORG); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_ASS, MODEL_ASS, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_TORSO, MODEL_TORSO, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_STRONG, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_HEAD, MODEL_HEAD, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_RIGHTUPPERARM, MODEL_RIGHT_UPPER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_RIGHTLOWERARM, MODEL_RIGHT_LOWER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_LEFTUPPERARM, MODEL_LEFT_UPPER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_LEFTLOWERARM, MODEL_LEFT_LOWER_ARM, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_RIGHTUPPERLEG, MODEL_RIGHT_UPPER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_RIGHTLOWERLEG, MODEL_RIGHT_LOWER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_LEFTUPPERLEG, MODEL_LEFT_UPPER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_LEFTLOWERLEG, MODEL_LEFT_LOWER_LEG, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_FOOTRIGHT, MODEL_FOOT, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_FOOTLEFT, MODEL_FOOT, TEXTURE_CYBORG, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); if (m_EctType!=CBT_GROUND) { AddAttachmentToModel(this, *GetModelObject(), CYBORG_ATTACHMENT_BIKE, MODEL_BIKE, TEXTURE_BIKE, TEX_REFL_LIGHTMETAL01, TEX_SPEC_MEDIUM, 0); // fly in air SetHealth(90.0f); m_fMaxHealth = 90.0f; ChangeCollisionToAir(); SetPhysicsFlags(EPF_MODEL_FLYING); m_iScore = 1000; } else { // walk on ground SetHealth(60.0f); m_fMaxHealth = 60.0f; ChangeCollisionToGround(); SetPhysicsFlags(EPF_MODEL_WALKING); m_iScore = 500; } StandingAnim(); // setup moving speed m_fWalkSpeed = FRnd()*3.0f + 6.0f; m_aWalkRotateSpeed = FRnd()*20.0f + 700.0f; m_fAttackRunSpeed = m_fWalkSpeed; m_aAttackRotateSpeed = m_aWalkRotateSpeed; m_fCloseRunSpeed = m_fWalkSpeed; m_aCloseRotateSpeed = m_aWalkRotateSpeed; m_fWalkSpeed/=3; // setup attack distances m_fAttackDistance = 100.0f; m_fCloseDistance = 2.5f; m_fStopDistance = 1.5; m_fAttackFireTime = 3.0f; m_fCloseFireTime = 2.0f; m_fIgnoreRange = 200.0f; // fly moving properties m_fFlyAboveEnemy = 10.0f+FRnd()*1.0f; m_fFlySpeed = FRnd()*5.0f + 20.0f; m_aFlyRotateSpeed = FRnd()*25.0f + 100.0f; // damage/explode properties m_fBlowUpAmount = 90.0f; m_fDamageWounded = 50.0f; // continue behavior in base class jump CEnemyBase::MainLoop(); }; };