Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Units will attack traps they trigger when they can #3245

Merged
merged 5 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion config/fxdata/trapdoor.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ PointerSprites = 11
PanelTabIndex = 9
; Crate object model which stores this item before it's deployed.
Crate = WRKBOX_WOOD
; Manufacturing parameters.
; Number of workshop tiles needed in dungeon to build item:
; 0 - Any workshop
; 1 - 10 or more
; 2 - 17 or more
; 3 - 26 or more
; 4 - 37 or more
ManufactureLevel = 0
; Amount of workshop points it takes to create it. See creature workshop skill.
ManufactureRequired = 18000
; Gold revenue when selling this item.
SellingValue = 250
Expand Down
25 changes: 25 additions & 0 deletions src/creature_states_combt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3004,6 +3004,31 @@ short creature_object_combat(struct Thing *creatng)
return 0;
}

TbBool creature_start_combat_with_trap_if_available(struct Thing* creatng, struct Thing* traptng)
{
if (!creature_will_do_combat(creatng))
{
return false;
}
if (!combat_enemy_exists(creatng,traptng))
{
return false;
}
struct CreatureControl* cctrl = creature_control_get_from_thing(creatng);
if (cctrl->combat.battle_enemy_idx == traptng->index)
{
return false;
}
if (!creature_can_navigate_to(creatng, &traptng->mappos, NavRtF_Default))
{
if (!creature_has_ranged_weapon(creatng))
return false;
if (!creature_can_see_combat_path(creatng, traptng, get_combat_distance(creatng, traptng)))
return false;
}
return set_creature_object_combat(creatng, traptng);
}

TbBool creature_look_for_combat(struct Thing *creatng)
{
SYNCDBG(9,"Starting for %s index %d",thing_model_name(creatng),(int)creatng->index);
Expand Down
1 change: 1 addition & 0 deletions src/creature_states_combt.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ TbBool creature_look_for_enemy_heart_combat(struct Thing *thing);
TbBool creature_look_for_enemy_heart_snipe(struct Thing* thing);
TbBool creature_look_for_enemy_door_combat(struct Thing *thing);
TbBool creature_look_for_enemy_object_combat(struct Thing* thing);
TbBool creature_start_combat_with_trap_if_available(struct Thing* creatng, struct Thing* traptng);

struct Thing *check_for_door_to_fight(struct Thing *thing);
struct Thing* check_for_object_to_fight(struct Thing* thing);
Expand Down
5 changes: 5 additions & 0 deletions src/thing_shots.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "bflib_math.h"
#include "bflib_sound.h"
#include "creature_states.h"
#include "creature_states_combt.h"
#include "thing_data.h"
#include "thing_factory.h"
#include "thing_effects.h"
Expand Down Expand Up @@ -1180,6 +1181,10 @@ long shot_hit_creature_at(struct Thing *shotng, struct Thing *trgtng, struct Coo
{
apply_shot_experience_from_hitting_creature(shooter, trgtng, shotng->model);
}
if (thing_is_deployed_trap(shooter) && thing_is_creature(trgtng))
{
creature_start_combat_with_trap_if_available(trgtng, shooter);
}
if (((shotst->model_flags & ShMF_NoHit) != 0) || (trgtng->health < 0)) {
return 0;
}
Expand Down
33 changes: 20 additions & 13 deletions src/thing_traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "bflib_planar.h"

#include "thing_data.h"
#include "creature_states_combt.h"
#include "config_creature.h"
#include "config_terrain.h"
#include "creature_states.h"
Expand Down Expand Up @@ -196,6 +197,17 @@ TbBool thing_is_deployed_trap(const struct Thing* thing)
return true;
}

TbBool creature_available_for_trap_trigger(struct Thing* creatng)
{
if (!creature_is_being_unconscious(creatng) && !thing_is_dragged_or_pulled(creatng)
&& !creature_is_kept_in_custody_by_enemy(creatng) && !creature_is_dying(creatng)
&& !creature_is_being_dropped(creatng) && !flag_is_set(get_creature_model_flags(creatng),CMF_IsSpectator))
{
return true;
}
return false;
}

TbBool update_trap_trigger_line_of_sight_90_on_subtile(struct Thing *traptng, MapSubtlCoord stl_x, MapSubtlCoord stl_y)
{
struct Map* mapblk = get_map_block_at(stl_x, stl_y);
Expand All @@ -217,9 +229,8 @@ TbBool update_trap_trigger_line_of_sight_90_on_subtile(struct Thing *traptng, Ma
// Trigger for enemy player, or any player for neutral traps (otherwise neutral traps would be useless)
if (players_are_enemies(traptng->owner,thing->owner) || is_neutral_thing(traptng))
{
if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing) && !thing_is_picked_up(thing)
&& !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing)
&& ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0)) {
if (creature_available_for_trap_trigger(thing))
{
activate_trap(traptng, thing);
return true;
}
Expand Down Expand Up @@ -622,17 +633,12 @@ TbBool find_pressure_trigger_trap_target_passing_by_subtile(const struct Thing *
}
i = thing->next_on_mapblk;
// Per thing code start
if (thing_is_creature(thing) && (thing->owner != traptng->owner))
if (creature_available_for_trap_trigger(thing) && (thing->owner != traptng->owner))
{
if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing)
&& !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing)
&& ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0))
if (!is_neutral_thing(thing) && !players_are_mutual_allies(traptng->owner, thing->owner))
{
if (!is_neutral_thing(thing) && !players_are_mutual_allies(traptng->owner,thing->owner))
{
*found_thing = thing;
return true;
}
*found_thing = thing;
return true;
}
}
// Per thing code end
Expand Down Expand Up @@ -683,9 +689,10 @@ TbBool update_trap_trigger_pressure_subtile(struct Thing *traptng)
TbBool update_trap_trigger_line_of_sight(struct Thing* traptng)
{
struct Thing* trgtng = get_nearest_enemy_creature_in_sight_and_range_of_trap(traptng);
if (!thing_is_invalid(trgtng))
if (!thing_is_invalid(trgtng) && (creature_available_for_trap_trigger(trgtng)))
{
activate_trap(traptng, trgtng);
creature_start_combat_with_trap_if_available(trgtng, traptng);
return true;
}
return false;
Expand Down
Loading