16 Apr, 2010, boblinski wrote in the 1st comment:
Votes: 0
I'm just wondering if someone can run me through how ROM handles Damroll, Strength, dice_type, dice_number, weapon_type and ArmorClass.. to calculate how hard someone hits someone else?
16 Apr, 2010, JohnnyStarr wrote in the 2nd comment:
Votes: 0
/*
* Hit one guy once.
*/
void one_hit( Character *ch, Character *victim, int dt )
{
Object *wield;
int victim_ac;
int thac0;
int thac0_00;
int thac0_32;
int dam;
int diceroll;
int sn,skill;
int dam_type;
bool result;

sn = -1;


/* just in case */
if (victim == ch || ch == NULL || victim == NULL)
return;

/*
* Can't beat a dead char!
* Guard against weird room-leavings.
*/
if ( victim->position == POS_DEAD || ch->in_room != victim->in_room )
return;

/*
* Figure out the type of damage message.
*/
wield = get_eq_char( ch, WEAR_WIELD );

if ( dt == TYPE_UNDEFINED )
{
dt = TYPE_HIT;
if ( wield != NULL && wield->item_type == ITEM_WEAPON )
dt += wield->value[3];
else
dt += ch->dam_type;
}

if (dt < TYPE_HIT)
if (wield != NULL)
dam_type = attack_table[wield->value[3]].damage;
else
dam_type = attack_table[ch->dam_type].damage;
else
dam_type = attack_table[dt - TYPE_HIT].damage;

if (dam_type == -1)
dam_type = DAM_BASH;

/* get the weapon skill */
sn = get_weapon_sn(ch);
skill = 20 + get_weapon_skill(ch,sn);

/*
* Calculate to-hit-armor-klass-0 versus armor.
*/
if ( IS_NPC(ch) )
{
thac0_00 = 20;
thac0_32 = -4; /* as good as a thief */
if (IS_SET(ch->act,ACT_WARRIOR))
thac0_32 = -10;
else if (IS_SET(ch->act,ACT_THIEF))
thac0_32 = -4;
else if (IS_SET(ch->act,ACT_CLERIC))
thac0_32 = 2;
else if (IS_SET(ch->act,ACT_MAGE))
thac0_32 = 6;
}
else
{
thac0_00 = class_table[ch->klass].thac0_00;
thac0_32 = class_table[ch->klass].thac0_32;
}
thac0 = interpolate( ch->level, thac0_00, thac0_32 );

if (thac0 < 0)
thac0 = thac0/2;

if (thac0 < -5)
thac0 = -5 + (thac0 + 5) / 2;

thac0 -= GET_HITROLL(ch) * skill/100;
thac0 += 5 * (100 - skill) / 100;

if (dt == gsn_backstab)
thac0 -= 10 * (100 - get_skill(ch,gsn_backstab));

switch(dam_type)
{
case(DAM_PIERCE):victim_ac = GET_AC(victim,AC_PIERCE)/10; break;
case(DAM_BASH): victim_ac = GET_AC(victim,AC_BASH)/10; break;
case(DAM_SLASH): victim_ac = GET_AC(victim,AC_SLASH)/10; break;
default: victim_ac = GET_AC(victim,AC_EXOTIC)/10; break;
};

if (victim_ac < -15)
victim_ac = (victim_ac + 15) / 5 - 15;

if ( !can_see( ch, victim ) )
victim_ac -= 4;

if ( victim->position < POS_FIGHTING)
victim_ac += 4;

if (victim->position < POS_RESTING)
victim_ac += 6;

/*
* The moment of excitement!
*/
while ( ( diceroll = number_bits( 5 ) ) >= 20 )
;

if ( diceroll == 0
|| ( diceroll != 19 && diceroll < thac0 - victim_ac ) )
{
/* Miss. */
damage( ch, victim, 0, dt, dam_type, TRUE );
tail_chain( );
return;
}

/*
* Hit.
* Calc damage.
*/
if ( IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL))
if (!ch->pIndexData->new_format)
{
dam = number_range( ch->level / 2, ch->level * 3 / 2 );
if ( wield != NULL )
dam += dam / 2;
}
else
dam = dice(ch->damage[DICE_NUMBER],ch->damage[DICE_TYPE]);

