Skip to content

Commit

Permalink
Move polearm mastery, opportunist and zone of control attacks into th…
Browse files Browse the repository at this point in the history
…eir own functions
  • Loading branch information
NickMcConnell committed Nov 14, 2024
1 parent c1d14c4 commit 725cd57
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 107 deletions.
15 changes: 2 additions & 13 deletions src/mon-move.c
Original file line number Diff line number Diff line change
Expand Up @@ -3485,19 +3485,8 @@ static void monster_turn(struct monster *mon)
}

/* If adjacent, player gets a chance for an opportunist attack,
* which might kill them (skip_next_turn is there to stop the
* player getting opportunist attacks afer knocking back) */
if (player_active_ability(player, "Opportunist") &&
monster_is_visible(mon) &&
!mon->skip_next_turn &&
(mon->alertness >= ALERTNESS_ALERT) && !player->truce &&
!player->timed[TMD_CONFUSED] &&
!player->timed[TMD_AFRAID] &&
!player->timed[TMD_ENTRANCED] &&
(player->timed[TMD_STUN] <= 100) &&
(distance(tgrid, player->grid) == 1)) {
py_attack_real(player, tgrid, ATT_OPPORTUNIST);
}
* which might kill the monster */
player_opportunist_or_zone(player, tgrid, player->grid, true);

/* Removes the monster if it is still alive */
delete_monster(cave, tgrid);
Expand Down
153 changes: 59 additions & 94 deletions src/mon-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,64 @@ static void monster_fall_in_chasm(struct loc grid)
}
}

/**
* Does any opportunist or zone of control attack necessary when player moves
*
* Note the use of skip_next_turn to stop the player getting opportunist
* attacks after knocking back
*/
void monster_opportunist_or_zone(struct player *p, struct loc grid_to)
{
int y, x;

/* Handle Opportunist and Zone of Control */
for (y = p->grid.y - 1; y <= p->grid.y + 1; y++) {
for (x = p->grid.x - 1; x <= p->grid.x + 1; x++) {
struct loc grid = loc(x, y);
char m_name[80];
struct monster *mon = square_monster(cave, grid);

if (mon && (mon->alertness >= ALERTNESS_ALERT) &&
!mon->m_timed[MON_TMD_CONF] && !mon->skip_next_turn &&
(mon->stance != STANCE_FLEEING) && !mon->skip_this_turn) {
bool opp = rf_has(mon->race->flags, RF_OPPORTUNIST);
bool zone = rf_has(mon->race->flags, RF_ZONE);
struct monster_lore *lore = get_lore(mon->race);

/* Opportunist */
if (opp && (distance(grid_to, grid) > 1)) {
monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);
msg("%s attacks you as you step away.", m_name);
make_attack_normal(mon, p);

/* Remember that the monster can do this */
if (monster_is_visible(mon)) {
rf_on(lore->flags, RF_OPPORTUNIST);
}
}

/* Zone of control */
if (zone && (distance(grid_to, p->grid) == 1)) {
monster_desc(m_name, sizeof(m_name), mon, MDESC_POSS);
msg("You move through %s zone of control.", m_name);
make_attack_normal(mon, p);

/* Remember that the monster can do this */
if (monster_is_visible(mon)) {
rf_on(lore->flags, RF_ZONE);
}
}
}
}
}
}

