|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 35194 (0x897a) Types: TextFile Names: »creature.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Umoria/creature.c.orig«
#include <stdio.h> #include "constants.h" #include "config.h" #include "types.h" #include "externs.h" #ifdef USG #include <string.h> #else #include <strings.h> #endif #ifdef sun /* correct SUN stupidity in the stdio.h file */ char *sprintf(); #endif extern int search_flag; extern int moria_flag; /* Updates screen when monsters move about -RAK- */ update_mon(monptr) int monptr; { int flag; char tmp_str[2]; register cave_type *c_ptr; register monster_type *m_ptr; register creature_type *r_ptr; m_ptr = &m_list[monptr]; c_ptr = &cave[m_ptr->fy][m_ptr->fx]; flag = FALSE; if (m_ptr->cdis <= MAX_SIGHT) if (py.flags.blind < 1) if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) /* Wizard sight... */ if (wizard2) flag = TRUE; /* Normal sight... */ else if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) { r_ptr = &c_list[m_ptr->mptr]; if ((c_ptr->pl) || (c_ptr->tl)) { if (py.flags.see_inv) flag = TRUE; else if ((0x10000 & r_ptr->cmove) == 0) flag = TRUE; } /* Infra vision... */ else if (py.flags.see_infra > 0) if (m_ptr->cdis <= py.flags.see_infra) if (0x2000 & r_ptr->cdefense) flag = TRUE; } /* Light it up... */ if (flag) { if (!m_ptr->ml) { tmp_str[0] = c_list[m_ptr->mptr].cchar; tmp_str[1] = '\0'; print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx); m_ptr->ml = TRUE; if (search_flag) search_off(); if (py.flags.rest > 0) rest_off(); flush(); if (find_flag) { find_flag = FALSE; move_light (char_row, char_col, char_row, char_col); } } } /* Turn it off... */ else if (m_ptr->ml) { m_ptr->ml = FALSE; if ((c_ptr->tl) || (c_ptr->pl)) lite_spot((int)m_ptr->fy, (int)m_ptr->fx); else unlite_spot((int)m_ptr->fy, (int)m_ptr->fx); } } /* Choose correct directions for monster movement -RAK- */ get_moves(monptr, mm) int monptr; register int *mm; { int y, ay, x, ax, move_val; y = m_list[monptr].fy - char_row; x = m_list[monptr].fx - char_col; if (y < 0) { move_val = 8; ay = -y; } else { move_val = 0; ay = y; } if (x > 0) { move_val += 4; ax = x; } else ax = -x; if (ay > (ax*1.7321)) move_val += 2; else if (ax > (ay*1.7321)) move_val++; switch(move_val) { case 0: mm[0] = 9; if (ay > ax) { mm[1] = 8; mm[2] = 6; mm[3] = 7; mm[4] = 3; } else { mm[1] = 6; mm[2] = 8; mm[3] = 3; mm[4] = 7; } break; case 1: case 9: mm[0] = 6; if (y < 0) { mm[1] = 3; mm[2] = 9; mm[3] = 2; mm[4] = 8; } else { mm[1] = 9; mm[2] = 3; mm[3] = 8; mm[4] = 2; } break; case 2: case 6: mm[0] = 8; if (x < 0) { mm[1] = 9; mm[2] = 7; mm[3] = 6; mm[4] = 4; } else { mm[1] = 7; mm[2] = 9; mm[3] = 4; mm[4] = 6; } break; case 4: mm[0] = 7; if (ay > ax) { mm[1] = 8; mm[2] = 4; mm[3] = 9; mm[4] = 1; } else { mm[1] = 4; mm[2] = 8; mm[3] = 1; mm[4] = 9; } break; case 5: case 13: mm[0] = 4; if (y < 0) { mm[1] = 1; mm[2] = 7; mm[3] = 8; mm[4] = 2; } else { mm[1] = 7; mm[2] = 1; mm[3] = 2; mm[4] = 8; } break; case 8: mm[0] = 3; if (ay > ax) { mm[1] = 2; mm[2] = 6; mm[3] = 1; mm[4] = 9; } else { mm[1] = 6; mm[2] = 2; mm[3] = 9; mm[4] = 1; } break; case 10: case 14: mm[0] = 2; if (x < 0) { mm[1] = 1; mm[2] = 3; mm[3] = 4; mm[4] = 6; } else { mm[1] = 3; mm[2] = 1; mm[3] = 6; mm[4] = 4; } break; case 12: mm[0] = 1; if (ay > ax) { mm[1] = 2; mm[2] = 4; mm[3] = 3; mm[4] = 7; } else { mm[1] = 4; mm[2] = 2; mm[3] = 7; mm[4] = 3; } break; } } /* Make an attack on the player (chuckle...) -RAK- */ make_attack(monptr) int monptr; { int xpos, attype, adesc, dam; int i, j, l; vtype attstr, attx; vtype cdesc, ddesc, tmp_str; dtype damstr; int flag; register creature_type *c_ptr; monster_type *m_ptr; register struct misc *p_ptr; register struct flags *f_ptr; register treasure_type *i_ptr; char *string; m_ptr = &m_list[monptr]; c_ptr = &c_list[m_ptr->mptr]; (void) strcpy(attstr, c_ptr->damage); if ((0x10000 & c_ptr->cmove) && (!py.flags.see_inv)) (void) strcpy(cdesc, "It "); else if (py.flags.blind > 0) (void) strcpy(cdesc, "It "); else if (!m_ptr->ml) (void) strcpy(cdesc, "It "); else (void) sprintf(cdesc, "The %s ", c_ptr->name); /* For "DIED_FROM" string */ if (0x80000000 & c_ptr->cmove) (void) sprintf(ddesc, "The %s", c_ptr->name); else (void) sprintf(ddesc, "& %s", c_ptr->name); (void) strcpy(inventory[INVEN_MAX].name, ddesc); inventory[INVEN_MAX].number = 1; objdes(ddesc, INVEN_MAX, TRUE); /* End DIED_FROM */ while (strlen(attstr) > 0) { string = index(attstr, '|'); if (string) xpos = strlen(attstr) - strlen(string); else xpos = -1; if (xpos >= 0) { (void) strncpy(attx, attstr, xpos); attx[xpos] = '\0'; (void) strcpy(attstr, &attstr[xpos+1]); } else { (void) strcpy(attx, attstr); attstr[0] = '\0'; } (void) sscanf(attx, "%d %d %s", &attype, &adesc, damstr); flag = FALSE; if (py.flags.protevil > 0) if (c_ptr->cdefense & 0x0004) if ((py.misc.lev + 1) > c_ptr->level) { attype = 99; adesc = 99; } p_ptr = &py.misc; switch(attype) { case 1: /*Normal attack */ if (test_hit(60, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 2: /*Poison Strength*/ if (test_hit(-3, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 3: /*Confusion attack*/ if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 4: /*Fear attack */ if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 5: /*Fire attack */ if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 6: /*Acid attack */ if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 7: /*Cold attack */ if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 8: /*Lightning attack*/ if (test_hit(10, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 9: /*Corrosion attack*/ if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 10: /*Blindness attack*/ if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 11: /*Paralysis attack*/ if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 12: /*Steal Money */ if (test_hit(5, (int)c_ptr->level, 0, (int)py.misc.lev)) if (py.misc.au > 0) flag = TRUE; break; case 13: /*Steal Object */ if (test_hit(2, (int)c_ptr->level, 0, (int)py.misc.lev)) if (inven_ctr > 0) flag = TRUE; break; case 14: /*Poison */ if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 15: /*Lose dexterity*/ if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 16: /*Lose constitution*/ if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 17: /*Lose intelligence*/ if (test_hit(2, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 18: /*Lose wisdom*/ if (test_hit(0, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 19: /*Lose experience*/ if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 20: /*Aggravate monsters*/ flag = TRUE; break; case 21: /*Disenchant */ if (test_hit(20, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 22: /*Eat food */ if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 23: /*Eat light */ if (test_hit(5, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 24: /*Eat charges */ if (test_hit(15, (int)c_ptr->level, 0, p_ptr->pac+p_ptr->ptoac)) flag = TRUE; break; case 99: flag = TRUE; break; default: break; } if (flag) { /* can not strcat to cdesc because the creature may have multiple attacks */ (void) strcpy(tmp_str, cdesc); switch(adesc) { case 1: msg_print(strcat(tmp_str, "hits you.")); break; case 2: msg_print(strcat(tmp_str, "bites you.")); break; case 3: msg_print(strcat(tmp_str, "claws you.")); break; case 4: msg_print(strcat(tmp_str, "stings you.")); break; case 5: msg_print(strcat(tmp_str, "touches you.")); break; case 6: msg_print(strcat(tmp_str, "kicks you.")); break; case 7: msg_print(strcat(tmp_str, "gazes at you.")); break; case 8: msg_print(strcat(tmp_str, "breathes on you.")); break; case 9: msg_print(strcat(tmp_str, "spits on you.")); break; case 10: msg_print(strcat(tmp_str,"makes a horrible wail."));break; case 11: msg_print(strcat(tmp_str, "embraces you.")); break; case 12: msg_print(strcat(tmp_str, "crawls on you.")); break; case 13: msg_print(strcat(tmp_str, "releases a cloud of spores.")); break; case 14: msg_print(strcat(tmp_str, "begs you for money.")); break; case 15: msg_print("You've been slimed!"); break; case 16: msg_print(strcat(tmp_str, "crushes you.")); break; case 17: msg_print(strcat(tmp_str, "tramples you.")); break; case 18: msg_print(strcat(tmp_str, "drools on you.")); break; case 19: switch(randint(9)) { case 1: msg_print(strcat(tmp_str, "insults you!")); break; case 2: msg_print(strcat(tmp_str, "insults your mother!")); break; case 3: msg_print(strcat(tmp_str, "gives you the finger!")); break; case 4: msg_print(strcat(tmp_str, "humiliates you!")); break; case 5: msg_print(strcat(tmp_str, "wets on your leg!")); break; case 6: msg_print(strcat(tmp_str, "defiles you!")); break; case 7: msg_print(strcat(tmp_str, "dances around you!"));break; case 8: msg_print(strcat(tmp_str, "makes obscene gestures!")); break; case 9: msg_print(strcat(tmp_str, "moons you!!!")); break; } break; case 99: msg_print(strcat(tmp_str, "is repelled.")); break; default: break; } switch(attype) { case 1: /*Normal attack */ dam = damroll(damstr); dam -= (int)((((p_ptr->pac+p_ptr->ptoac)/200.0)*dam)+.5); take_hit(dam, ddesc); prt_chp(); break; case 2: /*Poison Strength*/ take_hit(damroll(damstr), ddesc); if (py.flags.sustain_str) msg_print("You feel weaker for a moment, it passes."); else if (randint(2) == 1) { msg_print("You feel weaker."); py.stats.cstr = de_statp(py.stats.cstr); prt_strength(); /* adjust misc stats */ py_bonuses(blank_treasure, 0); } prt_chp(); break; case 3: /*Confusion attack*/ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (randint(2) == 1) { if (f_ptr->confused < 1) { msg_print("You feel confused."); f_ptr->confused += randint((int)c_ptr->level); } f_ptr->confused += 3; } prt_chp(); break; case 4: /*Fear attack */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (player_saves(wis_adj())) msg_print("You resist the effects!"); else if (f_ptr->afraid < 1) { msg_print("You are suddenly afraid!"); f_ptr->afraid += 3 + randint((int)c_ptr->level); } else f_ptr->afraid += 3; prt_chp(); break; case 5: /*Fire attack */ msg_print("You are enveloped in flames!"); fire_dam(damroll(damstr), ddesc); break; case 6: /*Acid attack */ msg_print("You are covered in acid!"); acid_dam(damroll(damstr), ddesc); break; case 7: /*Cold attack */ msg_print("You are covered with frost!"); cold_dam(damroll(damstr), ddesc); break; case 8: /*Lightning attack*/ msg_print("Lightning strikes you!"); light_dam(damroll(damstr), ddesc); break; case 9: /*Corrosion attack*/ msg_print("A stinging red gas swirls about you."); corrode_gas(ddesc); take_hit(damroll(damstr), ddesc); prt_chp(); break; case 10: /*Blindness attack*/ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (f_ptr->blind < 1) { f_ptr->blind += 10 + randint((int)c_ptr->level); msg_print("Your eyes begin to sting."); } f_ptr->blind += 5; prt_chp(); break; case 11: /*Paralysis attack*/ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (player_saves(con_adj())) msg_print("You resist the effects!"); else if (f_ptr->paralysis < 1) { if (f_ptr->free_act) msg_print("You are unaffected."); else { f_ptr->paralysis = randint((int)c_ptr->level) + 3; msg_print("You are paralyzed."); } } prt_chp(); break; case 12: /*Steal Money */ if ((randint(124) < py.stats.cdex) && (py.flags.paralysis < 1)) msg_print("You quickly protect your money pouch!"); else { i = (p_ptr->au/10) + randint(25); if (i > p_ptr->au) p_ptr->au = 0; else p_ptr->au -= i; msg_print("Your purse feels lighter."); prt_gold(); } if (randint(2) == 1) { msg_print("There is a puff of smoke!"); teleport_away(monptr, MAX_SIGHT); } break; case 13: /*Steal Object */ if ((randint(124) < py.stats.cdex) && (py.flags.paralysis < 1)) msg_print("You grab hold of your backpack!"); else { i = randint(inven_ctr) - 1; inven_destroy(i); msg_print("Your backpack feels lighter."); } if (randint(2) == 1) { msg_print("There is a puff of smoke!"); teleport_away(monptr, MAX_SIGHT); } break; case 14: /*Poison */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); prt_chp(); msg_print("You feel very sick."); f_ptr->poisoned += randint((int)c_ptr->level)+5; break; case 15: /*Lose dexterity */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (f_ptr->sustain_dex) msg_print("You feel clumsy for a moment, it passes."); else { msg_print("You feel more clumsy."); py.stats.cdex = de_statp(py.stats.cdex); prt_dexterity(); /* adjust misc stats */ py_bonuses(blank_treasure, 0); } prt_chp(); break; case 16: /*Lose constitution */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (f_ptr->sustain_con) msg_print("Your body resists the effects of the disease."); else { msg_print("Your health is damaged!"); py.stats.ccon = de_statp(py.stats.ccon); prt_constitution(); } prt_chp(); break; case 17: /*Lose intelligence */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (f_ptr->sustain_int) { msg_print("You feel your memories fading..."); msg_print("Your memories are suddenly restored!"); } else { msg_print("You feel your memories fading..."); py.stats.cint = de_statp(py.stats.cint); prt_intelligence(); } prt_chp(); break; case 18: /*Lose wisdom */ f_ptr = &py.flags; take_hit(damroll(damstr), ddesc); if (f_ptr->sustain_wis) msg_print("Your wisdom is sustained."); else { msg_print("Your wisdom is drained."); py.stats.cwis = de_statp(py.stats.cwis); prt_wisdom(); } prt_chp(); break; case 19: /*Lose experience */ msg_print("You feel your life draining away!"); i = damroll(damstr) + (py.misc.exp / 100)*MON_DRAIN_LIFE; lose_exp(i); break; case 20: /*Aggravate monster*/ (void) aggravate_monster(5); break; case 21: /*Disenchant */ flag = FALSE; switch(randint(7)) { case 1: i = INVEN_WIELD; break; case 2: i = INVEN_BODY; break; case 3: i = INVEN_ARM; break; case 4: i = INVEN_OUTER; break; case 5: i = INVEN_HANDS; break; case 6: i = INVEN_HEAD; break; case 7: i = INVEN_FEET; break; } i_ptr = &inventory[i]; if (i_ptr->tohit > 0) { i_ptr->tohit -= randint(2); flag = TRUE; } if (i_ptr->todam > 0) { i_ptr->todam -= randint(2); flag = TRUE; } if (i_ptr->toac > 0) { i_ptr->toac -= randint(2); flag = TRUE; } if (flag) { msg_print("There is a static feeling in the air..."); py_bonuses(blank_treasure, 1); } break; case 22: /*Eat food */ if (find_range(80, -1, &i, &j)) inven_destroy(i); break; case 23: /*Eat light */ i_ptr = &inventory[INVEN_LIGHT]; if (i_ptr->p1 > 0) { i_ptr->p1 -= (250 + randint(250)); if (i_ptr->p1 < 1) i_ptr->p1 = 1; msg_print("Your light dims..."); } break; case 24: /*Eat charges */ i = randint(inven_ctr) - 1; l = c_ptr->level; i_ptr = &inventory[i]; if ((i_ptr->tval == 55) || (i_ptr->tval == 60) || (i_ptr->tval == 65)) if (i_ptr->p1 > 0) { m_ptr->hp += l*i_ptr->p1; i_ptr->p1 = 0; msg_print("Energy drains from your pack!"); } break; case 99: break; default: break; } } else switch(adesc) { case 1: case 2: case 3: case 6: (void) strcpy(tmp_str, cdesc); msg_print(strcat(tmp_str, "misses you.")); break; default: break; } } } /* Make the move if possible, five choices -RAK- */ int make_move(monptr, mm) int monptr; int *mm; { int i, j, newy, newx; unsigned int movebits; int flag, tflag; int res; register cave_type *c_ptr; register monster_type *m_ptr; register treasure_type *t_ptr; register creature_type *r_ptr; char tmp_str[80]; vtype m_name; i = 0; flag = FALSE; res = FALSE; movebits = c_list[m_list[monptr].mptr].cmove; do { /* Get new position */ newy = m_list[monptr].fy; newx = m_list[monptr].fx; (void) move(mm[i], &newy, &newx); c_ptr = &cave[newy][newx]; if (c_ptr->fval != 15) { tflag = FALSE; /* Floor is open? */ if (c_ptr->fopen) tflag = TRUE; /* Creature moves through walls? */ else if (movebits & 0x40000) tflag = TRUE; /* Creature can open doors? */ else if (c_ptr->tptr != 0) { t_ptr = &t_list[c_ptr->tptr]; m_ptr = &m_list[monptr]; if (movebits & 0x20000) { /* Creature can open doors... */ switch(t_ptr->tval) { case 105: /* Closed doors... */ if (t_ptr->p1 == 0) /* Closed doors */ { tflag = TRUE; if (los(char_row, char_col, newy, newx)) { t_list[c_ptr->tptr] = door_list[0]; c_ptr->fopen = TRUE; lite_spot(newy, newx); tflag = FALSE; } } else if (t_ptr->p1 > 0) /* Locked doors */ { if (randint(100-t_ptr->level) < 5) t_ptr->p1 = 0; } else if (t_ptr->p1 < 0) /* Stuck doors */ { if (randint(m_ptr->hp+1) > (10+abs(t_ptr->p1))) t_ptr->p1 = 0; } break; case 109: /* Secret doors... */ tflag = TRUE; if (los(char_row, char_col, newy, newx)) { t_list[c_ptr->tptr] = door_list[0]; c_ptr->fopen = TRUE; lite_spot(newy, newx); tflag = FALSE; } break; default: break; } } else { /* Creature can not open doors, must bash them */ switch(t_ptr->tval) { case 105: /* Closed doors... */ j = abs(t_ptr->p1) + 20; if (randint(m_ptr->hp+1) > j) { tflag = TRUE; if (los(char_row, char_col, newy, newx)) { t_list[c_ptr->tptr] = door_list[0]; t_list[c_ptr->tptr].p1 = randint(2) - 1; c_ptr->fopen = TRUE; lite_spot(newy, newx); tflag = FALSE; } } break; case 109: /* Secret doors... */ break; default: break; } } } /* Glyph of warding present? */ if (tflag) /* Scare Monster trap */ if (c_ptr->tptr != 0) if (t_list[c_ptr->tptr].tval == 102) if (t_list[c_ptr->tptr].subval == 99) { if (randint(OBJ_RUNE_PROT) < c_list[m_list[monptr].mptr].level) { if ((newy==char_row) && (newx==char_col)) msg_print("The rune of protection is broken!"); (void) delete_object(newy, newx); } else tflag = FALSE; } /* Creature has attempted to move on player? */ if (tflag) if (c_ptr->cptr == 1) { if (!m_list[monptr].ml) update_mon(monptr); if (search_flag) search_off(); if (py.flags.rest > 0) rest_off(); if (find_flag) { find_flag = FALSE; move_light (char_row, char_col, char_row, char_col); } flush(); make_attack(monptr); /* Player has read a Confuse Monster? */ /* Monster gets a saving throw... */ if (py.flags.confuse_monster) { m_ptr = &m_list[monptr]; r_ptr = &c_list[m_ptr->mptr]; msg_print("Your hands stop glowing."); py.flags.confuse_monster = FALSE; /* Does the player know what he's fighting? */ if ((0x10000 & r_ptr->cmove) && (!py.flags.see_inv)) (void) strcpy(m_name, "It"); else if (py.flags.blind > 0) (void) strcpy(m_name, "It"); else if (!m_ptr->ml) (void) strcpy(m_name, "It"); else (void) sprintf(m_name, "The %s", r_ptr->name); if ((randint(MAX_MONS_LEVEL) < r_ptr->level) || (0x1000 & r_ptr->cdefense)) { (void) sprintf(tmp_str, "%s is unaffected.", m_name); msg_print(tmp_str); } else { (void) sprintf(tmp_str, "%s appears confused.", m_name); msg_print(tmp_str); m_ptr->confused = TRUE; } } tflag = FALSE; flag = TRUE; } /* Creature is attempting to move on other creature? */ else if ((c_ptr->cptr > 1) && ((newy != m_list[monptr].fy) || (newx != m_list[monptr].fx))) { /* Creature eats other creatures? */ if (movebits & 0x80000) delete_monster((int)c_ptr->cptr); else tflag = FALSE; } /* Creature has been allowed move... */ if (tflag) { m_ptr = &m_list[monptr]; /* Pick up or eat an object */ if (movebits & 0x100000) { c_ptr = &cave[newy][newx]; if (c_ptr->tptr != 0) if (t_list[c_ptr->tptr].tval < 100) (void) delete_object(newy, newx); } /* Move creature record */ move_rec((int)m_ptr->fy, (int)m_ptr->fx, newy, newx); m_ptr->fy = newy; m_ptr->fx = newx; flag = TRUE; res = TRUE; } } i++; /* Up to 5 attempts at moving, give up... */ } while ((!flag) && (i < 5)); return(res); } /* Creatures can cast spells too. (Dragon Breath) -RAK- */ /* cast_spell = true if creature changes position */ /* took_turn = true if creature casts a spell */ int mon_cast_spell(monptr, took_turn) int monptr; int *took_turn; { unsigned int i; int y, x; register int k; int chance, thrown_spell; double r1; int spell_choice[30]; vtype cdesc, ddesc, outval; int flag; register monster_type *m_ptr; register creature_type *r_ptr; int cast; m_ptr = &m_list[monptr]; r_ptr = &c_list[m_ptr->mptr]; chance = (int)((r_ptr->spells & 0x0000000F)); /* 1 in x chance of casting spell */ if (randint(chance) != 1) { cast = FALSE; *took_turn = FALSE; } /* Must be within certain range */ else if (m_ptr->cdis > MAX_SPELL_DIS) { cast = FALSE; *took_turn = FALSE; } /* Must have unobstructed Line-Of-Sight */ else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) { cast = FALSE; *took_turn = FALSE; } else /* Creature is going to cast a spell */ { *took_turn = TRUE; cast = TRUE; /* Describe the attack */ flag = TRUE; if (!m_ptr->ml) flag = FALSE; else if ((0x10000 & c_list[m_ptr->mptr].cmove) && (!py.flags.see_inv)) flag = FALSE; else if (py.flags.blind > 0) flag = FALSE; if (flag) (void) sprintf(cdesc, "The %s ", r_ptr->name); else (void) strcpy(cdesc, "It "); /* For "DIED_FROM" string */ if (0x80000000 & r_ptr->cmove) (void) sprintf(ddesc, "The %s", r_ptr->name); else (void) sprintf(ddesc, "& %s", r_ptr->name); (void) strcpy(inventory[INVEN_MAX].name, ddesc); inventory[INVEN_MAX].number = 1; objdes(ddesc, INVEN_MAX, TRUE); /* End DIED_FROM */ /* Extract all possible spells into spell_choice */ i = (r_ptr->spells & 0xFFFFFFF0); k = 0; while (i != 0) { spell_choice[k] = bit_pos(&i); k++; } /* Choose a spell to cast */ thrown_spell = spell_choice[randint(k) - 1]; thrown_spell++; /* Cast the spell... */ switch(thrown_spell) { case 5: /*Teleport Short*/ teleport_away(monptr, 5); break; case 6: /*Teleport Long */ teleport_away(monptr, MAX_SIGHT); break; case 7: /*Teleport To */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); teleport_to((int)m_ptr->fy, (int)m_ptr->fx); break; case 8: /*Light Wound */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else take_hit(damroll("3d8"), ddesc); break; case 9: /*Serious Wound */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else take_hit(damroll("8d8"), ddesc); break; case 10: /*Hold Person */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (py.flags.free_act) msg_print("You are unaffected..."); else if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else if (py.flags.paralysis > 0) py.flags.paralysis += 2; else py.flags.paralysis = randint(5)+4; break; case 11: /*Cause Blindness*/ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else if (py.flags.blind > 0) py.flags.blind += 6; else py.flags.blind += 12 + randint(3); break; case 12: /*Cause Confuse */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else if (py.flags.confused > 0) py.flags.confused += 2; else py.flags.confused = randint(5) + 3; break; case 13: /*Cause Fear */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else if (py.flags.afraid > 0) py.flags.afraid += 2; else py.flags.afraid = randint(5) + 3; break; case 14: /*Summon Monster*/ (void) strcat(cdesc, "magically summons a monster!"); msg_print(cdesc); y = char_row; x = char_col; (void) summon_monster(&y, &x, FALSE); check_mon_lite(y, x); break; case 15: /*Summon Undead*/ (void) strcat(cdesc, "magically summons an undead!"); msg_print(cdesc); y = char_row; x = char_col; (void) summon_undead(&y, &x); check_mon_lite(y, x); break; case 16: /*Slow Person */ (void) strcat(cdesc, "casts a spell."); msg_print(cdesc); if (py.flags.free_act) msg_print("You are unaffected..."); else if (player_saves(wis_adj())) msg_print("You resist the effects of the spell."); else if (py.flags.slow > 0) py.flags.slow += 2; else py.flags.slow = randint(5) + 3; break; case 17: /*Drain Mana */ if ((py.misc.cmana) > 0) { (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc); msg_print(outval); if (flag) { (void) sprintf(outval, "%sappears healthier...", cdesc); msg_print(outval); } r1 = ( randint((int)r_ptr->level) / 2 ) + 1; if (r1 > py.misc.cmana) r1 = py.misc.cmana; py.misc.cmana -= r1; m_ptr->hp += 6*(r1); } break; case 20: /*Breath Light */ (void) strcat(cdesc, "breathes lightning."); msg_print(cdesc); breath(1, char_row, char_col, (int)(m_ptr->hp/4.0), ddesc); break; case 21: /*Breath Gas */ (void) strcat(cdesc, "breathes gas."); msg_print(cdesc); breath(2, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc); break; case 22: /*Breath Acid */ (void) strcat(cdesc, "breathes acid."); msg_print(cdesc); breath(3, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc); break; case 23: /*Breath Frost */ (void) strcat(cdesc, "breathes frost."); msg_print(cdesc); breath(4, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc); break; case 24: /*Breath Fire */ (void) strcat(cdesc, "breathes fire."); msg_print(cdesc); breath(5, char_row, char_col, (int)(m_ptr->hp/3.0), ddesc); break; default: msg_print("Creature cast unknown spell."); cdesc[0] = '\0'; } /* End of spells */ } return(cast); } /* Move the critters about the dungeon -RAK- */ int mon_move(monptr) int monptr; { register int i, j; int k; int move_test; int movem; register creature_type *c_ptr; register monster_type *m_ptr; int mm[5]; /* Main procedure for monster movement (MON_MOVE) -RAK- */ movem = FALSE; c_ptr = &c_list[m_list[monptr].mptr]; /* Does the critter multiply? */ if (c_ptr->cmove & 0x00200000) if (MAX_MON_MULT >= mon_tot_mult) if ((py.flags.rest % MON_MULT_ADJ) == 0) { m_ptr = &m_list[monptr]; k = 0; for (i = m_ptr->fy-1; i <= m_ptr->fy+1; i++) for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++) if (in_bounds(i, j)) if (cave[i][j].cptr > 1) k++; /* can't call randint with a value of zero, increment counter to allow creature multiplication */ if (k == 0) k++; if (k < 4) if (randint(k*MON_MULT_ADJ) == 1) multiply_monster((int)m_ptr->fy, (int)m_ptr->fx, (int)m_ptr->mptr, FALSE); } /* Creature is confused? Chance it becomes un-confused */ move_test = FALSE; if (m_list[monptr].confused) { mm[0] = randint(9); mm[1] = randint(9); mm[2] = randint(9); mm[3] = randint(9); mm[4] = randint(9); /* don't move him if he is not supposed to move! */ if (!(c_ptr->cmove & 0x00000001)) movem = make_move(monptr, mm); if (randint(8) == 1) m_list[monptr].confused = FALSE; move_test = TRUE; } /* Creature may cast a spell */ else if (c_ptr->spells != 0) movem = mon_cast_spell(monptr, &move_test); if (!move_test) { /* 75% random movement */ if ((randint(100) < 75) && (c_ptr->cmove & 0x00000020)) { mm[0] = randint(9); mm[1] = randint(9); mm[2] = randint(9); mm[3] = randint(9); mm[4] = randint(9); movem = make_move(monptr, mm); } /* 40% random movement */ else if ((randint(100) < 40) && (c_ptr->cmove & 0x00000010)) { mm[0] = randint(9); mm[1] = randint(9); mm[2] = randint(9); mm[3] = randint(9); mm[4] = randint(9); movem = make_move(monptr, mm); } /* 20% random movement */ else if ((randint(100) < 20) && (c_ptr->cmove & 0x00000008)) { mm[0] = randint(9); mm[1] = randint(9); mm[2] = randint(9); mm[3] = randint(9); mm[4] = randint(9); movem = make_move(monptr, mm); } /* Normal movement */ else if (c_ptr->cmove & 0x00000002) { if (randint(200) == 1) { mm[0] = randint(9); mm[1] = randint(9); mm[2] = randint(9); mm[3] = randint(9); mm[4] = randint(9); } else get_moves(monptr, mm); movem = make_move(monptr, mm); } /* Attack, but don't move */ else if (c_ptr->cmove & 0x00000001) if (m_list[monptr].cdis < 2) { get_moves(monptr, mm); movem = make_move(monptr, mm); } } return(movem); } /* Creatures movement and attacking are done from here -RAK- */ creatures(attack) int attack; { register int i, j, k; int moldy, moldx; register monster_type *m_ptr; /* Main procedure for creatures -RAK- */ /* Process the monsters */ i = muptr; while ((i > 0) && (!moria_flag)) { m_ptr = &m_list[i]; m_ptr->cdis = distance(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx); if (attack) /* Attack is argument passed to CREATURE*/ { k = movement_rate(m_ptr->cspeed); if (k > 0) for (j = 0; j < movement_rate(m_ptr->cspeed); j++) { if ((m_ptr->cdis <= c_list[m_ptr->mptr].aaf) || (m_ptr->ml)) { if (m_ptr->csleep > 0) if (py.flags.aggravate) m_ptr->csleep = 0; else if (py.flags.rest < 1) if (randint(10) > py.misc.stl) m_ptr->csleep -= (75.0/m_ptr->cdis); if (m_ptr->stunned > 0) m_ptr->stunned--; if ((m_ptr->csleep <= 0) && (m_ptr->stunned <= 0)) { moldy = m_ptr->fy; moldx = m_ptr->fx; if (mon_move(i)) if (m_ptr->ml) { m_ptr->ml = FALSE; if (test_light(moldy, moldx)) lite_spot(moldy, moldx); else unlite_spot(moldy, moldx); } } } update_mon(i); } else update_mon(i); } else update_mon(i); i = m_list[i].nptr; } /* End processing monsters */ }