else
{
if (sn != -1)
check_improve(ch,sn,TRUE,5);
if ( wield != NULL )
{
if (wield->pIndexData->new_format)
dam = dice(wield->value[1],wield->value[2]) * skill/100;
else
dam = number_range( wield->value[1] * skill/100,
wield->value[2] * skill/100);

if (get_eq_char(ch,WEAR_SHIELD) == NULL) /* no shield = more */
dam = dam * 11/10;

/* sharpness! */
if (IS_WEAPON_STAT(wield,WEAPON_SHARP))
{
int percent;

if ((percent = number_percent()) <= (skill / 8))
dam = 2 * dam + (dam * 2 * percent / 100);
}
}
else
dam = number_range( 1 + 4 * skill/100, 2 * ch->level/3 * skill/100);
}

/*
* Bonuses.
*/
if ( get_skill(ch,gsn_enhanced_damage) > 0 )
{
diceroll = number_percent();
if (diceroll <= get_skill(ch,gsn_enhanced_damage))
{
check_improve(ch,gsn_enhanced_damage,TRUE,6);
dam += 2 * ( dam * diceroll/300);
}
}

if ( !IS_AWAKE(victim) )
dam *= 2;
else if (victim->position < POS_FIGHTING)
dam = dam * 3 / 2;

if ( dt == gsn_backstab && wield != NULL)
if ( wield->value[0] != 2 )
dam *= 2 + (ch->level / 10);
else
dam *= 2 + (ch->level / 8);

dam += GET_DAMROLL(ch) * UMIN(100,skill) /100;

if ( dam <= 0 )
dam = 1;

result = damage( ch, victim, dam, dt, dam_type, TRUE );

/* but do we have a funky weapon? */
if (result && wield != NULL)
{
int dam;

if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_POISON))
{
int level;
AFFECT_DATA *poison, af;

if ((poison = affect_find(wield->affected,gsn_poison)) == NULL)
level = wield->level;
else
level = poison->level;

if (!saves_spell(level / 2,victim,DAM_POISON))
{
send_to_char("You feel poison coursing through your veins.",
victim);
act("$n is poisoned by the venom on $p.",
victim,wield,NULL,TO_ROOM);

af.where = TO_AFFECTS;
af.type = gsn_poison;
af.level = level * 3/4;
af.duration = level / 2;
af.location = APPLY_STR;
af.modifier = -1;
af.bitvector = AFF_POISON;
affect_join( victim, &af );
}

/* weaken the poison if it's temporary */
if (poison != NULL)
{
poison->level = UMAX(0,poison->level - 2);
poison->duration = UMAX(0,poison->duration - 1);

if (poison->level == 0 || poison->duration == 0)
act("The poison on $p has worn off.",ch,wield,NULL,TO_CHAR);
}
}


if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_VAMPIRIC))
{
dam = number_range(1, wield->level / 5 + 1);
act("$p draws life from $n.",victim,wield,NULL,TO_ROOM);
act("You feel $p drawing your life away.",
victim,wield,NULL,TO_CHAR);
damage(ch,victim,dam,0,DAM_NEGATIVE,FALSE);
ch->alignment = UMAX(-1000,ch->alignment - 1);
ch->hit += dam/2;
}

if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_FLAMING))
{
dam = number_range(1,wield->level / 4 + 1);
act("$n is burned by $p.",victim,wield,NULL,TO_ROOM);
act("$p sears your flesh.",victim,wield,NULL,TO_CHAR);
fire_effect( (void *) victim,wield->level/2,dam,TARGET_CHAR);
damage(ch,victim,dam,0,DAM_FIRE,FALSE);
}

