Greater Enchant Weapon Spell

Posted by Ithildin on Sun 28 Aug 2005 04:42 PM — 10 posts, 35,296 views.

USA #0
I am making a new enchant spell for my mages. It's a level 9 spell which they get at level 74. I am having trouble with the for statements. What I am wanting is this:

A mage can greater enchant a weapon and just put hit dam on it, or he can craft a scroll to recite. This scroll will enable him to put an attribute on it as well as hit dam. So example would be this:

Level 80 mage enchants a weapon without a scroll

obj has 14/10 hit dam on it and becomes casters level.

Level 80 mage enchants a weapon with scroll

obj has 14/10 hit dam along with whichever scroll he wrote. So lets say a strength scroll. SO now the weapon has 14/10 hit dam plus 2 str on it.

I know I'm doing something wrong with my for statements, just wantin to know exactly what I'm doing wrong.


void
spell_greater_enchant_weapon(int sn, int level, CHAR_DATA * ch, void *vo)
{
	OBJ_DATA       *obj = (OBJ_DATA *) vo;
    OBJ_DATA *sobj;
    OBJ_DATA *dobj;
    OBJ_DATA *cobj;
    OBJ_DATA *iobj;
    OBJ_DATA *wobj;
	AFFECT_DATA    *paf;
	int hitmod;
	int dammod;
	int attmod;

	if (obj->item_type != ITEM_WEAPON
	    || IS_OBJ_STAT(obj, ITEM_MAGIC)
	    || obj->affected) {
		send_to_char("That item cannot be enchanted.\n\r", ch);
		return;
	}
	if (obj->wear_loc != WEAR_NONE)
		remove_obj(ch, obj->wear_loc, TRUE);

	if (!affect_free) {
		paf = alloc_perm(sizeof(*paf));
	} else {
		paf = affect_free;
		affect_free = affect_free->next;
	}

	hitmod = (8 + (ch->level - 74));
	dammod = (4 + (ch->level - 74));
	attmod = (UMIN (level / 40.0f , 4.0f));

	ZeroMemory(paf, sizeof(AFFECT_DATA) );
	paf->type = sn;
	paf->duration = -1;
	paf->location = APPLY_HITROLL;
/* caps off mortal enchants*/
        if (IS_IMMORTAL(ch))
	  paf->modifier = 20;
        else
          paf->modifier = hitmod;
	paf->next = obj->affected;
	obj->affected = paf;

	if (!affect_free) {
		paf = alloc_perm(sizeof(*paf));
	} else {
		paf = affect_free;
		affect_free = affect_free->next;
	}

	paf->type = sn;
	paf->duration = -1;
	paf->location = APPLY_DAMROLL;
  /* caps off mortal enchants*/
        if (IS_IMMORTAL(ch))
   	  paf->modifier = 15;
        else 
          paf->modifier = dammod;
	paf->next = obj->affected;
	obj->affected = paf;
	obj->level = ch->level;

	if (IS_GOOD(ch)) {
		SET_BIT(obj->extra_flags, ITEM_ANTI_EVIL);
		act("$p^B glows blue.^w", ch, obj, NULL, TO_CHAR);
	} else if (IS_EVIL(ch)) {
		SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD);
		act("$p^r glows red.^w", ch, obj, NULL, TO_CHAR);
	} else {
		SET_BIT(obj->extra_flags, ITEM_ANTI_EVIL);
		SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD);
		act("$p^Y glows yellow.^w", ch, obj, NULL, TO_CHAR);
	}
     if (IS_IMMORTAL(ch))
      {
      char newname[MAX_INPUT_LENGTH];
      sprintf(newname,"%s %c%c%c",obj->name,ch->name[0],ch->name[1],
                 ch->name[2]);
      free_string (obj->name);
      obj->name = str_dup (newname);
      obj->dura = DURA_INDESTRUCTIBLE;
      }
	else 
	{
	char newname[MAX_INPUT_LENGTH];
	sprintf(newname, "%s %s", obj->name, ch->name);
	free_string (obj->name);
	obj->name = str_dup (newname);
	}

		// Strength attribute
	for (sobj = ch->carrying; sobj; sobj = sobj->next_content)
    {
      if (sobj->pIndexData->vnum == OBJ_VNUM_STR_SCROLL)
	  {
		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_STR;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
		send_to_char("ok", ch);
		break;
	   }

	
  if (!sobj)
    {
      
	// Dexterity Attribute
	for (dobj = ch->carrying; dobj; dobj = dobj->next_content)
    {
      if (dobj->pIndexData->vnum == OBJ_VNUM_DEX_SCROLL)
		  		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_DEX;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
send_to_char("ok", ch);
	break;
    }
  if (!dobj)
    {

	// Constitution Attribute
	for (cobj = ch->carrying; cobj; cobj = cobj->next_content)
    {
      if (cobj->pIndexData->vnum == OBJ_VNUM_CON_SCROLL)
		  		  		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_CON;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
send_to_char("ok", ch);
	break;
    }
  if (!cobj)
    {


	// Intelligence Attribute
	for (iobj = ch->carrying; iobj; iobj = iobj->next_content)
    {
      if (iobj->pIndexData->vnum == OBJ_VNUM_INT_SCROLL)
		  		  		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_INT;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
		send_to_char("ok", ch);
	break;
    }
  if (!iobj)
    {


	//Wisdom Attribute
	for (wobj = ch->carrying; wobj; wobj = wobj->next_content)
    {
      if (wobj->pIndexData->vnum == OBJ_VNUM_WIS_SCROLL)
		  		  		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_WIS;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
send_to_char("ok", ch);
	break;
    }
  if (!wobj)
    {
	  send_to_char("ok", ch);
	return;
  }}}}}}
  send_to_char("ok", ch);
  return;
}


