Welcome to the Builder Academy

Question Item Durability

More
18 May 2013 02:47 #2373 by Vatiken
Replied by Vatiken on topic Item Durability
Code:
struct obj_data *targ; /* Item Durability */ if ((targ = GET_EQ(ch, rand_number(0, NUM_WEARS)) != NULL) { if (rand_number(1, 10) == 10 && GET_OBJ_TYPE(targ) == ITEM_ARMOR && GET_OBJ_MAX_DURAB(targ)) { send_to_char(ch, "\tRWith that blow, %s has been damaged!\tn\n", GET_OBJ_SHORT(targ)); GET_OBJ_DURABILITY(targ) = MAX(GET_OBJ_DURABILITY(targ) -rand_number(1, 6), 0); if (!GET_OBJ_DURABILITY(targ)) { send_to_char(victim, "\trWith that final blow, %s that you were wearing fall apart!\tn\n",GET_OBJ_SHORT(targ)); send_to_room(IN_ROOM(victim), "\tr%s is less protected as %s falls apart after that last blow!\tn\n", GET_NAME(victim), GET_OBJ_SHORT(targ)); obj_to_char(unequip_char(victim, targ->worn_on), victim); } } }
The first step would be to clean up your code as much as possible. The above snippet should work in replace of the entire switch() as well as some of the other code. The problem with large switches that include the same lines of code over and over again is that: A) more time needed to program, B) more chance of human error and C) more difficult to accurately debug.

tbaMUD developer/programmer
The following user(s) said Thank You: Papaya Pete

Please Log in or Create an account to join the conversation.

More
18 May 2013 06:14 - 18 May 2013 06:54 #2382 by Papaya Pete
Replied by Papaya Pete on topic Item Durability
Yeah, that did it! Thank you so much. :)

So much simpler too... the switch was pretty huge, and was a pain if I wanted to change something about the code. There was something up with it too, because, before work, I tried just checking one location very simply and there was no crash.

So next week, it's onto trying to get the condition to show when you see it lying in the room or in your inventory/equipment list.

Having a much better idea on how to use gdb now, I might be able to see if I can squash some bug that causes the mud to crash on shutdown. My suspicion is leaning towards one of the snippets I've done in the past... will need to update that.

Edit: which I just did in around a half hour. Yeah... it's an ugly series of if-thens, but better than trying to do a switch and had little choice due to the messages being different. Oh well. It works!

So last step (besides copying all these changes into a txt file) is getting shops to repair damaged items. Should be fun.
Last edit: 18 May 2013 06:54 by Papaya Pete. Reason: Finished item condition descs.

Please Log in or Create an account to join the conversation.

More
20 May 2013 17:40 #2453 by Papaya Pete
Replied by Papaya Pete on topic Item Durability
So I put in a special procedure one can add to shopkeepers to make them be able to repair items. So far, I just have armor and weapons being the only things that can be repaired... though thinking about it, you can add wear and tear for most things. Containers, for example, might have a check that is run to see if it is almost full. If so, that can reduce the condition. Notes can experience wear and tear as well whenever they're read. I don't think I'll try to do those things, though.

So it looks like this snippet is done! I just need to test a couple things out and then finish putting the instructions together.

