/**************************************************************************/
// magic_ce.cpp - spells/skills written by Celrion
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with the dawn license *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
**************************************************************************/
#include "include.h"
#include "magic.h"
// Local functions
DECLARE_DO_FUN( do_affects );
/**************************************************************************/
SPRESULT spell_chaotic_poison( int sn, int level, char_data *, void *vo, int )
{
char_data *victim = ( char_data * ) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ))
{
act("$n is already very ill.",victim,NULL,NULL,TO_ROOM);
return HALF_MANA;
}
if ( saves_spell( level, victim, DAMTYPE(sn))
|| HAS_CLASSFLAG(victim, CLASSFLAG_POISON_IMMUNITY))
{
act("$n turns slightly green, but it passes.",victim,NULL,NULL,TO_ROOM);
victim->printf( "You feel momentarily ill, but it passes.\r\n" );
return FULL_MANA;
}
af.where = WHERE_AFFECTS;
af.type = sn;
af.level = number_range( victim->level-5, victim->level+5 );
af.duration = number_range( victim->level-5, victim->level+5 );
af.location = APPLY_ST;
af.modifier = number_range( -10, -2 );
af.bitvector = AFF_POISON;
affect_join( victim, &af );
if ( af.level > 60 )
victim->printf( "You feel extremely sick.\r\n" );
else if ( af.level > 40 )
victim->printf( "You feel incredibly sick.\r\n" );
else if ( af.level > 20 )
victim->printf( "You feel very sick.\r\n" );
else
victim->printf( "You feel somewhat sick.\r\n" );
act("$n looks very ill.",victim,NULL,NULL,TO_ROOM);
return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_protection_acid( int sn, int level, char_data *, void *vo, int )
{
char_data *victim = (char_data *) vo;
AFFECT_DATA af;
if(!is_affected(victim,sn))
{
af.where = WHERE_RESIST;
af.type = sn;
af.level = level;
af.duration = level/4+10;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = RES_ACID;
affect_to_char(victim, &af);
victim->printf( "You are protected from all forms of acid.\r\n" );
}
else
{
victim->printf( "You are already protected from acid.\r\n" );
return HALF_MANA;
}
return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_holy_beam( int sn, int level, char_data *ch, void *vo, int )
{
char_data *victim = (char_data *) vo;
AFFECT_DATA af;
int dam;
act("$n summons forth a divine beam of light!",ch,NULL,NULL,TO_ROOM);
ch->printf( "You summon forth a divine light.\r\n" );
if ( saves_spell( level, victim, DAMTYPE(sn)))
{
ch->printf( "They seem unaffected.\r\n" );
return FULL_MANA;
}
dam = dice(level, 6)+10;
if ( IS_AFFECTED( victim, AFF_BLIND ) )
{
ch->printf( "They already appear to be blinded.\r\n" );
dam /= 2;
}
else
{
af.where = WHERE_AFFECTS;
af.type = gsn_blindness;
af.level = level;
af.location = APPLY_HITROLL;
af.modifier = -4;
af.duration = level+5;
af.bitvector = AFF_BLIND;
affect_to_char( victim, &af );
victim->printf( "You are blinded by a beam of light!\r\n" );
act("$n appears to be badly blinded by a beam of light.",victim,NULL,NULL,TO_ROOM);
}
victim->printf( "You feel your retina being seared.\r\n" );
damage_spell( ch, victim, dam, sn, DAMTYPE(sn),true );
return FULL_MANA;
}
/**************************************************************************/
void do_diagnose( char_data *ch, char *argument )
{
char arg[MIL], buf[MSL];
char_data *patient; /* <grin> */
int chance;
one_argument(argument,arg);
if ( ( chance = get_skill ( ch, gsn_diagnose ) ) == 0
|| (!IS_NPC(ch) &&
ch->level < skill_table[gsn_diagnose].skill_level[ch->clss]))
{
ch->printf( "You couldn't diagnose a cold, much less anything else.\r\n" );
return;
}
if (arg[0] == '\0')
{
ch->printf( "Diagnose who?\r\n" );
return;
}
if ( ( patient = get_char_room ( ch, arg ) ) == NULL )
{
ch->printf( "They aren't here.\r\n" );
return;
}
if ( patient == ch )
{
do_affects ( ch, "" );
return;
}
if ( patient->position >= POS_STANDING )
{
ch->printf( "Have your patient sit or rest first.\r\n" );
return;
}
if ( patient->mounted_on )
{
ch->printf( "You can't very well diagnose someone who is mounted.\r\n" );
return;
}
chance += ( ch->modifiers[STAT_EM] + ch->modifiers[STAT_RE] ) / 2;
chance += ( ch->level - patient->level );
act("$n looks over $N thoroughly.",ch,NULL,patient,TO_NOTVICT);
act("$n looks you over thoroughly.",ch,NULL,patient,TO_VICT);
if ( number_percent() < chance )
{
act("You look over $N and come to the following conclusions:",
ch,NULL,patient,TO_CHAR);
if ( !IS_NPC( patient ))
{
sprintf(buf, " They are");
if ( patient->pcdata->tired > 16 ) strcat( buf, " tired," );
( patient->pcdata->condition[COND_HUNGER] == 0 ) ?
strcat( buf, " hungry," ) : strcat( buf, " full," );
( patient->pcdata->condition[COND_DRUNK] == 0 ) ?
strcat( buf, " sober" ) : strcat( buf, " drunk" );
( patient->pcdata->condition[COND_THIRST] == 0 ) ?
strcat( buf, ", thirsty." ) : strcat( buf, "." );
strcat( buf, "\r\n" );
ch->printf( "%s\r\n", buf );
}
if ( is_affected( patient, gsn_blindness ))
ch->printf( " They appear to be blind.\r\n" );
if ( is_affected( patient, gsn_curse ))
ch->printf( " They are cursed.\r\n" );
if ( is_affected( patient, gsn_plague ))
ch->printf( " They look to have the plague.\r\n" );
if ( is_affected( patient, gsn_poison ))
ch->printf( " They appear poisoned.\r\n" );
if ( is_affected( patient, gsn_change_sex ))
ch->printf( " Their gender isn't what it used to be.\r\n" );
if ( is_affected( patient, gsn_weaken ))
ch->printf( " They appear incredibly weak.\r\n" );
if ( is_affected( patient, gsn_haste ))
ch->printf( " They appear to be moving incredibly fast.\r\n" );
if ( is_affected( patient, gsn_slow ))
ch->printf( " They appear to be stuck in slow motion.\r\n" );
if ( is_affected( patient, gsn_deafness) )
ch->printf( " They appear to be deaf.\r\n" );
if ( is_affected( patient, gsn_cause_headache) )
ch->printf( " They appear to have a headache.\r\n" );
check_improve(ch,gsn_diagnose,true,6);
}
else
{
act("You can't seem to diagnose $N properly.", ch, NULL, patient, TO_CHAR);
check_improve(ch,gsn_diagnose,false,6);
}
WAIT_STATE(ch,skill_table[gsn_diagnose].beats);
return;
}
/**************************************************************************/
SPRESULT spell_resist_weapons( int sn, int level, char_data *ch, void *,int )
{
AFFECT_DATA af;
if( is_affected(ch, sn) )
{
ch->printf( "You're already protected against weapons!\r\n" );
return HALF_MANA;
}
af.where = WHERE_RESIST;
af.type = sn;
af.level = level;
af.duration = level/4;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = RES_WEAPON;
affect_to_char(ch, &af);
ch->printf( "You feel more resistant to weapons.\r\n" );
act( "$n's skin ripples slightly.", ch, NULL, NULL, TO_ROOM );
return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_strength_of_the_land( int sn, int level, char_data *ch, void *, int )
{
AFFECT_DATA af;
if ( is_affected( ch, gsn_illusions_grandeur )) {
ch->printf( "Spell failed.\r\n" );
return HALF_MANA;
}
//Switch to check sectors
switch ( ch->in_room->sector_type ) {
case SECT_INSIDE:
case SECT_CITY:
ch->printf( "You're too far from Nature to summon the strength.\r\n" );
return HALF_MANA;
break;
case SECT_AIR:
ch->printf( "You try to summon the land's strength, but are too high in the air.\r\n" );
return HALF_MANA;
break;
case SECT_WATER_SWIM:
case SECT_WATER_NOSWIM:
ch->printf( "You try to summon the land's strength, but are too far from land itself.\r\n" );
return HALF_MANA;
break;
case SECT_UNDERWATER:
ch->printf( "You try to summon the land's strength, but are too deep underwater to do so.\r\n" );
return HALF_MANA;
break;
// Always happens if not in the above sectors :)
// default: //Should never happen.
// return HALF_MANA;
// break;
}
if ( !is_affected(ch,sn) )
{
af.where = WHERE_AFFECTS;
af.type = sn;
af.level = level;
af.duration = level/8;
af.location = APPLY_HIT;
af.modifier = level;
af.bitvector = 0;
affect_to_char( ch, &af );
ch->printf( "The power of the land enriches you!\r\n" );
act( "$n glows bright green for a moment.\r\n", ch, NULL, NULL, TO_ROOM );
}
else
{
ch->printf( "You are already enriched with the power of the land.\r\n" );
return HALF_MANA;
}
return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_deafness( int sn, int level, char_data *ch, void *vo, int )
{
char_data *victim = (char_data *) vo;
AFFECT_DATA af;
if( is_affected( victim, gsn_augment_hearing ))
if( check_dispel( level, victim, gsn_augment_hearing ))
{
act( "Your magic unravels a spell on $N.", ch, NULL, victim, TO_CHAR );
act( "Your hearing returns.", victim, NULL, NULL, TO_CHAR );
return FULL_MANA;
}
else
{
ch->printf( "You failed.\r\n" );
return FULL_MANA;
}
if ( is_affected(victim, sn) )
{
ch->printf( "They have already been deafened.\r\n" );
return HALF_MANA;
}
if (saves_spell(level,victim,DAMTYPE(sn)))
{
ch->printf( "They seem unaffected.\r\n" );
return FULL_MANA;
}
af.where = WHERE_AFFECTS;
af.type = sn;
af.level = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.duration = 1+level;
af.bitvector = 0;
affect_to_char( victim, &af );
victim->printf( "You have been deafened!\r\n" );
act("$n's ears glow for a moment.",victim,NULL,NULL,TO_ROOM);
return FULL_MANA;
}
/**************************************************************************/
SPRESULT spell_cure_deafness(int ,int level,char_data *ch,void *vo,int )
{
char_data *victim = (char_data *) vo;
if ( !is_affected( victim, gsn_deafness ) )
{
if (victim == ch)
ch->printf( "You aren't deaf.\r\n" );
else
act("$N doesn't appear to be deafened.",ch,NULL,victim,TO_CHAR);
return HALF_MANA;
}
if (check_dispel(level,victim,gsn_deafness))
{
victim->printf( "Your hearing returns!\r\n" );
act("$n is no longer deafened.",victim,NULL,NULL,TO_ROOM);
}
else
ch->printf( "Spell failed.\r\n" );
return FULL_MANA;
}
/**************************************************************************/
void do_sharpen( char_data *ch, char *)
{
OBJ_DATA *weapon = ( get_eq_char( ch, WEAR_WIELD ));
OBJ_DATA *stone = ( get_eq_char( ch, WEAR_HOLD ));
OBJ_INDEX_DATA *scrap;
int chance, degrade;
if ((chance = get_skill(ch,gsn_sharpen)) == 0)
{
do_huh(ch,"");
return;
}
if ( !weapon )
{
ch->printf( "You need to be wielding something to sharpen.\r\n" );
return;
}
if ( !stone || str_cmp( stone->pIndexData->material, "whetstone" ) )
{
ch->printf( "You need to be holding a sharpening stone.\r\n" );
return;
}
if ( (weapon->value[0] != WEAPON_DAGGER
&& weapon->value[0] != WEAPON_SWORD
&& weapon->value[0] != WEAPON_AXE)
|| IS_WEAPON_STAT(weapon,WEAPON_VORPAL))
{
act("You cannot sharpen $p.", ch, weapon, NULL, TO_CHAR);
return;
}
//Chance changes
chance += ch->modifiers[STAT_SD];
chance += ch->modifiers[STAT_ST] / 5;
//Condition change
degrade = chance > 100 ? number_range(100, chance) : number_range(chance, 100);
degrade = degrade > 100 ? degrade - 100 : 100 - degrade;
weapon->condition -= degrade;
act("You begin to sharpen $p.", ch, weapon, NULL, TO_CHAR);
act("$n begins to sharpen $p.", ch, weapon, NULL, TO_ROOM);
if ( weapon->condition <= 0 || chance < number_range(25, 75) )
{
act("You wind up completely ruining $p!", ch, weapon, NULL, TO_CHAR);
act("$n turns $p into a pile of scrap.", ch, weapon, NULL, TO_ROOM);
obj_from_char( weapon );
if (( scrap = get_obj_index( OBJ_VNUM_MUSHROOM )) == NULL )
{
ch->printf( "Non-existant item for sharpen, please report this with a note to admin.\r\n" );
bug("Non-existant item for sharpen.");
return;
}
weapon = create_object( scrap);
free_string( weapon->description );
free_string( weapon->name );
free_string( weapon->short_descr );
weapon->description = str_dup( "A pile of scrap metal lies here." );
weapon->short_descr = str_dup( "a pile of scrap metal" );
weapon->name = str_dup( "scrap metal" );
weapon->item_type = ITEM_TRASH;
obj_to_char( weapon, ch );
check_improve( ch, gsn_sharpen, false, 1);
WAIT_STATE(ch, skill_table[gsn_sharpen].beats * 3/2);
return;
}
act("You complete your work on $p.", ch, weapon, NULL, TO_CHAR);
act("$n finishes sharpening $p.", ch, weapon, NULL, TO_ROOM);
if (!IS_WEAPON_STAT( weapon, WEAPON_SHARP ))
SET_BIT(weapon->value[4], WEAPON_SHARP);
check_improve( ch, gsn_sharpen, true, 1);
WAIT_STATE(ch, skill_table[gsn_sharpen].beats);
return;
}
/**************************************************************************/