Loopy switches and cases! (Weapon Type Snippet)

Posted by Saryn on Sun 17 Aug 2003 08:46 PM — 7 posts, 27,298 views.

USA #0
Ok I installed the weapon types snippet from samsons site.
Heres the error I get now.

build.c: In function `do_oset':
build.c:4196: case label not within a switch statement
build.c:4200: case label not within a switch statement
build.c:4209: case label not within a switch statement
build.c:4210: case label not within a switch statement
build.c:4211: case label not within a switch statement
build.c:4218: case label not within a switch statement
build.c:4219: case label not within a switch statement
build.c:4229: case label not within a switch statement
build.c:4234: case label not within a switch statement
build.c:4235: case label not within a switch statement
build.c:4236: case label not within a switch statement
build.c:4237: case label not within a switch statement
build.c:4195: break statement not within loop or switch
build.c:4199: break statement not within loop or switch
build.c:4208: break statement not within loop or switch
build.c:4217: break statement not within loop or switch
build.c:4228: break statement not within loop or switch
build.c:4233: break statement not within loop or switch
build.c:4243: break statement not within loop or switch
make[1]: *** [build.o] Error 1
make[1]: Leaving directory `/cygdrive/c/smaug/src'
make: *** [all] Error 2

The loops, cases and breaks strike me as odd.

