#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include "define.h" #include "struct.h" bool can_assist( char_data* ch, char_data* victim ) { if( ch == NULL || victim == NULL || ch->species != NULL ) return TRUE; if( ch->pcdata->clss != CLSS_CLERIC && ch->pcdata->clss != CLSS_PALADIN ) return TRUE; if( abs( ch->shdata->alignment%3-victim->shdata->alignment%3 ) != 2 ) return TRUE; send( ch, "You feel the energy drain from you, but for some reason the\ spirits refuse\n\ryour request.\n\r" ); return FALSE; } /* * HEALING SPELLS */ void heal_victim( char_data* ch, char_data* victim, int hp ) { const char *heal_message[] = { "You were not wounded so were not healed.\n\r", "$n was not wounded so was not healed.", "You are completely healed.\n\r", "$n is completely healed.", "Most of your wounds are gone.\n\r", "Most of $n's wounds disappear.", "Your wounds feel quite a bit better.\n\r", "$n looks quite a bit less injured.", "You are slightly healed.\n\r", "$n looks a little bit better." }; int damage = victim->max_hit-victim->hit; int i; if( !can_assist( ch, victim ) ) return; victim->hit = min( victim->max_hit, victim->hit+hp ); i = ( damage <= hp ? ( damage <= 0 ? 0 : 1 ) : ( 2*damage < 3*hp ? 2 : ( damage < 3*hp ? 3 : 4 ) ) ); send( victim, heal_message[2*i] ); act_notchar( heal_message[2*i+1], victim ); update_pos( victim ); update_max_move( victim ); return; } bool spell_cure_light( char_data* ch, char_data* victim, void*, int level, int ) { heal_victim( ch, victim, spell_damage( SPELL_CURE_LIGHT, level ) ); return TRUE; } bool spell_cure_serious( char_data* ch, char_data* victim, void*, int level, int ) { heal_victim( ch, victim, spell_damage( SPELL_CURE_SERIOUS, level ) ); return TRUE; } bool spell_group_serious( char_data* ch, char_data*, void*, int level, int ) { char_data* gch; for( int i = 0; i < *ch->array; i++ ) if( ( gch = player( ch->array->list[i] ) ) != NULL && is_same_group( gch, ch ) ) heal_victim( ch, gch, spell_damage( SPELL_GROUP_SERIOUS, level ) ); return TRUE; } bool spell_cure_critical( char_data* ch, char_data* victim, void*, int level, int ) { heal_victim( ch, victim, spell_damage( SPELL_CURE_CRITICAL, level ) ); return TRUE; } bool spell_group_critical( char_data* ch, char_data*, void*, int level, int ) { char_data* gch; for( int i = 0; i < *ch->array; i++ ) if( ( gch = player( ch->array->list[i] ) ) != NULL && is_same_group( gch, ch ) ) heal_victim( ch, gch, spell_damage( SPELL_GROUP_CRITICAL, level ) ); return TRUE; } bool spell_heal( char_data* ch, char_data* victim, void*, int level, int ) { heal_victim( ch, victim, spell_damage( SPELL_HEAL, level ) ); return TRUE; } bool spell_restoration( char_data* ch, char_data* victim, void*, int level, int ) { heal_victim( ch, victim, spell_damage( SPELL_RESTORATION, level ) ); return TRUE; } /* * REMOVE CURSE */ bool spell_remove_curse( char_data* ch, char_data* victim, void*, int level, int ) { obj_data* obj; int count = 0; if( !consenting( victim, ch, "curse removal" ) ) return TRUE; for( int i = victim->wearing.size-1; i >= 0; i-- ) { if( ( obj = object( victim->wearing[i] ) ) == NULL || ( !is_set( obj->extra_flags, OFLAG_NODROP ) && ( !is_set( obj->extra_flags, OFLAG_NOREMOVE ) ) ) ) continue; if( count++ > level/5 ) return TRUE; send( victim, "%s which you are wearing turns to dust.\n\r", obj ); send_seen( victim, "%s which %s is wearing turns to dust.\n\r", obj, victim ); obj->Extract( ); } for( int i = victim->contents.size-1; i >= 0; i-- ) { if( ( obj = object( victim->contents[i] ) ) == NULL || ( !is_set( obj->extra_flags, OFLAG_NODROP ) && ( !is_set( obj->extra_flags, OFLAG_NOREMOVE ) ) ) ) continue; if( count++ > level/5 ) return TRUE; send( victim, "%s which you are carrying turns to dust.\n\r", obj ); send_seen( victim, "%s which %s is carrying turns to dust.\n\r", obj, victim ); obj->Extract( ); } if( count == 0 ) if( victim == ch ) send( ch, "You weren't carrying anything cursed.\n\r" ); else send( ch, "%s wasn't carrying anything cursed.\n\r", victim ); return TRUE; } /* * POISON/DISEASE */ bool spell_cure_disease( char_data* ch, char_data* victim, void*, int, int ) { if( !is_set( victim->affected_by, AFF_PLAGUE ) ) { if( ch != victim ) send( ch, "%s wasn't diseased.\n\r", victim ); return TRUE; } strip_affect( victim, AFF_PLAGUE ); if( is_set( victim->affected_by, AFF_PLAGUE ) ) { send( ch, "%s is still diseased!?\n\r", victim ); send( victim, "You are still diseased!?" ); } return TRUE; } bool spell_cure_poison( char_data* ch, char_data* victim, void*, int, int ) { bool is_drunk; is_drunk = ( victim->species == NULL && ( victim->pcdata->condition[COND_ALCOHOL] > 0 || victim->pcdata->condition[COND_DRUNK] > 0 ) ); if( !is_drunk && !is_set( victim->affected_by, AFF_POISON ) ) { if( ch != victim ) send( ch, "%s wasn't poisoned.\n\r", victim ); return TRUE; } if( victim->pcdata != NULL ) { victim->pcdata->condition[ COND_ALCOHOL ] = 0; victim->pcdata->condition[ COND_DRUNK ] = 0; } strip_affect( victim, AFF_POISON ); if( is_set( victim->affected_by, AFF_POISON ) ) { if( ch != victim ) send( ch, "%s is still poisoned!?\n\r", victim ); send( victim, "You are still poisoned!?\n\r" ); } return TRUE; } /* * SILENCE SPELL */ bool spell_gift_of_tongues( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_GIFT_OF_TONGUES, AFF_TONGUES ); return TRUE; } bool spell_silence( char_data* ch, char_data* victim, void*, int level, int duration ) { if( makes_save( victim, ch, RES_MAGIC, SPELL_SILENCE, level ) ) return TRUE; spell_affect( ch, victim, level, duration, SPELL_SILENCE, AFF_SILENCE ); return TRUE; } bool spell_augury( char_data* ch, char_data*, void* vo, int, int ) { obj_data* obj = (obj_data*) vo; if( ch == NULL || obj == NULL ) return TRUE; if( !obj->Belongs( ch ) ) { fsend( ch, "%s glows black and you sense the true owner is %s.", obj, obj->owner->name ); } else { send( ch, "Nothing happens.\n\r" ); } return TRUE; } bool spell_true_sight( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_TRUE_SIGHT, AFF_TRUE_SIGHT ); return TRUE; } bool spell_protect_life( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_PROTECT_LIFE, AFF_LIFE_SAVING ); return TRUE; } bool spell_sense_life( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_SENSE_LIFE, AFF_SENSE_LIFE ); return TRUE; } /* * CREATION SPELLS */ bool spell_create_water( char_data* ch, char_data* victim, void* vo, int level, int duration ) { obj_data* obj = (obj_data*) vo; content_array* where; int liquid; int metal; /* DIP */ if( duration == -3 ) { if( ( metal = obj->metal( ) ) != 0 && number_range( 0,3 ) == 0 ) { if( obj->rust == 3 ) { send( *ch->array, "%s disintegrates into worthless pieces.\n\r", obj ); obj->Extract( 1 ); } else { send( *ch->array, "%s %s.\n\r", obj, material_table[ metal ].rust_name ); obj->rust++; } } return FALSE; } /* THROWING, REACTING */ if( ch == NULL || victim != NULL ) return FALSE; /* CAST */ liquid = LIQ_WATER; where = obj->array; if( number_range( 0, 100 ) < 2 ) { for( ; ; ) { if( ( liquid = number_range( 0, MAX_ENTRY_LIQUID-1 ) ) == LIQ_WATER || liquid_table[ liquid ].create ) break; } } obj = (obj_data*) obj->From( 1 ); obj->value[1] += 100*level; obj->value[2] = liquid; obj->selected = 1; include_empty = FALSE; include_liquid = FALSE; if( obj->value[1] >= obj->value[0] ) { send( *ch->array, "%s fills to overflowing with %s.\n\r", obj, liquid_table[ liquid ].name ); obj->value[1] = obj->value[0]; } else { send( *ch->array, "%s fills partially up with %s.\n\r", obj, liquid_table[ liquid ].name ); } include_empty = TRUE; include_liquid = TRUE; set_bit( obj->extra_flags, OFLAG_KNOWN_LIQUID ); obj->To( where ); react_filled( ch, obj, liquid ); return TRUE; } /* * OBJECT SPELLS */ bool spell_purify( char_data* ch, char_data* victim, void*, int, int ) { if( !is_set( victim->affected_by, AFF_SLEEP ) && !is_set( victim->affected_by, AFF_SLOW ) && !is_set( victim->affected_by, AFF_CURSE ) ) { if( ch != victim ) send( ch, "%s is not affected by anything which can be purified.\n\r", victim ); else send( victim, "You are not affected by anything which can be purified.\n\r" ); return TRUE; } if( is_set( victim->affected_by, AFF_SLEEP ) ) { if( ch != victim ) send( ch, "%s is no longer affected by magical sleep.\n\r", victim ); else send( victim, "You are no longer affected by magical sleep.\n\r" ); strip_affect( victim, AFF_SLEEP ); } if( is_set( victim->affected_by, AFF_CURSE ) ) { if( ch != victim ) send( ch, "%s is no longer cursed.\n\r", victim ); else send( victim, "You are no longer cursed.\n\r" ); strip_affect( victim, AFF_CURSE ); } if( is_set( victim->affected_by, AFF_SLOW ) ) { if( ch != victim ) send( ch, "%s is no longer slowed.\n\r", victim ); else send( victim, "You are no longer slowed.\n\r" ); strip_affect( victim, AFF_SLOW ); } return TRUE; } bool spell_sanctify( char_data* ch, char_data*, void *vo, int level, int ) { obj_data *obj = (obj_data*) vo; int dam; dam = obj->value[0]*(obj->value[1]+1); if( is_set( obj->extra_flags, OFLAG_SANCT ) ) { send( ch, "Nothing happens.\n\r" ); return TRUE; } if( dam > 3*level ) { fsend( *ch->array, "%s glows with a pale blue light which quickly fades.", obj ); return TRUE; } fsend( *ch->array, "%s glows with a pale blue light.\n\rThis\ slowly fades as if being absorbed into the item.", obj ); set_bit( obj->extra_flags, OFLAG_SANCT ); return TRUE; }; /* * PROTECTION SPELLS */ bool spell_armor( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_ARMOR, AFF_ARMOR ); return TRUE; } bool spell_bless( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_BLESS, AFF_BLESS ); return TRUE; } bool spell_protect_good( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_PROTECT_GOOD, AFF_PROTECT_GOOD ); return TRUE; } bool spell_protect_evil( char_data* ch, char_data* victim, void*, int level, int duration ) { spell_affect( ch, victim, level, duration, SPELL_PROTECT_EVIL, AFF_PROTECT_EVIL ); return TRUE; } /* * WRATH */ bool spell_holy_wrath( char_data *ch, char_data *victim, void*, int level, int duration ) { if( ch != NULL && ch->shdata->alignment%3 != victim->shdata->alignment%3 ) { send( ch, "You are unable to incite %s into a holy rage.\n\r", victim ); send( victim, "%s is unable to incite you into a holy rage.\n\r", ch ); return TRUE; } spell_affect( ch, victim, level, duration, SPELL_HOLY_WRATH, AFF_WRATH ); return TRUE; } /* * GOLEM SPELLS */ bool spell_animate_clay( char_data* ch, char_data*, void*, int, int ) { char_data* golem; species_data* species; if( null_caster( ch, SPELL_ANIMATE_CLAY ) ) return TRUE; for( int i = 0; i < ch->followers; i++ ) { golem = ch->followers[i]; if( is_set( &golem->status, STAT_PET ) && golem->shdata->race == RACE_GOLEM ) { send( ch, "The incarnation fails as you can only control one golem\ at a time.\n\r" ); return TRUE; } } if( ( species = get_species( MOB_CLAY_GOLEM ) ) == NULL ) { bug( "Animate_Clay: NULL species." ); return TRUE; } golem = create_mobile( species ); golem->To( ch->array ); add_follower( golem, ch ); set_bit( &golem->status, STAT_PET ); return TRUE; } /* * DEATH */ bool spell_resurrect( char_data*, char_data*, void*, int, int ) { return TRUE; } /* * FEAR */ bool spell_fear( char_data* ch, char_data* victim, void*, int level, int ) { /* if( ch == NULL ) { send( victim, "Tell merior she forgot about fear potions.\n\r" ); return TRUE; } */ if( makes_save( victim, ch, RES_MAGIC, SPELL_FEAR, level ) ) { send( ch, "You are unable to make %s afraid!\n\r", victim ); send( victim, "%s is unable to make you afraid!\n\r", ch ); send( *ch->array, "%s is unable to make %s afraid.\n\r", ch, victim ); return TRUE; } send( victim, "%s causes you to cringe in fear!\n\r", ch ); send( *ch->array, "%s cringes in fear!\n\r", victim ); disrupt_spell( victim ); set_delay( victim, 40+level ); return TRUE; }