Difference between revisions of "Implicit Facing"

From RogueBasin
Jump to navigation Jump to search
m
 
(5 intermediate revisions by 5 users not shown)
Line 1: Line 1:
<pre>
{{original|author=Jimmy Babcock|oldid=3824}}
Introduction


Several games have used systems which represent the player\'s facing, and many
== Introduction ==
 
Several games have used systems which represent the player's facing, and many
more have rejected it. The standard way of handling facing gives the player an
more have rejected it. The standard way of handling facing gives the player an
annoying extra element to manage, and so has been considered unworkable. This
annoying extra element to manage, and so has been considered unworkable. This
article proposes an alternate use for facing, which does not burden the player
article proposes an alternate use for facing, which does not burden the player
with additional details. It is best implemented as a replacement for the
with additional details. It is best implemented as a replacement for the
\"defense penalty for multiple attackers\" rule.
"defense penalty for multiple attackers" rule.


== Rules ==


Rules
The player's facing is determined by his previous move, and by the position of
monsters around him, as follows (rules applied in order):


The player\'s facing is determined by his previous move, and by the position of
* if the last move was to fire an arrow, zap a wand, throw a projectile, etc., then the player is facing in the direction he fired/zapped/threw in.
monsters around him, as follows (rules applied in order):
* Else if there is exactly one visible monster next to the player, the player faces towards it. Justification: Regardless of the direction of movement, the player is aware of and defending against attacks.
- If the last move was to fire an arrow, zap a wand, throw a projectile, etc.,
* Else if the last attack was to move or attack, facing is in the direction given by the move/attack.
then the player is facing in the direction he fired/zapped/threw in.
* Else facing is the same as it was last move.
- Else if there is exactly one visible monster next to the player, the player
faces towards it. Justification: Regardless of the direction of movement, the
player is aware of and defending against attacks.
- Else if the last attack was to move or attack, facing is in the direction
given by the move/attack.
- Else facing is the same as it was last move


Facing does NOT affect vision, movement speed, or any non-combat actions. The
Facing does NOT affect vision, movement speed, or any non-combat actions. The
Line 27: Line 24:
that will make it obvious that a facing system is in use.  
that will make it obvious that a facing system is in use.  


Melee
== Melee ==


On a given turn, the tiles around the player are divided into frontal, flank,
On a given turn, the tiles around the player are divided into frontal, flank,
Line 37: Line 34:
receives a substantial bonus.
receives a substantial bonus.


Fig. 1 - Melee
Facing @        Facing NE
Facing @        Facing NE
321  1: Front    211
321  1: Front    211
3@1  2: Flank    3@1
3@1  2: Flank    3@1
321  3: Rear    332
321  3: Rear    332
Fig. 1 - Melee




Missile
== Missile ==


A ranged attacker receives the benefit of a flank or ranged attack depending on
A ranged attacker receives the benefit of a flank or ranged attack depending on
which quadrant (see Fig. 2) it is in.
which quadrant (see Fig. 2) it is in.


Fig. 2 - Missile
Facing E  Facing NE
Facing E  Facing NE
  \222/      22|11
\\222/      22|11
  3\2/1      22|11  1: Front
3\\2/1      22|11  1: Front
  33@11      --@--  2: Flank
33@11      --@--  2: Flank
  3/2\1      33|22  3: Rear
3/2\\1      33|22  3: Rear
  /222\      33|22
/222\\      33|22
Fig. 2 - Missile


Quadrant borders are never in region 2. Assuming a bresenham line draw from
Quadrant borders are never in region 2. Assuming a bresenham line draw from
Line 63: Line 62:




A More Formal Definition
== A More Formal Definition ==


So long as we restrict ranged attacks to firing on straight or diagonal paths,
So long as we restrict ranged attacks to firing on straight or diagonal paths,
we can represent facing as an integer in the range of 0 to 7, going clockwise
we can represent facing as an integer in the range of 0 to 7, going clockwise
at 45-degree increments; to determine what region an attacker is in, we find
at 45-degree increments; to determine what region an attacker is in, we find
the facing which would be towards it, subtract the player\'s facing modulo 8,
the facing which would be towards it, subtract the player's facing modulo 8,
and take the absolute value; if the result is <= 1, it is a frontal attack;
and take the absolute value; if the result is <= 1, it is a frontal attack;
else if <=2, flank attack; else <=4, rear.
else if <=2, flank attack; else <=4, rear.
Line 82: Line 81:
instead.
instead.


float mod(float a, float b) {
float mod(float a, float b) {
    if(a&gt0) return floor(a/b) * b;
    if(a&gt;0) return floor(a/b) * b;
    else    return -floor(-a/b) * b;
    else    return -floor(-a/b) * b;
}
}


 
== More on Missiles ==
More on Missiles