Heres the code (somewhat modified by me...made only one break per case)


    /*
     * Make it easier to set special object values by name than number
     * 						-Thoric
     */
    tmp = -1;
    switch( obj->item_type )	
    {
	case ITEM_PROJECTILE:
	    if ( !str_cmp( arg2, "missiletype" ) )
	    {
		int x;

		value = -1;
		for ( x = 0; x < sizeof( projectiles ) / sizeof( projectiles[0] ); x++ )
		  if ( !str_cmp( arg3, projectiles[x] ) )
		    value = x;
		if ( value < 0 )
		{
		    send_to_char( "Unknown projectile type.\n\r", ch );
		    return;
		}
		tmp = 4;
			    }

	    if ( !str_cmp( arg2, "damtype" ) )
	    {
		int x;

		value = -1;
		for ( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
		  if ( !str_cmp( arg3, attack_table[x] ) )
		    value = x;
		if ( value < 0 )
		{
		    send_to_char( "Unknown damage type.\n\r", ch );
		    return;
		}
		tmp = 3;
		break;
	    }
	case ITEM_WEAPON:
	    if ( !str_cmp( arg2, "weapontype" ) )
	    {
		int x;

		value = -1;
		for ( x = 0; x < sizeof( weapon_skills ) / sizeof( weapon_skills[0] ); x++ )
		  if ( !str_cmp( arg3, weapon_skills[x] ) )
		    value = x;
		if ( value < 0 )
		{
		    send_to_char( "Unknown weapon type.\n\r", ch );
		    return;
		}
		tmp = 4;
			    }

	    if ( !str_cmp( arg2, "damtype" ) )
	    {
		int x;

		value = -1;
		for ( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
		  if ( !str_cmp( arg3, attack_table[x] ) )
		    value = x;
		if ( value < 0 )
		{
		    send_to_char( "Unknown damage type.\n\r", ch );
		    return;
		}
		tmp = 3;
			    }
	    if ( !str_cmp( arg2, "condition" ) )	tmp = 0;
	    

	    }
	    if ( !str_cmp( arg2, "condition" ) )	tmp = 0;
	    break;
	case ITEM_ARMOR:
	    if ( !str_cmp( arg2, "condition" ) )	tmp = 3;
	    if ( !str_cmp( arg2, "ac" )	)		tmp = 1;
	    break;
	case ITEM_SALVE:
	    if ( !str_cmp( arg2, "slevel"   ) )		tmp = 0;
	    if ( !str_cmp( arg2, "maxdoses" ) )		tmp = 1;
	    if ( !str_cmp( arg2, "doses"    ) )		tmp = 2;
	    if ( !str_cmp( arg2, "delay"    ) )		tmp = 3;
	    if ( !str_cmp( arg2, "spell1"   ) )		tmp = 4;
	    if ( !str_cmp( arg2, "spell2"   ) )		tmp = 5;
	    if ( tmp >=4 && tmp <= 5 )			value = skill_lookup(arg3);
	    break;
	case ITEM_SCROLL:
	case ITEM_POTION:
	case ITEM_PILL:
	    if ( !str_cmp( arg2, "slevel" ) )		tmp = 0;
	    if ( !str_cmp( arg2, "spell1" ) )		tmp = 1;
	    if ( !str_cmp( arg2, "spell2" ) )		tmp = 2;
	    if ( !str_cmp( arg2, "spell3" ) )		tmp = 3;
	    if ( tmp >=1 && tmp <= 3 )			value = skill_lookup(arg3);
	    break;
	case ITEM_STAFF:
	case ITEM_WAND:
	    if ( !str_cmp( arg2, "slevel" ) )		tmp = 0;
	    if ( !str_cmp( arg2, "spell" ) )
	    {
	    	tmp = 3;
		value = skill_lookup(arg3);
	    }
	    if ( !str_cmp( arg2, "maxcharges" )	)	tmp = 1;
	    if ( !str_cmp( arg2, "charges" ) )		tmp = 2;
	    break;
	case ITEM_CONTAINER:
	    if ( !str_cmp( arg2, "capacity" ) )		tmp = 0;
	    if ( !str_cmp( arg2, "cflags" ) )		tmp = 1;
	    if ( !str_cmp( arg2, "key" ) )		tmp = 2;
	    break;
	case ITEM_SWITCH:
	case ITEM_LEVER:
	case ITEM_PULLCHAIN:
	case ITEM_BUTTON:
	    if ( !str_cmp( arg2, "tflags" ) )
	    {
	    	tmp = 0;
		value = get_trigflag(arg3);
	    }	
	    break;
        if ( tmp >= 0 && tmp <= 3 )
    {
	if ( !can_omodify( ch, obj ) )
	  return;
	obj->value[tmp] = value;
	if ( IS_OBJ_STAT(obj, ITEM_PROTOTYPE) )
	  obj->pIndexData->value[tmp] = value;
	return;
    }



So what do you all think?

USA #1
Hmm could you post that code again, only this time with the line numbers at the very left of each line of code?

Eg:

4756: if ( ch->whatever != YOU_SUCK )
4757: {
4758: send_to_char( "Go to hell, you bastard!", ch );


Like that. It'll make it a lot easier to debug those errors that way =)
Amended on Tue 19 Aug 2003 09:41 AM by Kris
USA #2
Or at least every 5 lines or so :)
USA #3

if ( !str_cmp( arg2, "damtype" ) )
	    {
		int x;

		value = -1;
		for ( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
		  if ( !str_cmp( arg3, attack_table[x] ) )
		    value = x;
		if ( value < 0 )
		{
		    send_to_char( "Unknown damage type.\n\r", ch );
		    return;
		}
		tmp = 3;
			    }
	    if ( !str_cmp( arg2, "condition" ) )	tmp = 0;
	    

	    }


That last bracket shouldn't be there. You're closing your switch statement. To avoid this kind of problem, the code should be properly indented :) *nag nag* :P

Also, from an efficiency standpoint, you'd be better off leaving a break inside each ifcheck block. You already determined that the argument is "weapontype", so why check for damtype?
Amended on Tue 19 Aug 2003 11:11 AM by David Haley
USA #4
That's in case weapon, right before case armor, by the way. Forgot to mention that.
Australia Forum Administrator #5
Yes indeed. In fact you can find that by using an editor that does bracket matching. By an amazing coincidence MUSHclient's notepad will do that.

If you paste the offending code (from your post) into the notepad, put the cursor to the right of the very first brace, ie.


switch( obj->item_type )	
    {<---- here


Then use Edit -> Go to matching brace (Ctrl+E) and you will see the cursor move to - unexpectedly - half-way through the switch statement. Here, in fact ...


 if ( !str_cmp( arg2, "condition" ) )	tmp = 0;
 

 } <---- here 
 if ( !str_cmp( arg2, "condition" ) )	tmp = 0;
 break;
  
case ITEM_ARMOR:


This shows you the rogue brace, which you can remove. Handy things, bracket matchers. :)

Australia Forum Administrator #6
Of course, with the brace gone, the code looks strange still. It now reads:

if ( !str_cmp( arg2, "condition" ) ) tmp = 0;
if ( !str_cmp( arg2, "condition" ) ) tmp = 0;


I can't see that this is going to do much of use. Perhaps the snippet isn't properly installed?