diff --git a/src/actions.cc b/src/actions.cc index 1da504f..b732324 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -316,8 +316,32 @@ void _show_damage_to_object(Object* a1, int damage, int flags, Object* weapon, b sfx_name = sfxBuildCharName(a1, anim, CHARACTER_SOUND_EFFECT_UNUSED); animationRegisterPlaySoundEffect(a1, sfx_name, a10); + // SFALL + if (explosionEmitsLight()) { + // 0xFFFF0002: + // - distance: 2 + // - intensity: 65535 + // + // NOTE: Change intensity to 65536 (which is on par with + // `anim_set_check_light_fix` Sfall's hack). + animationRegisterSetLightIntensity(a1, 2, 65536, 0); + } + animationRegisterAnimate(a1, anim, 0); + // SFALL + if (explosionEmitsLight()) { + // 0x00010000: + // - distance: 0 + // - intensity: 1 + // + // NOTE: Change intensity to 0. I guess using 1 was a + // workaround for `anim_set_check_light_fix` hack which + // requires two upper bytes to be non-zero to override + // default behaviour. + animationRegisterSetLightIntensity(a1, 0, 0, -1); + } + int randomDistance = randomBetween(2, 5); int randomRotation = randomBetween(0, 5); @@ -692,7 +716,8 @@ int _action_ranged(Attack* attack, int anim) bool isGrenade = false; if (anim == ANIM_THROW_ANIM) { - if (damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) { + // SFALL + if (damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) { isGrenade = true; } } else { @@ -750,7 +775,12 @@ int _action_ranged(Attack* attack, int anim) objectHide(projectile, NULL); - objectSetLight(projectile, 9, projectile->lightIntensity, NULL); + // SFALL + if (explosionEmitsLight() && projectile->lightIntensity == 0) { + objectSetLight(projectile, projectileProto->item.lightDistance, projectileProto->item.lightIntensity, NULL); + } else { + objectSetLight(projectile, 9, projectile->lightIntensity, NULL); + } int projectileOrigin = _combat_bullet_start(attack->attacker, attack->defender); objectSetLocation(projectile, projectileOrigin, attack->attacker->elevation, NULL); @@ -774,7 +804,8 @@ int _action_ranged(Attack* attack, int anim) v24 = attack->tile; } - if (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION) { + // SFALL + if (isGrenade || damageType == explosionGetDamageType()) { if ((attack->attackerFlags & DAM_DROP) == 0) { int explosionFrmId; if (isGrenade) { @@ -793,6 +824,12 @@ int _action_ranged(Attack* attack, int anim) explosionFrmId = 10; } + // SFALL + int explosionFrmIdOverride = explosionGetFrm(); + if (explosionFrmIdOverride != -1) { + explosionFrmId = explosionFrmIdOverride; + } + if (isGrenade) { animationRegisterSetFid(projectile, weaponFid, -1); } @@ -803,9 +840,23 @@ int _action_ranged(Attack* attack, int anim) const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_HIT, weapon, attack->hitMode, attack->defender); animationRegisterPlaySoundEffect(projectile, sfx, 0); - animationRegisterAnimateAndHide(projectile, ANIM_STAND, 0); + // SFALL + if (explosionEmitsLight()) { + animationRegisterAnimate(projectile, ANIM_STAND, 0); + // 0xFFFF0008 + // - distance: 8 + // - intensity: 65535 + animationRegisterSetLightIntensity(projectile, 8, 65536, 0); + } else { + animationRegisterAnimateAndHide(projectile, ANIM_STAND, 0); + } - for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) { + // SFALL + int startRotation; + int endRotation; + explosionGetPattern(&startRotation, &endRotation); + + for (int rotation = startRotation; rotation < endRotation; rotation++) { if (objectCreateWithFidPid(&(neighboors[rotation]), explosionFid, -1) != -1) { objectHide(neighboors[rotation], NULL); @@ -864,7 +915,8 @@ int _action_ranged(Attack* attack, int anim) } } - if (projectile != NULL && (isGrenade || damageType == DAMAGE_TYPE_EXPLOSION)) { + // SFALL + if (projectile != NULL && (isGrenade || damageType == explosionGetDamageType())) { animationRegisterHideObjectForced(projectile); } else if (anim == ANIM_THROW_ANIM && projectile != NULL) { animationRegisterSetFid(projectile, weaponFid, -1); diff --git a/src/animation.cc b/src/animation.cc index 1208ed2..682f810 100644 --- a/src/animation.cc +++ b/src/animation.cc @@ -64,6 +64,10 @@ typedef enum AnimationKind { ANIM_KIND_26 = 26, ANIM_KIND_27 = 27, ANIM_KIND_NOOP = 28, + + // New animation to update both light distance and intensity. Required to + // impement Sfall's explosion light effects without resorting to hackery. + ANIM_KIND_SET_LIGHT_INTENSITY, } AnimationKind; typedef enum AnimationSequenceFlags { @@ -197,6 +201,9 @@ typedef struct AnimationDescription { // ANIM_KIND_CALLBACK3 void* param3; + + // ANIM_KIND_SET_LIGHT_INTENSITY + int lightIntensity; }; CacheEntry* artCacheKey; } AnimationDescription; @@ -1527,6 +1534,11 @@ static int animationRunSequence(int animationSequenceIndex) tileWindowRefreshRect(&rect, animationDescription->owner->elevation); rc = _anim_set_continue(animationSequenceIndex, 0); break; + case ANIM_KIND_SET_LIGHT_INTENSITY: + objectSetLight(animationDescription->owner, animationDescription->lightDistance, animationDescription->lightIntensity, &rect); + tileWindowRefreshRect(&rect, animationDescription->owner->elevation); + rc = _anim_set_continue(animationSequenceIndex, 0); + break; case ANIM_KIND_20: rc = _anim_move_on_stairs(animationDescription->owner, animationDescription->tile, animationDescription->elevation, animationDescription->anim, animationSequenceIndex); break; @@ -3330,3 +3342,24 @@ static unsigned int animationComputeTicksPerFrame(Object* object, int fid) return 1000 / fps; } + +int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay) +{ + if (_check_registry(owner) == -1) { + _anim_cleanup(); + return -1; + } + + AnimationSequence* animationSequence = &(gAnimationSequences[gAnimationSequenceCurrentIndex]); + AnimationDescription* animationDescription = &(animationSequence->animations[gAnimationDescriptionCurrentIndex]); + animationDescription->kind = ANIM_KIND_SET_LIGHT_INTENSITY; + animationDescription->artCacheKey = NULL; + animationDescription->owner = owner; + animationDescription->lightDistance = lightDistance; + animationDescription->lightIntensity = lightIntensity; + animationDescription->delay = delay; + + gAnimationDescriptionCurrentIndex++; + + return 0; +} diff --git a/src/animation.h b/src/animation.h index e9296c3..c4b2c10 100644 --- a/src/animation.h +++ b/src/animation.h @@ -154,4 +154,6 @@ void _dude_stand(Object* obj, int rotation, int fid); void _dude_standup(Object* a1); void animationStop(); +int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay); + #endif /* ANIMATION_H */ diff --git a/src/combat.cc b/src/combat.cc index f9674e7..56a4f52 100644 --- a/src/combat.cc +++ b/src/combat.cc @@ -3430,6 +3430,9 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) _critter_set_who_hit_me(a1, a2); } + // SFALL + explosionSettingsReset(); + _combat_call_display = 1; _combat_cleanup_enabled = 1; aiInfoSetLastTarget(a1, a2); @@ -3707,7 +3710,8 @@ static int attackCompute(Attack* attack) bool isGrenade = false; int damageType = weaponGetDamageType(attack->attacker, attack->weapon); - if (anim == ANIM_THROW_ANIM && (damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP)) { + // SFALL + if (anim == ANIM_THROW_ANIM && (damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP)) { isGrenade = true; } @@ -3835,7 +3839,8 @@ static int attackCompute(Attack* attack) } } - if ((damageType == DAMAGE_TYPE_EXPLOSION || isGrenade) && ((attack->attackerFlags & DAM_HIT) != 0 || (attack->attackerFlags & DAM_CRITICAL) == 0)) { + // SFALL + if ((damageType == explosionGetDamageType() || isGrenade) && ((attack->attackerFlags & DAM_HIT) != 0 || (attack->attackerFlags & DAM_CRITICAL) == 0)) { _compute_explosion_on_extras(attack, 0, isGrenade, 0); } else { if ((attack->attackerFlags & DAM_EXPLODE) != 0) { @@ -3882,7 +3887,10 @@ void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4 int rotation = 0; int v5 = -1; int v19 = tile; - while (attack->extrasLength < 6) { + + // SFALL + int maxTargets = explosionGetMaxTargets(); + while (attack->extrasLength < maxTargets) { if (v22 != 0 && (v5 == -1 || (v5 = tileGetTileInDirection(v5, rotation, 1)) != v19)) { v20++; if (v20 % v22 == 0) { diff --git a/src/game_sound.cc b/src/game_sound.cc index 2ce4157..84ef973 100644 --- a/src/game_sound.cc +++ b/src/game_sound.cc @@ -1399,7 +1399,10 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta v6 = 1; } - if (effectTypeCode != 'H' || target == NULL || weaponIsGrenade(weapon)) { + int damageType = weaponGetDamageType(NULL, weapon); + + // SFALL + if (effectTypeCode != 'H' || target == NULL || damageType == explosionGetDamageType() || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) { materialCode = 'X'; } else { const int type = FID_TYPE(target->fid); diff --git a/src/inventory.cc b/src/inventory.cc index 370bf10..fd9288a 100644 --- a/src/inventory.cc +++ b/src/inventory.cc @@ -3277,7 +3277,7 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType) } } } - } else if (item->pid == PROTO_ID_DYNAMITE_II || item->pid == PROTO_ID_PLASTIC_EXPLOSIVES_II) { + } else if (explosiveIsActiveExplosive(item->pid)) { _dropped_explosive = 1; _obj_drop(v41, item); } else { diff --git a/src/item.cc b/src/item.cc index 3f28cf0..6b82bc6 100644 --- a/src/item.cc +++ b/src/item.cc @@ -30,6 +30,7 @@ #include +#include #include #define ADDICTION_COUNT (9) @@ -62,6 +63,10 @@ static void booksInitCustom(); static void booksAdd(int bookPid, int messageId, int skill); static void booksExit(); +static void explosionsInit(); +static void explosionsReset(); +static void explosionsExit(); + typedef struct DrugDescription { int drugPid; int gvar; @@ -74,6 +79,13 @@ typedef struct BookDescription { int skill; } BookDescription; +typedef struct ExplosiveDescription { + int pid; + int activePid; + int minDamage; + int maxDamage; +} ExplosiveDescription; + // 0x509FFC static char _aItem_1[] = ""; @@ -153,6 +165,20 @@ static Object* _wd_obj; static int _wd_gvar; static std::vector gBooks; +static bool gExplosionEmitsLight; +static int gGrenadeExplosionRadius; +static int gRocketExplosionRadius; +static int gDynamiteMinDamage; +static int gDynamiteMaxDamage; +static int gPlasticExplosiveMinDamage; +static int gPlasticExplosiveMaxDamage; +static std::vector gExplosives; +static int gExplosionStartRotation; +static int gExplosionEndRotation; +static int gExplosionFrm; +static int gExplosionRadius; +static int gExplosionDamageType; +static int gExplosionMaxTargets; // 0x4770E0 int itemsInit() @@ -170,6 +196,7 @@ int itemsInit() // SFALL booksInit(); + explosionsInit(); return 0; } @@ -177,7 +204,8 @@ int itemsInit() // 0x477144 void itemsReset() { - return; + // SFALL + explosionsReset(); } // 0x477148 @@ -187,6 +215,7 @@ void itemsExit() // SFALL booksExit(); + explosionsExit(); } // NOTE: Collapsed. @@ -2002,13 +2031,23 @@ int _item_w_area_damage_radius(Object* weapon, int hitMode) // 0x479180 int _item_w_grenade_dmg_radius(Object* weapon) { - return 2; + // SFALL + if (gExplosionRadius != -1) { + return gExplosionRadius; + } + + return gGrenadeExplosionRadius; } // 0x479188 int _item_w_rocket_dmg_radius(Object* weapon) { - return 3; + // SFALL + if (gExplosionRadius != -1) { + return gExplosionRadius; + } + + return gRocketExplosionRadius; } // 0x479190 @@ -3353,3 +3392,221 @@ bool booksGetInfo(int bookPid, int* messageIdPtr, int* skillPtr) } return false; } + +static void explosionsInit() +{ + gExplosionEmitsLight = false; + configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_EXPLOSION_EMITS_LIGHT_KEY, &gExplosionEmitsLight); + + explosionsReset(); +} + +static void explosionsReset() +{ + gGrenadeExplosionRadius = 2; + gRocketExplosionRadius = 3; + + gDynamiteMinDamage = 30; + gDynamiteMaxDamage = 50; + gPlasticExplosiveMinDamage = 40; + gPlasticExplosiveMaxDamage = 80; + + if (configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DYNAMITE_MAX_DAMAGE_KEY, &gDynamiteMaxDamage)) { + gDynamiteMaxDamage = std::clamp(gDynamiteMaxDamage, 0, 9999); + } + + if (configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DYNAMITE_MIN_DAMAGE_KEY, &gDynamiteMinDamage)) { + gDynamiteMinDamage = std::clamp(gDynamiteMinDamage, 0, gDynamiteMaxDamage); + } + + if (configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PLASTIC_EXPLOSIVE_MAX_DAMAGE_KEY, &gPlasticExplosiveMaxDamage)) { + gPlasticExplosiveMaxDamage = std::clamp(gPlasticExplosiveMaxDamage, 0, 9999); + } + + if (configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PLASTIC_EXPLOSIVE_MIN_DAMAGE_KEY, &gPlasticExplosiveMinDamage)) { + gPlasticExplosiveMinDamage = std::clamp(gPlasticExplosiveMinDamage, 0, gPlasticExplosiveMaxDamage); + } + + gExplosives.clear(); + + explosionSettingsReset(); +} + +static void explosionsExit() +{ + gExplosives.clear(); +} + +bool explosionEmitsLight() +{ + return gExplosionEmitsLight; +} + +void weaponSetGrenadeExplosionRadius(int value) +{ + gGrenadeExplosionRadius = value; +} + +void weaponSetRocketExplosionRadius(int value) +{ + gRocketExplosionRadius = value; +} + +void explosiveAdd(int pid, int activePid, int minDamage, int maxDamage) +{ + ExplosiveDescription explosiveDescription; + explosiveDescription.pid = pid; + explosiveDescription.activePid = activePid; + explosiveDescription.minDamage = minDamage; + explosiveDescription.maxDamage = maxDamage; + gExplosives.push_back(std::move(explosiveDescription)); +} + +bool explosiveIsExplosive(int pid) +{ + if (pid == PROTO_ID_DYNAMITE_I) return true; + if (pid == PROTO_ID_PLASTIC_EXPLOSIVES_I) return true; + + for (const auto& explosive : gExplosives) { + if (explosive.pid == pid) return true; + } + + return false; +} + +bool explosiveIsActiveExplosive(int pid) +{ + if (pid == PROTO_ID_DYNAMITE_II) return true; + if (pid == PROTO_ID_PLASTIC_EXPLOSIVES_II) return true; + + for (const auto& explosive : gExplosives) { + if (explosive.activePid == pid) return true; + } + + return false; +} + +bool explosiveActivate(int* pidPtr) +{ + if (*pidPtr == PROTO_ID_DYNAMITE_I) { + *pidPtr = PROTO_ID_DYNAMITE_II; + return true; + } + + if (*pidPtr == PROTO_ID_PLASTIC_EXPLOSIVES_I) { + *pidPtr = PROTO_ID_PLASTIC_EXPLOSIVES_II; + return true; + } + + for (const auto& explosive : gExplosives) { + if (explosive.pid == *pidPtr) { + *pidPtr = explosive.activePid; + return true; + } + } + + return false; +} + +bool explosiveSetDamage(int pid, int minDamage, int maxDamage) +{ + if (pid == PROTO_ID_DYNAMITE_I) { + gDynamiteMinDamage = minDamage; + gDynamiteMaxDamage = maxDamage; + return true; + } + + if (pid == PROTO_ID_PLASTIC_EXPLOSIVES_I) { + gPlasticExplosiveMinDamage = minDamage; + gPlasticExplosiveMaxDamage = maxDamage; + return true; + } + + // NOTE: For unknown reason this function do not update custom explosives + // damage. Since we're after compatibility (at least at this time), the + // only way to follow this behaviour. + + return false; +} + +bool explosiveGetDamage(int pid, int* minDamagePtr, int* maxDamagePtr) +{ + if (pid == PROTO_ID_DYNAMITE_I) { + *minDamagePtr = gDynamiteMinDamage; + *maxDamagePtr = gDynamiteMaxDamage; + return true; + } + + if (pid == PROTO_ID_PLASTIC_EXPLOSIVES_I) { + *minDamagePtr = gPlasticExplosiveMinDamage; + *maxDamagePtr = gPlasticExplosiveMaxDamage; + return true; + } + + for (const auto& explosive : gExplosives) { + if (explosive.pid == pid) { + *minDamagePtr = explosive.minDamage; + *maxDamagePtr = explosive.maxDamage; + return true; + } + } + + return false; +} + +void explosionSettingsReset() +{ + gExplosionStartRotation = 0; + gExplosionEndRotation = ROTATION_COUNT; + gExplosionFrm = -1; + gExplosionRadius = -1; + gExplosionDamageType = DAMAGE_TYPE_EXPLOSION; + gExplosionMaxTargets = 6; +} + +void explosionGetPattern(int* startRotationPtr, int* endRotationPtr) +{ + *startRotationPtr = gExplosionStartRotation; + *endRotationPtr = gExplosionEndRotation; +} + +void explosionSetPattern(int startRotation, int endRotation) +{ + gExplosionStartRotation = startRotation; + gExplosionEndRotation = endRotation; +} + +int explosionGetFrm() +{ + return gExplosionFrm; +} + +void explosionSetFrm(int frm) +{ + gExplosionFrm = frm; +} + +void explosionSetRadius(int radius) +{ + gExplosionRadius = radius; +} + +int explosionGetDamageType() +{ + return gExplosionDamageType; +} + +void explosionSetDamageType(int damageType) +{ + gExplosionDamageType = damageType; +} + +int explosionGetMaxTargets() +{ + return gExplosionMaxTargets; +} + +void explosionSetMaxTargets(int maxTargets) +{ + gExplosionMaxTargets = maxTargets; +} diff --git a/src/item.h b/src/item.h index 677a138..2bd2189 100644 --- a/src/item.h +++ b/src/item.h @@ -124,5 +124,24 @@ int itemGetMoney(Object* obj); int itemSetMoney(Object* obj, int a2); bool booksGetInfo(int bookPid, int* messageIdPtr, int* skillPtr); +bool explosionEmitsLight(); +void weaponSetGrenadeExplosionRadius(int value); +void weaponSetRocketExplosionRadius(int value); +void explosiveAdd(int pid, int activePid, int minDamage, int maxDamage); +bool explosiveIsExplosive(int pid); +bool explosiveIsActiveExplosive(int pid); +bool explosiveActivate(int* pidPtr); +bool explosiveSetDamage(int pid, int minDamage, int maxDamage); +bool explosiveGetDamage(int pid, int* minDamagePtr, int* maxDamagePtr); +void explosionSettingsReset(); +void explosionGetPattern(int* startRotationPtr, int* endRotationPtr); +void explosionSetPattern(int startRotation, int endRotation); +int explosionGetFrm(); +void explosionSetFrm(int frm); +void explosionSetRadius(int radius); +int explosionGetDamageType(); +void explosionSetDamageType(int damageType); +int explosionGetMaxTargets(); +void explosionSetMaxTargets(int maxTargets); #endif /* ITEM_H */ diff --git a/src/object.cc b/src/object.cc index 329206e..6d1e6f5 100644 --- a/src/object.cc +++ b/src/object.cc @@ -2090,7 +2090,8 @@ int _obj_inven_free(Inventory* inventory) bool _obj_action_can_use(Object* obj) { int pid = obj->pid; - if (pid != PROTO_ID_LIT_FLARE && pid != PROTO_ID_DYNAMITE_II && pid != PROTO_ID_PLASTIC_EXPLOSIVES_II) { + // SFALL + if (pid != PROTO_ID_LIT_FLARE && !explosiveIsActiveExplosive(pid)) { return _proto_action_can_use(pid); } else { return false; diff --git a/src/proto_instance.cc b/src/proto_instance.cc index 8edd05a..cb56dc9 100644 --- a/src/proto_instance.cc +++ b/src/proto_instance.cc @@ -843,10 +843,8 @@ static int _obj_use_explosive(Object* explosive) MessageListItem messageListItem; int pid = explosive->pid; - if (pid != PROTO_ID_DYNAMITE_I - && pid != PROTO_ID_PLASTIC_EXPLOSIVES_I - && pid != PROTO_ID_DYNAMITE_II - && pid != PROTO_ID_PLASTIC_EXPLOSIVES_II) { + // SFALL + if (!explosiveIsExplosive(pid)) { return -1; } @@ -865,11 +863,8 @@ static int _obj_use_explosive(Object* explosive) displayMonitorAddMessage(messageListItem.text); } - if (pid == PROTO_ID_DYNAMITE_I) { - explosive->pid = PROTO_ID_DYNAMITE_II; - } else if (pid == PROTO_ID_PLASTIC_EXPLOSIVES_I) { - explosive->pid = PROTO_ID_PLASTIC_EXPLOSIVES_II; - } + // SFALL + explosiveActivate(&(explosive->pid)); int delay = 10 * seconds; @@ -1048,7 +1043,8 @@ int _protinst_use_item(Object* critter, Object* item) // 0x49BFE8 static int _protinstTestDroppedExplosive(Object* a1) { - if (a1->pid == PROTO_ID_DYNAMITE_II || a1->pid == PROTO_ID_PLASTIC_EXPLOSIVES_II) { + // SFALL + if (explosiveIsActiveExplosive(a1->pid)) { Attack attack; attackInit(&attack, gDude, 0, HIT_MODE_PUNCH, HIT_LOCATION_TORSO); attack.attackerFlags = DAM_HIT; diff --git a/src/queue.cc b/src/queue.cc index 59e3583..6c780bc 100644 --- a/src/queue.cc +++ b/src/queue.cc @@ -478,15 +478,9 @@ static int _queue_do_explosion_(Object* explosive, bool a2) int maxDamage; int minDamage; - if (explosive->pid == PROTO_ID_DYNAMITE_I || explosive->pid == PROTO_ID_DYNAMITE_II) { - // Dynamite - minDamage = 30; - maxDamage = 50; - } else { - // Plastic explosive - minDamage = 40; - maxDamage = 80; - } + + // SFALL + explosiveGetDamage(explosive->pid, &minDamage, &maxDamage); // FIXME: I guess this is a little bit wrong, dude can never be null, I // guess it needs to check if owner is dude. diff --git a/src/sfall_config.h b/src/sfall_config.h index 5dc0f14..ce0e40f 100644 --- a/src/sfall_config.h +++ b/src/sfall_config.h @@ -35,6 +35,11 @@ #define SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY "ComputeSpray_CenterDiv" #define SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY "ComputeSpray_TargetMult" #define SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY "ComputeSpray_TargetDiv" +#define SFALL_CONFIG_DYNAMITE_MIN_DAMAGE_KEY "Dynamite_DmgMin" +#define SFALL_CONFIG_DYNAMITE_MAX_DAMAGE_KEY "Dynamite_DmgMax" +#define SFALL_CONFIG_PLASTIC_EXPLOSIVE_MIN_DAMAGE_KEY "PlasticExplosive_DmgMin" +#define SFALL_CONFIG_PLASTIC_EXPLOSIVE_MAX_DAMAGE_KEY "PlasticExplosive_DmgMax" +#define SFALL_CONFIG_EXPLOSION_EMITS_LIGHT_KEY "ExplosionsEmitLight" #define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1 #define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3