[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     ! 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