How does combat work?

Combat begins when one party or the other uses the 'kill verb'. There may be other ways to start combat, such as adding a target directly, but using the kill verb is the most kosher. The kill verb is defined in /bin/kill.c

The kill verb does the following:
  * Checks to make sure that the target is valid (i.e. not yourself, and present in the room)
  * Checks that your readiness is >= 1000.
  * If the above are valid, it calls start_combat in this_player(), passing it a pointer to the object to be killed and the integer '1'. It also prints the message "~Name ~verbattack ~targ!"

---

start_combat() takes two parameters: A pointer to the enemy ('enemy'), and an 'initiative' value. The initiative parameter is unused.

start_combat() clamps readiness into the range RMIN_READINESS through RMAX_READINESS[1]. It then adds 'enemy' to the front of the target stack[2]. Note that it does not currently notify the target that it has been attacked. Finally, it turns on heart_beat for living.c.

---

heart_beat() is one of the most complex functions in combat. It is called every 2 seconds (on a lag-free server; it can be slower if server lag is high). The heart_beat function generally affects the creature in whom it is beating. It does the following, in this order:

* If the creature is dead, it sets the 'is_corpse' flag to true, and the 'doing' message to 0 (default). This is done in the heart beat, rather than at the moment they die, so that you don't get 'the corpse of ...' messages prematurely in combat messages.

* If the 'doing' flag is not 0, Then it decrements a doing_delay counter. When the counter reaches zero, the 'doing' message is set to 0. This is so that actions expire.

* If (hp < maxhp) and the creature is not dead, it increments 'heal_count'. Once (heal_count >= heal_delay), the creatuer gains a single hit point. This is how regeneration works.

* The same regeneration is done for mana using mana_heal_count, mana, and maxmana.

* The same regeneration is done for endurance using end_heal_count, endurance, and maxend.

* drop_invalid_targets() is called (see below for description).

* If the creature is not held ('held' variable is false) and not busy ('busy' variable is false), and if the creature's current readiness score is below MAX_READINESS, then their readiness is increased[3]. The function show_ready() is called (see below).

* If the creature is held (held > 0), then the 'held' time is decremented.

* If the creature is busy (busy > 0), and NOT currently held (held == 0), then the 'busy' time is decremented.

* get_battle_action() is called (see below), and the result is stored in the variable battle_action.

* A while loop is entered. The loop continues until

- You die
- You run out of targets AND you have no actions left to perform

Here is what the while loop does:
  - Calls drop_invalid_targets (again?)
  - Uses a nested loop to throw away invalid battle_action's (null actions or actions with no valid performing object).
  - Initializes 'morpheous' components of battle_action's to specifics (i.e. "me" or "guild" as an action performer, or -1 as a target).
  - If their readiness score is high enough to perform the action at the front of the queue:
    o Calls set_this_player() for messaging and convenience of action handlers (heart_beat() does not set this_player()).
    o Calls set_target() for messaging.
    o 

---

drop_invalid_targets() scans through the list of the creature's targets, and removes any from the list that are no longer valid combat targets. It is determined as follows:

* If any of the targets are 'false' (i.e., they have been destructed), they are dropped.
* Any target that returns true on 'query_dead' is dropped.
* If the target array is ({ }) by the end of the function call, then it is set to 0.
* If the current target has left the room, it is moved to the end of the target list. This is not done in a loop. If every target in the array has left the room, the list will simply spin around, one rotation per call to this function.

---

show_ready()

If this_object()->query_autoready() returns true, then this function writes out a 'readiness meter', which is a colorful display of the creature's current readiness (on a scale from 0-1000) and the next action on its combat queue. If query_autoready() is false, this function does nothing.

---

get_battle_action()

Returns the battle action on the front of the combat queue *without* popping it off. If there is none, it returns query_default_action().

---

Footnotes: Minor technical gotchas that seemed to confusing or detailed to be useful to most people.

(1) RMIN_READINESS is defined as -MAX_READINESS, and RMAX_READINESS is defined as 2*MAX_READINESS. MAX_READINESS is currently equal to 1000. These constants are in const/battconst.h (that is, /include/const/battconst.h -- since the include directory could be moved, it is conventional to leave it off).

(2) A list of current targets, stored as an array. It is allowed for it to be 0 if it is empty, so anything that modifies it should first check that it holds an array.

(3) Using the formula ((speed+speed_bonus)*3)d4 + ((will+will_bonus)*3)d6 ... the 'd#' is the D&D dice roll notation. Accurate dice probabilities are used.ect this, as would other magical items.