if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_FROST))
{
dam = number_range(1,wield->level / 6 + 2);
act("$p freezes $n.",victim,wield,NULL,TO_ROOM);
act("The cold touch of $p surrounds you with ice.",
victim,wield,NULL,TO_CHAR);
cold_effect(victim,wield->level/2,dam,TARGET_CHAR);
damage(ch,victim,dam,0,DAM_COLD,FALSE);
}

if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_SHOCKING))
{
dam = number_range(1,wield->level/5 + 2);
act("$n is struck by lightning from $p.",victim,wield,NULL,TO_ROOM);
act("You are shocked by $p.",victim,wield,NULL,TO_CHAR);
shock_effect(victim,wield->level/2,dam,TARGET_CHAR);
damage(ch,victim,dam,0,DAM_LIGHTNING,FALSE);
}
}
tail_chain( );
return;
}
16 Apr, 2010, boblinski wrote in the 3rd comment:
Votes: 0
if (IS_NPC (ch))
{
thac0_00 = 20;
thac0_32 = -4; /* as good as a thief */
if (IS_SET (ch->act, ACT_WARRIOR))
thac0_32 = -10;
else if (IS_SET (ch->act, ACT_THIEF))
thac0_32 = -4;
else if (IS_SET (ch->act, ACT_CLERIC))
thac0_32 = 2;
else if (IS_SET (ch->act, ACT_MAGE))
thac0_32 = 6;
}
else
{
thac0_00 = class_table[ch->class].thac0_00;
thac0_32 = class_table[ch->class].thac0_32;
}
thac0 = interpolate (ch->level, thac0_00, thac0_32);

if (thac0 < 0)
thac0 = thac0 / 2;

if (thac0 < -5)
thac0 = -5 + (thac0 + 5) / 2;

thac0 -= GET_HITROLL (ch) * skill / 100;
thac0 += 5 * (100 - skill) / 100;


What is this section doing?
16 Apr, 2010, Runter wrote in the 4th comment:
Votes: 0
It's the code that mainly determines hit/miss. thac0 stands to hit ac 0.
16 Apr, 2010, boblinski wrote in the 5th comment:
Votes: 0
So AC only helps to prevent hits? I always thought of Armor reducing the -damage- of hits.. not stopping them altogether.
16 Apr, 2010, 3squire wrote in the 6th comment:
Votes: 0
Yep. Prevents all damage. It's a statistical thing… in the long run, it means over many die rolls it does reduce damage. Just on any given die roll, it either does full damage or no damage. Kind of clever in an absurd way.
16 Apr, 2010, boblinski wrote in the 7th comment:
Votes: 0
Can you explain it a little more to me how AC works.. eg: what is thac0 and thac32.. why do we need both..
16 Apr, 2010, 3squire wrote in the 8th comment:
Votes: 0
Ok, so Thac0 represents the base "To Hit AC" for a level 0 character. And, you guessed it, Thaco32 is the base "To Hit AC" for a level 32 character. Back in the day you only got up to level 32 and you were happy about it!

You need both because as you gain levels you become more powerful, better able to inflict damage on your opponents. Diku did some crazy stuff. They were so lazy, rather than write out all 32 thacos, they wrote a function that "linearly interpolated" your intermediate Thaco at all levels between 0 and 32. That's why there's only two values.
16 Apr, 2010, KaVir wrote in the 9th comment:
Votes: 0
boblinski said:
Can you explain it a little more to me how AC works.. eg: what is thac0 and thac32..

THAC0 comes from AD&D, where it indicates the minimum roll needed on a 20-sided die "To Hit Armor Class 0".

3squire said:
Diku did some crazy stuff. They were so lazy, rather than write out all 32 thacos, they wrote a function that "linearly interpolated" your intermediate Thaco at all levels between 0 and 32.

