Skip to content

Commit 5170948

Browse files
committed
Add explosions improvements (#29)
1 parent 3ccb087 commit 5170948

File tree

12 files changed

+404
-34
lines changed

12 files changed

+404
-34
lines changed

src/actions.cc

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,32 @@ void _show_damage_to_object(Object* a1, int damage, int flags, Object* weapon, b
316316
sfx_name = sfxBuildCharName(a1, anim, CHARACTER_SOUND_EFFECT_UNUSED);
317317
animationRegisterPlaySoundEffect(a1, sfx_name, a10);
318318

319+
// SFALL
320+
if (explosionEmitsLight()) {
321+
// 0xFFFF0002:
322+
// - distance: 2
323+
// - intensity: 65535
324+
//
325+
// NOTE: Change intensity to 65536 (which is on par with
326+
// `anim_set_check_light_fix` Sfall's hack).
327+
animationRegisterSetLightIntensity(a1, 2, 65536, 0);
328+
}
329+
319330
animationRegisterAnimate(a1, anim, 0);
320331

332+
// SFALL
333+
if (explosionEmitsLight()) {
334+
// 0x00010000:
335+
// - distance: 0
336+
// - intensity: 1
337+
//
338+
// NOTE: Change intensity to 0. I guess using 1 was a
339+
// workaround for `anim_set_check_light_fix` hack which
340+
// requires two upper bytes to be non-zero to override
341+
// default behaviour.
342+
animationRegisterSetLightIntensity(a1, 0, 0, -1);
343+
}
344+
321345
int randomDistance = randomBetween(2, 5);
322346
int randomRotation = randomBetween(0, 5);
323347

@@ -692,7 +716,8 @@ int _action_ranged(Attack* attack, int anim)
692716

693717
bool isGrenade = false;
694718
if (anim == ANIM_THROW_ANIM) {
695-
if (damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
719+
// SFALL
720+
if (damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
696721
isGrenade = true;
697722
}
698723
} else {
@@ -750,7 +775,12 @@ int _action_ranged(Attack* attack, int anim)
750775

751776
objectHide(projectile, NULL);
752777

753-
objectSetLight(projectile, 9, projectile->lightIntensity, NULL);
778+
// SFALL
779+
if (explosionEmitsLight() && projectile->lightIntensity == 0) {
780+
objectSetLight(projectile, projectileProto->item.lightDistance, projectileProto->item.lightIntensity, NULL);
781+
} else {
782+
objectSetLight(projectile, 9, projectile->lightIntensity, NULL);
783+
}
754784

755785
int projectileOrigin = _combat_bullet_start(attack->attacker, attack->defender);
756786
objectSetLocation(projectile, projectileOrigin, attack->attacker->elevation, NULL);
@@ -774,7 +804,8 @@ int _action_ranged(Attack* attack, int anim)
774804
v24 = attack->tile;
775805
}
776806

777-
if (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION) {
807+
// SFALL
808+
if (isGrenade || damageType == explosionGetDamageType()) {
778809
if ((attack->attackerFlags & DAM_DROP) == 0) {
779810
int explosionFrmId;
780811
if (isGrenade) {
@@ -793,6 +824,12 @@ int _action_ranged(Attack* attack, int anim)
793824
explosionFrmId = 10;
794825
}
795826

827+
// SFALL
828+
int explosionFrmIdOverride = explosionGetFrm();
829+
if (explosionFrmIdOverride != -1) {
830+
explosionFrmId = explosionFrmIdOverride;
831+
}
832+
796833
if (isGrenade) {
797834
animationRegisterSetFid(projectile, weaponFid, -1);
798835
}
@@ -803,9 +840,23 @@ int _action_ranged(Attack* attack, int anim)
803840
const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_HIT, weapon, attack->hitMode, attack->defender);
804841
animationRegisterPlaySoundEffect(projectile, sfx, 0);
805842

806-
animationRegisterAnimateAndHide(projectile, ANIM_STAND, 0);
843+
// SFALL
844+
if (explosionEmitsLight()) {
845+
animationRegisterAnimate(projectile, ANIM_STAND, 0);
846+
// 0xFFFF0008
847+
// - distance: 8
848+
// - intensity: 65535
849+
animationRegisterSetLightIntensity(projectile, 8, 65536, 0);
850+
} else {
851+
animationRegisterAnimateAndHide(projectile, ANIM_STAND, 0);
852+
}
853+
854+
// SFALL
855+
int startRotation;
856+
int endRotation;
857+
explosionGetPattern(&startRotation, &endRotation);
807858

808-
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
859+
for (int rotation = startRotation; rotation < endRotation; rotation++) {
809860
if (objectCreateWithFidPid(&(neighboors[rotation]), explosionFid, -1) != -1) {
810861
objectHide(neighboors[rotation], NULL);
811862

@@ -864,7 +915,8 @@ int _action_ranged(Attack* attack, int anim)
864915
}
865916
}
866917

867-
if (projectile != NULL && (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION)) {
918+
// SFALL
919+
if (projectile != NULL && (isGrenade || damageType == explosionGetDamageType())) {
868920
animationRegisterHideObjectForced(projectile);
869921
} else if (anim == ANIM_THROW_ANIM && projectile != NULL) {
870922
animationRegisterSetFid(projectile, weaponFid, -1);

src/animation.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ typedef enum AnimationKind {
6464
ANIM_KIND_26 = 26,
6565
ANIM_KIND_27 = 27,
6666
ANIM_KIND_NOOP = 28,
67+
68+
// New animation to update both light distance and intensity. Required to
69+
// impement Sfall's explosion light effects without resorting to hackery.
70+
ANIM_KIND_SET_LIGHT_INTENSITY,
6771
} AnimationKind;
6872

6973
typedef enum AnimationSequenceFlags {
@@ -197,6 +201,9 @@ typedef struct AnimationDescription {
197201

198202
// ANIM_KIND_CALLBACK3
199203
void* param3;
204+
205+
// ANIM_KIND_SET_LIGHT_INTENSITY
206+
int lightIntensity;
200207
};
201208
CacheEntry* artCacheKey;
202209
} AnimationDescription;
@@ -1527,6 +1534,11 @@ static int animationRunSequence(int animationSequenceIndex)
15271534
tileWindowRefreshRect(&rect, animationDescription->owner->elevation);
15281535
rc = _anim_set_continue(animationSequenceIndex, 0);
15291536
break;
1537+
case ANIM_KIND_SET_LIGHT_INTENSITY:
1538+
objectSetLight(animationDescription->owner, animationDescription->lightDistance, animationDescription->lightIntensity, &rect);
1539+
tileWindowRefreshRect(&rect, animationDescription->owner->elevation);
1540+
rc = _anim_set_continue(animationSequenceIndex, 0);
1541+
break;
15301542
case ANIM_KIND_20:
15311543
rc = _anim_move_on_stairs(animationDescription->owner, animationDescription->tile, animationDescription->elevation, animationDescription->anim, animationSequenceIndex);
15321544
break;
@@ -3330,3 +3342,24 @@ static unsigned int animationComputeTicksPerFrame(Object* object, int fid)
33303342

33313343
return 1000 / fps;
33323344
}
3345+
3346+
int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay)
3347+
{
3348+
if (_check_registry(owner) == -1) {
3349+
_anim_cleanup();
3350+
return -1;
3351+
}
3352+
3353+
AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]);
3354+
AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]);
3355+
animationDescription->kind = ANIM_KIND_SET_LIGHT_INTENSITY;
3356+
animationDescription->artCacheKey = NULL;
3357+
animationDescription->owner = owner;
3358+
animationDescription->lightDistance = lightDistance;
3359+
animationDescription->lightIntensity = lightIntensity;
3360+
animationDescription->delay = delay;
3361+
3362+
gAnimationDescriptionCurrentIndex++;
3363+
3364+
return 0;
3365+
}

src/animation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,6 @@ void _dude_stand(Object* obj, int rotation, int fid);
154154
void _dude_standup(Object* a1);
155155
void animationStop();
156156

157+
int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay);
158+
157159
#endif /* ANIMATION_H */

