Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
auth_update crash
Dec 23, 2017, 10:15 pm
By Remcon
check_tumble
Dec 18, 2017, 7:21 pm
By Remcon
parse description bug
Dec 15, 2017, 10:08 pm
By Remcon
Couple bugs
Dec 12, 2017, 5:42 pm
By Remcon
Bug in disarm( )
Nov 12, 2017, 6:54 pm
By GatewaySysop
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
LOP Heroes Edition
Author: Vladaar
Submitted by: Vladaar
Heroes sound extras
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.3
Author: Vladaar
Submitted by: Vladaar
Users Online
CommonCrawl, Sogou, Yahoo!, Yandex, Bing

Members: 0
Guests: 6
Stats
Files
Topics
Posts
Members
Newest Member
478
3,708
19,242
612
Jacki72H
Today's Birthdays
There are no member birthdays today.
Related Links
» SmaugMuds.org » General » General Discussions » Adding critical hit support...
Forum Rules | Mark all | Recent Posts

Adding critical hit support...
< Newer Topic :: Older Topic > works.. but doesn't..

Pages:<< prev 1 next >>
Post is unread #1 Apr 26, 2006, 7:15 pm
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Ok, So I started working on adding critical hit support, similar to that in Dungeons and Dragons, to my SmaugFUSS code, and well.. while it works.. to some point.. it's not working in any other ways, and I've spent 2 days screwing with it trying to get it to work, and finally the staff is tired of my almost constant hotbooting to test new variations, and they told me, and I quote.. "Damnit, just go talk to the guys on the forums about it." So.. in an attemtp to maintain peace.. I'ma ask for help.. yet again.