If you have any more questions about it, please let me know.
USA #1
You say it doesn't work; what are some of the symptoms? It'd be easier to think about this if I know what it does, now that we know more or less what it's supposed to do.
USA #2
It stops the mud. I have it running in GDB but it doesn't error. It just stops it completely. It's still running but can't do antyhing on it. It's hung up. Here's the final output:

You complete your spell.
An ugly rattan sword glows red.
okok

So I know I have extra messages in there, but that's easily taken care of.
USA #3
Have you tried continue in gdb? It may be stuck in a loop.
USA #4
The first thing that would help would be to correctly format the program... that way it'll be immediately clear exactly how the different blocks are arranged.

Also interrupting the program in GDB as Zeno suggested is a good idea.
USA #5
How do I continue it when it's hung...it doesn't do anything in gdb. no error messages or antyhing.


	// Strength attribute
	for (sobj = ch->carrying; sobj; sobj = sobj->next_content)
    {
      if (sobj->pIndexData->vnum == OBJ_VNUM_STR_SCROLL)
	  {
		  	paf->type = sn;
		paf->duration = -1;
		paf->location = APPLY_STR;
	  /* caps off mortal enchants*/
			if (IS_IMMORTAL(ch))
   		  paf->modifier = 15;
			else 
			  paf->modifier = attmod;
		paf->next = obj->affected;
		obj->affected = paf;
		obj->level = ch->level;
		send_to_char("ok", ch);
		break;
	   }

	
	  if (!sobj)
		{
      
			// Dexterity Attribute
			for (dobj = ch->carrying; dobj; dobj = dobj->next_content)
			{
			  if (dobj->pIndexData->vnum == OBJ_VNUM_DEX_SCROLL)
		  		  			paf->type = sn;
				paf->duration = -1;
				paf->location = APPLY_DEX;
			  /* caps off mortal enchants*/
					if (IS_IMMORTAL(ch))
   				  paf->modifier = 15;
					else 
					  paf->modifier = attmod;
				paf->next = obj->affected;
				obj->affected = paf;
				obj->level = ch->level;
			    send_to_char("ok", ch);
			break;
			}
			  if (!dobj)
				{

				// Constitution Attribute
				for (cobj = ch->carrying; cobj; cobj = cobj->next_content)
				{
				  if (cobj->pIndexData->vnum == OBJ_VNUM_CON_SCROLL)
		  		  		  				paf->type = sn;
					paf->duration = -1;
					paf->location = APPLY_CON;
				  /* caps off mortal enchants*/
						if (IS_IMMORTAL(ch))
   					  paf->modifier = 15;
						else 
						  paf->modifier = attmod;
					paf->next = obj->affected;
					obj->affected = paf;
					obj->level = ch->level;
					send_to_char("ok", ch);
				break;
				}
				  if (!cobj)
					{


					// Intelligence Attribute
					for (iobj = ch->carrying; iobj; iobj = iobj->next_content)
					{
					  if (iobj->pIndexData->vnum == OBJ_VNUM_INT_SCROLL)
		  		  		  					paf->type = sn;
						paf->duration = -1;
						paf->location = APPLY_INT;
					  /* caps off mortal enchants*/
							if (IS_IMMORTAL(ch))
   						  paf->modifier = 15;
							else 
							  paf->modifier = attmod;
						paf->next = obj->affected;
						obj->affected = paf;
						obj->level = ch->level;
						send_to_char("ok", ch);
					break;
					}
					  if (!iobj)
						{


						//Wisdom Attribute
						for (wobj = ch->carrying; wobj; wobj = wobj->next_content)
						{
						  if (wobj->pIndexData->vnum == OBJ_VNUM_WIS_SCROLL)
		  		  		  						paf->type = sn;
							paf->duration = -1;
							paf->location = APPLY_WIS;
						  /* caps off mortal enchants*/
								if (IS_IMMORTAL(ch))
   							  paf->modifier = 15;
								else 
								  paf->modifier = attmod;
							paf->next = obj->affected;
							obj->affected = paf;
							obj->level = ch->level;
					send_to_char("ok", ch);
						break;
						}
						  if (!wobj)
							{
							  send_to_char("ok", ch);
							return;
							}
						}
					}
				}
			}
		}
  send_to_char("ok", ch);
  return;
}