:lol:
16 Apr, 2010, Cratylus wrote in the 10th comment:
Votes: 0
Normal forums have scrollbars for longass codeboxes. Kiasyn. Davion.
16 Apr, 2010, David Haley wrote in the 11th comment:
Votes: 0
Quote
Normal forums have scrollbars for longass codeboxes.

Please no. It means that many more boxes to scroll and code is annoying to read in small scrolling boxes.
16 Apr, 2010, JohnnyStarr wrote in the 12th comment:
Votes: 0
David Haley said:
Quote
Normal forums have scrollbars for longass codeboxes.

Please no. It means that many more boxes to scroll and code is annoying to read in small scrolling boxes.


Maybe it could be a toggle in your control panel?
16 Apr, 2010, Davion wrote in the 13th comment:
Votes: 0
We have a pastebin for such things! You can even use the 'link' BBCode! :) hmm. seems you can't. I shall make it so.
16 Apr, 2010, boblinski wrote in the 14th comment:
Votes: 0
Among other things, I'm trying to get a guide written out for my builders.. what I'm wanting to know are things like..

What AC a level X piece of armor should have?

What sort of HITROLL should I aim to have max level players attain with good equipment? (max level=50)

Are there tables for this kind of thing?

Thanks…… again. :biggrin:
16 Apr, 2010, Runter wrote in the 15th comment:
Votes: 0
I think hit/miss and AC is one of the first things I would redo on a stock mud even if I planned on keeping a lot of the stock code intact.

There simply wasn't a lot of time spent balancing this code and there's no surprise it's barely coherent and not data driven.
16 Apr, 2010, boblinski wrote in the 16th comment:
Votes: 0
So you think I should remove AC, thac0 and thac32 and redo all that stuff completely?
16 Apr, 2010, Runter wrote in the 17th comment:
Votes: 0
boblinski said:
So you think I should remove AC, thac0 and thac32 and redo all that stuff completely?


At the very least you should come up with standards and make the code driven by the data you provide. Don't try to mine out from the code what you think balances the game based on that code.
17 Apr, 2010, quixadhal wrote in the 18th comment:
Votes: 0
If you want to properly balance such a system, you really should grab a copy of the Dungeons & Dragons rule set and read up on how those work. The Diku guys didn't do it quite the same, but that's the system they based things on, and so knowing how the original worked will make the Diku version much easier to understand.

You can download PDF's of some of the manuals (minus artwork) for free, or check your local used comic/game store and see if they have the 2nd edition AD&D player's handbook. Don't bother with the 3rd or 4th, as those were done much later and changed the system in pretty drastic ways.
17 Apr, 2010, boblinski wrote in the 19th comment:
Votes: 0
I'm wanting to equate:

For "ch" =
Hitroll (which already takes into account the DEX.. therefore Haste).
Class (A predefined rating… Basically each class will be given a rating between 0 and 20[?]… mages 5ish, thieves 16ish, warrior 12ish, you get the picture… )
Weapon Skill
Wear Leather/Chain/Plate

vs

For "vict" =
Hitroll
Weapon Skill
Wear Leather/Chain/Plate
Size (? I'm thinking.. a giant would be much easier to hit than a pixie…. this will be balanced by Size being a factor in DAM_AMOunt.. where a pixie will take more damage per hit.. vs giants being more tough)
Dodge, Parry, Riposte, Counter, Blink, Shield Block, Evade etc


I'm not sure what the best way to go about deciding whether a hit is successful.. and I don't really have too many ideas..
17 Apr, 2010, David Haley wrote in the 20th comment:
Votes: 0
If you don't want to design your own system, it would be really good to do something like Quix suggested and borrow from something like D&D. Dikurivatives originally used (A)D&D rules but over time things got sloppy, and "features" were introduced (intentionally or not) into the combat system. So as several have said, do not assume that that code is sane or correct.
0.0/30