On a side note though.... I did find a bug that causes the mud to crash, at least if you happen to be using CYGWIN. It occurs when you have two characters that are separated by doors, and one of them opens that door. Here is the result of the backtrace... that's all I put this time because I don't think it's something I can deal with... but any ideas on how to resolve this would be much appreciated.
Code:
#0 strlen () at /usr/src/debug/cygwin-1.7.18-1/newlib/libc/machine/i386/strlen.S:38 #1 0x75381194 in WaitForSingleObjectEx () from /cygdrive/c/Windows/syswow64/kernel32.dll #2 0x75381148 in WaitForSingleObject () from /cygdrive/c/Windows/syswow64/kernel32.dll #3 0x610dd558 in sig_send (p=<optimized out>, si=..., tls=0x271318) at /usr/src/debug/cygwin-1.7.18-1/winsup/cygwin/sigproc.cc:682 #4 0x610303b4 in exception::handle (e=0x2715ec, frame=0x28ff14, in=0x27163c) at /usr/src/debug/cygwin-1.7.18-1/winsup/cygwin/exceptions.cc:644 #5 0x7776b459 in ntdll!LdrRemoveLoadAsDataTable () from /cygdrive/c/Windows/system32/ntdll.dll #6 0x002715ec in ?? () #7 0x7776b42b in ntdll!LdrRemoveLoadAsDataTable () from /cygdrive/c/Windows/system32/ntdll.dll #8 0x002715ec in ?? () #9 0x77720133 in ntdll!KiUserExceptionDispatcher () from /cygdrive/c/Windows/system32/ntdll.dll #10 0x002715ec in ?? () #11 0x61164487 in _svfprintf_r (data=0x28d41c, fp=0x271be0, fmt0=0x50b99c <wld_cmd_info+892> "The %s is %s%s from the other side.\r\n", ap=0x271cf0 "") at /usr/src/debug/cygwin-1.7.18-1/newlib/libc/stdio/vfprintf.c:1527 #12 0x6113a2d5 in _vsnprintf_r (ptr=0x28d41c, str=0x60b860 <txt.8440> "The \020\037'", size=49152, fmt=0x50b99c <wld_cmd_info+892> "The %s is %s%s from the other side.\r\n", ap=0x271ce8 "x\034'") at /usr/src/debug/cygwin-1.7.18-1/newlib/libc/stdio/vsnprintf.c:66 #13 0x6113a345 in vsnprintf (str=0x60b860 <txt.8440> "The \020\037'", size=49152, fmt=0x50b99c <wld_cmd_info+892> "The %s is %s%s from the other side.\r\n", ap=0x271ce8 "x\034'") at /usr/src/debug/cygwin-1.7.18-1/newlib/libc/stdio/vsnprintf.c:41 #14 0x610d75e5 in _sigfe () from /usr/bin/cygwin1.dll #15 0x0050b99c in wld_cmd_info () #16 0x00271ce8 in ?? () #17 0x004f9d5f in write_to_output (t=0x80f0c520, txt=0x50b99c <wld_cmd_info+892> "The %s is %s%s from the other side.\r\n") at comm.c:1270 #18 0x004fa499 in send_to_room (room=638, messg=0x50b99c <wld_cmd_info+892> "The %s is %s%s from the other side.\r\n") at comm.c:2430 #19 0x00402d08 in do_doorcmd (ch=<optimized out>, obj=<optimized out>, door=1, scmd=1) at act.movement.c:586 #20 0x0040429d in do_gen_door (ch=0x80f14ad0, argument=0x28a932 "east", cmd=465, subcmd=1) at act.movement.c:675

Please Log in or Create an account to join the conversation.

More
20 May 2013 21:13 #2460 by Rumble
Replied by Rumble on topic Item Durability
Tried reproducing the door crash without any luck. Feel free to stop by TBA to see if we can reproduce.

Rumble
The Builder Academy
tbamud.com 9091
rumble@tbamud.com

Please Log in or Create an account to join the conversation.

More
21 May 2013 06:16 - 21 May 2013 06:41 #2472 by Papaya Pete
Replied by Papaya Pete on topic Item Durability
Well this is very interesting! I managed to replicate it; when the key to an exit is set to 0, that's when the crash occurs. Here is another strange thing that's going on though; when you open or close a door, this is what you see on the other side.
Code:
close east Okay. (Other person sees this) The P' is (null)(null) from the other side.

This notifying the other room is found in the do_doorcmd function in act.movement.c, at the end.

This just might be a problem with CYGWIN though. I remember trying to use Vatiken's crafting snippet and it not working for some strange reason (even though the same thing worked for everyone else). It's making me seriously consider ditching CYGWIN for something else, though I don't have a free box to try and install (and learn) linux atm....

Edit: a combo of Windows 7 and CYGWIN actually, since I remember the former having issues with running older problems.

