History

age items when they are on the floor; make equipment menu; different armor types occupy different slots

mischief committed 11 years ago

Commit 145a76b1 parent 348199a6 files · +173 −73Browse files

Unified · Split

6 files
  1. dat.h +15 −6
  2. item.c +7 −0
  3. item.ndb +9 −1
  4. levelgen.c +35 −3
  5. monst.c +62 −42
  6. ui.c +45 −21
dat.h+15−6
@@ -51,6 +51,8 @@ enum · 50 unmodified lines
51{51{
52 /* possible item types */52 /* possible item types */
53 IWEAPON = 0,53 IWEAPON = 0,
54 IHELMET,
55 ISHIELD,
54 IARMOR,56 IARMOR,
55 57
56 /* item flags */58 /* item flags */
@@ -82,10 +84,18 @@ struct ItemData · 25 unmodified lines
82 int flags;84 int flags;
83};85};
84 86
87enum
88{
89 IMAXAGE = 250,
90};
91
85struct Item92struct Item
86{93{
87 Ref ref;94 Ref ref;
88 95
96 /* age, for automatic deletion */
97 int age;
98
89 /* count of items in stack */99 /* count of items in stack */
90 int count;100 int count;
91 101
@@ -215,10 +225,11 @@ struct Monster · 123 unmodified lines
215 /* inventory */225 /* inventory */
216 ItemList inv;226 ItemList inv;
217 227
218 /* equipped weapon */228 /* equipped weapon & armor */
219 Item *weapon;229 Item *weapon;
220 /* equipped armor */230 Item *helmet;
221 ItemList armor;231 Item *shield;
232 Item *armor;
222 233
223 /* no free */234 /* no free */
224 MonsterData *md;235 MonsterData *md;
@@ -234,9 +245,7 @@ void mpushstate(Monster *m, AIState *a); · 9 unmodified lines
234AIState *mpopstate(Monster *m);245AIState *mpopstate(Monster *m);
235int maction(Monster *m, int what, Point where);246int maction(Monster *m, int what, Point where);
236int mwield(Monster *m, int n);247int mwield(Monster *m, int n);
237int munwield(Monster *m);248int munwield(Monster *m, int type);
238int mwear(Monster *m, int n);
239void mnaked(Monster *m);
240void maddinv(Monster *m, Item *i);249void maddinv(Monster *m, Item *i);
241int xpcalc(int level);250int xpcalc(int level);
242 251
item.c+7−0
@@ -32,6 +32,8 @@ static char *itemdbcmd[] = { · 31 unmodified lines
32 32
33static char *itemtype[] = {33static char *itemtype[] = {
34[IWEAPON] "weapon",34[IWEAPON] "weapon",
35[IHELMET] "helmet",
36[ISHIELD] "shield",
35[IARMOR] "armor",37[IARMOR] "armor",
36};38};
37 39
@@ -55,6 +57,8 @@ ifmt(Fmt *f) · 17 unmodified lines
55 case IWEAPON:57 case IWEAPON:
56 snprint(extra, sizeof(extra), " (%dd%d)", i->id->rolls, i->id->atk);58 snprint(extra, sizeof(extra), " (%dd%d)", i->id->rolls, i->id->atk);
57 break;59 break;
60 case IHELMET:
61 case ISHIELD:
58 case IARMOR:62 case IARMOR:
59 snprint(extra, sizeof(extra), " (ac %d)", i->id->ac);63 snprint(extra, sizeof(extra), " (ac %d)", i->id->ac);
60 break;64 break;
@@ -213,6 +217,9 @@ missing: · 152 unmodified lines
213void217void
214ifree(Item *i)218ifree(Item *i)
215{219{
220 if(i == nil)
221 return;
222
216 if(decref(&i->ref) != 0)223 if(decref(&i->ref) != 0)
217 return;224 return;
218 225
item.ndb+9−1
@@ -4,8 +4,16 @@ · 3 unmodified lines
4item="dagger"4item="dagger"
5 tile=411 type=weapon cost=5 weight=5 atk=1d45 tile=411 type=weapon cost=5 weight=5 atk=1d4
6 stacks6 stacks
7item="longsword"
8 tile=431 type=weapon cost=10 weight=10 atk=1d8
9item="runesword"
10 tile=435 type=weapon cost=50 weight=10 atk=4d4
7 11
8# armor12# armor
13item="helmet"
14 tile=472 type=helmet cost=5 weight=2 ac=2
9item="shield"15item="shield"
10 tile=525 type=armor cost=5 weight=10 ac=216 tile=525 type=shield cost=5 weight=10 ac=2
17item="plate armor"
18 tile=496 type=armor cost=50 weight=15 ac=4
11 19
levelgen.c+35−3
@@ -191,12 +191,27 @@ mkmons(Level *l, Point p, char *type) · 190 unmodified lines
191 idle(m);191 idle(m);
192 192
193 /* items! */193 /* items! */
194 if(nrand(5) == 0){194 switch(nrand(100)){
195 case 0:
195 m->weapon = ibyname("dagger");196 m->weapon = ibyname("dagger");
197 break;
198 case 1:
199 m->weapon = ibyname("longsword");
200 case 3:
201 m->weapon = ibyname("runesword");
202 break;
196 }203 }
197 if(nrand(5) == 0){204 if(nrand(50) == 0){
205 maddinv(m, ibyname("helmet"));
206 mwield(m, 0);
207 }
208 if(nrand(50) == 0){
198 maddinv(m, ibyname("shield"));209 maddinv(m, ibyname("shield"));
199 mwear(m, 0);210 mwield(m, 0);
211 }
212 if(nrand(100) == 0){
213 maddinv(m, ibyname("plate armor"));
214 mwield(m, 0);
200 }215 }
201 return m;216 return m;
202}217}
@@ -261,6 +276,7 @@ levelexec(AIState *a) · 58 unmodified lines
261 Tile *t;276 Tile *t;
262 MonsterData *md;277 MonsterData *md;
263 Monster *m;278 Monster *m;
279 Item *it;
264 280
265 l = a->aux;281 l = a->aux;
266 282
@@ -293,6 +309,22 @@ levelexec(AIState *a) · 26 unmodified lines
293 several(l, &p, 1, sp->what, 0);309 several(l, &p, 1, sp->what, 0);
294 }310 }
295 }311 }
312
313 for(p.x = 0; p.x < l->width; p.x++){
314 for(p.y = 0; p.y < l->height; p.y++){
315 if(hasflagat(l, p, Fhasitem)){
316 t = tileat(l, p);
317 for(i = 0; i < t->items.count; i++){
318 it = ilnth(&t->items, i);
319 if(++it->age > IMAXAGE){
320 ifree(iltakenth(&t->items, i));
321 if(t->items.count == 0)
322 clrflagat(l, p, Fhasitem);
323 }
324 }
325 }
326 }
327 }
296}328}
297 329
298Level*330Level*
monst.c+62−42
@@ -195,7 +195,10 @@ mfree(Monster *m) · 194 unmodified lines
195 }195 }
196 196
197 ilfree(&m->inv);197 ilfree(&m->inv);
198 ilfree(&m->armor);198 ifree(m->weapon);
199 ifree(m->helmet);
200 ifree(m->shield);
201 ifree(m->armor);
199 202
200 free(m);203 free(m);
201}204}
@@ -328,8 +331,10 @@ mattack(Monster *m, Monster *mt) · 126 unmodified lines
328 mt->flags = Mdead;331 mt->flags = Mdead;
329 332
330 /* drop dead guy's stuff */333 /* drop dead guy's stuff */
331 munwield(mt);334 munwield(mt, IWEAPON);
332 mnaked(mt);335 munwield(mt, IHELMET);
336 munwield(mt, ISHIELD);
337 munwield(mt, IARMOR);
333 while(mt->inv.count > 0){338 while(mt->inv.count > 0){
334 i = iltakenth(&mt->inv, 0);339 i = iltakenth(&mt->inv, 0);
335 t = tileat(mt->l, mt->pt);340 t = tileat(mt->l, mt->pt);
@@ -464,74 +469,89 @@ maction(Monster *m, int what, Point where) · 128 unmodified lines
464 return -1;469 return -1;
465}470}
466 471
467/* wield n'th item in inventory. */472/* wield/wear n'th item in inventory. */
468int473int
469mwield(Monster *m, int n)474mwield(Monster *m, int n)
470{475{
471 Item *i;476 Item **ptr, *old, *new;
472
473 i = nil;
474 477
475 if(m->weapon != nil)478 old = nil;
476 i = m->weapon;479 new = iltakenth(&m->inv, n);
480 if(new == nil)
481 return 0;
477 482
478 m->weapon = iltakenth(&m->inv, n);483 switch(new->id->type){
479 if(m->weapon == nil){484 case IWEAPON:
480 m->weapon = i;485 ptr = &m->weapon;
486 break;
487 case IHELMET:
488 ptr = &m->helmet;
489 break;
490 case ISHIELD:
491 ptr = &m->shield;
492 break;
493 case IARMOR:
494 ptr = &m->armor;
495 break;
496 default:
497 iladd(&m->inv, new);
481 return 0;498 return 0;
482 }499 }
483 500
484 if(i != nil)501 if(*ptr != nil)
485 iladd(&m->inv, i);502 old = *ptr;
486 503
487 return 1;504 *ptr = new;
488}
489 505
490int506 if(old != nil){
491munwield(Monster *m)507 m->ac += old->id->ac;
492{508 maddinv(m, old);
493 if(m->weapon == nil)509 }
494 return 0;510
511 /* account for ac */
512 m->ac -= new->id->ac;
495 513
496 maddinv(m, m->weapon);
497 m->weapon = nil;
498 return 1;514 return 1;
499}515}
500 516
501/* put n'th inventory item on */
502int517int
503mwear(Monster *m, int n)518munwield(Monster *m, int type)
504{519{
505 Item *i;520 Item **ptr;
506 521
507 i = iltakenth(&m->inv, n);522 switch(type){
508 if(i == nil){523 case IWEAPON:
524 ptr = &m->weapon;
525 break;
526 case IHELMET:
527 ptr = &m->helmet;
528 break;
529 case ISHIELD:
530 ptr = &m->shield;
531 break;
532 case IARMOR:
533 ptr = &m->armor;
534 break;
535 default:
509 return 0;536 return 0;
510 }537 }
511 538
512 iladd(&m->armor, i);539 if(*ptr == nil)
540 return 0;
513 541
514 m->ac -= i->id->ac;542 m->ac += (*ptr)->id->ac;
543 maddinv(m, *ptr);
544 *ptr = nil;
515 return 1;545 return 1;
516}546}
517 547
518/* take off all armor */
519void
520mnaked(Monster *m)
521{
522 Item *i;
523
524 while((i = iltakenth(&m->armor, 0)) != nil){
525 m->ac += i->id->ac;
526 iladd(&m->inv, i);
527 }
528}
529
530void548void
531maddinv(Monster *m, Item *i)549maddinv(Monster *m, Item *i)
532{550{
533 Item *it;551 Item *it;
534 552
553 i->age = 0;
554
535 /* dedup item */555 /* dedup item */
536 if(i->id->flags & IFSTACKS){556 if(i->id->flags & IFSTACKS){
537 for(it = m->inv.head; it != nil; it = it->next){557 for(it = m->inv.head; it != nil; it = it->next){
ui.c+45−21
@@ -454,6 +454,38 @@ inventorymenu(int idx, char *s, int sz) · 453 unmodified lines
454 return idx+'a';454 return idx+'a';
455}455}
456 456
457static Rune
458equipmenu(int idx, char *s, int sz)
459{
460 switch(idx){
461 case 0:
462 if(player->weapon != nil){
463 snprint(s, sz, "weapon: %i", player->weapon);
464 return 'w';
465 }
466 return 0;
467 case 1:
468 if(player->helmet != nil){
469 snprint(s, sz, "helmet: %i", player->helmet);
470 return 'h';
471 }
472 return 0;
473 case 2:
474 if(player->shield != nil){
475 snprint(s, sz, "shield: %i", player->shield);
476 return 's';
477 }
478 return 0;
479 case 3:
480 if(player->armor!= nil){
481 snprint(s, sz, "armor: %i", player->armor);
482 return 'a';
483 }
484 return 0;
485 }
486 return Runemax;
487}
488
457static Rune489static Rune
458dirmenu(int idx, char *s, int /*sz*/)490dirmenu(int idx, char *s, int /*sz*/)
459{491{
@@ -584,23 +616,17 @@ uiexec(AIState *ai) · 124 unmodified lines
584 item = ilnth(&player->inv, i);616 item = ilnth(&player->inv, i);
585 switch(item->id->type){617 switch(item->id->type){
586 case IWEAPON:618 case IWEAPON:
587 if(!mwield(player, i))619 case IHELMET:
588 warn("can't equip that");620 case ISHIELD:
589 else {
590 item = player->weapon;
591 good("you are now wielding the %i!", item);
592 }
593 break;
594 case IARMOR:621 case IARMOR:
595 if(!mwear(player, i))622 if(!mwield(player, i))
596 warn("can't equip that");623 warn("can't equip that");
597 else {624 else
598 item = player->armor.head;625 good("you are now %sing the %i!", item->id->type==IWEAPON?"wield":"wear", item);
599 good("you are now wearing the %i!", item);
600 }
601 break;626 break;
602 default:627 default:
603 bad("you aren't sure what to do with the %i...", item);628 bad("you aren't sure what to do with the %i...", item);
629 break;
604 }630 }
605 }631 }
606 redraw(&ui, 0, 0);632 redraw(&ui, 0, 0);
@@ -622,17 +648,15 @@ uiexec(AIState *ai) · 15 unmodified lines
622 }648 }
623 redraw(&ui, 0, 0);649 redraw(&ui, 0, 0);
624 break;650 break;
625 case 'W':
626 /* take off weapon */
627 if(player->weapon != nil){
628 bad("you stop wielding the %i.", player->weapon);
629 munwield(player);
630 }
631 break;
632 case 'A':651 case 'A':
633 /* take off armor */652 /* take off armor */
634 bad("you take off all your armor.");653 km = (KeyMenu){"take off what?", equipmenu};
635 mnaked(player);654 i = menu(ui.kc, ui.mc, &km);
655 if(i >= 0 && i <= 3){
656 munwield(player, i);
657 item = ilnth(&player->inv, 0);
658 bad("you take off the %i.", item);
659 }
636 break;660 break;
637 case 'h':661 case 'h':
638 case Kleft:662 case Kleft: