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
5151 {
5252 /* possible item types */
5353 IWEAPON = 0,
54+ IHELMET,
55+ ISHIELD,
5456 IARMOR,
5557
5658 /* item flags */
@@ -82,10 +84,18 @@ struct ItemData · 25 unmodified lines
8284 int flags;
8385 };
8486
87+enum
88+{
89+ IMAXAGE = 250,
90+};
91+
8592 struct Item
8693 {
8794 Ref ref;
8895
96+ /* age, for automatic deletion */
97+ int age;
98+
8999 /* count of items in stack */
90100 int count;
91101
@@ -215,10 +225,11 @@ struct Monster · 123 unmodified lines
215225 /* inventory */
216226 ItemList inv;
217227
218− /* equipped weapon */
228+ /* equipped weapon & armor */
219229 Item *weapon;
220− /* equipped armor */
221− ItemList armor;
230+ Item *helmet;
231+ Item *shield;
232+ Item *armor;
222233
223234 /* no free */
224235 MonsterData *md;
@@ -234,9 +245,7 @@ void mpushstate(Monster *m, AIState *a); · 9 unmodified lines
234245 AIState *mpopstate(Monster *m);
235246 int maction(Monster *m, int what, Point where);
236247 int mwield(Monster *m, int n);
237−int munwield(Monster *m);
238−int mwear(Monster *m, int n);
239−void mnaked(Monster *m);
248+int munwield(Monster *m, int type);
240249 void maddinv(Monster *m, Item *i);
241250 int xpcalc(int level);
242251
item.c+7−0
@@ -32,6 +32,8 @@ static char *itemdbcmd[] = { · 31 unmodified lines
3232
3333 static char *itemtype[] = {
3434 [IWEAPON] "weapon",
35+[IHELMET] "helmet",
36+[ISHIELD] "shield",
3537 [IARMOR] "armor",
3638 };
3739
@@ -55,6 +57,8 @@ ifmt(Fmt *f) · 17 unmodified lines
5557 case IWEAPON:
5658 snprint(extra, sizeof(extra), " (%dd%d)", i->id->rolls, i->id->atk);
5759 break;
60+ case IHELMET:
61+ case ISHIELD:
5862 case IARMOR:
5963 snprint(extra, sizeof(extra), " (ac %d)", i->id->ac);
6064 break;
@@ -213,6 +217,9 @@ missing: · 152 unmodified lines
213217 void
214218 ifree(Item *i)
215219 {
220+ if(i == nil)
221+ return;
222+
216223 if(decref(&i->ref) != 0)
217224 return;
218225
item.ndb+9−1
@@ -4,8 +4,16 @@ · 3 unmodified lines
44 item="dagger"
55 tile=411 type=weapon cost=5 weight=5 atk=1d4
66 stacks
7+item="longsword"
8+ tile=431 type=weapon cost=10 weight=10 atk=1d8
9+item="runesword"
10+ tile=435 type=weapon cost=50 weight=10 atk=4d4
711
812 # armor
13+item="helmet"
14+ tile=472 type=helmet cost=5 weight=2 ac=2
915 item="shield"
10− tile=525 type=armor cost=5 weight=10 ac=2
16+ tile=525 type=shield cost=5 weight=10 ac=2
17+item="plate armor"
18+ tile=496 type=armor cost=50 weight=15 ac=4
1119
levelgen.c+35−3
@@ -191,12 +191,27 @@ mkmons(Level *l, Point p, char *type) · 190 unmodified lines
191191 idle(m);
192192
193193 /* items! */
194− if(nrand(5) == 0){
194+ switch(nrand(100)){
195+ case 0:
195196 m->weapon = ibyname("dagger");
197+ break;
198+ case 1:
199+ m->weapon = ibyname("longsword");
200+ case 3:
201+ m->weapon = ibyname("runesword");
202+ break;
196203 }
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){
198209 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);
200215 }
201216 return m;
202217 }
@@ -261,6 +276,7 @@ levelexec(AIState *a) · 58 unmodified lines
261276 Tile *t;
262277 MonsterData *md;
263278 Monster *m;
279+ Item *it;
264280
265281 l = a->aux;
266282
@@ -293,6 +309,22 @@ levelexec(AIState *a) · 26 unmodified lines
293309 several(l, &p, 1, sp->what, 0);
294310 }
295311 }
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+ }
296328 }
297329
298330 Level*
monst.c+62−42
@@ -195,7 +195,10 @@ mfree(Monster *m) · 194 unmodified lines
195195 }
196196
197197 ilfree(&m->inv);
198− ilfree(&m->armor);
198+ ifree(m->weapon);
199+ ifree(m->helmet);
200+ ifree(m->shield);
201+ ifree(m->armor);
199202
200203 free(m);
201204 }
@@ -328,8 +331,10 @@ mattack(Monster *m, Monster *mt) · 126 unmodified lines
328331 mt->flags = Mdead;
329332
330333 /* drop dead guy's stuff */
331− munwield(mt);
332− mnaked(mt);
334+ munwield(mt, IWEAPON);
335+ munwield(mt, IHELMET);
336+ munwield(mt, ISHIELD);
337+ munwield(mt, IARMOR);
333338 while(mt->inv.count > 0){
334339 i = iltakenth(&mt->inv, 0);
335340 t = tileat(mt->l, mt->pt);
@@ -464,74 +469,89 @@ maction(Monster *m, int what, Point where) · 128 unmodified lines
464469 return -1;
465470 }
466471
467−/* wield n'th item in inventory. */
472+/* wield/wear n'th item in inventory. */
468473 int
469474 mwield(Monster *m, int n)
470475 {
471− Item *i;
472−
473− i = nil;
476+ Item **ptr, *old, *new;
474477
475− if(m->weapon != nil)
476− i = m->weapon;
478+ old = nil;
479+ new = iltakenth(&m->inv, n);
480+ if(new == nil)
481+ return 0;
477482
478− m->weapon = iltakenth(&m->inv, n);
479− if(m->weapon == nil){
480− m->weapon = i;
483+ switch(new->id->type){
484+ case IWEAPON:
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);
481498 return 0;
482499 }
483500
484− if(i != nil)
485− iladd(&m->inv, i);
501+ if(*ptr != nil)
502+ old = *ptr;
486503
487− return 1;
488−}
504+ *ptr = new;
489505
490−int
491−munwield(Monster *m)
492−{
493− if(m->weapon == nil)
494− return 0;
506+ if(old != nil){
507+ m->ac += old->id->ac;
508+ maddinv(m, old);
509+ }
510+
511+ /* account for ac */
512+ m->ac -= new->id->ac;
495513
496− maddinv(m, m->weapon);
497− m->weapon = nil;
498514 return 1;
499515 }
500516
501−/* put n'th inventory item on */
502517 int
503−mwear(Monster *m, int n)
518+munwield(Monster *m, int type)
504519 {
505− Item *i;
520+ Item **ptr;
506521
507− i = iltakenth(&m->inv, n);
508− if(i == nil){
522+ switch(type){
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:
509536 return 0;
510537 }
511538
512− iladd(&m->armor, i);
539+ if(*ptr == nil)
540+ return 0;
513541
514− m->ac -= i->id->ac;
542+ m->ac += (*ptr)->id->ac;
543+ maddinv(m, *ptr);
544+ *ptr = nil;
515545 return 1;
516546 }
517547
518−/* take off all armor */
519−void
520−mnaked(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−
530548 void
531549 maddinv(Monster *m, Item *i)
532550 {
533551 Item *it;
534552
553+ i->age = 0;
554+
535555 /* dedup item */
536556 if(i->id->flags & IFSTACKS){
537557 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
454454 return idx+'a';
455455 }
456456
457+static Rune
458+equipmenu(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+
457489 static Rune
458490 dirmenu(int idx, char *s, int /*sz*/)
459491 {
@@ -584,23 +616,17 @@ uiexec(AIState *ai) · 124 unmodified lines
584616 item = ilnth(&player->inv, i);
585617 switch(item->id->type){
586618 case IWEAPON:
587− if(!mwield(player, i))
588− warn("can't equip that");
589− else {
590− item = player->weapon;
591− good("you are now wielding the %i!", item);
592− }
593− break;
619+ case IHELMET:
620+ case ISHIELD:
594621 case IARMOR:
595− if(!mwear(player, i))
622+ if(!mwield(player, i))
596623 warn("can't equip that");
597− else {
598− item = player->armor.head;
599− good("you are now wearing the %i!", item);
600− }
624+ else
625+ good("you are now %sing the %i!", item->id->type==IWEAPON?"wield":"wear", item);
601626 break;
602627 default:
603628 bad("you aren't sure what to do with the %i...", item);
629+ break;
604630 }
605631 }
606632 redraw(&ui, 0, 0);
@@ -622,17 +648,15 @@ uiexec(AIState *ai) · 15 unmodified lines
622648 }
623649 redraw(&ui, 0, 0);
624650 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;
632651 case 'A':
633652 /* take off armor */
634− bad("you take off all your armor.");
635− mnaked(player);
653+ km = (KeyMenu){"take off what?", equipmenu};
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+ }
636660 break;
637661 case 'h':
638662 case Kleft: