/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
/***************************************************************************
* _/ _/ *
* _/_/_/ _/_/ _/_/_/ _/ _/_/ _/ _/ _/_/_/ *
* _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ *
* _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ *
* _/ _/ _/ _/_/_/ _/ _/_/ _/_/_/ _/_/_/ *
***************************************************************************
* Mindcloud Copyright 2001-2003 by Jeff Boschee (Zarius), *
* Additional credits are in the help file CODECREDITS *
* All Rights Reserved. *
***************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "interp.h"
int calculate_dam args (( CHAR_DATA *ch, CHAR_DATA *victim, int type ));
char *get_keywords_from_mob args (( MOB_INDEX_DATA *pMob ));
char *get_description_from_mob args (( MOB_INDEX_DATA *pMob ));
void do_reform( CHAR_DATA *ch, char *argument )
{
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE) && !IS_CLASS(ch, CLASS_SAMURAI))
{
send_to_char("Huh?\n\r", ch );
return;
}
if (ch->power[DISC_FAE_ARCANE] < 1 && IS_CLASS(ch, CLASS_FAE))
{
send_to_char("You need level 1 discipline in arcane.\n\r",ch);
return;
}
ch->loc_hp[0] = 0;
ch->loc_hp[1] = 0;
ch->loc_hp[2] = 0;
ch->loc_hp[3] = 0;
ch->loc_hp[4] = 0;
ch->loc_hp[5] = 0;
ch->loc_hp[6] = 0;
if (IS_CLASS(ch, CLASS_FAE))
{
ch->pcdata->powers[FAE_PLASMA_TICK] = 0;
ch->pcdata->powers[FAE_WILL_TICK] = 0;
ch->pcdata->powers[FAE_ENERGY_TICK] = 0;
ch->pcdata->powers[FAE_MATTER_TICK] = 0;
ch->pcdata->powers[FAE_PLASMA_GROWTH] = 0;
ch->pcdata->powers[FAE_WILL_GROWTH] = 0;
ch->pcdata->powers[FAE_ENERGY_GROWTH] = 0;
ch->pcdata->powers[FAE_MATTER_GROWTH] = 0;
ch->pcdata->powers[FAE_SHIELD] = 0;
}
send_to_char("#pYou reform your body, regrowing lost limbs.#n\n\r",ch);
return;
}
void do_elementalform( CHAR_DATA *ch, char *argument )
{
char buf [MAX_STRING_LENGTH];
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (ch->power[DISC_FAE_NATURE] < 10)
{
send_to_char("You are not a true master of nature.\n\r",ch);
return;
}
if (IS_SET(ch->newbits, NEW_CUBEFORM))
{
REMOVE_BIT(ch->newbits, NEW_CUBEFORM);
REMOVE_BIT(ch->affected_by, AFF_POLYMORPH);
if (IS_SET(ch->affected_by, AFF_PASS_DOOR)) REMOVE_BIT(ch->affected_by, AFF_PASS_DOOR);
act( "$n turns into a Fae.",ch,NULL,NULL,TO_ROOM);
send_to_char("You turn into your normal form.\n\r",ch);
ch->damroll -=350;
ch->hitroll -=350;
free_string(ch->morph);
ch->morph=str_dup("");
return;
}
if (ch->move < 2000 || ch->mana < 2000)
{
send_to_char("You need 2000 mana and 2000 move to change into elemental form.\n\r",ch);
return;
}
else
{
act( "$n transforms into an elemental storm.",ch,NULL,NULL,TO_ROOM);
send_to_char("You become one with the elements, letting your rage guide you.\n\r",ch);
if (!IS_SET(ch->affected_by, AFF_PASS_DOOR)) SET_BIT(ch->affected_by, AFF_PASS_DOOR);
SET_BIT(ch->newbits, NEW_CUBEFORM);
SET_BIT(ch->affected_by, AFF_POLYMORPH);
xprintf(buf,"#oAn #sElemental #oStorm #0(#g%s#0)#n",ch->name);
free_string(ch->morph);
ch->morph = str_dup(buf);
ch->move -= 2000;
ch->mana -= 2000;
ch->damroll +=350;
ch->hitroll +=350;
return;
}
return;
}
void do_channel(CHAR_DATA *ch, char *argument)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
do_channels(ch, argument);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if (arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char("Start channeling what, and at what speed?\n\r",ch);
return;
}
if (!is_number(arg2) || (atoi(arg2) < 1 || atoi(arg2) > 3))
{
send_to_char("The speed should be a number between 1 and 3.\n\r",ch);
return;
}
if (!str_prefix(arg1,"matter"))
{
if (atoi(arg2) > ch->pcdata->powers[FAE_MATTER])
{
send_to_char("You can't channel faster than your current level.\n\r",ch);
return;
}
ch->pcdata->powers[FAE_MATTER_GROWTH] = atoi(arg2);
if (ch->pcdata->powers[FAE_MATTER_TICK] == 0)
ch->pcdata->powers[FAE_MATTER_TICK] = atoi(arg2);
send_to_char("#pOk, you start channeling matter#n.\n\r",ch);
}
else if (!str_prefix(arg1,"will"))
{
if (atoi(arg2) > ch->pcdata->powers[FAE_WILL])
{
send_to_char("You can't channel faster than your current level.\n\r",ch);
return;
}
ch->pcdata->powers[FAE_WILL_GROWTH] = atoi(arg2);
if (ch->pcdata->powers[FAE_WILL_TICK] == 0)
ch->pcdata->powers[FAE_WILL_TICK] = atoi(arg2);
send_to_char("#pOk, you start concentrating your willpower#n.\n\r",ch);
}
else if (!str_prefix(arg1,"plasma"))
{
if (atoi(arg2) > ch->pcdata->powers[FAE_PLASMA])
{
send_to_char("You can't channel faster than your current level.\n\r",ch);
return;
}
ch->pcdata->powers[FAE_PLASMA_GROWTH] = atoi(arg2);
if (ch->pcdata->powers[FAE_PLASMA_TICK] == 0)
ch->pcdata->powers[FAE_PLASMA_TICK] = atoi(arg2);
send_to_char("#pOk, you start channeling plasma.#n\n\r",ch);
}
else if (!str_prefix(arg1,"energy"))
{
if (atoi(arg2) > ch->pcdata->powers[FAE_ENERGY])
{
send_to_char("You can't channel faster than your current level.\n\r",ch);
return;
}
ch->pcdata->powers[FAE_ENERGY_GROWTH] = atoi(arg2);
if (ch->pcdata->powers[FAE_ENERGY_TICK] == 0)
ch->pcdata->powers[FAE_ENERGY_TICK] = atoi(arg2);
send_to_char("#pOk, you start channeling energy.#n\n\r",ch);
}
else send_to_char("You cannot channel that.\n\r",ch);
return;
}
void do_infuse(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int dam,i,sn;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (arg1[0] == '\0')
{
send_to_char("Infuse what into whom?\n\r",ch);
return;
}
if (!str_prefix(arg1,"matter"))
{
if (ch->pcdata->powers[FAE_MATTER_TICK] == 0)
{
send_to_char("Your not charging matter.\n\r",ch);
return;
}
if (ch->pcdata->powers[FAE_SHIELD] > 0)
{
send_to_char("Your shield still exists.\n\r",ch);
return;
}
send_to_char("You weave a shield of charged matter from the fabric of the arcane.\n\r",ch);
act("$n mutters a series of arcane words and weaves a shimmering shield around $m.", ch, NULL, NULL, TO_ROOM);
ch->pcdata->powers[FAE_SHIELD] = ch->pcdata->powers[FAE_MATTER_TICK]*7; // turns on the shield.
ch->pcdata->powers[FAE_MATTER_TICK] = 0;
ch->pcdata->powers[FAE_MATTER_GROWTH] = 0;
WAIT_STATE(ch,12);
return;
}
if (arg2[0] == '\0' && ch->fighting != NULL) victim = ch->fighting;
else if ((victim = get_char_room(ch, NULL, arg2)) == NULL)
{
send_to_char("They are not here.\n\r", ch );
return;
}
if (is_safe(ch,victim)) return;
if (!str_prefix(arg1,"energy"))
{
if (ch->pcdata->powers[FAE_ENERGY_TICK] == 0)
{
send_to_char("Your not charging energy.\n\r",ch);
return;
}
act("#pYour infuse $N's body with static energy, causing great pain.#n" ,ch,NULL,victim,TO_CHAR);
act("#p$n#p touches you and chilling energies flow through your body.#n",ch,NULL,victim,TO_VICT);
act("#p$n#p touches $N, sending sparks flying.#n" ,ch,NULL,victim,TO_NOTVICT);
dam = calculate_dam(ch,victim, FAE_ENERGY);
damage(ch, victim, dam, gsn_lightning);
ch->pcdata->powers[FAE_ENERGY_GROWTH] = 0;
ch->pcdata->powers[FAE_ENERGY_TICK] = 0;
WAIT_STATE(ch,6);
return;
}
else if (!str_prefix(arg1,"plasma"))
{
if (ch->pcdata->powers[FAE_PLASMA_TICK] == 0)
{
send_to_char("Your not charging plasma.\n\r",ch);
return;
}
act("#pYour body pulsates as you channel pure plasma into $N.#n" ,ch,NULL,victim,TO_CHAR);
act("#p$n#p's body pulsates as $e channels pure plasma into you.#n",ch,NULL,victim,TO_VICT);
act("#p$n#p's body pulsates as $e channels pure plasma into $N.#n" ,ch,NULL,victim,TO_NOTVICT);
dam = calculate_dam(ch,victim, FAE_PLASMA);
for (i = 0; i < ch->pcdata->powers[FAE_PLASMA_TICK]; i++)
{
damage(ch, victim, dam, gsn_plasma);
dam *= 0.9;
}
ch->pcdata->powers[FAE_PLASMA_GROWTH] = 0;
ch->pcdata->powers[FAE_PLASMA_TICK] = 0;
WAIT_STATE(ch,12);
return;
}
else if (!str_prefix(arg1,"will"))
{
if (ch->pcdata->powers[FAE_WILL_TICK] == 0)
{
send_to_char("Your not trying to concentrate your will.\n\r",ch);
return;
}
act("#pYou bend the laws of gravity with your will and slam $N#p with stones, following up with a few spells.#n" ,ch,NULL,victim,TO_CHAR);
act("#p$n#p stares at you while muttering a few arcane words.#n",ch,NULL,victim,TO_VICT);
act("#pStones fly from the ground and slams into you while\n\r$n#p continues with the spellcasting.#n",ch,NULL,victim,TO_VICT);
act("#pstones fly from the gound and slams into $N while\n\r$n#p mutters some arcane phrases.#n" ,ch,NULL,victim,TO_NOTVICT);
for (i = 0; i < ch->pcdata->powers[FAE_WILL_TICK]; i+=2)
{
dam = calculate_dam(ch,victim, FAE_WILL);
damage(ch, victim, dam, gsn_telekinetic);
}
if ((sn = skill_lookup( "curse" ) ) > 0) (*skill_table[sn].spell_fun) (sn,50,ch,victim);
if ((sn = skill_lookup( "web" ) ) > 0) (*skill_table[sn].spell_fun) (sn,50,ch,victim);
ch->pcdata->powers[FAE_WILL_GROWTH] = 0;
ch->pcdata->powers[FAE_WILL_TICK] = 0;
WAIT_STATE(ch,12);
return;
}
else send_to_char("You have no idea how to infuse that.\n\r",ch);
return;
}
void do_conjurebow(CHAR_DATA *ch, char *argument)
{
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *obj;
AFFECT_DATA paf;
char arg[MAX_INPUT_LENGTH];
int vnum = 33260;
int cost;
argument = one_argument( argument, arg );
if (IS_NPC(ch)) return;
if( !IS_CLASS(ch, CLASS_FAE))
{
send_to_char("What?\n\r",ch);
return;
}
if (arg[0] == '\0')
{
send_to_char("How much bones do you want to spend on the bow (max 20K) ?\n\r",ch);
return;
}
if (!is_number(arg))
{
send_to_char("A number please.\n\r",ch);
return;
}
cost = atoi(arg);
if (cost < 1000 || cost > 20000)
{
send_to_char("between 1K and 20K please.\n\r",ch);
return;
}
if (ch->bones < cost)
{
send_to_char("You don't have that many qps.\n\r",ch);
return;
}
if ((pObjIndex = get_obj_index( vnum )) == NULL)
{
send_to_char("Missing object, please inform a God.\n\r",ch);
return;
}
obj = create_object(pObjIndex, 50);
obj->questowner = str_dup(ch->pcdata->switchname);
obj->ownerid = ch->pcdata->playerid;
if (cost > 19000)
{
obj->value[1] = 60;
obj->value[2] = 90;
}
else if (cost > 15000)
{
obj->value[1] = 50;
obj->value[2] = 80;
}
else if (cost > 10000)
{
obj->value[1] = 50;
obj->value[2] = 70;
}
else if (cost > 5000)
{
obj->value[1] = 40;
obj->value[2] = 60;
}
else
{
obj->value[1] = 30;
obj->value[2] = 50;
}
paf.type = 0;
paf.duration = -1;
paf.location = APPLY_HITROLL;
paf.modifier = cost/40;
paf.bitvector = 0;
affect_to_obj(obj, &paf);
paf.type = 0;
paf.duration = -1;
paf.location = APPLY_DAMROLL;
paf.modifier = cost/40;
paf.bitvector = 0;
affect_to_obj(obj, &paf);
paf.type = 0;
paf.duration = -1;
paf.location = APPLY_AC;
paf.modifier = -cost/30;
paf.bitvector = 0;
affect_to_obj(obj, &paf);
obj_to_char(obj, ch);
ch->bones -= cost;
act("You stretch your mind into the plane of energy and draw $p directly from the weave of energy.",ch,obj,NULL,TO_CHAR);
act("$p appears in $n's hands in a flash of energy.",ch,obj,NULL,TO_ROOM);
return;
}
void do_ancients(CHAR_DATA *ch, char *argument)
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
int new_power;
int cost = 2000000; // 2 million
argument = one_argument( argument, arg );
if (IS_NPC(ch)) return;
if( !IS_CLASS(ch, CLASS_FAE))
{
send_to_char("What?\n\r",ch);
return;
}
if (arg[0] == '\0')
{
xprintf(buf,"#pPlasma #G[#Y%d#G] #pMatter #G[#Y%d#G] #pEnergy #G[#Y%d#G] #pWill #G[#Y%d#G]#n\n\r",
ch->pcdata->powers[FAE_PLASMA], ch->pcdata->powers[FAE_MATTER],
ch->pcdata->powers[FAE_ENERGY], ch->pcdata->powers[FAE_WILL]);
send_to_char(buf,ch);
send_to_char("\n\r#p Which ancient would you like to improve?#n\n\r",ch);
return;
}
if (!str_cmp(arg,"plasma")) new_power = FAE_PLASMA;
else if (!str_cmp(arg,"will")) new_power = FAE_WILL;
else if (!str_cmp(arg,"energy")) new_power = FAE_ENERGY;
else if (!str_cmp(arg,"matter")) new_power = FAE_MATTER;
else
{
send_to_char("No such ancients.\n\r",ch);
return;
}
if (ch->pcdata->powers[new_power] > 7)
{
send_to_char("You know it all, your the champ.\n\r",ch);
return;
}
if (ch->wpn[6] < (ch->pcdata->powers[new_power]+1)*100)
{
send_to_char("Your blasting powers are not good enough.\n\r",ch);
return;
}
cost = cost * (ch->pcdata->powers[new_power]+1) * (ch->pcdata->powers[new_power]+1);
if (ch->exp < cost)
{
xprintf(buf,"You need %d more exp to gain that ancient.\n\r", cost - ch->exp);
send_to_char(buf,ch);
return;
}
ch->exp -= cost;
ch->pcdata->powers[new_power]++;
send_to_char("Ok.\n\r",ch);
return;
}
void do_will(CHAR_DATA *ch, char *argument)
{
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (ch->pcdata->powers[FAE_WILL] < 8)
{
send_to_char("You have not mastered your own will yet.\n\r",ch);
return;
}
if (IS_SET(ch->affected_by, AFF_FLYING))
{
REMOVE_BIT(ch->affected_by, AFF_FLYING);
send_to_char("You release your control and float slowly to the ground.\n\r",ch);
}
else
{
SET_BIT(ch->affected_by, AFF_FLYING);
send_to_char("You concentrate on the forces of gravity, and slowly float into the air.\n\r",ch);
}
WAIT_STATE(ch, 8);
return;
}
void do_matter(CHAR_DATA *ch, char *argument)
{
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (ch->pcdata->powers[FAE_MATTER] < 8)
{
send_to_char("Your control over matter is to weak.\n\r",ch);
return;
}
if (IS_AFFECTED(ch, AFF_SANCTUARY))
{
REMOVE_BIT(ch->affected_by, AFF_SANCTUARY);
send_to_char("No longer needing the shield, you disband it.\n\r",ch);
}
else
{
SET_BIT(ch->affected_by, AFF_SANCTUARY);
send_to_char("You bend the fabric of space to form a shimmering shield around you.\n\r",ch);
}
WAIT_STATE(ch,8);
return;
}
void do_energy(CHAR_DATA *ch, char *argument)
{
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (ch->pcdata->powers[FAE_ENERGY] < 8)
{
send_to_char("You cannot harness the energy yet.\n\r",ch);
return;
}
if (IS_SET(ch->itemaffect, ITEMA_CHAOSSHIELD))
{
if(IS_ITEMAFF(ch, ITEMA_FIRESHIELD))
REMOVE_BIT(ch->itemaffect, ITEMA_FIRESHIELD);
if(IS_ITEMAFF(ch, ITEMA_ACIDSHIELD))
REMOVE_BIT(ch->itemaffect, ITEMA_ACIDSHIELD);
if(IS_ITEMAFF(ch, ITEMA_SHOCKSHIELD))
REMOVE_BIT(ch->itemaffect, ITEMA_SHOCKSHIELD);
if(IS_ITEMAFF(ch, ITEMA_ICESHIELD))
REMOVE_BIT(ch->itemaffect, ITEMA_ICESHIELD);
if(IS_ITEMAFF(ch, ITEMA_CHAOSSHIELD))
REMOVE_BIT(ch->itemaffect, ITEMA_CHAOSSHIELD);
REMOVE_BIT(ch->itemaffect, ITEMA_CHAOSHANDS);
send_to_char("Your shields flicker and die.\n\r",ch);
}
else
{
if(!IS_ITEMAFF(ch, ITEMA_FIRESHIELD))
SET_BIT(ch->itemaffect, ITEMA_FIRESHIELD);
if(!IS_ITEMAFF(ch, ITEMA_ACIDSHIELD))
SET_BIT(ch->itemaffect, ITEMA_ACIDSHIELD);
if(!IS_ITEMAFF(ch, ITEMA_SHOCKSHIELD))
SET_BIT(ch->itemaffect, ITEMA_SHOCKSHIELD);
if(!IS_ITEMAFF(ch, ITEMA_ICESHIELD))
SET_BIT(ch->itemaffect, ITEMA_ICESHIELD);
if(!IS_ITEMAFF(ch, ITEMA_CHAOSSHIELD))
SET_BIT(ch->itemaffect, ITEMA_CHAOSSHIELD);
SET_BIT(ch->itemaffect, ITEMA_CHAOSHANDS);
send_to_char("You form shields of different colors, each representing the different energies in the universe.\n\r",ch);
}
WAIT_STATE(ch, 8);
return;
}
void do_plasma2(CHAR_DATA *ch, char *argument)
{
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r",ch);
return;
}
if (ch->pcdata->powers[FAE_PLASMA] < 8)
{
send_to_char("The plasma refuse to do your bidding.\n\r",ch);
return;
}
if (IS_AFFECTED(ch, AFF_PROTECT) || IS_AFFECTED(ch, AFF_PROTECT_GOOD))
{
if (IS_SET(ch->affected_by, AFF_PROTECT)) REMOVE_BIT(ch->affected_by, AFF_PROTECT);
if (IS_SET(ch->affected_by, AFF_PROTECT_GOOD)) REMOVE_BIT(ch->affected_by, AFF_PROTECT_GOOD);
send_to_char("You call off your shield of protection.\n\r",ch);
}
else
{
if (IS_GOOD(ch))
{
SET_BIT(ch->affected_by, AFF_PROTECT);
send_to_char("You summon a mystical force to protect you from evil.\n\r",ch);
}
else if (IS_EVIL(ch))
{
SET_BIT(ch->affected_by, AFF_PROTECT_GOOD);
send_to_char("You summon a mystical force to protect you from good.\n\r",ch);
}
else send_to_char("Nothing happens.\n\r",ch);
}
WAIT_STATE(ch, 8);
return;
}
int calculate_dam(CHAR_DATA *ch, CHAR_DATA *victim, int type)
{
int dam = 0;
dam += char_damroll(ch)/5;
if (type == FAE_PLASMA)
{
dam *= 1 + ch->pcdata->powers[FAE_PLASMA]/4;
dam *= ch->pcdata->powers[FAE_PLASMA_TICK]/1.3;
}
else if (type == FAE_ENERGY)
{
dam *= 1 + ch->pcdata->powers[FAE_ENERGY]/2;
dam *= ch->pcdata->powers[FAE_ENERGY_TICK]*1.5;
}
else if (type == FAE_WILL)
{
dam *= 1 + ch->pcdata->powers[FAE_WILL]/4;
dam *= ch->pcdata->powers[FAE_WILL_TICK]/1.8;
}
dam = number_range(dam/3, dam/2);
if (dam > ch->damcap[DAM_CAP]) dam = ch->damcap[DAM_CAP] + number_range(-100,100);
if (IS_AFFECTED(victim, AFF_SANCTUARY)) dam /= 2;
return dam;
}
void do_djinn(CHAR_DATA *ch, char *argument)
{
MOB_INDEX_DATA *pMobIndex;
MOB_TRIGGER *mProg;
CHAR_DATA *mob;
ROOM_INDEX_DATA *pRoom;
int vnum;
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r", ch);
return;
}
if (ch->power[DISC_FAE_NATURE] < 8)
{
send_to_char("You need at least level 8 in nature to summon The Djinn.\n\r",ch);
return;
}
if (!TIME_UP(ch, TIMER_DJINN))
{
send_to_char("You can only summon the djinn once every 24 hours.\n\r", ch);
return;
}
if ((pRoom = get_room_index(3001)) == NULL) return;
if (pRoom->area == ch->in_room->area)
{
send_to_char("This power cannot function in midgaard.\n\r", ch);
return;
}
if ((pMobIndex = get_mob_index(20)) == NULL)
{
send_to_char("Bug, please report this to an immortal.\n\r", ch);
return;
}
SET_TIMER(ch, TIMER_DJINN, 24);
mob = create_mobile(pMobIndex);
mob->decay_pulse = number_range(4, 8);
for (vnum = ch->in_room->area->lvnum; vnum <= ch->in_room->area->uvnum; vnum++)
{
if ((pMobIndex = get_mob_index(vnum)) != NULL)
{
if (trigger_free == NULL)
{
mProg = alloc_perm(sizeof(*mProg));
}
else
{
mProg = trigger_free;
trigger_free = trigger_free->next;
}
mProg->type = MTRIG_SAY;
mProg->vnum = 0;
mProg->keywords = str_dup(get_keywords_from_mob(pMobIndex));
mProg->roomOutput = str_dup(get_description_from_mob(pMobIndex));
mProg->chOutput = str_dup("");
mProg->next = mob->triggers;
mob->triggers = mProg;
}
}
char_to_room(mob, ch->in_room);
do_say(ch, "Oh mighty djinn of the seven ages, I bid you to join my service");
act("$n appears in a puff of smoke.", mob, NULL, NULL, TO_ROOM);
do_say(mob, "I come to do your bidding master.");
return;
}
void do_genie(CHAR_DATA *ch, char *argument)
{
MOB_INDEX_DATA *pMobIndex;
MOB_TRIGGER *mProg;
CHAR_DATA *mob;
if (IS_NPC(ch)) return;
if (!IS_CLASS(ch, CLASS_FAE))
{
send_to_char("Huh?\n\r", ch);
return;
}
if (ch->power[DISC_FAE_ARCANE] < 8)
{
send_to_char("You need at least level 8 in arcane to summon The Genie.\n\r",ch);
return;
}
if (!TIME_UP(ch, TIMER_GENIE))
{
send_to_char("You can only summon The Genie once every 24 hours.\n\r", ch);
return;
}
if ((pMobIndex = get_mob_index(21)) == NULL)
{
send_to_char("Bug, please report this to an immortal.\n\r", ch);
return;
}
SET_TIMER(ch, TIMER_GENIE, 24);
mob = create_mobile(pMobIndex);
mob->decay_pulse = number_range(4, 8);
/*
if (trigger_free == NULL)
{
mProg = alloc_perm(sizeof(*mProg));
}
else
{
mProg = trigger_free;
trigger_free = trigger_free->next;
}
mProg->type = MTRIG_SCRY;
mProg->vnum = 0;
mProg->keywords = str_dup("&scry*");
mProg->roomOutput = str_dup("");
mProg->chOutput = str_dup("");
mProg->next = mob->triggers;
mob->triggers = mProg;
*/
if (trigger_free == NULL)
{
mProg = alloc_perm(sizeof(*mProg));
}
else
{
mProg = trigger_free;
trigger_free = trigger_free->next;
}
mProg->type = MTRIG_LOCATE;
mProg->vnum = 0;
mProg->keywords = str_dup("&locate*");
mProg->roomOutput = str_dup("I suggest you walk the following path, '%s'.");
mProg->chOutput = str_dup("I'm afraid I cannot locate that person master.");
mProg->next = mob->triggers;
mob->triggers = mProg;
char_to_room(mob, ch->in_room);
do_say(ch, "Oh mighty genie, bloodson to the Prince of the East, head my call");
act("$n appears in a puff of smoke.", mob, NULL, NULL, TO_ROOM);
do_say(mob, "Ask your questions mortal, before I bid you goodbye.");
return;
}
char *get_keywords_from_mob(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
char *ptr, *ptr2, *ptr3;
buf[0] = '\0';
ptr = pMob->player_name;
ptr2 = buf;
ptr3 = "&what*|";
while ((*ptr2 = *ptr3) != '\0')
++ptr2, ++ptr3;
while (*ptr != '\0')
{
if (*ptr != ' ') *ptr2 = *ptr;
else
{
*ptr2 = '*';
}
ptr++; ptr2++;
}
*ptr2 = '*'; ptr2++; *ptr2 = '\0';
return buf;
}
char *mob_might(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
if (pMob->level < 100)
xprintf(buf, "a pitiful creature");
else if (pMob->level < 250)
xprintf(buf, "a dangerous creature");
else if (pMob->level < 500)
xprintf(buf, "a fierce beast");
else if (pMob->level < 1000)
xprintf(buf, "a mighty beast");
else
xprintf(buf, "a powerful being");
return buf;
}
char *mob_toughness(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
if (pMob->toughness < - 50)
xprintf(buf, "a frail body");
else if (pMob->toughness < 0)
xprintf(buf, "a weak body");
else if (pMob->toughness < 25)
xprintf(buf, "a normal toughness");
else if (pMob->toughness < 50)
xprintf(buf, "increased toughness");
else
xprintf(buf, "superior toughness");
return buf;
}
char *mob_attacks(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
if (pMob->extra_attack < 1)
xprintf(buf, "a few");
else if (pMob->extra_attack < 5)
xprintf(buf, "some");
else if (pMob->extra_attack < 10)
xprintf(buf, "many");
else if (pMob->extra_attack < 15)
xprintf(buf, "increadible many");
else
xprintf(buf, "a huge amount of");
return buf;
}
char *mob_damage(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
if (pMob->dam_modifier < 2)
xprintf(buf, "a normal amount of");
else if (pMob->dam_modifier == 2)
xprintf(buf, "an increased amount of");
else if (pMob->dam_modifier > 2)
xprintf(buf, "a huge amount of");
return buf;
}
char *get_description_from_mob(MOB_INDEX_DATA *pMob)
{
static char buf[MAX_STRING_LENGTH];
xprintf(buf, "%s is %s with %s. It has %s attacks, each dealing %s damage.",
pMob->short_descr, mob_might(pMob), mob_toughness(pMob), mob_attacks(pMob), mob_damage(pMob));
return buf;
}
char *cut_after_tracking(char *str)
{
static char buf[MAX_STRING_LENGTH];
char *ptr;
bool found = FALSE;
buf[0] = '\0';
ptr = buf;
if (!is_contained2(" tracking ", str)) return NULL;
for (;;)
{
while (*str != ' ') str++;
str++;
while (*str != '\0' && *str != ' ')
{
*ptr = *str;
ptr++; str++;
}
*ptr = '\0';
if (found) return buf;
if (!str_cmp(buf, "tracking"))
found = TRUE;
buf[0] = '\0';
ptr = buf;
}
return buf;
}
char *cut_after_locate(char *str)
{
static char buf[MAX_STRING_LENGTH];
char *ptr;
bool found = FALSE;
buf[0] = '\0';
ptr = buf;
if (!is_contained2(" locate ", str)) return NULL;
for (;;)
{
while (*str != ' ') str++;
str++;
while (*str != '\0' && *str != ' ')
{
*ptr = *str;
ptr++; str++;
}
*ptr = '\0';
if (found) return buf;
if (!str_cmp(buf, "locate"))
found = TRUE;
buf[0] = '\0';
ptr = buf;
}
return buf;
}
char *cut_after_scry(char *str)
{
static char buf[MAX_STRING_LENGTH];
char *ptr;
bool found = FALSE;
buf[0] = '\0';
ptr = buf;
if (!is_contained2(" scry ", str)) return NULL;
for (;;)
{
while (*str != ' ') str++;
str++;
while (*str != '\0' && *str != ' ')
{
*ptr = *str;
ptr++; str++;
}
*ptr = '\0';
if (found) return buf;
if (!str_cmp(buf, "scry"))
found = TRUE;
buf[0] = '\0';
ptr = buf;
}
return buf;
}