Pretty much, what I want it doing is checking to see if it has the str scroll, if not, then go to the dex scroll, if not then go to the con, then the int, then the wis. If none of thsoe scrolls are there, then it's done. If the mage has one, then it adds the attribute.
Amended on Sun 28 Aug 2005 11:46 PM by Ithildin
USA #6
When it freezes, attach gdb to the process, and type c.

[EDIT] You've got some for loops in there, being caught in a loop is a definite possibility.
Amended on Mon 29 Aug 2005 12:13 AM by Zeno
USA #7
I think that's pretty much what it is. I'm not very good with loops. I just need to know how to end them really.

---------------------------------------------------

After looking at it. It makes my player file about 84MB so it's creating a HUGE number I'm guessing. I guess that might be from the infinite looping maybe?

[EDIT]
Yea, that's exactly what it's doing. My item gets an infinite affect added on it. So when it hangs, it's just still trying to write the affects. I just need to write those for loops better.
Amended on Mon 29 Aug 2005 12:42 AM by Ithildin
USA #8
If you want it to stop after one scroll, then you should enforce that with returns. Also, you probably shouldn't be adding the effect manually; isn't there a helper function for that kind of thing?

And finally, your indents are a little funny. Not only that but you don't need to have the whole thing be nested like that. You can have it all "flat" i.e. all the for loops on the same indent level. This isn't just a cosmetic issue; having cleanly structured code makes it much easier to think about. I tend to avoid even looking at code that isn't indented correctly.
USA #9
Some programs on Linux (Kate I know does this), has a clear indent or equizelent tool. It will clean up the code somewhat well and make it a bit more legible.

If you're on Windoze though, have fun :)