Newbie code snippet problem

More
5 years 2 months ago - 5 years 2 months ago #5599 by evorg
Newbie code snippet problem was created by evorg
EDIT: I forgot about act.h (DOH)
EDIT: Please ignore!

I'm trying to copy/paste this snippet into my TBA mud:

www.circlemud.org/pub/CircleMUD/contrib/...ts/skills/forage.txt

I'm getting this error when I make:
$ make
make ../bin/circle
make[1]: Entering directory '/home/Parker/tba/src'
gcc -g -O2 -Wall -Wno-char-subscripts    -c -o class.o class.c
gcc -g -O2 -Wall -Wno-char-subscripts    -c -o interpreter.o interpreter.c
interpreter.c:151:44: error: ‘do_forage’ undeclared here (not in a function)
   { "forage"   , "fora"    , POS_STANDING, do_forage   , 0, 0 },
                                            ^
<builtin>: recipe for target 'interpreter.o' failed
make[1]: *** [interpreter.o] Error 1
make[1]: Leaving directory '/home/Parker/tba/src'
Makefile:30: recipe for target 'all' failed
make: *** [all] Error 2

I followed the instructions and I added my own object and added the command to spells.h,
spell_parser.c and interpreter.c. The skill itself is in act.other.c - What am I doing wrong?

My code looks like this:
ACMD(do_forage)
{
  struct obj_data *item_found = '\0';
  int item_no = 27219; /* Initialize with first item poss. */
  *buf = '\0';

  if GET_CLASS(ch) != CLASS_THIEF && GET_LEVEL(ch) <= 100) {
    send_to_char("You have no idea how to forage for survival!\r\n", ch);
    return; }

  if(GET_MOVE(ch) < 100) {
    send_to_char("You do not have enough energy right now.\r\n", ch);
    return; }

  if(SECT(ch->in_room) != SECT_FIELD && SECT(ch->in_room) != SECT_FOREST && SECT(ch->in_room) != SECT_HILLS && SECT(ch->in_room) != SECT_MOUNTAIN  && SECT(ch->in_room) != SECT_SWAMP) {
    send_to_char("You cannot forage on this type of terrain!\r\n", ch);
    return; }

   if(GET_SKILL(ch, SKILL_FORAGE) <= 0) {
     send_to_char("You have no idea how to forage!\r\n", ch);
     return; }

     send_to_char("You start searching the area for signs of food.\r\n", ch);
     act("$n starts foraging the area for food.\r\n", FALSE, ch, 0, 0, TO_ROOM);
   if(number(1,101) > GET_SKILL(ch, SKILL_FORAGE)) {
     WAIT_STATE(ch, PULSE_VIOLENCE * 2);
     GET_MOVE(ch) -= (100 - GET_LEVEL(ch));
     send_to_char("\r\nYou have no luck finding anything to eat.\r\n", ch);
     return;
    }
   else
    {
    switch (number(1,2))
     {
     case 1:
      item_no = 27219; break;  /*<--- Here are the objects you need to code */
     case 2:                   /* Add more or remove some, just change the */
      item_no = 10; break;  /* switch(number(1, X) */
     }
		WAIT_STATE( ch, PULSE_VIOLENCE * 2);  /* Not really necessary */
		GET_MOVE(ch) -= (150 - GET_LEVEL(ch));
		item_found = read_object( item_no, VIRTUAL);
		obj_to_char(item_found, ch);
		sprintf(buf, "%sYou have found %s!\r\n", buf, item_found->short_description);
		send_to_char(buf, ch);
		act("$n has found something in his forage attempt.\r\n", FALSE, ch, 0, 0, TO_ROOM);
     return;
     }
}

Thanks.
Last edit: 5 years 2 months ago by evorg.

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

More
5 years 2 months ago #5600 by thomas
Replied by thomas on topic Newbie code snippet problem
You need to add the line

ACMD(do_forage);

above the long array in interpreter.c. It's called "declaring" the function, and you need to declare a function before using it (like do_forage in the line youæve added already).

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

More
5 years 2 months ago #5601 by WhiskyTest
Replied by WhiskyTest on topic Newbie code snippet problem
Learning from old snippets is great, that's how I started.
You've probably done this already, but for anyone else learning from these older snippets there are a few changes before you can drop them into tbaMUD...

Send_to_char is backwards:
- send_to_char("You have no idea how to forage for survival!\r\n", ch);
+ send_to_char(ch, "You have no idea how to forage for survival!\r\n");

Sprintf is deprecated, you should use snprintf:
- sprintf(buf, "%sYou have found %s!\r\n", buf, item_found->short_description);
+ snprintf(buf, sizeof(buf), "%sYou have found %s!\r\n", buf, item_found->short_description);