Ok, In Fight.c I've added the following boolean function:
bool check_critical( CHAR_DATA * ch, CHAR_DATA * victim, int dam )
{
  OBJ_DATA *wield;
  int diceroll;
     
   if( ( wield = get_eq_char( ch, WEAR_WIELD ) ) != NULL )
   {
      diceroll = ( number_bits( 5 ) >= 20 );
      
             if( !IS_NPC( ch ) && wield )
             {
               switch( wield->value[4] )
               {            
                  default:
                    if( diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_BAREHAND:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_SWORD:
                    if( diceroll == 17 || diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_DAGGER:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_WHIP:
                    if( diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_TALON:
                    if( diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_BOW:
                    if( diceroll == 17 || diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_MACE:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_ARCHERY:
                    if( diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_BLOWGUN:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_SLING:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_AXE:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_SPEAR:
                    if( diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_STAFF:
                    if( diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_CROSSBOW:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;    
                  case WEP_LANCE:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_KNIFE:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_HAMMER:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_CLUB:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_HALBERD:
                    if( diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_SCYTHE:
                    if( diceroll == 20 )
                    dam = dam*4;
                    break;
                  case WEP_FLAIL:
                    if( diceroll == 18 || diceroll == 19 || diceroll == 20 )
                    dam = dam*3;
                    break;
                  case WEP_PICK:
                    if( diceroll == 20 )
                    dam = dam*4;
                    break;
                  case WEP_GREAT_AXE:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
                  case WEP_GREATSWORD:
                    if( diceroll == 19 || diceroll == 20 )
                    dam = dam*2;
                    break;
               }
             return TRUE;
             }
             else
             return FALSE;
   }

   return FALSE;
}


And then in ch_ret one_hit I added a call to it:
 /*
    * Hit.
    * Calc damage.
    */

   if( !wield )   /* bare hand dice formula fixed by Thoric */
      /*
       * Fixed again by korbillian@mud.tka.com 4000 (Cold Fusion Mud) 
       */
      dam = number_range( ch->barenumdie, ch->baresizedie * ch->barenumdie ) + ch->damplus;
   else
      dam = number_range( wield->value[1], wield->value[2] );
   
   /* 
    * Critical Hits
    */
   if( diceroll == 19 || diceroll == 20 )
        check_critical( ch, victim, dam );
       
   /*
    * Bonuses.
    */
   dam += GET_DAMROLL( ch );

   if( prof_bonus )
      dam += prof_bonus / 4;


then in ch_ret damage, the following was modified to stop tumble/parry/dodge of criticals:
 /*
       * Check for disarm, trip, parry, dodge and tumble.
       */
      if( dt >= TYPE_HIT && ch->in_room == victim->in_room && !check_critical )
      {
         if( IS_NPC( ch ) && xIS_SET( ch->defenses, DFND_DISARM ) && ch->level > 9 && number_percent(  ) < ch->level / 3 ) /* Was 2 try this --Shaddai */
            disarm( ch, victim );

         if( IS_NPC( ch ) && xIS_SET( ch->attacks, ATCK_TRIP ) && ch->level > 5 && number_percent(  ) < ch->level / 2 )
            trip( ch, victim );

         if( check_parry( ch, victim ) )
            return rNONE;
         if( check_dodge( ch, victim ) )
            return rNONE;
         if( check_tumble( ch, victim ) )
            return rNONE;
      }


finally in new_dam_message, I attempted to allow for a seperate message for a critical hit:
 else if( dt > TYPE_HIT && is_wielding_poisoned( ch ) )
   {
      if( dt < TYPE_HIT + sizeof( attack_table ) / sizeof( attack_table[0] ) )
         attack = attack_table[dt - TYPE_HIT];
      else
      {
         bug( "Dam_message: bad dt %d from %s in %d.", dt, ch->name, ch->in_room->vnum );
         dt = TYPE_HIT;
         attack = attack_table[0];
      }

      snprintf( buf1, 256, "$n's poisoned %s %s $N%c &w[%d]", attack, vp, punct, dam );
      snprintf( buf2, 256, "Your poisoned %s %s $N%c &w[%d]", attack, vp, punct, dam );
      snprintf( buf3, 256, "$n's poisoned %s %s you%c &O[%d]", attack, vp, punct, dam );
   }
   else if( dt > TYPE_HIT && check_critical )
   {
      if( dt < TYPE_HIT + sizeof( attack_table ) / sizeof( attack_table[0] ) )
         attack = attack_table[dt - TYPE_HIT];
      else
      {
         bug( "Dam_message: bad dt %d from %s in %d.", dt, ch->name, ch->in_room->vnum );
         dt = TYPE_HIT;
         attack = attack_table[0];
      }

      snprintf( buf1, 256, "$n's critical %s %s $N%c &w[%d]", attack, vp, punct, dam );
      snprintf( buf2, 256, "Your critical %s %s $N%c &w[%d]", attack, vp, punct, dam );
      snprintf( buf3, 256, "$n's critical %s %s you%c &O[%d]", attack, vp, punct, dam );
   } 
   else
   {
      if( skill )


Now, the problems I'm finding are:
1. Damage isn't being modified by the switch statement in the boolean, (wasn't 100% sure this would work, to begin with.)
2. critical message in new_dam_message has replaced the default message, so every hit appears to be a critical hit.
3. Dodge/Parry/Tumble won't fire at all for mobiles..

So.. My guess is.. in my determination to solve this problem by myself, without asking here, and being even more of a burden than I already have been.. I screwed something important up.. so now.. I gotta call for help.. If more is needed from new_dam_message, I can post the rest of the function, was just trying to conserve space. :/

Thanks in advance...
       
Post is unread #2 Apr 26, 2006, 7:29 pm
Go to the top of the page
Go to the bottom of the page

Zeno
Sorcerer
GroupMembers
Posts723
JoinedMar 5, 2005

Have you checked out the critical hit snippet?
       
Post is unread #3 Apr 26, 2006, 7:38 pm
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

The one on MudMagic? Yeah, It sucks, even if you get a critical, your opponent can still dodge/parry/tumble and your critical is useless.
       
Post is unread #4 Apr 26, 2006, 8:57 pm   Last edited Apr 26, 2006, 8:58 pm by Remcon
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,868
JoinedJul 26, 2005

I once added a critical hit to mine, I followed no snippet just went on what I thought was best. First off its better handled after all the dodge/parry/tumble second its best to send the message itself from the check_critical deal. I also wouldnt bother with the whole different damage for verious weapons just increase the damage they would have done. I not only did that I even did a counter one that worked sort of like dodge etc... only it would take a swing at the one they were fighting. In the end its very cool you just seem to be over thinking it :)
       
Post is unread #5 Apr 26, 2006, 9:52 pm
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Over thinking it.. Yeah.. Quite possible. I overthink/overanalyze a lot.. The areaconvert.c deal should be proof enough. :P

But, lemme make sure I'm understanding you right. Your saying I should send the messages from the check_critical bool, and move the call from one_hit to after the check for dodge/parry/tumble?

I was trying to go for a system similar to D&D, wher eyou roll the attack die, and if it's within the threat range, typically a roll of 19 or 20, you roll again and try and roll within the weapons critical range, which was the diceroll in the boolean, and different weapon types had different critical damages, most bows would multiply your damage by 3, most swords by 2, and then Some massive hulking weapons like scythes and such would be x4 damage. This was actually an idea from a member of my staff, who happens to be a Dungeons and Dragons purist, and I like the way her idea works, I just haven't found a way to make it work. :/
       
Post is unread #6 Apr 27, 2006, 4:21 am
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,868
JoinedJul 26, 2005

Well that doesnt sound like a bad idea. Heres the thing though i see like !check_critical but no code to show what check_critical should do if no arguments for it like the function itself needs CHAR_DATA etc... but you only specify all that in one place, the rest are just checking nothing.

One reason I choose after the dodge etc... were checked is because you can't have a critical hit if you arent going to actually get the hit in it just would make no sense, and just because you would have gotten a critical doesnt make the other one less likly to dodge your attack now does it? You could still do the whole damage modify and display of damage display inside the actual check for critical hit. And although I could be wrong here I dont see how the current setup you have here will actually increase the damage. Dam is sent to check_critical it does its modifying of it, but never does anything else with it. If check_critical returned an int and was used like dam = check_critical( ch, victim, dam ); or something along that line then they would actually get a benifit from it. One of the best ways to fiqure out the best way to handle this would probably be to take a look at enhanced damage it does something similar (doesnt actually display when it increases the damage), but you get the point. Another good idea instead of making it so the code handles the actual increase based on type why not toss in for an empty value for weapons be used to decide critical like maybe v# is the damage boost during a critical.
       
Post is unread #7 Apr 27, 2006, 11:16 am
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

that's not a bad idea on using a v# for extra damage, the only problem I see though is with Samson's Weapon Proficiencies and Archery code in, builders wouldn't be able to add critical bonuses to ranged weapons, unless I added in a sixth v#, Oh Well, Let me play with it a bit and see what I can figure out. This may just turn out to be another areaconvert.c :P
       
Post is unread #8 Apr 27, 2006, 4:42 pm   Last edited Apr 27, 2006, 5:38 pm by Harbinger
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Alright, So I tried a bunch of stuff, and still got nothing, when I took the damage out of the function and moved the check to after dodge/parry/tumble, it literally quit working entirely. Where before I'd see the exra message I'd added so that I knew it fired, but it wouldn't mod the damage, Now.. I'm just not seeing anything at all. Just standard damage messages. and I'm really getting sick of screwing with them. 3 days now, and seems like only backwards progress..

[Edit]: For now, I've removed all calls to the boolean.. I'm tired of screwing with it, and 3 days with nothing but backwards progress.. I'm on the verge of killing someone.. :P
       
Post is unread #9 Apr 29, 2006, 7:46 am
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,639
JoinedJan 1, 2002

What you need to do for the bollean part is not have it be boolean. check_critical should return an integer. So you'd want to call it like so:

   /* 
    * Critical Hits
    */
   if( diceroll == 19 || diceroll == 20 )
        dam = check_critical( ch, victim, dam );


Then everywhere in check_critical you have it return TRUE or FALSE, just return dam instead since you're modifying a known value. That will take care of the damage calculation and let you stick to the purist D&D formula. The only problem is you'd have to come up with a way to see if the damage value increased, so you'll probably need a new boolean that defaults to FALSE, and a temporary "olddam" value to compare against when check_critical comes back to see if the damage value got bigger.
       
Pages:<< prev 1 next >>