Anything that occupies a tile and can be hit: the player and every monster.
One struct covers both. The player has kind: :scriber and is built by scriber/1;
monsters have one of the other kinds and are built by spawn/4 from a fixed archetype
table. Combat, death and drawing treat the two alike — only who chooses the next action
differs, and that is Scriber.Game's concern.
Fields:
id— unique within a run; the player is always0kind— one ofkind/0pos—{x, y}on the current levelhp/max_hp— current and maximum integrity;hpnever goes below 0power— base damage before the weapon and bonuses inScriber.Gamedefense— damage subtracted per incoming hitspeed— tiles moved per turn; an entity strikes at most once a turn however fastpace— a turn everypaceturns is one the entity acts on;2is slowart— sprite name inScriber.Artglyph— the same thing for terminals without graphics; kept separately because several kinds may share a glyph while having distinct spritescolor—{r, g, b}the glyph is drawn inshards— paid to the killer when this entity diesawake?— whether the entity acts; monsters start asleep, and one that has not seen the player for a while sleeps againseen_at— the turn the entity last saw the player, ornilgoal— where the entity last knew the player, or a noise, to be walked tocarries—{:fragment, n}when the entity holds a piece of the gate's code, dropped where it dies
Example
monster = Scriber.Entity.spawn(:sentry, 4, {12, 9}, 3)
monster.hp
#=> 24
Summary
Functions
Whether the entity has any integrity left, and so still acts.
A line on what a kind is and how it behaves, for the moment it is first noticed.
The entity with amount subtracted from hp, floored at 0.
The entity with max_hp raised by amount, and hp with it.
The entity with amount added to hp, capped at max_hp.
Whether the kind moves at all.
The player at the start of a run, standing at pos with id 0 and 50 integrity.
Build a monster of kind with id, standing at pos, scaled for depth.
Types
@type kind() :: :scriber | :mite | :sentry | :daemon | :husk
@type t() :: %Scriber.Entity{ art: atom(), awake?: boolean(), carries: {:fragment, non_neg_integer()} | nil, color: {0..255, 0..255, 0..255}, defense: non_neg_integer(), glyph: String.t(), goal: {integer(), integer()} | nil, hp: integer(), id: pos_integer(), kind: kind(), max_hp: pos_integer(), name: String.t(), pace: pos_integer(), pos: {integer(), integer()}, power: pos_integer(), seen_at: non_neg_integer() | nil, shards: non_neg_integer(), speed: pos_integer() }
Functions
Whether the entity has any integrity left, and so still acts.
A line on what a kind is and how it behaves, for the moment it is first noticed.
@spec damage(t(), non_neg_integer()) :: t()
The entity with amount subtracted from hp, floored at 0.
@spec harden(t(), non_neg_integer()) :: t()
The entity with max_hp raised by amount, and hp with it.
@spec heal(t(), non_neg_integer()) :: t()
The entity with amount added to hp, capped at max_hp.
Whether the kind moves at all.
The player at the start of a run, standing at pos with id 0 and 50 integrity.
@spec spawn(kind(), pos_integer(), {integer(), integer()}, pos_integer()) :: t()
Build a monster of kind with id, standing at pos, scaled for depth.
kind must be one of :mite, :husk, :sentry or :daemon; :scriber and any other
value raise a FunctionClauseError. Use scriber/1 for the player.
depth scales the archetype: hp and max_hp gain (depth - 1) * 2, and power gains
div(depth - 1, 2). defense, speed, pace and shards do not change with depth.
The entity starts asleep (awake?: false) and at full health.