src/combat.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,6 +3430,9 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
34303430
_critter_set_who_hit_me(a1, a2);
34313431
}
34323432

3433+
// SFALL
3434+
explosionSettingsReset();
3435+
34333436
_combat_call_display = 1;
34343437
_combat_cleanup_enabled = 1;
34353438
aiInfoSetLastTarget(a1, a2);
@@ -3707,7 +3710,8 @@ static int attackCompute(Attack* attack)
37073710

37083711
bool isGrenade = false;
37093712
int damageType = weaponGetDamageType(attack->attacker, attack->weapon);
3710-
if (anim == ANIM_THROW_ANIM && (damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP)) {
3713+
// SFALL
3714+
if (anim == ANIM_THROW_ANIM && (damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP)) {
37113715
isGrenade = true;
37123716
}
37133717

@@ -3835,7 +3839,8 @@ static int attackCompute(Attack* attack)
38353839
}
38363840
}
38373841

3838-
if ((damageType == DAMAGE_TYPE_EXPLOSION || isGrenade) && ((attack->attackerFlags & DAM_HIT) != 0 || (attack->attackerFlags & DAM_CRITICAL) == 0)) {
3842+
// SFALL
3843+
if ((damageType == explosionGetDamageType() || isGrenade) && ((attack->attackerFlags & DAM_HIT) != 0 || (attack->attackerFlags & DAM_CRITICAL) == 0)) {
38393844
_compute_explosion_on_extras(attack, 0, isGrenade, 0);
38403845
} else {
38413846
if ((attack->attackerFlags & DAM_EXPLODE) != 0) {
@@ -3882,7 +3887,10 @@ void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4
38823887
int rotation = 0;
38833888
int v5 = -1;
38843889
int v19 = tile;
3885-
while (attack->extrasLength < 6) {
3890+
3891+
// SFALL
3892+
int maxTargets = explosionGetMaxTargets();
3893+
while (attack->extrasLength < maxTargets) {
38863894
if (v22 != 0 && (v5 == -1 || (v5 = tileGetTileInDirection(v5, rotation, 1)) != v19)) {
38873895
v20++;
38883896
if (v20 % v22 == 0) {

src/game_sound.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1399,7 +1399,10 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta
13991399
v6 = 1;
14001400
}
14011401

1402-
if (effectTypeCode != 'H' || target == NULL || weaponIsGrenade(weapon)) {
1402+
int damageType = weaponGetDamageType(NULL, weapon);
1403+
1404+
// SFALL
1405+
if (effectTypeCode != 'H' || target == NULL || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
14031406
materialCode = 'X';
14041407
} else {
14051408
const int type = FID_TYPE(target->fid);

src/inventory.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3277,7 +3277,7 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
32773277
}
32783278
}
32793279
}
3280-
} else if (item->pid == PROTO_ID_DYNAMITE_II || item->pid == PROTO_ID_PLASTIC_EXPLOSIVES_II) {
3280+
} else if (explosiveIsActiveExplosive(item->pid)) {
32813281
_dropped_explosive = 1;
32823282
_obj_drop(v41, item);
32833283
} else {

0 commit comments

Comments
 (0)