[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  SMAUG
. -> [Folder]  SMAUG coding
. . -> [Subject]  My Own Remort Nightmare...

My Own Remort Nightmare...

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Toy   (206 posts)  [Biography] bio
Date Fri 04 Jun 2004 06:14 AM (UTC)

Amended on Fri 04 Jun 2004 06:16 AM (UTC) by Toy

Message
After hearing someone tell me about the remort snippet, I decided to download and try it out. I like the idea, but I need to alter it to my own need. Here's my dilema: I need to set it up so once players can only evolve (remort as I call it) into a class specific to their own class. For example, a cavalier would be able to evolve into either a paladin or an anti-paladin based on their alignment after reaching level 50.

The way it's set up now is once you're able to evolve, you can evolve into any of the classes in the game. So for starters I know I need to set the code up into a switch for each class, problem is, as a novice I don't know how to set up a set switch. :p

the current code for the class selection looks like this:


    else
    {
       if (ch->level == LEVEL_HERO)
          ch->pcdata->tier++;
       for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
       {
	  if ( class_table[iClass]->who_name[0] != '\0' && class_table[iClass]->evolve_class <= ch->pcdata->tier-1)
	  {
	     if (!str_cmp(arg, class_table[iClass]->who_name))
	        break;
	  }
       }
       if (iClass == MAX_PC_CLASS)
       {
          if (ch->level == LEVEL_HERO)
             ch->pcdata->tier--;
          send_to_char("That is not a valid class.\n\r", ch);
          return;
       }
    } 


Can someone push me off this cliff in the right direction?

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #1 on Fri 04 Jun 2004 11:52 PM (UTC)
Message
OK, so I figured I'd attempt for first switch, and I didn't do very well.

    else
    {
       if (ch->level == LEVEL_HERO)
          ch->pcdata->tier++;
       for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
       {
  if ( class_table[iClass]->who_name[0] != '\0' && class_table[iClass]->evolve_class <= ch->pcdata->tier-1)
  {
      Switch (ch->class)
      {
	case 'Warrior':
		return Barbarian;
		return Knight;
		return Ranger;
		return Samurai;
		break;
	case 'Thief':
		return Assassin;
		return Ninja;
		return Smuggler;
		break;
	case 'Mage':
		return Conjurer;
		return Elementalist;
		return Illusionist;
		return Psionicist;
		break;
	case 'Cleric':
		return Druid;
		return Monk;
		return Necromancer;
		break;
	case 'Cavalier':
		return Paladin;
		return Anti-Paladin;
		break;
      }
  }
       }
       if (iClass == MAX_PC_CLASS)
       {
          if (ch->level == LEVEL_HERO)
             ch->pcdata->tier--;
          send_to_char("That is not a valid class.\n\r", ch);
          return;
       }
    } 


so I compiled and ended up with a bunch of errors:
make smaug
gcc -c -O -g3 -Wall -Wuninitialized -DSMAUG -DTIMEFORMAT -DREGEX evolve.c
evolve.c: In function `do_evolve':
evolve.c:127: warning: implicit declaration of function `Switch'
evolve.c:128: syntax error before `{'
evolve.c:129: character constant too long
evolve.c:131: `Knight' undeclared (first use in this function)
evolve.c:131: (Each undeclared identifier is reported only once
evolve.c:131: for each function it appears in.)
evolve.c:131: warning: `return' with a value, in function returning void
evolve.c:132: `Ranger' undeclared (first use in this function)
evolve.c:132: warning: `return' with a value, in function returning void
evolve.c:133: `Samurai' undeclared (first use in this function)
evolve.c:133: warning: `return' with a value, in function returning void
evolve.c:135: character constant too long
evolve.c:135: case label not within a switch statement
evolve.c:136: `Assassin' undeclared (first use in this function)
evolve.c:136: warning: `return' with a value, in function returning void
evolve.c:137: `Ninja' undeclared (first use in this function)
evolve.c:137: warning: `return' with a value, in function returning void
evolve.c:138: `Smuggler' undeclared (first use in this function)
evolve.c:138: warning: `return' with a value, in function returning void
evolve.c:140: warning: multi-character character constant
evolve.c:140: case label not within a switch statement
evolve.c:141: `Conjurer' undeclared (first use in this function)
evolve.c:141: warning: `return' with a value, in function returning void
evolve.c:142: `Elementalist' undeclared (first use in this function)
evolve.c:142: warning: `return' with a value, in function returning void
evolve.c:143: `Illusionist' undeclared (first use in this function)
evolve.c:143: warning: `return' with a value, in function returning void
evolve.c:144: `Psionicist' undeclared (first use in this function)
evolve.c:144: warning: `return' with a value, in function returning void
evolve.c:146: character constant too long
evolve.c:146: case label not within a switch statement
evolve.c:147: `Druid' undeclared (first use in this function)
evolve.c:147: warning: `return' with a value, in function returning void
evolve.c:148: `Monk' undeclared (first use in this function)
evolve.c:148: warning: `return' with a value, in function returning void
evolve.c:149: `Necromancer' undeclared (first use in this function)
evolve.c:149: warning: `return' with a value, in function returning void
evolve.c:151: character constant too long
evolve.c:151: case label not within a switch statement
evolve.c:152: `Paladin' undeclared (first use in this function)
evolve.c:152: warning: `return' with a value, in function returning void
evolve.c:153: `Anti' undeclared (first use in this function)
evolve.c:153: warning: `return' with a value, in function returning void
evolve.c:40: warning: unused variable `iLang'
evolve.c:39: warning: unused variable `oldch'
evolve.c:37: warning: unused variable `buf'
evolve.c:38: warning: `iClass' might be used uninitialized in this function
evolve.c: At top level:
evolve.c:189: syntax error before `else'
*** Error code 1

Stop in /usr/home/toy/smaug/dist/src.
*** Error code 1

Stop in /usr/home/toy/smaug/dist/src.
>

Can someone show me what I did wrong?

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #2 on Sat 05 Jun 2004 05:52 PM (UTC)
Message
Eh. I decided to throw out the switch and try to it through a bunch of ifchecks. Thanks anyways.

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Meerclar   USA  (733 posts)  [Biography] bio
Date Reply #3 on Sat 05 Jun 2004 08:21 PM (UTC)

Amended on Sat 05 Jun 2004 08:28 PM (UTC) by Meerclar

Message
Class names to be returned need to be in quotes (ie "warrior") and switch should I believe be lower case otherwise it thinks you want to define a new function. Try those fixes and see what errors you still get.

--edit--

Having looked at the error messages again, I think your returns need to be send_to_char functions instead.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #4 on Sat 05 Jun 2004 10:09 PM (UTC)
Message
Well, after failing the switch changes Meerclar mentioned, I decided to throw this together. I'm done yet, I've reached the half way point, after listing the classes. I'm done to just restricted which classes can evolve to what.

void do_evolve( CHAR_DATA *ch, char *argument )
{
    	DESCRIPTOR_DATA *d;
    	char arg[MAX_INPUT_LENGTH];
    	char buf[MAX_INPUT_LENGTH];
	int iClass;
	int iLang;
    	CHAR_DATA *oldch;

    
    	if ( IS_NPC(ch) || ( d = ch->desc ) == NULL )
		return;
	
    	if (ch->level < LEVEL_HERO )
    	{
       		send_to_char("You have yet to possess the skills to evolve, try reaching Hero status first.\n\r", ch);
       		return;
    	}

    	if (argument[0] == '\0')
    	{
          		send_to_char("Syntax: evolve <name of class>\n\r", ch);
          		send_to_char("Syntax: evolve class list\n\r", ch);
          		return;
    	}

    	if ( ch->level > LEVEL_IMMORTAL )
    	{
        	send_to_char( "Evolution is for mortals only, trust me, you don't want to do this.\n\r", ch);
        	return;
    	}
    
    	if (ch->fighting)
    	{
       		send_to_char("You cannot be in combat if you wish to evolve.\n\r", ch);
       		return;
    	}

    	if (!str_cmp(argument, "class list"))
    	{
       		if (ch->level <= LEVEL_HERO)
          		ch->pcdata->tier++;

       		for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
       		{
                                if (ch->class == CLASS_WARRIOR)
                                send_to_char("Your Evolution choices are Barbarian, Knight, Ranger, or Samurai.\n\r", ch);
                                else
				if (ch->class == CLASS_THIEF)
                                send_to_char("Your Evolution choices are Assassin, Ninja, or Smuggler.\n\r", ch);
                                else
                                if (ch->class == CLASS_MAGE)
                                send_to_char("Your Evolution choices are Conjurer, Elementalist, Illusionist, or Psionicist.\n\r", ch);
                                else
                                if (ch->class == CLASS_CLERIC)
                                send_to_char("Your Evolution choices are Druid, Monk, or Necromancer.\n\r", ch);
                                else
                                if (ch->class == CLASS_CAVALIER)
                                send_to_char("Your Evolution choices are Paladin or Anti-Paladin.\n\r", ch);
                                return;
       		}

       		if (ch->level <= LEVEL_HERO)
          		ch->pcdata->tier--;
       			return;
    	}


I'll post the rest once I get it working, or if I get stuck.
-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #5 on Sat 05 Jun 2004 11:27 PM (UTC)
Message
Quote:


Switch (ch->class)
      {
	case 'Warrior':
		return Barbarian;
		return Knight;
		return Ranger;
		return Samurai;
		break;




OK, here goes ...


  1. You cannot switch on strings. They need to an integer or similar. Thus you cannot do this:


    case "Warrior":


  2. Strings (like "warrior") need to be in double-quotes. Single-quotes are for putting a short character literal into an integer. Hence the error message "character constant too long".

    For example, a "char" variable might hold:

    unsigned char a = 'x';

    A "short" variable might hold two characters

    unsigned short b = 'xy';

    A "long" variable might hold four characters

    unsigned long c = 'wxyz';

    However none of these are the same as the *string* "wxyz".

  3. The word "switch" is a C reserved word. It is case-sensitive. You have "Switch". Hence the error message "warning: implicit declaration of function `Switch'".

  4. Your multiple "return" statements do not make any sense:


    return Barbarian;
    return Knight;
    return Ranger;
    return Samurai;
    break;


    Control will always return at "return Barbarian", thus "return Knight", "return Ranger" etc. will never be executed and are useless, as well as confusing to people like me who are wondering what they are there for.

  5. Your function is declared as "void" however you are returning values (eg. "return Barbarian"), you cannot do that. If you want to return something you must declare the sort of thing you are returning. eg.

    
    int add (const int a, const int b)
      {
      return a + b;
      }
    


    In my simple example above I have a function that adds two numbers and returns the result. However I have declared "int add" to say that "add" returns "int". Otherwise I would have got an error message on "return a + b".



There are so many problems here I suggest you work through some simpler C examples. You need to understand what you are doing, and what I said above, or you will continue to have lots of problems.







- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Sat 05 Jun 2004 11:39 PM (UTC)
Message
This is a better place for a switch statement:

Quote:



if (ch->class == CLASS_WARRIOR)
  send_to_char("Your Evolution choices are Barbarian, Knight, Ranger, or Samurai.\n\r", ch);
else
if (ch->class == CLASS_THIEF)
  send_to_char("Your Evolution choices are Assassin, Ninja, or Smuggler.\n\r", ch);
else
if (ch->class == CLASS_MAGE)
  send_to_char("Your Evolution choices are Conjurer, Elementalist, Illusionist, or Psionicist.\n\r", ch);
else
if (ch->class == CLASS_CLERIC)
  send_to_char("Your Evolution choices are Druid, Monk, or Necromancer.\n\r", ch);
else
if (ch->class == CLASS_CAVALIER)
  send_to_char("Your Evolution choices are Paladin or Anti-Paladin.\n\r", ch);
return;



You could use "switch" here like this:


switch (ch->class)
  {
  case CLASS_WARRIOR:
    send_to_char("Your Evolution choices are Barbarian, Knight, Ranger, or Samurai.\n\r", ch);
    break;

  case CLASS_THIEF:
    send_to_char("Your Evolution choices are Assassin, Ninja, or Smuggler.\n\r", ch);
    break;

  case CLASS_MAGE:
    send_to_char("Your Evolution choices are Conjurer, Elementalist, Illusionist, or Psionicist.\n\r", ch);
    break;

  case CLASS_CLERIC:
    send_to_char("Your Evolution choices are Druid, Monk, or Necromancer.\n\r", ch);
    break;

  case CLASS_CAVALIER:
    send_to_char("Your Evolution choices are Paladin or Anti-Paladin.\n\r", ch);
    break;

  } // end of switch

  return;


See how the switch statement makes it look simpler, because you have less "if" tests?

However your code still has problems. See this part ...


for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
  {

  if (ch->class == CLASS_WARRIOR)
    send_to_char("Your Evolution choices are Barbarian, Knight, Ranger, or Samurai.\n\r", ch);
  else
  if (ch->class == CLASS_THIEF)
    send_to_char("Your Evolution choices are Assassin, Ninja, or Smuggler.\n\r", ch);
  else
  if (ch->class == CLASS_MAGE)
    send_to_char("Your Evolution choices are Conjurer, Elementalist, Illusionist, or Psionicist.\n\r", ch);
  else
  if (ch->class == CLASS_CLERIC)
    send_to_char("Your Evolution choices are Druid, Monk, or Necromancer.\n\r", ch);
  else
  if (ch->class == CLASS_CAVALIER)
    send_to_char("Your Evolution choices are Paladin or Anti-Paladin.\n\r", ch);

  return;  // will return first time through loop 
  }


Your indenting hides it, but the "return" inside the loop will return the first time through. So why have the loop?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #7 on Sun 06 Jun 2004 12:15 AM (UTC)
Message
Thanks for explaining alot of the things I was doing wrong. I have this bad habit of diving into things I'm very bad at. :)

I'll keep trying to work on these switches. Maybe I'll get the habit of them someday.

-Toy is drowning in his n00bness..

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #8 on Sun 06 Jun 2004 12:41 AM (UTC)
Message
Was looking over Nick's post, and I'm confused about something. Switches can output depending on a case, I understand that part. What I don't understand would be something like this:

case "Warrior"
(allow certain classes)

I guess what I'm confused about is the variables would work in this situation.

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #9 on Sun 06 Jun 2004 01:02 AM (UTC)
Message
Switches dont 'output' anything, rather, they are somewhat like shorthand for if-statements. They're useful for control flow, not output.

And, you cannot do a switch statement and have string cases. It's just not allowed, the reasons for which are technical.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #10 on Sun 06 Jun 2004 01:17 AM (UTC)
Message
Ah, I think I understand now. Well, at least now I know a switch can't be used for what I need. Thanks.

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #11 on Sun 06 Jun 2004 03:57 AM (UTC)
Message
Actually, it can be used for what you were trying to do, you were just doing it the wrong way:


Switch (ch->class)
      {
	case 'Warrior':
		return Barbarian;
		return Knight;
		return Ranger;
		return Samurai;
		break;


If you look at ch->class it is an int, not a string, and thus the problem really was that you can't match on 'Warrior' but CLASS_WARRIOR, which is what you did anyway later on in your "if" version.

So, this is OK:



switch (ch->class)
      {
	case CLASS_WARRIOR:
               // do something if class is Warrior	
		break;




- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #12 on Sun 06 Jun 2004 06:08 AM (UTC)
Message
Through playing around I ran into this while trying to set up the part where a player picks the class, here's what I did:

    	argument = one_argument(argument, arg);

       		if (ch->level == LEVEL_HERO)
          		ch->pcdata->tier++;
       		for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ )
       		{
	  		if ( ch->class == CLASS_WARRIOR && str_cmp(arg, "barbarian") )
	  		{
                                if (!str_cmp(arg, class_table[iClass]->who_name))
                                        break;
	  		}
       		}

       		if (iClass == MAX_PC_CLASS)
       		{
          		if (ch->level <= LEVEL_HERO)
             			ch->pcdata->tier--;

		          	send_to_char("That is not a valid class.\n\r", ch);
          			return;
       		}

Although it sorta worked backwards from what I wanted. If you select "barbarian" it said the class wasn't available, but would still allow you to change to any other class.

-Toy

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by Toy   (206 posts)  [Biography] bio
Date Reply #13 on Sun 06 Jun 2004 05:54 PM (UTC)
Message
OK, I got the do_evolve code to work by doing alot of little ifchecks like this:

	  		if (ch->class == CLASS_WARRIOR 
			&& (str_cmp(arg, "mage"))
			&& (str_cmp(arg, "cleric"))
  			&& (str_cmp(arg, "thief"))
			&& (str_cmp(arg, "cavalier"))
			&& (str_cmp(arg, "assassin"))
			&& (str_cmp(arg, "ninja"))
			&& (str_cmp(arg, "smuggler"))
			&& (str_cmp(arg, "elementalist"))
			&& (str_cmp(arg, "illusionist"))
			&& (str_cmp(arg, "conjurer"))
			&& (str_cmp(arg, "psionicist"))
			&& (str_cmp(arg, "druid"))
			&& (str_cmp(arg, "monk"))
			&& (str_cmp(arg, "necromancer"))
			&& (str_cmp(arg, "paladin"))
			&& (str_cmp(arg, "anti-paladin")))
	  		{
                                if (!str_cmp(arg, class_table[iClass]->who_name))
                                        break;
	  		}


And now it works fine. Allows only warriors to evolve into barbarian, samurai, knight, or ranger. And refuses all classes. Also worked out so those who evolved couldn't evolve again. Thanks for all the help everyone. :)

It's always good to know how far you are willing to go to be the best...

Karl Mancine
aka
Toy the Dark Puppet
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #14 on Mon 07 Jun 2004 12:58 AM (UTC)
Message
You know, it would be much better to list what it CAN be, as opposted to what it CAN'T be. :)

i.e.

if ( !strcmp(arg, bla) || !stcmp(arg, bla) ... )

Instead of having to list off all other classes, you just list off the smaller list of what it can become.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


32,925 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]