[BACK]Return to weapons.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / urogue

Annotation of early-roguelike/urogue/weapons.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     weapons.c - Functions for dealing with problems brought about by weapons
                      3:
                      4:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
                      5:     Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <ctype.h>
                     20: #include <string.h>
                     21: #include "rogue.h"
                     22:
                     23: /*
                     24:     missile()
                     25:         Fire a missile in a given direction
                     26: */
                     27:
                     28: void
                     29: missile(int ydelta, int xdelta, struct linked_list *item, struct thing *tp)
                     30: {
                     31:     struct object   *obj;
                     32:     struct linked_list  *nitem;
                     33:
                     34:     if (item == NULL)   /* Get which thing we are hurling */
                     35:         return;
                     36:
                     37:     obj = OBJPTR(item);
                     38:
                     39:     if (!dropcheck(obj) || is_current(obj))
                     40:         return;
                     41:
                     42:     /*
                     43:      * Get rid of the thing. If it is a non-multiple item object, or if
                     44:      * it is the last thing, just drop it. Otherwise, create a new item
                     45:      * with a count of one.
                     46:     */
                     47:
                     48:     if (obj->o_count < 2)
                     49:     {
                     50:         if (tp->t_pack == pack)
                     51:             rem_pack(obj);
                     52:         else
                     53:             detach(tp->t_pack, item);
                     54:     }
                     55:     else
                     56:     {
                     57:         obj->o_count--;
                     58:         nitem = (struct linked_list *) new_item(sizeof *obj);
                     59:         obj = OBJPTR(nitem);
                     60:         *obj = *(OBJPTR(item));
                     61:         obj->o_count = 1;
                     62:         item = nitem;
                     63:     }
                     64:
                     65:     switch (obj->o_type)
                     66:     {
                     67:         case ARTIFACT:
                     68:             has_artifact &= ~(1 << obj->o_which);
                     69:             break;
                     70:
                     71:         case SCROLL:
                     72:             if (obj->o_which == S_SCARE && obj->o_flags & ISBLESSED)
                     73:                 obj->o_flags &= ~ISBLESSED;
                     74:             else
                     75:                 obj->o_flags |= ISCURSED;
                     76:     }
                     77:
                     78:     updpack();
                     79:     obj->o_pos = do_motion(obj->o_type, ydelta, xdelta, tp);
                     80:
                     81:     /*
                     82:      * AHA! Here it has hit something. If it is a wall or a door, or if
                     83:      * it misses (combat) the monster, put it on the floor
                     84:      */
                     85:
                     86:     if (!hit_monster(obj->o_pos.y, obj->o_pos.x, obj, tp))
                     87:     {
                     88:         if (obj->o_type == WEAPON && obj->o_which == GRENADE)
                     89:         {
                     90:             hearmsg("BOOOM!");
                     91:             aggravate();
                     92:
                     93:             if (ntraps + 1 < 2 * MAXTRAPS &&
                     94:                 fallpos(obj->o_pos, &traps[ntraps].tr_pos))
                     95:             {
                     96:                 mvaddch(traps[ntraps].tr_pos.y, traps[ntraps].tr_pos.x,
                     97:                     TRAPDOOR);
                     98:                 traps[ntraps].tr_type = TRAPDOOR;
                     99:                 traps[ntraps].tr_flags = ISFOUND;
                    100:                 traps[ntraps].tr_show = TRAPDOOR;
                    101:                 ntraps++;
                    102:                 light(&hero);
                    103:             }
                    104:             discard(item);
                    105:         }
                    106:         else if (obj->o_flags & ISLOST)
                    107:         {
                    108:             if (obj->o_type == WEAPON)
                    109:                 addmsg("The %s", weaps[obj->o_which].w_name);
                    110:             else
                    111:                 addmsg(inv_name(obj, LOWERCASE));
                    112:
                    113:             msg(" vanishes in a puff of greasy smoke.");
                    114:             discard(item);
                    115:         }
                    116:         else
                    117:         {
                    118:             fall(&player, item, TRUE, TRUE);
                    119:
                    120:             if (obj->o_flags & CANRETURN)
                    121:                 msg("You have %s.", inv_name(obj, LOWERCASE));
                    122:         }
                    123:     }
                    124:     else if (obj->o_flags & ISOWNED)
                    125:     {
                    126:         add_pack(item, NOMESSAGE);
                    127:         msg("You have %s.", inv_name(obj, LOWERCASE));
                    128:     }
                    129:
                    130:     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    131: }
                    132:
                    133: /*
                    134:     do_motion()
                    135:         do the actual motion on the screen done by an object
                    136:         traveling across the room
                    137: */
                    138:
                    139: coord
                    140: do_motion(int ob, int ydelta, int xdelta, struct thing *tp)
                    141: {
                    142:     coord pos;
                    143:     /* Come fly with us ... */
                    144:
                    145:     pos = tp->t_pos;
                    146:
                    147:     for (;;)
                    148:     {
                    149:         int ch;
                    150:
                    151:         /* Erase the old one */
                    152:
                    153:         if (!ce(pos, tp->t_pos) &&
                    154:             cansee(pos.y, pos.x) &&
                    155:             mvwinch(cw, pos.y, pos.x) != ' ')
                    156:         {
                    157:             mvwaddch(cw, pos.y, pos.x, show(pos.y, pos.x));
                    158:         }
                    159:
                    160:         /* Get the new position */
                    161:
                    162:         pos.y += ydelta;
                    163:         pos.x += xdelta;
                    164:
                    165:         if (shoot_ok(ch = winat(pos.y, pos.x)) &&
                    166:             ch != DOOR && !ce(pos, hero))
                    167:         {
                    168:             /* It hasn't hit anything yet, so display it if it alright. */
                    169:
                    170:             if (cansee(pos.y, pos.x) &&
                    171:                 mvwinch(cw, pos.y, pos.x) != ' ')
                    172:             {
                    173:                 mvwaddch(cw, pos.y, pos.x, ob);
                    174:                 wrefresh(cw);
                    175:             }
                    176:
                    177:             continue;
                    178:
                    179:         }
                    180:         break;
                    181:     }
                    182:
                    183:     return(pos);
                    184: }
                    185:
                    186: /*
                    187:     fall()
                    188:         Drop an item someplace around here.
                    189: */
                    190:
                    191: void
                    192: fall(struct thing *tp, struct linked_list *item, int pr, int player_owned)
                    193: {
                    194:     struct object *obj;
                    195:     struct room   *rp;
                    196:     coord   fpos;
                    197:
                    198:     obj = OBJPTR(item);
                    199:     rp = roomin(tp->t_pos);
                    200:
                    201:     if (player_owned && obj->o_flags & CANRETURN)
                    202:     {
                    203:         add_pack(item, NOMESSAGE);
                    204:         msg("You have %s.", inv_name(obj, LOWERCASE));
                    205:         return;
                    206:     }
                    207:     else if (fallpos(obj->o_pos, &fpos))
                    208:     {
                    209:         if (obj->o_flags & CANBURN && obj->o_type == WEAPON
                    210:             && obj->o_which == MOLOTOV
                    211:             && ntraps + 1 < 2 * MAXTRAPS)
                    212:         {
                    213:             mvaddch(fpos.y, fpos.x, FIRETRAP);
                    214:             traps[ntraps].tr_type  = FIRETRAP;
                    215:             traps[ntraps].tr_flags = ISFOUND;
                    216:             traps[ntraps].tr_show  = FIRETRAP;
                    217:             traps[ntraps].tr_pos   = fpos;
                    218:             ntraps++;
                    219:
                    220:             if (rp != NULL)
                    221:                 rp->r_flags &= ~ISDARK;
                    222:         }
                    223:         else
                    224:         {
                    225:             obj->o_pos = fpos;
                    226:             add_obj(item, fpos.y, fpos.x);
                    227:         }
                    228:
                    229:         if (rp != NULL &&
                    230:             (!(rp->r_flags & ISDARK) ||
                    231:              (rp->r_flags & HASFIRE)))
                    232:         {
                    233:             light(&hero);
                    234:             mvwaddch(cw, hero.y, hero.x, PLAYER);
                    235:         }
                    236:         return;
                    237:     }
                    238:
                    239:     /* get here only if there isn't a place to put it */
                    240:
                    241:     if (pr)
                    242:     {
                    243:         if (cansee(obj->o_pos.y, obj->o_pos.x))
                    244:         {
                    245:             if (obj->o_type == WEAPON)
                    246:                 addmsg("The %s", weaps[obj->o_which].w_name);
                    247:             else
                    248:                 addmsg(inv_name(obj, LOWERCASE));
                    249:
                    250:             msg(" vanishes as it hits the ground.");
                    251:         }
                    252:     }
                    253:     discard(item);
                    254: }
                    255:
                    256: /*
                    257:     init_weapon()
                    258:         Set up the initial goodies for a weapon
                    259: */
                    260:
                    261: void
                    262: init_weapon(struct object *weap, int type)
                    263: {
                    264:     struct init_weps *iwp = &weaps[type];
                    265:
                    266:     weap->o_damage  = iwp->w_dam;
                    267:     weap->o_hurldmg = iwp->w_hrl;
                    268:     weap->o_launch  = iwp->w_launch;
                    269:     weap->o_flags   = iwp->w_flags;
                    270:     weap->o_weight  = iwp->w_wght;
                    271:
                    272:     if (weap->o_flags & ISMANY)
                    273:     {
                    274:         weap->o_count = rnd(8) + 8;
                    275:         weap->o_group = ++group;
                    276:     }
                    277:     else
                    278:         weap->o_count = 1;
                    279: }
                    280:
                    281: /*
                    282:     hit_monster()
                    283:         does the missile hit the target?
                    284: */
                    285:
                    286: int
                    287: hit_monster(int y, int x, struct object *weapon, struct thing *thrower)
                    288: {
                    289:     struct linked_list *mon;
                    290:     coord target;
                    291:
                    292:     target.y = y;
                    293:     target.x = x;
                    294:
                    295:     if (thrower == &player)
                    296:         return(fight(&target, weapon, THROWN));
                    297:
                    298:     if (ce(target, hero))
                    299:     {
                    300:         if (good_monster(*thrower))
                    301:         {
                    302:             if (on(*thrower, ISFAMILIAR))
                    303:                 msg("Please get out of the way, Master!  I nearly hit you.");
                    304:             else
                    305:                 msg("Get out of the way %s!", whoami);
                    306:
                    307:             return(FALSE);
                    308:         }
                    309:
                    310:         return(attack(thrower, weapon, THROWN));
                    311:     }
                    312:
                    313:     if ((mon = find_mons(y, x)) != NULL)
                    314:         return(mon_mon_attack(thrower, mon, weapon, THROWN));
                    315:     else
                    316:         return(FALSE);
                    317: }
                    318:
                    319:
                    320: /*
                    321:     num()
                    322:         Figure out the plus number for armor/weapons
                    323: */
                    324:
                    325: char *
                    326: num(int n1, int n2, char *buf)
                    327: {
                    328:     if (buf == NULL)
                    329:         return("UltraRogue Error #104");
                    330:
                    331:     if (n1 == 0 && n2 == 0)
                    332:     {
                    333:         strcpy(buf,"+0");
                    334:         return(buf);
                    335:     }
                    336:
                    337:     if (n2 == 0)
                    338:         sprintf(buf, "%s%d", n1 < 0 ? "" : "+", n1);
                    339:     else
                    340:         sprintf(buf, "%s%d, %s%d", n1 < 0 ? "" : "+",
                    341:             n1, n2 < 0 ? "" : "+", n2);
                    342:
                    343:     return(buf);
                    344: }
                    345:
                    346: /*
                    347:     wield()
                    348:         Pull out a certain weapon
                    349: */
                    350:
                    351: void
                    352: wield(void)
                    353: {
                    354:     struct linked_list *item;
                    355:     struct object *obj, *oweapon;
                    356:
                    357:     oweapon = cur_weapon;
                    358:
                    359:     if (!dropcheck(cur_weapon))
                    360:     {
                    361:         cur_weapon = oweapon;
                    362:         return;
                    363:     }
                    364:
                    365:     cur_weapon = oweapon;
                    366:
                    367:     if ((item = get_item("wield", WEAPON)) == NULL)
                    368:     {
                    369:         after = FALSE;
                    370:         return;
                    371:     }
                    372:
                    373:     obj = OBJPTR(item);
                    374:
                    375:     if (is_current(obj))
                    376:     {
                    377:         after = FALSE;
                    378:         return;
                    379:     }
                    380:
                    381:     wield_ok(&player, obj, TRUE);
                    382:
                    383:     msg("You are now wielding %s.", inv_name(obj, LOWERCASE));
                    384:
                    385:     cur_weapon = obj;
                    386: }
                    387:
                    388: /*
                    389:     fallpos()
                    390:         pick a random position around the given (y, x) coordinates
                    391: */
                    392:
                    393: int
                    394: fallpos(coord pos, coord *newpos) /*ARGSUSED*/
                    395: {
                    396:     int   y, x, cnt;
                    397:        coord places[9];
                    398:
                    399:     cnt = 0;
                    400:
                    401:     /* look for all the places that qualify */
                    402:
                    403:     for (y = pos.y - 1; y <= pos.y + 1; y++)
                    404:        {
                    405:         for (x = pos.x - 1; x <= pos.x + 1; x++)
                    406:         {
                    407:             switch(CCHAR(mvwinch(stdscr,y,x)))
                    408:             {
                    409:                 case GOLD:
                    410:                 case POTION:
                    411:                 case SCROLL:
                    412:                 case FOOD:
                    413:                 case WEAPON:
                    414:                 case ARMOR:
                    415:                 case RING:
                    416:                 case STICK:
                    417:                 case FLOOR:
                    418:                 case PASSAGE:
                    419:                 case ARTIFACT:
                    420:                     places[cnt].y = y;
                    421:                     places[cnt].x = x;
                    422:                     cnt++;
                    423:             }
                    424:         }
                    425:     }
                    426:
                    427:        /* now, pick one of the places, if there are any */
                    428:
                    429:     if (cnt > 0)
                    430:        {
                    431:         int which = rnd(cnt);
                    432:
                    433:         newpos->y = places[which].y;
                    434:         newpos->x = places[which].x;
                    435:
                    436:         debug("Dropping object at %d, %d", newpos->y, newpos->x);
                    437:     }
                    438:
                    439:     return(cnt);
                    440: }
                    441:
                    442: /*
                    443:     wield_ok()
                    444:         enforce player class weapons restrictions
                    445: */
                    446:
                    447: int
                    448: wield_ok(struct thing *wieldee, struct object *obj, int print_message)
                    449: {
                    450:     int ret_val = TRUE;
                    451:     int class_type = wieldee->t_ctype;
                    452:
                    453:     if (obj->o_type != WEAPON)
                    454:     {
                    455:         ret_val = FALSE;
                    456:         return(ret_val);
                    457:     }
                    458:     else
                    459:         switch (class_type)
                    460:         {
                    461:             case C_MAGICIAN: /* need one hand free */
                    462:             case C_ILLUSION:
                    463:                 if (obj->o_flags & ISTWOH)
                    464:                     ret_val = FALSE;
                    465:                 break;
                    466:
                    467:             case C_THIEF:    /* need portable weapon  */
                    468:             case C_ASSASIN:
                    469:             case C_NINJA:
                    470:                 if (obj->o_flags & ISTWOH)
                    471:                     ret_val = FALSE;
                    472:                 break;
                    473:
                    474:             case C_CLERIC:   /* No sharp weapons */
                    475:                 if (obj->o_flags & ISSHARP)
                    476:                     ret_val = FALSE;
                    477:                 break;
                    478:
                    479:             case C_DRUID:    /* No non-silver metal weapons */
                    480:                 if (obj->o_flags & ISMETAL && !(obj->o_flags & ISSILVER))
                    481:                     ret_val = FALSE;
                    482:                 break;
                    483:
                    484:             case C_PALADIN:  /* must wield sharp stuff */
                    485:                 if ((obj->o_flags & ISSHARP) == FALSE)
                    486:                     ret_val = FALSE;
                    487:                 break;
                    488:
                    489:             case C_FIGHTER:  /* wield anything */
                    490:             case C_RANGER:
                    491:             case C_MONSTER:
                    492:                 break;
                    493:
                    494:             default:  /* Unknown class */
                    495:                 debug("Unknown class %d.", class_type);
                    496:                 break;
                    497:         }
                    498:
                    499:     if (itemweight(obj) > 18 * pstats.s_str)
                    500:     {
                    501:         if (wieldee == &player && print_message == TRUE)
                    502:             msg("That is too heavy for you to swing effectively!");
                    503:
                    504:         ret_val = FALSE;
                    505:         return(ret_val);
                    506:     }
                    507:
                    508:     if (ret_val == FALSE && print_message == MESSAGE)
                    509:         switch (class_type)
                    510:         {
                    511:             case C_MAGICIAN:
                    512:             case C_ILLUSION:
                    513:                 msg("You'll find it hard to cast spells while wielding that!");
                    514:                 break;
                    515:
                    516:             case C_THIEF:
                    517:             case C_ASSASIN:
                    518:             case C_NINJA:
                    519:                 msg("Don't expect to backstab anyone while wielding that!");
                    520:                 break;
                    521:
                    522:             case C_CLERIC:
                    523:             case C_DRUID:
                    524:             case C_PALADIN:
                    525:                 msg("Your god strongly disapproves of your wielding that!");
                    526:                 break;
                    527:
                    528:             case C_FIGHTER:
                    529:             case C_RANGER:
                    530:             case C_MONSTER:
                    531:                 break;
                    532:         }
                    533:
                    534:     return(ret_val);
                    535: }
                    536:
                    537: /*
                    538:     shoot_ok()
                    539:         returns true if it is ok for type to shoot over ch
                    540: */
                    541:
                    542: int
                    543: shoot_ok(int ch)
                    544: {
                    545:     switch(ch)
                    546:     {
                    547:         case ' ':
                    548:         case '|':
                    549:         case '-':
                    550:         case SECRETDOOR:
                    551:             return(FALSE);
                    552:
                    553:         default:
                    554:             return(!isalpha(ch));
                    555:     }
                    556: }

CVSweb