One of the goals of implicit facing is to not allow the player to control his
One of the goals of implicit facing is to not allow the player to control his
facing directly, and to make it so that he doesn\'t need to. A problem case is
facing directly, and to make it so that he doesn't need to. A problem case is
when the player moves, with no monsters adjacent, but with missile attackers
when the player moves, with no monsters adjacent, but with missile attackers
around. If the character is aware of their presence, it makes sense for him to
around. If the character is aware of their presence, it makes sense for him to
Line 108: Line 106:
could be left undefined until one of the monsters attacks, and set to be
could be left undefined until one of the monsters attacks, and set to be
towards that monster. Unfortunately, this means that the specific order of
towards that monster. Unfortunately, this means that the specific order of
missile attacks becomes relevant, which is not particularly desireable.
missile attacks becomes relevant, which is not particularly desirable.
 
Jimmy Babcock [jimmy_b@earthlink.net]
</pre>


[[Category:Articles]]
[[Category:Articles]]

Latest revision as of 04:41, 19 July 2011

Original by Jimmy Babcock


Introduction

Several games have used systems which represent the player's facing, and many more have rejected it. The standard way of handling facing gives the player an annoying extra element to manage, and so has been considered unworkable. This article proposes an alternate use for facing, which does not burden the player with additional details. It is best implemented as a replacement for the "defense penalty for multiple attackers" rule.

Rules

The player's facing is determined by his previous move, and by the position of monsters around him, as follows (rules applied in order):

  • if the last move was to fire an arrow, zap a wand, throw a projectile, etc., then the player is facing in the direction he fired/zapped/threw in.
  • Else if there is exactly one visible monster next to the player, the player faces towards it. Justification: Regardless of the direction of movement, the player is aware of and defending against attacks.
  • Else if the last attack was to move or attack, facing is in the direction given by the move/attack.
  • Else facing is the same as it was last move.

Facing does NOT affect vision, movement speed, or any non-combat actions. The current facing should not be featured prominently on the HUD, or anywhere else that will make it obvious that a facing system is in use.

Melee

On a given turn, the tiles around the player are divided into frontal, flank, and rear tiles (see Fig. 1). If an attacking melee monster is in a flank or rear tile, the player does not receive defensive benefits from a shield. (Variation: one flank receives shield benefits, depending on which hand holds the shield.) Furthermore, if the attacker is in a flank tile it receives a small (system-dependent) to-hit bonus, while if it is in a rear tile it receives a substantial bonus.

Facing @         Facing NE
321  1: Front    211
3@1  2: Flank    3@1
321  3: Rear     332

Fig. 1 - Melee


Missile

A ranged attacker receives the benefit of a flank or ranged attack depending on which quadrant (see Fig. 2) it is in.

Facing E   Facing NE
 \222/      22|11
 3\2/1      22|11  1: Front
 33@11      --@--  2: Flank
 3/2\1      33|22  3: Rear
 /222\      33|22

Fig. 2 - Missile

Quadrant borders are never in region 2. Assuming a bresenham line draw from attacker to player represents the path of the projectile, this is approximately equivalent to representing the projectile as a melee attack when it is one step away from the player.


A More Formal Definition

So long as we restrict ranged attacks to firing on straight or diagonal paths, we can represent facing as an integer in the range of 0 to 7, going clockwise at 45-degree increments; to determine what region an attacker is in, we find the facing which would be towards it, subtract the player's facing modulo 8, and take the absolute value; if the result is <= 1, it is a frontal attack; else if <=2, flank attack; else <=4, rear.

If we do not make this restriction, then we must allow both for the player to face in arbitrary angles, and accurately represent the angle of origin for ranged attacks. The angle from the player to an attacker is atan2(monst.y- plr.y, monst.x-plr.x) radians. As before, we take attack abs(angle - player facing % (2*pi)). (There is some complication this time with using modulus, since C does not support use of the modulus operator on floats.) This is frontal if result <= pi/4, flank if <= 3*pi/4, else <= pi, rear. As a workaround for the lack of modulus on floats, you can use the C function below instead.

float mod(float a, float b) {
    if(a>0) return floor(a/b) * b;
    else    return -floor(-a/b) * b;
}

More on Missiles

One of the goals of implicit facing is to not allow the player to control his facing directly, and to make it so that he doesn't need to. A problem case is when the player moves, with no monsters adjacent, but with missile attackers around. If the character is aware of their presence, it makes sense for him to consciously face towards them, but this is not what actually happens with the rules given. The situation is even worse when there are *multiple* missile attackers around. Certainly, it is tempting to ignore the case and expect that the player be aware of the facing rules, but this is not the best solution.

One possibility is to divide up the angles around the player into regions, and face towards the region which contains the most known in-range missile attackers. The regions should be overlapping, and should not be too large (for accuracy) or small (for speed); 60 degree regions with 20 degree overlap should work nicely.

Another possibility is to simply face towards the nearest monster. Or, facing could be left undefined until one of the monsters attacks, and set to be towards that monster. Unfortunately, this means that the specific order of missile attacks becomes relevant, which is not particularly desirable.