/***************************************************************************
* OBLIVION 1.2 is copyright by Wes Wagner August, 1996 *
* by using this code you have agreed to the terms of the Oblivion License*
**************************************************************************/
/* this section of code is purely oblivion coding */
#if defined(macintosh)^M
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "magic.h"
#include "color.h"
#include "obmagsys.h"
#include "recycle.h"
const struct magic_flag magic_table[MAX_SCHOOLS] =
{
{ "abjuration", "abjuration", SCHOOL_ABJURATION, 0 },
{ "alteration", "alteration", SCHOOL_ALTERATION, 0 },
{ "conjuration","conjuration", SCHOOL_CONJURATION, 0 },
{ "summoning", "summoning", SCHOOL_SUMMONING, 0 },
{ "illusion", "illusion", SCHOOL_ILLUSION, 0 },
{ "phantasm", "phantasm", SCHOOL_PHANTASM, 0 },
{ "invocation","invocation", SCHOOL_INVOCATION, 0 },
{ "evocation", "evocation", SCHOOL_EVOCATION, 0 },
{ "enchantment","enchantment", SCHOOL_ENCHANTMENT, 0 },
{ "charm", "charm", SCHOOL_CHARM, 0 },
{ "divination", "divination", SCHOOL_DIVINATION, 0 },
{ "necromancy", "necromancy", SCHOOL_NECROMANCY, 0 },
{ "wild magic", "wild magic", DISC_WILD_MAGIC, 1 },
{ "earth", "earth", DISC_ELEM_EARTH, 1 },
{ "air", "air", DISC_ELEM_AIR, 1 },
{ "water", "water", DISC_ELEM_WATER, 1 },
{ "fire", "fire", DISC_ELEM_FIRE, 1 },
{ "healing", "healing", SPHERE_HEALING, 1 },
{ "weather", "weather", SPHERE_WEATHER, 1 },
{ "protection", "protection", SPHERE_PROTECTION, 1 },
{ "plant", "plant", SPHERE_PLANT, 1 },
{ "law", "law", SPHERE_LAW, 1 },
{ "sun", "sun", SPHERE_SUN, 1 },
{ "animal", "animal", SPHERE_ANIMAL, 1 },
{ "combat", "combat", SPHERE_COMBAT, 1 },
{ "creation", "creation", SPHERE_CREATION, 1 },
{ "time", "time", SPHERE_TIME, 1 }
};
void check_realm_imp(CHAR_DATA * ch, int sn, bool success)
{
int i;
for(i=0; i<MAX_SCHOOLS; i++)
{
if(magic_table[i].is_sphere)
{
if(IS_SET(skill_table[sn].sphere_req, magic_table[i].flag))
{
check_improve(ch,skill_lookup(magic_table[i].school_name),
success,5);
}
}
else
{
if(IS_SET(skill_table[sn].realm_req, magic_table[i].flag))
{
check_improve(ch,skill_lookup(magic_table[i].school_name),
success,5);
}
}
}
return ;
}
void set_char_magic_bits(CHAR_DATA * ch)
{
int i;
if(IS_NPC(ch))
return ;
for(i=0; i<MAX_SCHOOLS; i++)
{
if(get_skill(ch,skill_lookup(magic_table[i].school_name))>0)
{
if(!magic_table[i].is_sphere)
SET_BIT(ch->pcdata->schools, magic_table[i].flag);
else
SET_BIT(ch->pcdata->spheres, magic_table[i].flag);
}
}
return ;
}
bool has_spell_req(CHAR_DATA * ch, int sn)
{
if(IS_NPC(ch))
return TRUE;
if((IS_SET(ch->pcdata->schools, skill_table[sn].realm_req) ||
skill_table[sn].realm_req==0) &&
(IS_SET(ch->pcdata->spheres, skill_table[sn].sphere_req) ||
skill_table[sn].sphere_req== 0 ))
return TRUE;
return FALSE;
}
int get_avg(CHAR_DATA * ch, int sn)
/*
* returns the average skills % for the character in all spell realms
* schools, disciplines and spheres for a given spell
*/
{
int i;
int count=0;
int total=0;
int chance=0;
for(i=0; i<MAX_SCHOOLS; i++)
{
if(magic_table[i].is_sphere)
{
if(IS_SET(skill_table[sn].sphere_req, magic_table[i].flag))
{
count++;
total+=get_skill(ch,skill_lookup(magic_table[i].school_name));
}
}
else
{
if(IS_SET(skill_table[sn].realm_req, magic_table[i].flag))
{
count++;
total+=get_skill(ch,skill_lookup(magic_table[i].school_name));
}
}
}
if(count==0)
return 0;
chance=total/count;
return chance;
}
bool check_learn_spell(CHAR_DATA * ch, int sn)
{
int chance;
if(IS_NPC(ch))
return FALSE;
if(!has_spell_req(ch,sn))
return FALSE;
if(get_skill(ch, sn)>0)
return FALSE;
chance=get_avg(ch, sn);
if(( number_range(1,100) < (chance-(skill_table[sn].skill_level[ch->class])*10) * (ch->level/10+1) / skill_table[sn].rating[ch->class] )
&& ( skill_table[sn].skill_level[ch->class]*10-10<ch->level && number_range(1,3)==3 ))
return TRUE;
return FALSE;
}
void on_level_learn(CHAR_DATA * ch)
{
int i;
char buf[MAX_STRING_LENGTH];
if(IS_NPC(ch))
return ;
set_char_magic_bits(ch);
for(i=skill_lookup("acid blast"); i<=skill_lookup("wrath"); i++)
{
if(check_learn_spell(ch,i))
{
check_realm_imp(ch,i,TRUE);
ch->pcdata->learned[i]=1;
sprintf(buf,"You have mastered the spell %s.\n\r", skill_table[i].name);
send_to_char(buf,ch);
}
}
return ;
}
void do_spinfo(CHAR_DATA *ch, char * argument)
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
int i, j, k;
bool found=FALSE;
one_argument(argument,arg);
if(arg[0]=='\0')
{
send_to_char("Realms:\n\r",ch);
send_to_char("Abjuration Alteration Conjuration Summoning Illusion\n\r",ch);
send_to_char("Phantasm Invocation Evocation Enchantment Charm Necromancy\n\r",ch);
send_to_char("Spheres:\n\r",ch);
send_to_char("Wild magic Earth Air Water Fire Healing Weather\n\r",ch);
send_to_char("Protection Plant Law Sun Animal Combat Creation Time\n\r",ch);
return ;
}
for(i=0; i<MAX_SCHOOLS; i++)
{
if(!str_cmp(magic_table[i].school_name, arg))
{
found=TRUE;
break ;
}
}
if(!found)
{
send_to_char("No such school, discipline or sphere of influence.\n\r",ch);
return ;
}
sprintf(buf, "Spell: Required realms and Spheres of Influence\n\r____________________________________________________________________\n\r");
send_to_char(buf,ch);
for(j=skill_lookup("acid blast"); j<=skill_lookup("wrath"); j++)
{
if(((magic_table[i].is_sphere) && IS_SET(skill_table[j].sphere_req,
magic_table[i].flag)) ||
((!magic_table[i].is_sphere) && IS_SET(skill_table[j].realm_req,
magic_table[i].flag)))
{
sprintf(buf, "%-20s:", skill_table[j].name);
send_to_char(buf,ch);
for(k=0; k<MAX_SCHOOLS; k++)
{
if(((magic_table[k].is_sphere) && IS_SET(skill_table[j].sphere_req,
magic_table[k].flag)) ||
((!magic_table[k].is_sphere) && IS_SET(skill_table[j].realm_req,
magic_table[k].flag)))
{
sprintf(buf, "%s ",magic_table[k].school_name);
send_to_char(buf,ch);
}
}
send_to_char("\n\r", ch);
}
}
return ;
}
void do_spells(CHAR_DATA *ch, char * argument)
{
bool found=FALSE;
int i;
int counter=0;
char buf[MAX_STRING_LENGTH];
char col[MAX_STRING_LENGTH];
BUFFER *output;
if(IS_NPC(ch))
return ;
output = new_buf();
for(i=skill_lookup("acid blast"); i<=skill_lookup("wrath"); i++)
{
if(ch->pcdata->learned[i])
{
found=TRUE;
if(ch->pcdata->learned[i]>90)
strcpy(col,FG_LT_BLUE);
else if(ch->pcdata->learned[i]>70)
strcpy(col,FG_LT_GREEN);
else if(ch->pcdata->learned[i]>50)
strcpy(col,FG_YELLOW);
else if(ch->pcdata->learned[i]>20)
strcpy(col,FG_LT_RED);
else strcpy(col,FG_DK_GRAY);
sprintf(buf,"%s%-20s %3d ", IS_SET(ch->act, PLR_COLOR) ? col : "",
skill_table[i].name, skill_table[i].min_mana);
counter++;
add_buf( output, buf );
if(counter>2)
{
add_buf( output, "\n\r" );
counter=0;
}
}
}
if(!found)
send_to_char("You have no spells.\n\r",ch);
else {
add_buf( output, "\n\r" );
page_to_char( str_dup( buf_string(output)), ch );
}
free_buf(output);
return ;
}
void do_study(CHAR_DATA * ch, char * argument)
{
char arg1[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
OBJ_DATA *scroll;
int i;
if(IS_NPC(ch))
return ;
set_char_magic_bits(ch);
argument = one_argument( argument, arg1 );
if ( ( scroll = get_obj_carry( ch, arg1 ) ) == NULL )
{
send_to_char( "You do not have that scroll.\n\r", ch );
return;
}
if ( scroll->item_type != ITEM_SCROLL )
{
send_to_char( "You can study only scrolls.\n\r", ch );
return;
}
for(i=1; i<=3; i++)
{
if(scroll->value[i]<1)
continue ;
if(ch->pcdata->learned[scroll->value[i]]>0)
{
sprintf(buf, "You already know %s.\n\r",
skill_table[scroll->value[i]].name);
send_to_char(buf,ch);
continue ;
}
if(!has_spell_req(ch,scroll->value[i]))
{
sprintf(buf, "You do not have the requirements to learn %s.\n\r",
skill_table[scroll->value[i]].name);
send_to_char(buf,ch);
continue ;
}
if(check_learn_spell(ch,scroll->value[i]))
{
ch->pcdata->learned[scroll->value[i]]=1;
sprintf(buf, "Your studious nature has paid off.\n\rYou have learned %s.\n\r",
skill_table[scroll->value[i]].name);
send_to_char(buf,ch);
check_realm_imp(ch,scroll->value[i], TRUE);
}
else
{
sprintf(buf, "You have failed to learn %s.\n\r",
skill_table[scroll->value[i]].name);
check_realm_imp(ch,scroll->value[i], FALSE);
}
}
extract_obj(scroll);
WAIT_STATE(ch, 300);
return ;
}
void do_teach(CHAR_DATA *ch, char * argument)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
int sn;
CHAR_DATA *victim;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if(arg1[0]=='\0' || arg2[0]=='\0')
{
send_to_char("Syntax: teach <character> <spell>\n\r",ch);
return ;
}
if ( ( victim = get_char_room( ch, arg1 ) ) == NULL )
{
send_to_char( "They aren't here.\n\r", ch );
return ;
}
if(IS_SET(victim->act, PLR_NOTEACH))
{
send_to_char( "They can not be taught.\n\r", ch);
return ;
}
if( ( sn = skill_lookup(arg2) ) == -1 ||
sn < skill_lookup("acid blast") ||
sn > skill_lookup("wrath") )
{
send_to_char("That is not a spell.\n\r", ch);
return ;
}
if(IS_NPC(ch) || IS_NPC(victim))
{
send_to_char("Not with npcs.\n\r", ch);
return ;
}
set_char_magic_bits(victim);
if(ch->pcdata->learned[sn]<1)
{
send_to_char("You do not know that spell.\n\r",ch);
return ;
}
if(victim->pcdata->learned[sn]>0)
{
send_to_char("They already know tht spell.\n\r",ch);
return ;
}
if(victim->position>POS_RESTING)
{
send_to_char("Your student must be in a relaxed state.\n\r",ch);
return ;
}
if(victim->position<POS_RESTING)
{
send_to_char("Your student must be awake.\n\r",ch);
return ;
}
if(check_learn_spell(victim,sn))
{
victim->pcdata->learned[sn]=1;
sprintf(buf,"You have learned %s from %s.\n\r",
skill_table[sn].name, ch->name);
send_to_char(buf,victim);
send_to_char("You have taught your student well.\n\r",ch);
check_realm_imp(ch,sn,TRUE);
check_realm_imp(ch,sn,TRUE);
}
else
{
send_to_char("You have failed.\n\r", ch);
send_to_char("Your teacher was unable to help you.\n\r", victim);
check_realm_imp(victim,sn,FALSE);
}
WAIT_STATE(ch, 400);
WAIT_STATE(victim, 400);
return ;
}