Also, looking at the entire function, it looks like part of the problem is that the pointer *back is initialized at NULL but is then never defined. Maybe I was being too harsh on windows and cywgin. Hehe (you can tell I edited this post a couple times). I'll take another look sometime tomorrow.
Code:
static void do_doorcmd(struct char_data *ch, struct obj_data *obj, int door, int scmd) { char buf[MAX_STRING_LENGTH]; size_t len; room_rnum other_room = NOWHERE; struct room_direction_data *back = NULL; if (!door_mtrigger(ch, scmd, door)) return; if (!door_wtrigger(ch, scmd, door)) return; len = snprintf(buf, sizeof(buf), "$n %ss ", cmd_door[scmd]); if (!obj && ((other_room = EXIT(ch, door)->to_room) != NOWHERE)) if ((back = world[other_room].dir_option[rev_dir[door]]) != NULL) if (back->to_room != IN_ROOM(ch)) back = NULL; switch (scmd) { case SCMD_OPEN: OPEN_DOOR(IN_ROOM(ch), obj, door); if (back) OPEN_DOOR(other_room, obj, rev_dir[door]); send_to_char(ch, "%s", CONFIG_OK); break; case SCMD_CLOSE: CLOSE_DOOR(IN_ROOM(ch), obj, door); if (back) CLOSE_DOOR(other_room, obj, rev_dir[door]); send_to_char(ch, "%s", CONFIG_OK); break; case SCMD_LOCK: LOCK_DOOR(IN_ROOM(ch), obj, door); if (back) LOCK_DOOR(other_room, obj, rev_dir[door]); send_to_char(ch, "*Click*\r\n"); break; case SCMD_UNLOCK: UNLOCK_DOOR(IN_ROOM(ch), obj, door); if (back) UNLOCK_DOOR(other_room, obj, rev_dir[door]); send_to_char(ch, "*Click*\r\n"); break; case SCMD_PICK: TOGGLE_LOCK(IN_ROOM(ch), obj, door); if (back) TOGGLE_LOCK(other_room, obj, rev_dir[door]); send_to_char(ch, "The lock quickly yields to your skills.\r\n"); len = strlcpy(buf, "$n skillfully picks the lock on ", sizeof(buf)); break; } /* Notify the room. */ if (len < sizeof(buf)) snprintf(buf + len, sizeof(buf) - len, "%s%s.", obj ? "" : "the ", obj ? "$p" : EXIT(ch, door)->keyword ? "$F" : "door"); if (!obj || IN_ROOM(obj) != NOWHERE) act(buf, FALSE, ch, obj, obj ? 0 : EXIT(ch, door)->keyword, TO_ROOM); /* Notify the other room */ if (back && (scmd == SCMD_OPEN || scmd == SCMD_CLOSE)) send_to_room(EXIT(ch, door)->to_room, "The %s is %s%s from the other side.\r\n", back->keyword ? fname(back->keyword) : "door", cmd_door[scmd], scmd == SCMD_CLOSE ? "d" : "ed"); }
Last edit: 21 May 2013 06:41 by Papaya Pete. Reason: Looked at the problem a bit more.

Please Log in or Create an account to join the conversation.

More
21 May 2013 15:14 #2491 by Papaya Pete
Replied by Papaya Pete on topic Item Durability
So I've taken a closer look... and *back is defined early on in the function. It's done in an if statement...
Code:
len = snprintf(buf, sizeof(buf), "$n %ss ", cmd_door[scmd]); if (!obj && ((other_room = EXIT(ch, door)->to_room) != NOWHERE)) if ((back = world[other_room].dir_option[rev_dir[door]]) != NULL) if (back->to_room != IN_ROOM(ch)) back = NULL;

I did some checking, and threw in some send_to_char to see if those values are getting filled. Sure enough, they are.
Code:
/* Notify the other room */ send_to_char(ch, "Value of back->keyword is %s\n", back->keyword); send_to_char(ch, "If that's the case, then fname(back->keyword) should be %s\n", fname(back->keyword)); if (back && (scmd == SCMD_OPEN || scmd == SCMD_CLOSE)) send_to_room(EXIT(ch, door)->to_room, "The %s is %s%s from the other side.\r\n", back->keyword ? fname(back->keyword) : "door", cmd_door[scmd], scmd == SCMD_CLOSE ? "d" : "ed");

For some reason, everything comes up as NULL, which is very puzzling. I'm going to take back taking back what I said; cygwin has issues. How would values that were previously defined suddenly be NULLed? And on top of that, I'm assuming that this isn't happening to everyone else.

Please Log in or Create an account to join the conversation.

Time to create page: 0.207 seconds