/**
* Swap the players/monsters (if any) at two locations.
*/
void monster_swap(struct loc grid1, struct loc grid2)
{
struct monster *mon;
char m_name[80];

/* Monsters */
int m1 = square(cave, grid1)->mon;
Expand All @@ -273,38 +324,15 @@ void monster_swap(struct loc grid1, struct loc grid2)

/* Monster 1 */
if (m1 > 0) {
bool opp = player_active_ability(player, "Opportunist");
bool zone = player_active_ability(player, "Zone of Control");

/* Monster */
m1_is_monster = true;
mon = cave_monster(cave, m1);

/* Handle Opportunist and Zone of Control */
if ((opp || zone) && monster_is_visible(mon) && !mon->skip_next_turn &&
!player->truce && !player->timed[TMD_CONFUSED] &&
!player->timed[TMD_AFRAID] && !player->timed[TMD_ENTRANCED] &&
(player->timed[TMD_STUN] < 100) &&
(distance(grid1, player->grid) == 1) &&
(!OPT(player, forgo_attacking_unwary) ||
(mon->alertness >= ALERTNESS_ALERT))) {
monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);

/* Zone of control */
if (zone && (distance(grid2, player->grid) == 1)) {
msg("%s moves through your zone of control.", m_name);
py_attack_real(player, grid1, ATT_ZONE_OF_CONTROL);
}
player_opportunist_or_zone(player, grid1, grid2, false);

/* Opportunist */
if (opp && (distance(grid2, player->grid) > 1)) {
msg("%s moves away from you.", m_name);
py_attack_real(player, grid1, ATT_OPPORTUNIST);
}

/* Monster may be dead */
if (mon->hp <= 0) return;
}
/* Monster may be dead */
if (mon->hp <= 0) return;

/* Makes noise when moving */
if (mon->noise == 0) {
Expand All @@ -322,51 +350,11 @@ void monster_swap(struct loc grid1, struct loc grid2)
/* Redraw monster list */
player->upkeep->redraw |= (PR_MONLIST);
} else if (m1 < 0) {
int y, x;

/* Handle Opportunist and Zone of Control */
for (y = player->grid.y - 1; y <= player->grid.y + 1; y++) {
for (x = player->grid.x - 1; x <= player->grid.x + 1; x++) {
struct loc grid = loc(x, y);
mon = square_monster(cave, grid);

if (mon && (mon->alertness >= ALERTNESS_ALERT) &&
!mon->m_timed[MON_TMD_CONF] && !mon->skip_next_turn &&
(mon->stance != STANCE_FLEEING) && !mon->skip_this_turn) {
bool opp = rf_has(mon->race->flags, RF_OPPORTUNIST);
bool zone = rf_has(mon->race->flags, RF_ZONE);
struct monster_lore *lore = get_lore(mon->race);

/* Opportunist */
if (opp && (distance(grid2, mon->grid) > 1)) {
monster_desc(m_name, sizeof(m_name), mon,
MDESC_STANDARD);
msg("%s attacks you as you step away.", m_name);
make_attack_normal(mon, player);

/* Remember that the monster can do this */
if (monster_is_visible(mon)) {
rf_on(lore->flags, RF_OPPORTUNIST);
}
}

/* Zone of control */
if (zone && (distance(grid2, player->grid) == 1)) {
monster_desc(m_name, sizeof(m_name), mon, MDESC_POSS);
msg("You move through %s zone of control.", m_name);
make_attack_normal(mon, player);

/* Remember that the monster can do this */
if (monster_is_visible(mon)) {
rf_on(lore->flags, RF_ZONE);
}
}
monster_opportunist_or_zone(player, grid2);

/* Player may be dead */
if (player->chp < 0) return;
}
}
}
/* Player may be dead */
if (player->chp < 0) return;

/* Move player */
player->grid = grid2;
Expand Down Expand Up @@ -425,30 +413,7 @@ void monster_swap(struct loc grid1, struct loc grid2)

/* Deal with set polearm attacks */
if (player_active_ability(player, "Polearm Mastery") && m1_is_monster) {
mon = square_monster(cave, grid2);
if (mon && monster_is_visible(mon)) {
struct object *obj = equipped_item_by_slot_name(player, "weapon");

if (!OPT(player, forgo_attacking_unwary) ||
(mon->alertness >= ALERTNESS_ALERT)) {
if ((distance(grid1, player->grid) > 1) &&
(distance(grid2, player->grid) == 1) &&
!player->truce && !player->timed[TMD_CONFUSED] &&
!player->timed[TMD_AFRAID] && of_has(obj->flags, OF_POLEARM)
&& player->focused) {
char o_name[80];

/* Get the basic name of the object */
object_desc(o_name, sizeof(o_name), obj, ODESC_BASE,
player);

monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);

msg("%s comes into reach of your %s.", m_name, o_name);
py_attack_real(player, grid2, ATT_POLEARM);
}
}
}
player_polearm_passive_attack(player, grid1, grid2);
}

/* Deal with falling down chasms */
Expand Down
1 change: 1 addition & 0 deletions src/mon-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void create_mon_flag_mask(bitflag *f, ...);
struct monster_race *lookup_monster(const char *name);
struct monster_base *lookup_monster_base(const char *name);
bool match_monster_bases(const struct monster_base *base, ...);
void monster_opportunist_or_zone(struct player *p, struct loc grid_to);
void monster_swap(struct loc grid1, struct loc grid2);
void monster_wake(struct monster *mon, bool notify, int aware_chance);
bool monster_can_see(struct chunk *c, struct monster *mon, struct loc grid);
Expand Down
71 changes: 71 additions & 0 deletions src/player-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,77 @@ void player_flanking_or_retreat(struct player *p, struct loc grid)
}
}

