/**************************************************************************/ // 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; } /**************************************************************************/