[CF-Devel] I want to be poisoned and blinded! :-)

Andreas Vogl andi.vogl at gmx.net
Wed Aug 23 10:59:46 CDT 2000


Hi everybody,

(Sorry this mail is a bit long...)

I´ve noticed that a character at high overall level (like 110) never gets
hit by any special-effect attacktypes like poison, paralyze, confusion,
fear, slow, blind,... . Without wearing immunities of course.
And that is independant from the attacker´s level. Even a level 200
monster can´t hit me with those attacktypes.
That irritates me since there are already so many immunities on my
equipment. Why should life as a high level char be all that easy?

So I looked at the code and here´s a copy of the important parts that do
the specific calculations:

--------------------------
server/attack.c:
~~~~~~~~~~~~~~~~
...

int hit_player_attacktype(object *op, object *hitter, int dam, 
			  uint32 attacktype, int magic)
{

...

if (op->speed && (QUERY_FLAG(op, FLAG_MONSTER) || op->type==PLAYER) &&
    !(RANDOM()%((attacktype&AT_SLOW?6:3))) && (RANDOM()%20 + 1 +
    ((op->protected&attacktype)?4:0) - ((op->vulnerable&attacktype)?4:0) 
    < savethrow[op->level]))
  {
     /* Player has been hit by something */
     if (attacktype & AT_CONFUSION) confuse_player(op,hitter,dam);
     else if (attacktype & AT_POISON) poison_player(op,hitter,dam);
     else if (attacktype & AT_SLOW) slow_player(op,hitter,dam);
     else if (attacktype & AT_PARALYZE) paralyze_player(op,hitter,dam);
     else if (attacktype & AT_FEAR) SET_FLAG(op, FLAG_SCARED);
     else if (attacktype & AT_CANCELLATION) cancellation(op);
     else if (attacktype & AT_DEPLETE) drain_stat(op);
     else if (attacktype & AT_BLIND && !QUERY_FLAG(op,FLAG_UNDEAD) &&
	      !QUERY_FLAG(op,FLAG_GENERATOR))
	      blind_player(op,hitter,dam);
   }

...

}


common/living.c:
~~~~~~~~~~~~~~~

#define MAXLEVEL      110

...

int savethrow[MAXLEVEL+1]={
  18,
  18,17,16,15,14,14,13,13,12,12,12,11,11,11,11,10,10,10,10, 9,
   9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
   6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
   4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2,
   2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
--------------------------------

I´ll try to explain how the chance of being hit is calculated above:

We have a value that consist of a random number between 1 and 20,
plus 4 if player is protected against attack, minus 4 if player is
vulnerable to attack. Let´s call this value "variable1".
The player gets hit if variable1 is less than savethrow[*player´s level*].
Now notice that savethrow[>90] is always one, while variable1 is always
greater than zero.

Conclusion: A naked player past overall level 90 is perfectly immune to
all special attacktypes!

That doesn´t make any sense does it? Why should a level 100 monster not
be able to hit a level 100 player with poison? Why should a high level
character never get blinded, etc?

My own humble opinion is that chance of being hit should not depend
on the player´s level only, but on the difference between player´s and
attacker´s level instead.

Therefor, I suggest the following change:

------------------------------------
server/attack.c:
~~~~~~~~~~~~~~~~

int hit_player_attacktype(object *op, object *hitter, int dam, 
			  uint32 attacktype, int magic)
{
int diff;

...

diff = abs(op->level - hitter->level);
if (diff > 110) diff = 110;       /* savethrow has only 111 elements */

if (... && ... || ... && ... && (RANDOM()%20 + 1 +
    ((op->protected&attacktype)?4:0) - ((op->vulnerable&attacktype)?4:0) 
    < savethrow[diff]))
  {
     /* Player has been hit by something */
     ...
  }

...

}
------------------------------------------

Before we could use poison at higher levels happily, there´s still a
second problem:
A level 100 poison cloud-infection would drain the player´s Str, Con,
Dex and Int down to about 1. "Str 1" means the player is almost unable
to move and thus doomed to die.
So we should set an upper limit to stats draining in the poison_player()
function in attack.c:

------------------------------------------
void poison_player(object *op, object *hitter, int dam)
{
  object *tmp=present_arch_in_ob(at,op);
  
  ...
  
  if(op->type==PLAYER)
    {
    tmp->stats.Con= -(dam/4+1);
    tmp->stats.Str= -(dam/3+2);
    tmp->stats.Dex= -(dam/6+1);
    tmp->stats.Int= -dam/7;

    /* a limit for all tmp->stats.* is needed, like -10 or something */
    tmp->stats.Con = tmp->stats.Str < -10 ? -10 : tmp->stats.Str;
    tmp->stats.Str = tmp->stats.Str < -10 ? -10 : tmp->stats.Str;
    tmp->stats.Dex = tmp->stats.Str < -10 ? -10 : tmp->stats.Str;
    tmp->stats.Int = tmp->stats.Str < -10 ? -10 : tmp->stats.Str;
    
    SET_FLAG(tmp,FLAG_APPLIED);
    fix_player(op);
    new_draw_info(NDI_UNIQUE, 0,op,"You suddenly feel very ill.");
    }
  
  ...
}
---------------------------------------------

I´d be glad to hear if other people agree to my thoughts...

-- 
Sent through GMX FreeMail - 
     
     http://www.gmx.net
     
     
    


More information about the crossfire mailing list