/**
* Does any opportunist or zone of control attack necessary when player moves
*
* Note the use of skip_next_turn to stop the player getting opportunist
* attacks afer knocking back
*/
void player_opportunist_or_zone(struct player *p, struct loc grid1,
struct loc grid2, bool opp_only)
{
bool opp = player_active_ability(p, "Opportunist");
bool zone = player_active_ability(p, "Zone of Control") && !opp_only;

/* Monster */
char m_name[80];
struct monster *mon = square_monster(cave, grid1);

/* Handle Opportunist and Zone of Control */
if ((opp || zone) && monster_is_visible(mon) && !mon->skip_next_turn &&
!p->truce && !p->timed[TMD_CONFUSED] && !p->timed[TMD_AFRAID] &&
!p->timed[TMD_ENTRANCED] && (p->timed[TMD_STUN] < 100) &&
(distance(grid1, p->grid) == 1) &&
(!OPT(p, forgo_attacking_unwary) ||
(mon->alertness >= ALERTNESS_ALERT))) {
monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);

/* Zone of control */
if (zone && (distance(grid2, p->grid) == 1)) {
msg("%s moves through your zone of control.", m_name);
py_attack_real(p, grid1, ATT_ZONE_OF_CONTROL);
}

/* Opportunist */
if (opp && (distance(grid2, p->grid) > 1)) {
msg("%s moves away from you.", m_name);
py_attack_real(p, grid1, ATT_OPPORTUNIST);
}
}
}

/**
* Does any polearm attack when a monster moves close to the player
*/
void player_polearm_passive_attack(struct player *p, struct loc grid_from,
struct loc grid_to)
{
char m_name[80];
struct monster *mon = square_monster(cave, grid_to);
if (mon && monster_is_visible(mon)) {
struct object *obj = equipped_item_by_slot_name(p, "weapon");

if (!OPT(p, forgo_attacking_unwary) ||
(mon->alertness >= ALERTNESS_ALERT)) {
if ((distance(grid_from, p->grid) > 1) &&
(distance(grid_to, p->grid) == 1) &&
!p->truce && !p->timed[TMD_CONFUSED] &&
!p->timed[TMD_AFRAID] && of_has(obj->flags, OF_POLEARM)
&& p->focused) {
char o_name[80];

/* Get the basic name of the object */
object_desc(o_name, sizeof(o_name), obj, ODESC_BASE, p);

monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);

msg("%s comes into reach of your %s.", m_name, o_name);
py_attack_real(p, grid_to, ATT_POLEARM);
}
}
}
}

/**
* Player is able to start a leap
*/
Expand Down
4 changes: 4 additions & 0 deletions src/player-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void player_fall_in_pit(struct player *p, bool spiked);
void player_falling_damage(struct player *p, bool stun);
void player_fall_in_chasm(struct player *p);
void player_flanking_or_retreat(struct player *p, struct loc grid);
void player_opportunist_or_zone(struct player *p, struct loc grid1,
struct loc grid2, bool opp_only);
void player_polearm_passive_attack(struct player *p, struct loc grid_from,
struct loc grid_to);
bool player_can_leap(struct player *p, struct loc grid, int dir);
bool player_break_web(struct player *p);
bool player_escape_pit(struct player *p);
Expand Down

0 comments on commit 725cd57

Please sign in to comment.