@@ -27,6 +27,7 @@ namespace DaggerfallWorkshop.Game
2727 [ RequireComponent ( typeof ( CharacterController ) ) ]
2828 public class EnemyMotor : MonoBehaviour
2929 {
30+
3031 #region Member Variables
3132
3233 public float OpenDoorDistance = 2f ; // Maximum distance to open door
@@ -66,7 +67,9 @@ public class EnemyMotor : MonoBehaviour
6667 int searchMult ;
6768 int ignoreMaskForShooting ;
6869 bool canAct ;
70+ bool falls ;
6971 bool flyerFalls ;
72+ float lastGroundedY ; // Used for fall damage
7073 float originalHeight ;
7174
7275 EnemySenses senses ;
@@ -75,6 +78,7 @@ public class EnemyMotor : MonoBehaviour
7578 CharacterController controller ;
7679 DaggerfallMobileUnit mobile ;
7780 DaggerfallEntityBehaviour entityBehaviour ;
81+ EnemyBlood entityBlood ;
7882 EntityEffectManager entityEffectManager ;
7983 EntityEffectBundle selectedSpell ;
8084 EnemyAttack attack ;
@@ -103,6 +107,7 @@ void Start()
103107 mobile . Summary . Enemy . Behaviour == MobileBehaviour . Spectral ;
104108 swims = mobile . Summary . Enemy . Behaviour == MobileBehaviour . Aquatic ;
105109 entityBehaviour = GetComponent < DaggerfallEntityBehaviour > ( ) ;
110+ entityBlood = GetComponent < EnemyBlood > ( ) ;
106111 entityEffectManager = GetComponent < EntityEffectManager > ( ) ;
107112 entity = entityBehaviour . Entity as EnemyEntity ;
108113 attack = GetComponent < EnemyAttack > ( ) ;
@@ -113,6 +118,8 @@ void Start()
113118 // Add things AI should ignore when checking for a clear path to shoot.
114119 ignoreMaskForShooting = ~ ( 1 << LayerMask . NameToLayer ( "SpellMissiles" ) | 1 << LayerMask . NameToLayer ( "Ignore Raycast" ) ) ;
115120
121+ lastGroundedY = transform . position . y ;
122+
116123 // Get original height, before any height adjustments
117124 originalHeight = controller . height ;
118125 }
@@ -124,6 +131,7 @@ void FixedUpdate()
124131
125132 canAct = true ;
126133 flyerFalls = false ;
134+ falls = false ;
127135
128136 HandleParalysis ( ) ;
129137 KnockbackMovement ( ) ;
@@ -133,6 +141,7 @@ void FixedUpdate()
133141 UpdateTimers ( ) ;
134142 if ( canAct )
135143 TakeAction ( ) ;
144+ ApplyFallDamage ( ) ;
136145 UpdateToIdleOrMoveAnim ( ) ;
137146 OpenDoors ( ) ;
138147 HeightAdjust ( ) ;
@@ -276,6 +285,7 @@ void ApplyGravity()
276285 if ( ! flies && ! swims && ! IsLevitating && ! controller . isGrounded )
277286 {
278287 controller . SimpleMove ( Vector3 . zero ) ;
288+ falls = true ;
279289
280290 // Only cancel movement if actually falling. Sometimes mobiles can get stuck where they are !isGrounded but SimpleMove(Vector3.zero) doesn't help.
281291 // Allowing them to continue and attempt a Move() frees them, but we don't want to allow that if we can avoid it so they aren't moving
@@ -285,7 +295,10 @@ void ApplyGravity()
285295 }
286296
287297 if ( flyerFalls && flies && ! IsLevitating )
298+ {
288299 controller . SimpleMove ( Vector3 . zero ) ;
300+ falls = true ;
301+ }
289302 }
290303
291304 /// <summary>
@@ -1278,6 +1291,39 @@ void UpdateToIdleOrMoveAnim()
12781291 lastPosition = transform . position ;
12791292 }
12801293
1294+ void ApplyFallDamage ( )
1295+ {
1296+ // Assuming the same formula is used for the player and enemies
1297+ const float fallingDamageThreshold = 5.0f ;
1298+ const float HPPerMetre = 5f ;
1299+
1300+ if ( controller . isGrounded )
1301+ {
1302+ // did enemy just land?
1303+ if ( falls )
1304+ {
1305+ float fallDistance = lastGroundedY - transform . position . y ;
1306+ if ( fallDistance > fallingDamageThreshold )
1307+ {
1308+ int damage = ( int ) ( HPPerMetre * ( fallDistance - fallingDamageThreshold ) ) ;
1309+
1310+ EnemyEntity enemyEntity = entityBehaviour . Entity as EnemyEntity ;
1311+ enemyEntity . DecreaseHealth ( damage ) ;
1312+
1313+ if ( entityBlood )
1314+ {
1315+ // Like in classic, falling enemies bleed at the center. It must hurt the center of mass ;)
1316+ entityBlood . ShowBloodSplash ( 0 , transform . position ) ;
1317+ }
1318+
1319+ DaggerfallUI . Instance . DaggerfallAudioSource . PlayClipAtPoint ( ( int ) SoundClips . FallDamage , FindGroundPosition ( ) ) ;
1320+ }
1321+ }
1322+
1323+ lastGroundedY = transform . position . y ;
1324+ }
1325+ }
1326+
12811327 /// <summary>
12821328 /// Open doors that are in the way.
12831329 /// </summary>
0 commit comments