From 6658c3c51c66a5898b4e04184b113f6766580276 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:56:40 +0100 Subject: [PATCH 01/11] SpellEffectOnCubes --- config/fxdata/cubes.cfg | 10 ++++++ src/config_cubes.c | 77 +++++++++++++++++++++++++++++++++++++++-- src/config_cubes.h | 9 +++++ src/thing_creature.c | 26 +++++++++----- 4 files changed, 111 insertions(+), 11 deletions(-) diff --git a/config/fxdata/cubes.cfg b/config/fxdata/cubes.cfg index 1134ad4627..dbef7fa613 100644 --- a/config/fxdata/cubes.cfg +++ b/config/fxdata/cubes.cfg @@ -7,6 +7,16 @@ [cube0] Name = FREE_SPACE Textures = 0 0 0 0 0 0 +; Spell effect to cast on walk-by. Accepts both names and numbers. +SpellEffect = 0 +; Defines the level of 'SpellEffect' when cast. +SpellLevel = 0 +; Defines valid target for 'SpellEffect'. +; Options are: +; NEUTRAL - Cast on everyone. +; FRIENDLY - Only cast on allies. +; HOSTILE - Only cast on enemies. +Target = NEUTRAL Properties = UNCLAIMED_PATH ; Standard, diggable earth. diff --git a/src/config_cubes.c b/src/config_cubes.c index c24bee7016..c22560621f 100644 --- a/src/config_cubes.c +++ b/src/config_cubes.c @@ -24,6 +24,8 @@ #include "game_legacy.h" #include "config.h" #include "config_cubes.h" +#include "config_magic.h" +#include "console_cmd.h" #include "post_inc.h" #ifdef __cplusplus @@ -37,8 +39,11 @@ const struct NamedCommand cubes_cube_commands[] = { {"Textures", 2}, {"OwnershipGroup", 3}, {"Owner", 4}, - {"Properties", 5}, - {NULL, 0}, + {"SpellEffect", 5}, + {"SpellLevel", 6}, + {"Target", 7}, + {"Properties", 8}, + {NULL, 0}, }; const struct NamedCommand cubes_properties_flags[] = { @@ -49,6 +54,13 @@ const struct NamedCommand cubes_properties_flags[] = { {NULL, 0}, }; +const struct NamedCommand cubes_target[] = { + {"NEUTRAL", CT_Neutral}, + {"FRIENDLY", CT_Friendly}, + {"HOSTILE", CT_Hostile}, + {NULL, 0}, +}; + /******************************************************************************/ struct NamedCommand cube_desc[CUBE_ITEMS_MAX]; /******************************************************************************/ @@ -76,6 +88,10 @@ TbBool parse_cubes_cube_blocks(char *buf, long len, const char *config_textname, { cubest = &game.conf.cube_conf.cube_cfgstats[i]; memset(cubest->code_name, 0, COMMAND_WORD_LEN); + cubest->spell_effect = 0; + cubest->spell_level = 0; + cubest->target = 0; + cubest->properties_flags = 0; cube_desc[i].name = cubest->code_name; cube_desc[i].num = i; } @@ -190,7 +206,62 @@ TbBool parse_cubes_cube_blocks(char *buf, long len, const char *config_textname, n++; } break; - case 5: // Properties + case 5: // SpellEffect + if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + { + if (parameter_is_number(word_buf)) + { + k = atoi(word_buf); + } + else + { + k = get_id(spell_desc, word_buf); + } + if (k >= 0) + { + cubed->spell_effect = k; + n++; + } + } + if (n < 1) + { + CONFWRNLOG("Couldn't read \"%s\" parameter in [%.*s] block of %s file.", + COMMAND_TEXT(cmd_num), blocknamelen, blockname, config_textname); + } + break; + case 6: // SpellLevel + if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + { + k = atoi(word_buf); + if (k >= 0) + { + cubed->spell_level = k; + n++; + } + } + if (n < 1) + { + CONFWRNLOG("Couldn't read \"%s\" parameter in [%.*s] block of %s file.", + COMMAND_TEXT(cmd_num), blocknamelen, blockname, config_textname); + } + break; + case 7: // Target + if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + { + k = get_id(cubes_target, word_buf); + if (k >= 0) + { + cubed->target = k; + n++; + } + } + if (n < 1) + { + CONFWRNLOG("Couldn't read \"%s\" parameter in [%.*s] block of %s file.", + COMMAND_TEXT(cmd_num), blocknamelen, blockname, config_textname); + } + break; + case 8: // Properties cubed->properties_flags = 0; while (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) { diff --git a/src/config_cubes.h b/src/config_cubes.h index 9b8e60aa6f..f559e49046 100644 --- a/src/config_cubes.h +++ b/src/config_cubes.h @@ -40,11 +40,20 @@ enum CubePropertiesFlags { CPF_IsUnclaimedPath = 0x08, }; +enum CubeTarget { + CT_Neutral, + CT_Friendly, + CT_Hostile, +}; + struct CubeConfigStats { char code_name[COMMAND_WORD_LEN]; unsigned short texture_id[CUBE_TEXTURES]; unsigned char ownershipGroup; PlayerNumber owner; + SpellKind spell_effect; + CrtrExpLevel spell_level; + unsigned char target; unsigned char properties_flags; }; diff --git a/src/thing_creature.c b/src/thing_creature.c index eefd806afe..3120fa7e14 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6125,9 +6125,9 @@ void process_magic_fall_effect(struct Thing *thing) void process_landscape_affecting_creature(struct Thing *thing) { SYNCDBG(18,"Starting"); - thing->movement_flags &= ~TMvF_IsOnWater; - thing->movement_flags &= ~TMvF_IsOnLava; - thing->movement_flags &= ~TMvF_IsOnSnow; + clear_flag(thing->movement_flags, TMvF_IsOnWater); + clear_flag(thing->movement_flags, TMvF_IsOnLava); + clear_flag(thing->movement_flags, TMvF_IsOnSnow); struct CreatureControl* cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { @@ -6135,7 +6135,6 @@ void process_landscape_affecting_creature(struct Thing *thing) return; } cctrl->corpse_to_piss_on = 0; - int stl_idx = get_subtile_number(thing->mappos.x.stl.num, thing->mappos.y.stl.num); unsigned long navheight = get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num); if (subtile_coord(navheight,0) == thing->mappos.z.val) @@ -6145,11 +6144,22 @@ void process_landscape_affecting_creature(struct Thing *thing) { struct CreatureStats* crstat = creature_stats_get_from_thing(thing); apply_damage_to_thing_and_display_health(thing, crstat->hurt_by_lava, -1); - thing->movement_flags |= TMvF_IsOnLava; - } else - if (cube_is_water(i)) + set_flag(thing->movement_flags, TMvF_IsOnLava); + } + else if (cube_is_water(i)) { - thing->movement_flags |= TMvF_IsOnWater; + set_flag(thing->movement_flags, TMvF_IsOnWater); + } + struct CubeConfigStats* cubest = get_cube_model_stats(i); + if (cubest->spell_effect > 0) + { + PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); + if ((players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Friendly) + || (!players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Hostile) + || (cubest->target == CT_Neutral)) + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level, plyr_idx); + } } process_creature_leave_footsteps(thing); process_creature_standing_on_corpses_at(thing, &thing->mappos); From 96809c363180fd127d28e0633534146b29980813 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:07:32 +0100 Subject: [PATCH 02/11] play sound if any --- src/thing_creature.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/thing_creature.c b/src/thing_creature.c index 3120fa7e14..e7194fb8d9 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6158,6 +6158,11 @@ void process_landscape_affecting_creature(struct Thing *thing) || (!players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Hostile) || (cubest->target == CT_Neutral)) { + struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); + if (spconf->caster_affect_sound > 0) + { + thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); + } apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level, plyr_idx); } } From 69853405e40ad66c7127c35dbb41b57d1fda5f41 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:18:38 +0100 Subject: [PATCH 03/11] only cast if creature isn't already affected --- src/thing_creature.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index e7194fb8d9..28a0844730 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6150,20 +6150,35 @@ void process_landscape_affecting_creature(struct Thing *thing) { set_flag(thing->movement_flags, TMvF_IsOnWater); } + // Cubes can apply spell effect if set. struct CubeConfigStats* cubest = get_cube_model_stats(i); if (cubest->spell_effect > 0) { - PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); - if ((players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Friendly) - || (!players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Hostile) - || (cubest->target == CT_Neutral)) + // Check if already affected. + TbBool affected = false; + for (int k = 0; k < CREATURE_MAX_SPELLS_CASTED_AT; k++) { - struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); - if (spconf->caster_affect_sound > 0) + if (cctrl->casted_spells[k].spkind == cubest->spell_effect) { - thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); + affected = true; + break; + } + } + // Do not cast if already affected. + if (!affected) + { + PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); + if ((players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Friendly) + || (!players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Hostile) + || (cubest->target == CT_Neutral)) + { + struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); + if (spconf->caster_affect_sound > 0) + { + thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); + } + apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level, plyr_idx); } - apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level, plyr_idx); } } process_creature_leave_footsteps(thing); From a4382deedce3bd79c6138afd189a744e2822641b Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Tue, 14 Jan 2025 20:11:58 +0100 Subject: [PATCH 04/11] CastabilityFlags --- config/fxdata/cubes.cfg | 20 ++++++--- src/config_cubes.c | 40 +++++++++++------ src/config_cubes.h | 17 +++++--- src/thing_creature.c | 96 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 144 insertions(+), 29 deletions(-) diff --git a/config/fxdata/cubes.cfg b/config/fxdata/cubes.cfg index dbef7fa613..df4b0799b2 100644 --- a/config/fxdata/cubes.cfg +++ b/config/fxdata/cubes.cfg @@ -9,14 +9,20 @@ Name = FREE_SPACE Textures = 0 0 0 0 0 0 ; Spell effect to cast on walk-by. Accepts both names and numbers. SpellEffect = 0 -; Defines the level of 'SpellEffect' when cast. +; Defines the level of 'SpellEffect' when cast. A value of 0 uses the target’s level. SpellLevel = 0 -; Defines valid target for 'SpellEffect'. -; Options are: -; NEUTRAL - Cast on everyone. -; FRIENDLY - Only cast on allies. -; HOSTILE - Only cast on enemies. -Target = NEUTRAL +; Defines valid targets for 'SpellEffect'. Options are: +; FRIENDLY - Casts on allies. +; HOSTILE - Casts on enemies. +; NEUTRAL - Casts on neutrals. +; ONLY_DIGGER - Casts only on diggers. +; NOT_DIGGER - Does not cast on diggers. +; ONLY_EVIL - Casts only on evil creatures. +; NOT_EVIL - Does not cast on evil creatures. +; ONLY_FLYING - Casts only on flying creatures. +; NOT_FLYING - Does not cast on flying creatures. +; Example: 'Castability = FRIENDLY NOT_DIGGER NOT_FLYING' casts on allies that are neither flying nor diggers. +Castability = 0 Properties = UNCLAIMED_PATH ; Standard, diggable earth. diff --git a/src/config_cubes.c b/src/config_cubes.c index c22560621f..9d0ffc92bf 100644 --- a/src/config_cubes.c +++ b/src/config_cubes.c @@ -41,7 +41,7 @@ const struct NamedCommand cubes_cube_commands[] = { {"Owner", 4}, {"SpellEffect", 5}, {"SpellLevel", 6}, - {"Target", 7}, + {"Castability", 7}, {"Properties", 8}, {NULL, 0}, }; @@ -54,11 +54,17 @@ const struct NamedCommand cubes_properties_flags[] = { {NULL, 0}, }; -const struct NamedCommand cubes_target[] = { - {"NEUTRAL", CT_Neutral}, - {"FRIENDLY", CT_Friendly}, - {"HOSTILE", CT_Hostile}, - {NULL, 0}, +const struct NamedCommand cubes_castability_flags[] = { + {"FRIENDLY", CCF_Friendly}, + {"HOSTILE", CCF_Hostile}, + {"NEUTRAL", CCF_Neutral}, + {"ONLY_DIGGER", CCF_OnlyDigger}, + {"NOT_DIGGER", CCF_NotDigger}, + {"ONLY_EVIL", CCF_OnlyEvil}, + {"NOT_EVIL", CCF_NotEvil}, + {"ONLY_FLYING", CCF_OnlyFlying}, + {"NOT_FLYING", CCF_NotFlying}, + {NULL, 0}, }; /******************************************************************************/ @@ -90,7 +96,7 @@ TbBool parse_cubes_cube_blocks(char *buf, long len, const char *config_textname, memset(cubest->code_name, 0, COMMAND_WORD_LEN); cubest->spell_effect = 0; cubest->spell_level = 0; - cubest->target = 0; + cubest->castability_flags = 0; cubest->properties_flags = 0; cube_desc[i].name = cubest->code_name; cube_desc[i].num = i; @@ -245,15 +251,25 @@ TbBool parse_cubes_cube_blocks(char *buf, long len, const char *config_textname, COMMAND_TEXT(cmd_num), blocknamelen, blockname, config_textname); } break; - case 7: // Target - if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + case 7: // Castability + cubed->castability_flags = 0; + while (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) { - k = get_id(cubes_target, word_buf); - if (k >= 0) + if (parameter_is_number(word_buf)) { - cubed->target = k; + k = atoi(word_buf); + cubed->castability_flags = k; n++; } + else + { + k = get_id(cubes_castability_flags, word_buf); + if (k > 0) + { + set_flag(cubed->castability_flags, k); + n++; + } + } } if (n < 1) { diff --git a/src/config_cubes.h b/src/config_cubes.h index f559e49046..7defd7d6fe 100644 --- a/src/config_cubes.h +++ b/src/config_cubes.h @@ -40,10 +40,17 @@ enum CubePropertiesFlags { CPF_IsUnclaimedPath = 0x08, }; -enum CubeTarget { - CT_Neutral, - CT_Friendly, - CT_Hostile, +enum CubeCastabilityFlags { + CCF_None = 0x000, + CCF_Friendly = 0x001, + CCF_Hostile = 0x002, + CCF_Neutral = 0x004, + CCF_OnlyDigger = 0x008, + CCF_NotDigger = 0x010, + CCF_OnlyEvil = 0x020, + CCF_NotEvil = 0x040, + CCF_OnlyFlying = 0x080, + CCF_NotFlying = 0x100, }; struct CubeConfigStats { @@ -53,7 +60,7 @@ struct CubeConfigStats { PlayerNumber owner; SpellKind spell_effect; CrtrExpLevel spell_level; - unsigned char target; + unsigned short castability_flags; unsigned char properties_flags; }; diff --git a/src/thing_creature.c b/src/thing_creature.c index 28a0844730..c3f3b60019 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6122,6 +6122,87 @@ void process_magic_fall_effect(struct Thing *thing) } } +TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber plyr_idx, unsigned short castability_flags) +{ + // Exclude spectators immediately. + if (flag_is_set(get_creature_model_flags(thing), CMF_IsSpectator)) + { + return false; + } + // Handle digger-related flags. + if (flag_is_set(get_creature_model_flags(thing), CMF_IsSpecDigger)) + { + if (flag_is_set(castability_flags, CCF_NotDigger)) + { + return false; + } + } + else + { + if (flag_is_set(castability_flags, CCF_OnlyDigger)) + { + return false; + } + } + // Handle evil-related flags. + if (flag_is_set(get_creature_model_flags(thing), CMF_IsEvil)) + { + if (flag_is_set(castability_flags, CCF_NotEvil)) + { + return false; + } + } + else + { + if (flag_is_set(castability_flags, CCF_OnlyEvil)) + { + return false; + } + } + // Handle flying-related flags. + if (flag_is_set(thing->movement_flags, TMvF_Flying)) + { + if (flag_is_set(castability_flags, CCF_NotFlying)) + { + return false; + } + } + else + { + if (flag_is_set(castability_flags, CCF_OnlyFlying)) + { + return false; + } + } + // Handle owner-related flags. + if (!is_neutral_thing(thing)) + { + if (players_are_mutual_allies(thing->owner, plyr_idx)) + { + if (flag_is_set(castability_flags, CCF_Friendly)) + { + return true; + } + } + else + { + if (flag_is_set(castability_flags, CCF_Hostile)) + { + return true; + } + } + } + else + { + if (flag_is_set(castability_flags, CCF_Neutral)) + { + return true; + } + } + // Exclude target by default if no flags match. + return false; +} + void process_landscape_affecting_creature(struct Thing *thing) { SYNCDBG(18,"Starting"); @@ -6137,7 +6218,7 @@ void process_landscape_affecting_creature(struct Thing *thing) cctrl->corpse_to_piss_on = 0; int stl_idx = get_subtile_number(thing->mappos.x.stl.num, thing->mappos.y.stl.num); unsigned long navheight = get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num); - if (subtile_coord(navheight,0) == thing->mappos.z.val) + if (subtile_coord(navheight, 0) == thing->mappos.z.val) { int i = get_top_cube_at_pos(stl_idx); if (cube_is_lava(i)) @@ -6168,16 +6249,21 @@ void process_landscape_affecting_creature(struct Thing *thing) if (!affected) { PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); - if ((players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Friendly) - || (!players_are_mutual_allies(thing->owner, plyr_idx) && cubest->target == CT_Hostile) - || (cubest->target == CT_Neutral)) + if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags)) { struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); if (spconf->caster_affect_sound > 0) { thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); } - apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level, plyr_idx); + if (cubest->spell_level > 0) + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level-1, plyr_idx); + } + else + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->explevel, plyr_idx); + } } } } From d36e32c19cde955c4c266be1e78f5135856ff797 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 08:42:28 +0100 Subject: [PATCH 05/11] Update thing_creature.c Should now work correctly with flying creatures and related castability flags. --- src/thing_creature.c | 92 +++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index e42bd33896..047ff3578b 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6149,8 +6149,9 @@ void process_magic_fall_effect(struct Thing *thing) TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber plyr_idx, unsigned short castability_flags) { - // Exclude spectators immediately. - if (flag_is_set(get_creature_model_flags(thing), CMF_IsSpectator)) + // Exclude 'castability_flags == 0' or spectators immediately. + if ((castability_flags == 0) + || flag_is_set(get_creature_model_flags(thing), CMF_IsSpectator)) { return false; } @@ -6184,8 +6185,8 @@ TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber pl return false; } } - // Handle flying-related flags. - if (flag_is_set(thing->movement_flags, TMvF_Flying)) + // Handle flying-related flags. A creature is considered flying if its z-position is above floor height at x/y coordinates. Relevant for possession. + if (thing->mappos.z.val > subtile_coord(get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num), 0)) { if (flag_is_set(castability_flags, CCF_NotFlying)) { @@ -6228,6 +6229,46 @@ TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber pl return false; } +void process_cube_spell_effect_on_thing(struct Thing *thing, int cube_kind) +{ + // Cubes can apply spell effect if set. + struct CubeConfigStats* cubest = get_cube_model_stats(cube_kind); + if (cubest->spell_effect > 0) + { + // Check if already affected. + TbBool affected = false; + for (int k = 0; k < CREATURE_MAX_SPELLS_CASTED_AT; k++) + { + if (cctrl->casted_spells[k].spkind == cubest->spell_effect) + { + affected = true; + break; + } + } + // Do not cast if already affected. + if (!affected) + { + PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); + if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags)) + { + struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); + if (spconf->caster_affect_sound > 0) + { + thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); + } + if (cubest->spell_level > 0) + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level-1, plyr_idx); + } + else + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->explevel, plyr_idx); + } + } + } + } +} + void process_landscape_affecting_creature(struct Thing *thing) { SYNCDBG(18,"Starting"); @@ -6242,56 +6283,21 @@ void process_landscape_affecting_creature(struct Thing *thing) } cctrl->corpse_to_piss_on = 0; int stl_idx = get_subtile_number(thing->mappos.x.stl.num, thing->mappos.y.stl.num); + int cube_kind = get_top_cube_at_pos(stl_idx); + process_thing_with_cube_effect(thing, cube_kind); unsigned long navheight = get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num); if (subtile_coord(navheight, 0) == thing->mappos.z.val) { - int i = get_top_cube_at_pos(stl_idx); - if (cube_is_lava(i)) + if (cube_is_lava(cube_kind)) { struct CreatureStats* crstat = creature_stats_get_from_thing(thing); apply_damage_to_thing_and_display_health(thing, crstat->hurt_by_lava, -1); set_flag(thing->movement_flags, TMvF_IsOnLava); } - else if (cube_is_water(i)) + else if (cube_is_water(cube_kind)) { set_flag(thing->movement_flags, TMvF_IsOnWater); } - // Cubes can apply spell effect if set. - struct CubeConfigStats* cubest = get_cube_model_stats(i); - if (cubest->spell_effect > 0) - { - // Check if already affected. - TbBool affected = false; - for (int k = 0; k < CREATURE_MAX_SPELLS_CASTED_AT; k++) - { - if (cctrl->casted_spells[k].spkind == cubest->spell_effect) - { - affected = true; - break; - } - } - // Do not cast if already affected. - if (!affected) - { - PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); - if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags)) - { - struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); - if (spconf->caster_affect_sound > 0) - { - thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); - } - if (cubest->spell_level > 0) - { - apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level-1, plyr_idx); - } - else - { - apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->explevel, plyr_idx); - } - } - } - } process_creature_leave_footsteps(thing); process_creature_standing_on_corpses_at(thing, &thing->mappos); } From 1727ef2b1df81adf2e88c1c176893044a21dd2a0 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 08:46:25 +0100 Subject: [PATCH 06/11] re-add check for movement_flags 'TMvF_Flying' to avoid case of creatures being dropped by hand --- src/thing_creature.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index 047ff3578b..442b239a9b 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6186,7 +6186,8 @@ TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber pl } } // Handle flying-related flags. A creature is considered flying if its z-position is above floor height at x/y coordinates. Relevant for possession. - if (thing->mappos.z.val > subtile_coord(get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num), 0)) + if (flag_is_set(thing->movement_flags, TMvF_Flying) + && (thing->mappos.z.val > subtile_coord(get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num), 0))) { if (flag_is_set(castability_flags, CCF_NotFlying)) { From a4db08255c976754ee2fcdbf6cd177072bd40b2c Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 08:56:02 +0100 Subject: [PATCH 07/11] fixes mistakes fix incorrect name and missing CreatureControl struct --- src/thing_creature.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index 442b239a9b..e7e933469e 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6237,6 +6237,7 @@ void process_cube_spell_effect_on_thing(struct Thing *thing, int cube_kind) if (cubest->spell_effect > 0) { // Check if already affected. + struct CreatureControl* cctrl = creature_control_get_from_thing(thing); TbBool affected = false; for (int k = 0; k < CREATURE_MAX_SPELLS_CASTED_AT; k++) { @@ -6285,7 +6286,7 @@ void process_landscape_affecting_creature(struct Thing *thing) cctrl->corpse_to_piss_on = 0; int stl_idx = get_subtile_number(thing->mappos.x.stl.num, thing->mappos.y.stl.num); int cube_kind = get_top_cube_at_pos(stl_idx); - process_thing_with_cube_effect(thing, cube_kind); + process_cube_spell_effect_on_thing(thing, cube_kind); unsigned long navheight = get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num); if (subtile_coord(navheight, 0) == thing->mappos.z.val) { From 052dcdb592f3425a13d1fcb22f882b623310d74e Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 09:03:22 +0100 Subject: [PATCH 08/11] fix another mistake explevel -> exp_level /s who is that silly person that renamed that :p --- src/thing_creature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index e7e933469e..6761799c00 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6264,7 +6264,7 @@ void process_cube_spell_effect_on_thing(struct Thing *thing, int cube_kind) } else { - apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->explevel, plyr_idx); + apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->exp_level, plyr_idx); } } } From 3973444a3a637662baae3115e979c2864915a997 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 09:11:41 +0100 Subject: [PATCH 09/11] add immunity check // Even though immunity is handled in 'apply_spell_effect_to_thing', check it here to prevent sound effects. --- src/thing_creature.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index 6761799c00..4bd4f70f94 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6251,7 +6251,9 @@ void process_cube_spell_effect_on_thing(struct Thing *thing, int cube_kind) if (!affected) { PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); - if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags)) + if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags) + && !creature_is_immune_to_spell_effect(thing, spconf->spell_flags)) + // Even though immunity is handled in 'apply_spell_effect_to_thing', check it here to prevent sound effects. { struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); if (spconf->caster_affect_sound > 0) From 56e49af117c786a6da3b6f6236b0b3d535eb5838 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 3 Feb 2025 09:13:53 +0100 Subject: [PATCH 10/11] fix immunity check cleaner way --- src/thing_creature.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index 4bd4f70f94..53b073cc93 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6251,22 +6251,24 @@ void process_cube_spell_effect_on_thing(struct Thing *thing, int cube_kind) if (!affected) { PlayerNumber plyr_idx = get_slab_owner_thing_is_on(thing); - if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags) - && !creature_is_immune_to_spell_effect(thing, spconf->spell_flags)) - // Even though immunity is handled in 'apply_spell_effect_to_thing', check it here to prevent sound effects. + if (cube_castability_can_target_creature(thing, plyr_idx, cubest->castability_flags)) { struct SpellConfig* spconf = get_spell_config(cubest->spell_effect); - if (spconf->caster_affect_sound > 0) + // Even though immunity is handled in 'apply_spell_effect_to_thing', check it here to prevent sound effects. + if (!creature_is_immune_to_spell_effect(thing, spconf->spell_flags)) { - thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); - } - if (cubest->spell_level > 0) - { - apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level-1, plyr_idx); - } - else - { - apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->exp_level, plyr_idx); + if (spconf->caster_affect_sound > 0) + { + thing_play_sample(thing, spconf->caster_affect_sound + UNSYNC_RANDOM(spconf->caster_sounds_count), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); + } + if (cubest->spell_level > 0) + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cubest->spell_level-1, plyr_idx); + } + else + { + apply_spell_effect_to_thing(thing, cubest->spell_effect, cctrl->exp_level, plyr_idx); + } } } } From e48d26fb1f0de1caa5ede48d58620e709c43d133 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:42:58 +0100 Subject: [PATCH 11/11] Update thing_creature.c --- src/thing_creature.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/thing_creature.c b/src/thing_creature.c index 6e931a70b3..06a1bb58be 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -6185,8 +6185,7 @@ TbBool cube_castability_can_target_creature(struct Thing *thing, PlayerNumber pl } } // Handle flying-related flags. A creature is considered flying if its z-position is above floor height at x/y coordinates. Relevant for possession. - if (flag_is_set(thing->movement_flags, TMvF_Flying) - && (thing->mappos.z.val > subtile_coord(get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num), 0))) + if (thing->mappos.z.val > subtile_coord(get_navigation_map_floor_height(thing->mappos.x.stl.num, thing->mappos.y.stl.num), 0)) { if (flag_is_set(castability_flags, CCF_NotFlying)) {