number is oldschool, use rand_number - or even dice (rolls 1x 101 sided dice in the below example)
- if(number(1,101) > GET_SKILL(ch, SKILL_FORAGE)) {
+ if(rand_number(1,101) > GET_SKILL(ch, SKILL_FORAGE)) {
|+ if(dice(1,101) > GET_SKILL(ch, SKILL_FORAGE)) {
The following user(s) said Thank You: Chime

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

More
5 years 2 months ago #5602 by evorg
Replied by evorg on topic Newbie code snippet problem
Thank you for the nice and informative responses!

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

More
3 years 1 month ago - 3 years 1 month ago #7862 by Nibiru
Replied by Nibiru on topic Newbie code snippet problem
I'm trying to implement this snippet.
However this line of the code is creating a compiler error.

ACMD(do_forage)
{
struct obj_data *item_found = '\0';
int item_no = 10053; /* Initialize with first item poss. */
*buf = '\0';

$ make
make ../bin/circle
make[1]: Entering directory '/home/kadiya/tbamud/src'
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.other.o act.other.c
act.other.c: In function ‘do_forage’:
act.other.c:858:5: error: ‘buf’ undeclared (first use in this function)
*buf = '\0';


When I change *buf to int buf it will compile but any attempt to use the command instantly crashes the mud.

Any suggestions?

When the crash happens it is at the point where the action to forage would be taking place. It functions properly if on wrong terrain or if the player does not have the forage skill.

Nibiru
Last edit: 3 years 1 month ago by Nibiru. Reason: Additional Information:

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

More
3 years 1 month ago - 3 years 1 month ago #7863 by JTP
Replied by JTP on topic Newbie code snippet problem
You need:

char buf[MAX_INPUT_LENGTH] = "\0";

instead of *buf = '\0';
Last edit: 3 years 1 month ago by JTP.

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

More
3 years 1 month ago - 3 years 1 month ago #7864 by Nibiru
Replied by Nibiru on topic Newbie code snippet problem
That solved the compiling issue. :)

Any suggestions on troubleshooting the crashing issue?
These parts work- If attempting to forage on wrong terrain type it returns the message you can't forage here.
If player does not have the skill, it returns the message you don't know how.


At the point where the function is determining if an item is found/finding an item it crashes the mud.
I created items using the same item numbers as the original code, so it is possible to find the items.

These are my compiler warnings:

make[1]: Entering directory '/home/kadiya/tbamud/src'
gcc -g -O2 -Wall -Wno-char-subscripts -Wno-unused-but-set-variable -c -o act.other.o act.ot her.c
act.other.c: In function ‘do_forage’:
act.other.c:860:3: warning: suggest parentheses around assignment used as truth value [-Wparen theses]
if(GET_RACE(ch) = RACE_BUBATIN && GET_LEVEL(ch) <= 2)
^~
act.other.c:912:16: warning: passing argument 1 of ‘obj_to_char’ from incompatible pointer typ e [-Wincompatible-pointer-types]
obj_to_char(ch,item_found );
^~
In file included from act.other.c:20:0:
handler.h:33:6: note: expected ‘struct obj_data *’ but argument is of type ‘struct char_data ’
void obj_to_char(struct obj_data *object, struct char_data *ch);
^~~~~~~~~~~
act.other.c:912:19: warning: passing argument 2 of ‘obj_to_char’ from incompatible pointer typ e [-Wincompatible-pointer-types]
obj_to_char(ch,item_found );
^~~~~~~~~~
In file included from act.other.c:20:0:
handler.h:33:6: note: expected ‘struct char_data *’ but argument is of type ‘struct obj_data ’
void obj_to_char(struct obj_data *object, struct char_data *ch);
^~~~~~~~~~~
act.other.c:913:17: warning: passing argument 2 of ‘sprintf’ makes pointer from integer withou t a cast [-Wint-conversion]
sprintf( buf,sizeof(buf),"%sYou have found %s!\r\n", buf, item_found->short_description)
^~~~~~
In file included from /usr/include/stdio.h:29:0,
from sysdep.h:69,
from act.other.c:15:
/usr/include/stdio.h:244:5: note: expected ‘const char * restrict’ but argument is of type ‘lo ng unsigned int’
int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)


This is the code after modifications for my mud:
ACMD(do_forage)
{
  struct obj_data *item_found = '\0';
  int item_no = 10053; /* Initialize with first item poss. */
  char buf[MAX_INPUT_LENGTH] = "\0";

  if(GET_RACE(ch) = RACE_BUBATIN && GET_LEVEL(ch) <= 2)
   {
    send_to_char(ch,"You have no idea how to forage for survival!\r\n");
    return; }

  if(GET_MOVE(ch) < 50)
    {
    send_to_char(ch,"You do not have enough energy right now.\r\n" );
    return; }

  if(SECT(ch->in_room) != SECT_FIELD && SECT(ch->in_room) != SECT_FOREST && SECT(ch->in_room) != SECT_HILLS && SECT(ch->in_room) != SECT_MOUNTAIN  && SECT(ch->in_room) != SECT_SWAMP)
   {
    send_to_char(ch, "You cannot forage on this type of terrain!\r\n");
    return; }

   if(GET_SKILL(ch, SKILL_FORAGE) <= 0)
     {
     send_to_char(ch,"You have no idea how to forage!\r\n" );
     return; }

     send_to_char(ch,"You start searching the area for signs of food.\r\n");
     act("$n starts foraging the area for food.\r\n", FALSE, ch, 0, 0, TO_ROOM)
;
   if(rand_number(1,101) > GET_SKILL(ch, SKILL_FORAGE))
    {
     WAIT_STATE(ch, PULSE_VIOLENCE * 2);
     GET_MOVE(ch) -= (50 - GET_LEVEL(ch));
     send_to_char(ch,"\r\nYou have no luck finding anything to eat.\r\n" );
     return;
    }
   else
    {
    switch (rand_number(1,7))
     {
     case 1:
      item_no = 10053; break;  /*<--- Here are the objects you need to code */
     case 2:                   /* Add more or remove some, just change the */
      item_no = 10054; break;  /* switch(number(1, X) */
     case 3:
      item_no = 10055; break;
     case 4:
      item_no = 10056; break;
     case 5:
      item_no = 10057; break;
     case 6:
      item_no = 10058; break;
     case 7:
      item_no = 10059; break;
     }
   WAIT_STATE( ch, PULSE_VIOLENCE * 2);  /* Not really necessary */
   GET_MOVE(ch) -= (50 - GET_LEVEL(ch));
   item_found = read_object( item_no, VIRTUAL);
   obj_to_char(ch,item_found );
   sprintf( buf,sizeof(buf),"%sYou have found %s!\r\n", buf, item_found->short_description)
;
   send_to_char(ch, buf, item_found );
   act("$n has found something in his forage attempt.\r\n", FALSE, ch, 0, 0, TO_ROOM);
     return;
     }
}

Nibiru
Last edit: 3 years 1 month ago by thomas. Reason: added [ code ] formatting

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

More
3 years 1 month ago #7865 by thomas
Replied by thomas on topic Newbie code snippet problem
Instead of the suggested
char buf[MAX_INPUT_LENGTH] = "\0";
use
char buf[MAX_INPUT_LENGTH];
*buf = '\0';

Secondly, you are using assignment (=) instead of equality checking (==) here:
-  if(GET_RACE(ch) = RACE_BUBATIN && GET_LEVEL(ch) <= 2)
+  if(GET_RACE(ch) == RACE_BUBATIN && GET_LEVEL(ch) <= 2)

Third, setting the object data to a string isn't a good idea:
-struct obj_data *item_found = '\0';
+struct obj_data *item_found = NULL;

Lastly, the order of operators to obj_to_char is obj_data pointer, then char_data pointer.
- obj_to_char(ch,item_found );
+ obj_to_char(item_found, ch );  
The following user(s) said Thank You: Chime

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

More
3 years 1 month ago #7866 by Nibiru
Replied by Nibiru on topic Newbie code snippet problem
Thank you,
Your suggestions, plus adding an additional if statement after the check to see if the player has the skill got me past the instant crash. So next weekend I'll see if I can get it to work as expected and load one of the items or produce the nothing found message.

Nibiru

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

More
3 years 1 month ago - 3 years 1 month ago #7870 by JTP
Replied by JTP on topic Newbie code snippet problem
What is the difference between
char buf[MAX_INPUT_LENGTH] = "\0";
And
char buf[MAX_INPUT_LENGTH];
*buf = "\0";

?

The first one compiles fine and never gave me trouble in game.
Last edit: 3 years 1 month ago by JTP.

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

More
3 years 1 month ago - 3 years 1 month ago #7871 by thomas
Replied by thomas on topic Newbie code snippet problem

What is the difference between
char buf[MAX_INPUT_LENGTH] = "\0";
And
char buf[MAX_INPUT_LENGTH];
*buf = "\0";

?

The first one compiles fine and never gave me trouble in game.


The initialization will work, because C does things differently when initializing the variable than when assigning it later.

However, it will only work there -- stackoverflow.com/a/579758/1768263 . Several other places in the code, we are resetting a "global" buffer with
*buf = '\0';
Note the ' (single quotes) instead of " (double quotes), signifying we're just inserting a NULL as first character.

So, to keep the code similar everywhere, I suggest using that convention here, too.
Last edit: 3 years 1 month ago by thomas.
The following user(s) said Thank You: JTP

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

Time to create page: 0.123 seconds