diff urogue/daemons.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children c4b12d2d1dcd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/urogue/daemons.c	Tue Jan 31 19:56:04 2017 -0500
@@ -0,0 +1,999 @@
+/*
+    daemons.c - All the daemon and fuse functions are in here
+  
+    UltraRogue: The Ultimate Adventure in the Dungeons of Doom
+    Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
+    All rights reserved.
+
+    Based on "Advanced Rogue"
+    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
+    All rights reserved.
+
+    Based on "Rogue: Exploring the Dungeons of Doom"
+    Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+    All rights reserved.
+
+    See the file LICENSE.TXT for full copyright and licensing information.
+*/
+
+#include "rogue.h"
+
+/*
+    doctor()
+        A healing daemon that restors spell and hit points after rest
+*/
+
+void
+doctor(daemon_arg *who)
+{
+    struct thing *tp = who->thingptr;
+    long ohp;   /* turn off ISFLEE? */
+    struct stats *curp;  /* current stats pointer */
+    struct stats *maxp;  /* max stats pointer */
+    int         turns_quiet, new_points;
+
+    curp = &(tp->t_stats);
+    maxp = &(tp->maxstats);
+
+    if (on(*tp, ISINWALL))
+    {
+        tp->t_rest_hpt = 0;
+        return;
+    }
+
+    /* Check for regenerating spell points first */
+
+    doctor_spell_points(tp);
+
+    if (curp->s_hpt == maxp->s_hpt)
+    {
+        tp->t_rest_hpt = 0;
+        return;
+    }
+
+    tp->t_rest_hpt++;
+
+    switch (tp->t_ctype)
+    {
+        case C_MAGICIAN:
+        case C_ILLUSION:
+            turns_quiet = 24 - curp->s_lvl;
+            new_points = curp->s_lvl / 2 - 4;
+            break;
+
+        case C_THIEF:
+        case C_ASSASIN:
+        case C_NINJA:
+            turns_quiet = 16 - curp->s_lvl;
+            new_points = curp->s_lvl / 2 - 1;
+            break;
+
+        case C_CLERIC:
+        case C_DRUID:
+            turns_quiet = 16 - curp->s_lvl;
+            new_points = curp->s_lvl / 2 - 2;
+            break;
+
+        case C_FIGHTER:
+        case C_RANGER:
+        case C_PALADIN:
+            turns_quiet = 8 - curp->s_lvl / 2;
+            new_points = curp->s_lvl / 2 - 1;
+            break;
+
+        case C_MONSTER:
+            turns_quiet = 16 - curp->s_lvl;
+            new_points = curp->s_lvl / 2 - 6;
+            break;
+
+        default:
+            debug("What a strange character you are!");
+            return;
+    }
+
+    ohp = curp->s_hpt;
+
+    if (off(*tp, HASDISEASE))
+    {
+        if (curp->s_lvl < 8)
+        {
+            if (tp->t_rest_hpt > turns_quiet)
+                curp->s_hpt++;
+        }
+        else if (tp->t_rest_hpt >= 15)
+            curp->s_hpt += rnd(new_points) + 1;
+    }
+
+    if (tp == &player)
+    {
+        if (curp->s_lvl > 10)
+            turns_quiet = 2;
+        else
+            turns_quiet = rnd(turns_quiet / 6) + 1;
+
+        if (is_wearing(R_REGEN))
+            curp->s_hpt += ring_value(R_REGEN);
+    }
+
+    if (on(*tp, ISREGEN))
+        curp->s_hpt += curp->s_lvl / 5 + 1;
+
+    if (ohp != curp->s_hpt)
+    {
+        if (curp->s_hpt >= maxp->s_hpt)
+        {
+            curp->s_hpt = maxp->s_hpt;
+
+            if (off(*tp, WASTURNED) && on(*tp, ISFLEE)
+                && tp != &player)
+            {
+                turn_off(*tp, ISFLEE);
+                tp->t_oldpos = tp->t_pos;
+                /* Start our trek over */
+            }
+        }
+        tp->t_rest_hpt = 0;
+    }
+
+    return;
+}
+
+
+/*
+    doctor_spell_points()
+        A healing daemon that restors spell points
+*/
+
+void
+doctor_spell_points(struct thing *tp)
+{
+    int        turns_quiet, new_points;
+    struct stats *curp;   /* current stats pointer */
+    struct stats *maxp;   /* max stats pointer */
+    int         opower; /* current power */
+
+    curp = &(tp->t_stats);
+    maxp = &(tp->maxstats);
+    opower = curp->s_power;
+
+    /* The right ring will let you regenerate while wearing bad armor */
+
+    if (off(*tp, CANCAST) ||
+        ((tp == &player) &&
+         (cur_armor && wear_ok(tp, cur_armor, NOMESSAGE) == FALSE) &&
+         !(is_wearing(R_WIZARD) || is_wearing(R_PIETY))))
+    {
+        tp->t_rest_pow = 0;
+        return;
+    }
+
+    tp->t_rest_pow++;
+
+    switch (tp->t_ctype)
+    {
+        case C_MAGICIAN:
+        case C_ILLUSION:
+            turns_quiet = 18 - curp->s_lvl / 2;
+            new_points = curp->s_lvl / 2;
+            break;
+        case C_CLERIC:
+        case C_DRUID:
+            turns_quiet = 24 - curp->s_lvl;
+            new_points = curp->s_lvl / 2 - 2;
+            break;
+        case C_THIEF:
+        case C_ASSASIN:
+        case C_NINJA:
+            turns_quiet = 32 - curp->s_lvl;
+            new_points = curp->s_lvl / 3 - 3;
+            break;
+        case C_FIGHTER:
+        case C_RANGER:
+        case C_PALADIN:
+            turns_quiet = 32 - curp->s_lvl;
+            new_points = curp->s_lvl / 3 - 4;
+            break;
+        case C_MONSTER:
+            turns_quiet = 24 - curp->s_lvl;
+            new_points = curp->s_lvl - 6;
+            break;
+        default:
+            return;
+    }
+
+    if (curp->s_lvl < 8)
+    {
+        if (tp->t_rest_pow > turns_quiet)
+            curp->s_power++;
+    }
+    else if (tp->t_rest_pow >= 15)
+        curp->s_power += rnd(new_points) + 1;
+
+    if (tp == &player && (is_wearing(R_WIZARD) || is_wearing(R_PIETY)))
+        curp->s_power += ring_value(R_WIZARD) + ring_value(R_PIETY);
+
+    curp->s_power = min(max(0, curp->s_power), maxp->s_power);
+
+    if (curp->s_power != opower)
+        tp->t_rest_pow = 0;
+
+    return;
+}
+
+/*
+    rollwand()
+        called to roll to see if a wandering monster starts up
+*/
+
+daemon
+rollwand(daemon_arg *arg)
+{
+    NOOP(arg);
+
+    if ((rnd(6) == 0) && (player.t_ctype != C_THIEF ||
+        (rnd(30) >= pstats.s_dext)))
+    {
+        wanderer();
+        kill_daemon(DAEMON_ROLLWAND);
+        light_fuse(FUSE_SWANDER, 0, WANDERTIME, BEFORE);
+    }
+
+    return;
+}
+
+/*
+    stomach()
+        digest the hero's food
+*/
+
+daemon
+stomach(daemon_arg *arg)
+{
+    int oldfood, old_hunger;
+    int amount;
+    int power_scale;
+
+    NOOP(arg);
+
+    old_hunger = hungry_state;
+
+    if (food_left <= 0)
+    {
+        /* the hero is fainting */
+
+        if (no_command || rnd(100) > 20)
+            return;
+
+        no_command = rnd(8) + 4;
+        running = FALSE;
+        count = 0;
+        hungry_state = F_FAINT;
+        feed_me(hungry_state);
+    }
+    else
+    {
+        oldfood = food_left;
+
+        amount = ring_eat(LEFT_1) + ring_eat(LEFT_2) +
+            ring_eat(LEFT_3) + ring_eat(LEFT_4) +
+            ring_eat(RIGHT_1) + ring_eat(RIGHT_2) +
+            ring_eat(RIGHT_3) + ring_eat(RIGHT_4) +
+            foodlev;
+
+        if (on(player, SUPEREAT))   /* artifact or regeneration munchies */
+            amount *= 2;
+
+        if (on(player, POWEREAT))  /* Used an artifact power */
+        {
+            amount += 40;
+            turn_off(player, POWEREAT);
+        }
+
+        power_scale = (on(player, POWERDEXT) + on(player, POWERSTR) +
+            on(player, POWERWISDOM) + on(player, POWERINTEL) +
+            on(player, POWERCONST) + 1);
+
+        food_left -= amount * power_scale;
+
+        if (food_left < MORETIME && oldfood >= MORETIME)
+        {
+            hungry_state = F_WEAK;
+            running = FALSE;
+            feed_me(hungry_state);
+        }
+        else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
+        {
+            hungry_state = F_HUNGRY;
+            running = FALSE;
+            feed_me(hungry_state);
+        }
+    }
+
+    if (old_hunger != hungry_state)
+        updpack();
+
+    wghtchk(NULL);
+}
+
+
+/*
+    runners()