/*
* Elkandu Magic System
*
* Written by Keolah for Rogue Winds
*
* This is an experiment at creating a non spell based magic system, involving
* different combinations of keywords to create a desired magical effect.
* Assumption: All players are mages, and can make at least minimal use of their magic.
*
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#ifdef sun
#include <strings.h>
#endif
#include <time.h>
#include "mud.h"
/* from act_move.c */
extern void drop_dream_items(CHAR_DATA *ch, OBJ_DATA *obj);
/* from birth.c */
extern void set_race(CHAR_DATA *ch, bool died);
/* from bodyparts.c */
extern void add_part(CHAR_DATA *ch, int part, int to_part);
/* from combat.c */
extern void ranged_attack(CHAR_DATA *ch, OBJ_DATA *obj, char *argument);
extern bool can_gain_exp(CHAR_DATA *ch, CHAR_DATA *victim);
/* from handler.c */
extern MATERIAL_DATA *material_lookup( int number );
extern SPECIES_DATA *find_species(char *name);
extern char *munch_colors(char *word);
/* from talent.c */
extern bool can_travel(int i, CHAR_DATA *ch, CHAR_DATA *victim);
typedef enum {
ACT_TRICKS, ACT_HARM, ACT_HELP, ACT_CHANGE, ACT_MOVE, ACT_FIND, ACT_CREATE,
ACT_ENHANCE, ACT_HINDER, ACT_FOCUS, ACT_RUNE, ACT_SING, ACT_CONTROL
} action_types;
void obj_trick(CHAR_DATA *ch, OBJ_DATA *obj, int type) {
char buf[MAX_STRING_LENGTH];
switch (type) {
default:
sprintf(buf, "&PRaw mana %s $p and %s.",
number_range(1,2) == 1 ? "surrounds" : "circles",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_FIRE:
sprintf(buf, "&R%s flames %s %s $p and %s.",
number_range(1,2) == 1 ? "Flickering" : "Lambent",
number_range(1,2) == 1 ? "streak" : "dance",
number_range(1,2) == 1 ? "over" : "along",
number_range(1,2) == 1 ? "vanish" : "disappear"
);
break;
case MAG_EARTH:
sprintf(buf, "&GLeaves %s %s $p and %s.",
number_range(1,2) == 1 ? "sprout" : "grow",
number_range(1,2) == 1 ? "from" : "all over",
number_range(1,2) == 1 ? "wither" : "fall off"
);
break;
case MAG_BLUNT:
sprintf(buf, "&O%s %s %s $p %s.",
number_range(1,2) == 1 ? "Tiny" : "Little",
number_range(1,2) == 1 ? "pebbles" : "bits of rock",
number_range(1,2) == 1 ? "pelt" : "strike",
number_range(1,2) == 1 ? "lightly" : "softly"
);
break;
case MAG_ELECTRICITY:
sprintf(buf, "&Y%s %s %s %s $p and %s.",
number_range(1,2) == 1 ? "Crackling" : "White",
number_range(1,2) == 1 ? "lightning" : "electricity",
number_range(1,2) == 1 ? "shoots" : "races",
number_range(1,2) == 1 ? "over" : "along",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_WIND:
sprintf(buf, "&c%s %s %s $p and %s %s.",
number_range(1,2) == 1 ? "Howling" : "Whipping",
number_range(1,2) == 1 ? "winds" : "storms",
number_range(1,2) == 1 ? "twist around" : "surround",
number_range(1,2) == 1 ? "abruptly" : "suddenly",
number_range(1,2) == 1 ? "cease" : "stop"
);
break;
case MAG_COLD:
sprintf(buf, "&CA %s layer of %s %s $p and %s.",
number_range(1,2) == 1 ? "light" : "thin",
number_range(1,2) == 1 ? "frost" : "ice",
number_range(1,2) == 1 ? "covers" : "spreads over",
number_range(1,2) == 1 ? "melts" : "vanishes"
);
break;
case MAG_WATER:
sprintf(buf, "&B%s %s of water %s $p and %s.",
number_range(1,2) == 1 ? "Small" : "Tiny",
number_range(1,2) == 1 ? "drops" : "droplets",
number_range(1,2) == 1 ? "cover" : "flow over",
number_range(1,2) == 1 ? "drip away" : "evaporate"
);
break;
case MAG_ACID:
sprintf(buf, "&g%s of acid %s from $p.",
number_range(1,2) == 1 ? "Flecks" : "Tiny droplets",
number_range(1,2) == 1 ? "drip" : "drizzle"
);
break;
case MAG_DREAM:
sprintf(buf, "&P$p %s %s as if %s from a %s.",
number_range(1,2) == 1 ? "flashes" : "flickers",
number_range(1,2) == 1 ? "for an instant" : "for a moment",
number_range(1,2) == 1 ? "an image" : "something",
number_range(1,2) == 1 ? "dream" : "nightmare"
);
break;
case MAG_SOUND:
sprintf(buf, "&Y$p %s %s for a %s.",
number_range(1,2) == 1 ? "hums" : "sings",
number_range(1,2) == 1 ? "eerily" : "faintly",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_HOLY:
sprintf(buf, "&z&W%s %s light %s $p %s.",
number_range(1,2) == 1 ? "Shimmering" : "Holy",
number_range(1,2) == 1 ? "white" : "silver",
number_range(1,2) == 1 ? "surrounds" : "encompasses",
number_range(1,2) == 1 ? "briefly" : "for a moment"
);
break;
case MAG_UNHOLY:
sprintf(buf, "&z$p %s a %s %s for a %s.",
number_range(1,2) == 1 ? "emits" : "casts",
number_range(1,2) == 1 ? "deep" : "dark",
number_range(1,2) == 1 ? "shadow" : "darkness",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_POISON:
sprintf(buf, "&g%s of %s %s %s $p.",
number_range(1,2) == 1 ? "Wisps" : "Puffs",
number_range(1,2) == 1 ? "smoke" : "poisonous gas",
number_range(1,2) == 1 ? "drift" : "waft",
number_range(1,2) == 1 ? "over" : "around"
);
break;
case MAG_CHANGE:
case MAG_TIME:
sprintf(buf, "&B$p %s %s %s.",
number_range(1,2) == 1 ? "twists" : "warps",
number_range(1,2) == 1 ? "strangely" : "eerily",
number_range(1,2) == 1 ? "briefly" : "for a moment"
);
break;
case MAG_TELEKINETIC:
sprintf(buf, "&Y$p %s and %s %s.",
number_range(1,2) == 1 ? "twitches" : "dances",
number_range(1,2) == 1 ? "tingles" : "hums",
number_range(1,2) == 1 ? "briefly" : "for a moment"
);
break;
case MAG_LIGHT:
case MAG_SEEK:
sprintf(buf, "&Y$p %s %s for a %s.",
number_range(1,2) == 1 ? "glows" : "shines",
number_range(1,2) == 1 ? "brightly" : "faintly",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_PSIONIC:
sprintf(buf, "&p$p %s %s with %s %s.",
number_range(1,2) == 1 ? "shimmers" : "shines",
number_range(1,2) == 1 ? "violet" : "faintly",
number_range(1,2) == 1 ? "mental" : "psionic",
number_range(1,2) == 1 ? "energy" : "power"
);
break;
case MAG_ANTIMATTER:
case MAG_ANTIMAGIC:
sprintf(buf, "&z%s black %s %s %s $p and %s.",
number_range(1,2) == 1 ? "Crackling" : "Humming",
number_range(1,2) == 1 ? "lightning" : "antimatter",
number_range(1,2) == 1 ? "shoots" : "streaks",
number_range(1,2) == 1 ? "around" : "along",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_ETHER:
sprintf(buf, "&w%s %s of %s %s %s $p.",
number_range(1,2) == 1 ? "Insubstantial" : "Pale",
number_range(1,2) == 1 ? "wisps" : "tendrils",
number_range(1,2) == 1 ? "ether" : "mist",
number_range(1,2) == 1 ? "float" : "drift",
number_range(1,2) == 1 ? "over" : "along"
);
break;
}
act(AT_ACTION, buf, ch, obj, NULL, TO_ROOM);
act(AT_ACTION, buf, ch, obj, NULL, TO_CHAR);
}
void ch_trick(CHAR_DATA *ch, int type) {
char buf[MAX_STRING_LENGTH];
switch (type) {
default:
sprintf(buf, "&PRaw mana %s $n and %s.",
number_range(1,2) == 1 ? "surrounds" : "circles",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_FIRE:
sprintf(buf, "&R%s flames %s %s $n and %s.",
number_range(1,2) == 1 ? "Flickering" : "Lambent",
number_range(1,2) == 1 ? "streak" : "dance",
number_range(1,2) == 1 ? "around" : "in front of",
number_range(1,2) == 1 ? "vanish" : "disappear");
break;
case MAG_EARTH:
sprintf(buf, "%s leaves %s %s $n and %s.",
number_range(1,2) == 1 ? "&GGreen" : "&OAutumn",
number_range(1,2) == 1 ? "swirl" : "blow",
number_range(1,2) == 1 ? "around" : "in front of",
number_range(1,2) == 1 ? "blow away" : "disappear"
);
break;
case MAG_BLUNT:
sprintf(buf, "&O%s %s %s $n %s.",
number_range(1,2) == 1 ? "Tiny" : "Little",
number_range(1,2) == 1 ? "pebbles" : "bits of rock",
number_range(1,2) == 1 ? "spin around" : "encircle",
number_range(1,2) == 1 ? "briefly" : "momentarily"
);
break;
case MAG_ELECTRICITY:
sprintf(buf, "&Y%s %s %s $n and %s.",
number_range(1,2) == 1 ? "Crackling" : "White",
number_range(1,2) == 1 ? "lightning" : "electricity",
number_range(1,2) == 1 ? "surrounds" : "splits around",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_WIND:
sprintf(buf, "&C%s %s %s $n and %s %s.",
number_range(1,2) == 1 ? "Howling" : "Whipping",
number_range(1,2) == 1 ? "winds" : "storms",
number_range(1,2) == 1 ? "swirl around" : "surround",
number_range(1,2) == 1 ? "abruptly" : "suddenly",
number_range(1,2) == 1 ? "cease" : "stop"
);
break;
case MAG_COLD:
sprintf(buf, "&C%s %s %s $n and %s %s.",
number_range(1,2) == 1 ? "Swirling cold" : "Frigid",
number_range(1,2) == 1 ? "winds" : "snowflakes",
number_range(1,2) == 1 ? "swirl around" : "surround",
number_range(1,2) == 1 ? "abruptly" : "suddenly",
number_range(1,2) == 1 ? "cease" : "stop"
);
break;
case MAG_WATER:
sprintf(buf, "&C%s bubbles %s around $n and %s with a %s.",
number_range(1,2) == 1 ? "Small" : "Shimmering",
number_range(1,2) == 1 ? "spin" : "swirl",
number_range(1,2) == 1 ? "vanish" : "disappear",
number_range(1,2) == 1 ? "pop" : "splash"
);
break;
case MAG_ACID:
sprintf(buf, "&gA %s of %s acid %s around $n.",
number_range(1,2) == 1 ? "shower" : "drizzle",
number_range(1,2) == 1 ? "glistening" : "tiny flecks of",
number_range(1,2) == 1 ? "swirls" : "spins"
);
break;
case MAG_DREAM:
sprintf(buf, "&P$n %s %s as if %s from a %s.",
number_range(1,2) == 1 ? "flashes" : "flickers",
number_range(1,2) == 1 ? "for an instant" : "for a moment",
number_range(1,2) == 1 ? "an image" : "something",
number_range(1,2) == 1 ? "dream" : "nightmare"
);
break;
case MAG_SOUND:
sprintf(buf, "&YA %s sound %s $n for a %s.",
number_range(1,2) == 1 ? "humming" : "singing",
number_range(1,2) == 1 ? "surrounds" : "eminates",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_HOLY:
sprintf(buf, "&z&W%s %s light %s $n for a %s.",
number_range(1,2) == 1 ? "Shimmering" : "Holy",
number_range(1,2) == 1 ? "white" : "silver",
number_range(1,2) == 1 ? "eminates from" : "surrounds",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_UNHOLY:
case MAG_DRAIN:
sprintf(buf, "&z%s %s %s $n for a %s.",
number_range(1,2) == 1 ? "Tendrils of" : "Eerie",
number_range(1,2) == 1 ? "shadows" : "darkness",
number_range(1,2) == 1 ? "surround" : "twist around",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_POISON:
sprintf(buf, "&g%s of %s %s %s $n.",
number_range(1,2) == 1 ? "Wisps" : "Puffs",
number_range(1,2) == 1 ? "smoke" : "poisonous gas",
number_range(1,2) == 1 ? "swirl" : "circle",
number_range(1,2) == 1 ? "in front of" : "around"
);
break;
case MAG_CHANGE:
case MAG_TIME:
sprintf(buf, "&B$n %s %s %s.",
number_range(1,2) == 1 ? "twists" : "warps",
number_range(1,2) == 1 ? "strangely" : "eerily",
number_range(1,2) == 1 ? "briefly" : "for a moment"
);
break;
case MAG_TELEKINETIC:
sprintf(buf, "&Y$n %s and %s for a %s.",
number_range(1,2) == 1 ? "shivers" : "itches",
number_range(1,2) == 1 ? "tickles" : "tingles",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_LIGHT:
case MAG_SEEK:
sprintf(buf, "&Y$n %s %s for a %s.",
number_range(1,2) == 1 ? "glows" : "shines",
number_range(1,2) == 1 ? "brightly" : "faintly",
number_range(1,2) == 1 ? "moment" : "while"
);
break;
case MAG_PSIONIC:
sprintf(buf, "&p$n %s %s with %s %s.",
number_range(1,2) == 1 ? "shimmers" : "shines",
number_range(1,2) == 1 ? "violet" : "faintly",
number_range(1,2) == 1 ? "mental" : "psionic",
number_range(1,2) == 1 ? "energy" : "power"
);
break;
case MAG_ANTIMATTER:
case MAG_ANTIMAGIC:
sprintf(buf, "&z%s black %s %s $n and %s.",
number_range(1,2) == 1 ? "Crackling" : "Humming",
number_range(1,2) == 1 ? "lightning" : "antimatter",
number_range(1,2) == 1 ? "surrounds" : "encircles",
number_range(1,2) == 1 ? "vanishes" : "disappears"
);
break;
case MAG_ETHER:
sprintf(buf, "&w%s %s of %s %s %s $n.",
number_range(1,2) == 1 ? "Insubstantial" : "Pale",
number_range(1,2) == 1 ? "wisps" : "tendrils",
number_range(1,2) == 1 ? "ether" : "mist",
number_range(1,2) == 1 ? "float" : "swirl",
number_range(1,2) == 1 ? "around" : "in front of"
);
break;
}
act(AT_ACTION, buf, ch, NULL, NULL, TO_ROOM);
act(AT_ACTION, buf, ch, NULL, NULL, TO_CHAR);
}
void obj_harm(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) {
AREA_DATA *area;
int vnum;
char buf[MAX_STRING_LENGTH];
if (ch->in_room->pShop) {
obj_trick(ch, obj, type);
return;
}
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_FIRE:
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)
|| obj->item_type == ITEM_FIRE) {
obj_trick(ch, obj, type);
break;
}
if (obj->weight * 30 > power) {
if (IS_OBJ_STAT(obj, ITEM_FLAMMABLE)) {
act(AT_FIRE, "You set $p on fire.",
ch, obj, NULL, TO_CHAR);
act(AT_FIRE, "$n set $p on fire.",
ch, obj, NULL, TO_ROOM);
obj->item_type = ITEM_FIRE;
obj->timer = obj->weight - (power / 30);
sprintf(buf, "burning %s", myobj(obj));
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(buf);
break;
} else {
obj_trick(ch, obj, type);
break;
}
}
if (IS_OBJ_STAT(obj, ITEM_FLAMMABLE)) {
act(AT_FIRE, "You burn $p into ashes.",
ch, obj, NULL, TO_CHAR);
act(AT_FIRE, "$n burns $p into ashes.",
ch, obj, NULL, TO_ROOM);
dump_container(obj);
extract_obj(obj);
return;
}
if (!obj->material || obj->material->number == 116 /* ether */) {
obj_trick(ch, obj, type);
break;
}
if (!IS_OBJ_STAT(obj, ITEM_METAL)) {
obj_trick(ch, obj, type);
break;
}
vnum = 0;
if (!stockobj)
for (area=first_area; area; area=area->next) {
if (!str_cmp( area->filename, "stockobj.are" )) {
stockobj = area;
vnum = area->hi_o_vnum;
break;
}
} else {
area = stockobj;
vnum=area->hi_o_vnum;
}
if (vnum == 0) {
bug("Cannot find stockobj.are!",0);
return;
}
act(AT_FIRE, "You melt $p into a misshapen lump of metal.",
ch, obj, NULL, TO_CHAR);
act(AT_FIRE, "$n melts $p into a misshapen lump of metal.",
ch, obj, NULL, TO_ROOM);
obj->cost -= obj->pIndexData->cost;
obj->pIndexData = get_obj_index(vnum);
STRFREE(obj->name);
obj->name = STRALLOC(obj->material->name);
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(obj->material->short_descr);
obj->item_type = ITEM_TREASURE;
xCLEAR_BITS(obj->parts);
break;
case MAG_ANTIMATTER:
if (ch->curr_talent[TAL_VOID] < 100) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (obj->weight * 10 > power) {
obj_trick(ch, obj, type);
break;
}
act(AT_DGREY, "You burn $p out of existance!",
ch, obj, NULL, TO_CHAR);
act(AT_DGREY, "$n burns $p out of existance!",
ch, obj, NULL, TO_ROOM);
dump_container(obj);
extract_obj(obj);
break;
case MAG_COLD:
if (ch->curr_talent[TAL_FROST] < 100) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (obj->weight * 30 > power) {
obj_trick(ch, obj, type);
break;
}
act(AT_FROST, "You freeze $p solid and shatter it!",
ch, obj, NULL, TO_CHAR);
act(AT_FROST, "$n freezes $p solid and shatters it!",
ch, obj, NULL, TO_ROOM);
dump_container(obj);
extract_obj(obj);
break;
case MAG_DRAIN:
if (ch->curr_talent[TAL_DEATH] < 20) {
obj_trick(ch, obj, type);
break;
}
if (obj->timer <= 0) {
act( AT_BLOOD, "$p starts to decay slowly.", ch, obj, NULL, TO_CHAR);
obj->timer = 100;
return;
}
act( AT_BLOOD, "$p decays further.", ch, obj, NULL, TO_CHAR);
obj->timer -= TALENT(ch, TAL_DEATH)/10;
if (obj->timer < 1)
obj->timer = 1;
break;
case MAG_ELECTRICITY:
if (ch->curr_talent[TAL_LIGHTNING] < 75) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (!IS_OBJ_STAT(obj, ITEM_EXPLOSIVE)) {
if (obj->weight*20 < power) {
obj->timer = 1;
xSET_BIT(obj->extra_flags, ITEM_EXPLOSIVE);
act(AT_FIRE, "You add an explosive charge to $p.",
ch, obj, NULL, TO_CHAR);
} else {
obj_trick(ch, obj, type);
break;
}
} else {
obj->timer = 0;
xREMOVE_BIT(obj->extra_flags, ITEM_EXPLOSIVE);
act(AT_FIRE, "You remove the explosive charge from $p.",
ch, obj, NULL, TO_CHAR);
}
break;
}
}
void ch_harm(CHAR_DATA *victim, CHAR_DATA *ch, int dam, int type, bool dont_wait) {
if (!victim || victim == NULL) {
ch_trick(ch, type);
return;
}
if (char_died(victim)) return;
if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) {
ch_trick(victim, type);
return;
}
if (!IS_SAME_PLANE(ch, victim)) {
if (CAN_SEE_PLANE(ch, victim))
send_to_char("That appears to have no affect.\n\r", ch);
return;
}
if (!dont_wait) {
STRFREE(ch->last_taken);
ch->last_taken = STRALLOC("channeling");
WAIT_STATE(ch, PULSE_VIOLENCE);
}
if (victim->shield == type) {
act(AT_MAGIC, "Your $t bounces off $N's shield!", ch,
magic_table[type], victim, TO_CHAR);
act(AT_MAGIC, "$n's $t bounces off $N's shield!", ch,
magic_table[type], victim, TO_NOTVICT);
act(AT_MAGIC, "$n's $t bounces off your shield!", ch,
magic_table[type], victim, TO_VICT);
/* don't keep them bouncing back and forth */
if (ch->shield == type) {
act(AT_MAGIC, "Your $t fizzles out harmlessly.", ch,
magic_table[type], NULL, TO_CHAR);
act(AT_MAGIC, "$n's $t fizzles out harmlessly", ch,
magic_table[type], NULL, TO_ROOM);
return;
}
/* send it back at them */
ch_harm(ch, victim, dam, type, TRUE);
return;
}
if (check_displacement(ch, victim)) return;
if (check_antimagic(ch, victim)) return;
if (type == MAG_UNHOLY) {
if (IS_AFFECTED(victim, AFF_ANGEL)) {
dam *= 2;
} else {
dam /= 2;
}
}
else if (type == MAG_HOLY) {
if (IS_AFFECTED(victim, AFF_DEMON)) {
dam *= 2;
} else {
dam /= 2;
}
}
else if (type == MAG_DREAM) {
if (IS_AFFECTED(victim, AFF_DREAMWORLD)) {
dam *= 3;
} else {
dam = 0;
}
}
else if (IS_UNDERWATER(victim)
&& type == MAG_FIRE)
dam /= 2;
else if (type == MAG_EARTH)
dam = (dam * 200) / (victim->in_room->curr_vegetation +10);
else if (type == MAG_WATER)
dam = (dam * 200) / (victim->in_room->curr_water +10);
dam = number_range(dam, dam*5);
dam = URANGE(1, dam, 5000);
/* dam = (100 - TALENT(victim, talent)) * dam / 100; */
if (type == MAG_DRAIN) {
dam /= 2;
ch->hit += dam;
if (ch->hit > ch->max_hit) ch->hit = ch->max_hit;
}
if (dam <= 0) {
act(AT_MAGIC, "The magic has no effect.", victim, NULL, NULL, TO_ROOM);
act(AT_MAGIC, "The magic has no effect.", victim, NULL, NULL, TO_CHAR);
if (IS_NPC(ch) && number_range(20,50) < get_curr_int(ch))
xSET_BIT(ch->act, ACT_MAG_FAIL);
return;
}
act(AT_MAGIC, "Your $t hits $N!", ch,
magic_table[type], victim, TO_CHAR);
act(AT_MAGIC, "$n's $t hits $N!", ch,
magic_table[type], victim, TO_NOTVICT);
act(AT_MAGIC, "$n's $t hits you!", ch,
magic_table[type], victim, TO_VICT);
victim->last_hit = ch;
ch->last_hit = victim;
if (can_gain_exp(ch, victim))
gain_exp(ch, get_exp_worth(victim) * dam / 100);
direct_damage(victim, dam);
if (char_died(victim)) return;
pain(victim, dam);
climate_affect(victim, type);
}
void obj_help(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) {
int amt;
bool found;
AFFECT_DATA *paf;
if ( IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
return;
}
separate_obj(obj);
amt = 50;
found = FALSE;
if (obj->mana < amt
&& type != MAG_TIME
&& type != MAG_ALL
&& type != MAG_LIGHT
&& type != MAG_UNHOLY) {
obj_trick(ch, obj, type);
return;
}
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_ALL:
if (obj->mana < amt
|| IS_OBJ_STAT(obj, ITEM_MAGIC)
|| ch->curr_talent[TAL_CATALYSM] < 40) {
act(AT_MAGIC, "You funnel raw energy into $p.",
ch, obj, NULL, TO_CHAR);
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
send_to_char("The magic is absorbed with no effect.\n\r",ch);
return;
}
power /= obj->weight == 0 ? 1 : obj->weight;
obj->raw_mana += power;
if (obj->gem)
obj->gem->raw_mana += power;
if (obj->raw_mana > 2000
+ TALENT(ch, TAL_CATALYSM)*5
+ ch->pcdata->noncombat[SK_CHANNEL]*20) {
act(AT_DANGER, "The overcharged item explodes in your hands!",
ch, NULL, NULL, TO_CHAR);
act(AT_ACTION, "$p explodes in $n's hands.", ch, obj, NULL, TO_ROOM);
lose_hp(ch, obj->mana*3 + (obj->raw_mana / 20));
extract_obj(obj);
} else if (obj->raw_mana > 2000)
act(AT_PURPLE, "$p vibrates violently!", ch, obj, NULL, TO_CHAR);
return;
}
act(AT_PINK, "The raw mana settles into $n's $p, emitting a mystic glow.",
ch, obj, NULL, TO_ROOM);
act(AT_PINK, "The raw mana settles into $p, emitting a mystic glow.",
ch, obj, NULL, TO_CHAR);
xSET_BIT(obj->extra_flags, ITEM_MAGIC);
break;
case MAG_HOLY:
amt = 500;
if (IS_OBJ_STAT(obj, ITEM_SHIELD)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_SECURITY]
+ ch->curr_talent[TAL_CATALYSM] < 195) {
obj_trick(ch, obj, type);
return;
}
if (obj->mana < amt) {
obj_trick(ch, obj, type);
return;
}
act(AT_WHITE, "A holy light eminates from $n's $p, coalescing into a protective barrier.",
ch, obj, NULL, TO_ROOM);
act(AT_WHITE, "A holy light eminates from $p, coalescing into a protective barrier.",
ch, obj, NULL, TO_CHAR);
xSET_BIT(obj->extra_flags, ITEM_SHIELD);
obj->cost += 450000;
break;
case MAG_LIGHT:
if (IS_OBJ_STAT(obj, ITEM_GLOW)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_ILLUSION] < 30) {
obj_trick(ch, obj, type);
return;
}
if (IS_OBJ_STAT(obj, ITEM_DARK)) {
if (obj->value[4] == BRAND_ANTI_MATTER) {
send_to_char("The weapon absorbs all the light and remains dark.\n\r", ch);
return;
}
act( AT_YELLOW, "The $t takes in some of the light around it.",
ch, myobj(obj), NULL, TO_CHAR);
act( AT_YELLOW, "$n's $t takes in some of the light around it.",
ch, myobj(obj), NULL, TO_ROOM);
xREMOVE_BIT(obj->extra_flags, ITEM_DARK);
return;
}
act( AT_YELLOW, "The $t shines brightly!", ch, myobj(obj), NULL, TO_CHAR);
act( AT_YELLOW, "$n's $t shines brightly!", ch, myobj(obj), NULL, TO_ROOM);
xSET_BIT(obj->extra_flags, ITEM_GLOW);
return;
case MAG_UNHOLY:
if (IS_OBJ_STAT(obj, ITEM_DARK)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_DEATH] < 30) {
obj_trick(ch, obj, type);
return;
}
if (IS_OBJ_STAT(obj, ITEM_GLOW)) {
if (obj->value[4] == BRAND_RADIANT) {
send_to_char("You are unable to quench this radiant light.\n\r", ch);
return;
}
act( AT_MAGIC, "The $t grows dim and ceases to shine.",
ch, myobj(obj), NULL, TO_CHAR);
act( AT_MAGIC, "$n's $t grows dim and ceases to shine.",
ch, myobj(obj), NULL, TO_ROOM);
xREMOVE_BIT(obj->extra_flags, ITEM_GLOW);
return;
}
act( AT_MAGIC, "Swirling shadows shroud the $t.", ch, myobj(obj), NULL, TO_CHAR);
act( AT_MAGIC, "Swirling shadows shroud $n's $t.", ch, myobj(obj), NULL, TO_ROOM);
xSET_BIT(obj->extra_flags, ITEM_DARK);
return;
case MAG_TELEKINETIC:
amt = 100;
if (IS_OBJ_STAT(obj, ITEM_RETURNING)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_MOTION] < 50
&& TALENT(ch, TAL_MOTION) < 50) {
obj_trick(ch, obj, type);
return;
}
if (obj->mana < amt) {
obj_trick(ch, obj, type);
return;
}
act(AT_YELLOW, "$n's $p twitches for a moment, as a telekinetic enchantment settles in.",
ch, obj, NULL, TO_ROOM);
act(AT_YELLOW, "$p twitches for a moment, as a telekinetic enchantment settles in.",
ch, obj, NULL, TO_CHAR);
xSET_BIT(obj->extra_flags, ITEM_RETURNING);
break;
case MAG_WATER:
if (ch->curr_talent[TAL_WATER] < 40) {
obj_trick(ch, obj, type);
return;
}
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_AFFECT;
SET_BIT(paf->modifier, 1 << AFF_AQUA_BREATH);
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_BLUE, "Bubbles erupt from $n's $p as it glows with a watery film.",
ch, obj, NULL, TO_ROOM);
act(AT_BLUE, "Bubbles erupt from $p as it glows with a watery film.",
ch, obj, NULL, TO_CHAR);
break;
case MAG_WIND:
if (ch->curr_talent[TAL_WIND] < 60) {
obj_trick(ch, obj, type);
return;
}
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_AFFECT;
SET_BIT(paf->modifier, 1 << AFF_FLYING);
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_LBLUE, "$n's $p sprouts a pair of tiny wings.",
ch, obj, NULL, TO_ROOM);
act(AT_LBLUE, "$p sprouts a pair of tiny wings.",
ch, obj, NULL, TO_CHAR);
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_SEEKING] < 80) {
obj_trick(ch, obj, type);
return;
}
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_AFFECT;
SET_BIT(paf->modifier, 1 << AFF_TRUESIGHT);
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_YELLOW, "$n's $p glows for a long while with a pure and true light.",
ch, obj, NULL, TO_ROOM);
act(AT_YELLOW, "$p glows for a long while with a pure and true light.",
ch, obj, NULL, TO_CHAR);
break;
case MAG_DRAIN:
if (obj->item_type != ITEM_WEAPON
&& obj->item_type != ITEM_MISSILE_WEAPON) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_DEATH] < 10) {
obj_trick(ch, obj, type);
return;
}
amt = URANGE(10, 250 - TALENT(ch, TAL_DEATH), 200);
amt += obj->value[2];
if (obj->mana < amt) {
obj_trick(ch, obj, type);
return;
}
obj->value[2] += 5;
act(AT_DGREY, "$n's $p glints with a deadly power.",
ch, obj, NULL, TO_ROOM);
act(AT_DGREY, "$p glints with a deadly power.",
ch, obj, NULL, TO_CHAR);
break;
case MAG_ANTIMATTER:
if (obj->item_type != ITEM_CONTAINER) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_VOID] >= 10) {
obj_trick(ch, obj, type);
return;
}
amt = URANGE(10, 250 - TALENT(ch, TAL_VOID), 200);
amt += obj->value[0] / 10;
if (obj->mana < amt) {
obj_trick(ch, obj, type);
return;
}
obj->value[0] += TALENT(ch, TAL_VOID) / 10;
act(AT_DGREY, "$n's $p ripples strangely, the space within stretching to infinity.",
ch, obj, NULL, TO_ROOM);
act(AT_DGREY, "$p ripples strangely, the space within stretching to infinity.",
ch, obj, NULL, TO_CHAR);
break;
case MAG_BLUNT:
amt = 200;
if (IS_OBJ_STAT(obj, ITEM_DURABLE)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_SECURITY]
+ ch->curr_talent[TAL_EARTH] < 100) {
obj_trick(ch, obj, type);
return;
}
if (obj->mana < amt) {
obj_trick(ch, obj, type);
return;
}
act(AT_ORANGE, "$n's $p radiates strentch and durability.", ch, obj, NULL, TO_ROOM);
act(AT_ORANGE, "$p radiates strentch and durability.", ch, obj, NULL, TO_CHAR);
xSET_BIT(obj->extra_flags, ITEM_DURABLE);
break;
case MAG_TIME:
if (ch->curr_talent[TAL_TIME] < 10) {
obj_trick(ch, obj, type);
return;
}
if (obj->timer <= 0
|| IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
return;
}
obj->timer += TALENT(ch, TAL_TIME);
if (obj->timer > 100) obj->timer = 0;
act(AT_MAGIC, "$p flickers for a moment.", ch, obj, NULL, TO_CHAR);
return;
}
WAIT_STATE(ch, PULSE_VIOLENCE*2);
obj->mana -= amt;
obj->cost += 50000;
}
void ch_help(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) {
PART_DATA *part;
AFFECT_DATA af;
int sn;
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_HOLY:
if (victim == ch) {
act(AT_MAGIC, "You close your eyes and relax, focusing on healing.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n closes $s eyes and breathes deeply, $s wounds closing.",
ch, NULL, NULL, TO_ROOM);
} else {
act(AT_MAGIC, "$n concentrates on you, and pain eases out of your body",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "$n concentrates on $N, whose wounds begin to close.",
ch, NULL, victim, TO_NOTVICT);
act(AT_MAGIC, "You concentrate on $N, easing $S pain and healing $S wounds.",
ch, NULL, victim, TO_CHAR);
}
if (IS_AFFECTED(ch, AFF_UNHOLY) && power != 0) power /= 2;
if (IS_AFFECTED(ch, AFF_HOLY)) power *= 2;
if (victim == ch) power *= 2;
if (!IS_FIGHTING(ch)) power *= 2;
victim->hit += power;
for (part = victim->first_part;part;part = part->next) {
if (part->flags == PART_SEVERED
&& part->cond == PART_WELL
&& (part->connect_to
? part->connect_to->flags != PART_SEVERED
: TRUE)
&& power > 300) {
act(AT_MAGIC, "Your $t grows back!",
victim, part_locs[part->loc], NULL, TO_CHAR);
act(AT_MAGIC, "$n's $t grows back!",
victim, part_locs[part->loc], NULL, TO_ROOM);
part->flags = PART_WELL;
return; /* No more healing after a part is regened */
} else {
part->cond = UMIN(PART_WELL, part->cond+power/10);
}
}
if (victim->hit > victim->max_hit)
victim->hit = victim->max_hit;
break;
case MAG_LIGHT:
if (power > TALENT(ch, TAL_ILLUSION)) {
ch->pcdata->wizinvis = TALENT(ch, TAL_ILLUSION);
} else {
ch->pcdata->wizinvis = power;
}
if (xIS_SET(ch->act, PLR_WIZINVIS)) {
xREMOVE_BIT(ch->act, PLR_WIZINVIS);
act( AT_IMMORT, "$n slowly fades into existence.", ch, NULL, NULL, TO_ROOM );
send_to_char( "You slowly fade back into existence.\n\r", ch );
} else {
if (ch->pcdata->wizinvis < 1 || ch->pcdata->wizinvis > TALENT(ch, TAL_ILLUSION))
ch->pcdata->wizinvis = TALENT(ch, TAL_ILLUSION);
act(AT_IMMORT, "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM);
send_to_char("You slowly vanish into thin air.\n\r", ch);
xSET_BIT(ch->act, PLR_WIZINVIS);
}
break;
case MAG_POISON:
if (ch->curr_talent[TAL_HEALING] < 15) {
ch_trick(victim, type);
return;
}
if ( !is_affected( victim, gsn_poison ) ) {
ch_trick(victim, type);
return;
}
affect_strip( victim, gsn_poison );
set_char_color( AT_MAGIC, victim);
send_to_char( "A warm feeling runs through your body.\n\r", victim);
victim->mental_state = URANGE( -100, victim->mental_state, -10 );
act( AT_MAGIC, "A flush of health washes over $N.",
ch, NULL, victim, TO_NOTVICT);
if ( ch != victim ) {
act( AT_MAGIC, "You lift the poison from $N's body.",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_DRAIN:
if (ch->curr_talent[TAL_HEALING] < 60) {
ch_trick(victim, type);
return;
}
if ( !is_affected( victim, gsn_mummy_rot ) ) {
ch_trick(victim, type);
return;
}
affect_strip( victim, gsn_mummy_rot );
set_char_color( AT_MAGIC, victim);
send_to_char( "Your flesh feels more resilient.\n\r", victim);
victim->mental_state = URANGE( -100, victim->mental_state, -10 );
act( AT_MAGIC, "$N's flesh stops rotting.",
ch, NULL, victim, TO_NOTVICT);
if ( ch != victim ) {
act( AT_MAGIC, "You cure the rotting disease from $N's body.",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_HEALING] < 25
&& ch->curr_talent[TAL_SEEKING] < 25) {
ch_trick(victim, type);
return;
}
if ( !is_affected( victim, gsn_blindness ) ) {
ch_trick(victim, type);
return;
}
affect_strip( victim, gsn_blindness );
set_char_color( AT_MAGIC, victim);
send_to_char( "Your vision returns!\n\r", victim );
if ( ch != victim )
send_to_char( "You work your cure, restoring vision.\n\r", ch );
break;
case MAG_CHANGE:
if (ch->curr_talent[TAL_HEALING] < 25
&& ch->curr_talent[TAL_CHANGE] < 25) {
ch_trick(victim, type);
return;
}
if (!is_affected( victim, gsn_corruption)) {
ch_trick(victim, type);
return;
}
affect_strip( victim, gsn_corruption );
set_char_color( AT_MAGIC, victim );
send_to_char( "Waves of magic cleanse your body.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You cleanse $N's body of corruption.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N's body returns to normal again.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_fire;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_RESISTANT;
af.modifier = RIS_FIRE;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
send_to_char( "You are protected from heat.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You protect $N from heat.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N is protected from heat.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_COLD:
if (ch->curr_talent[TAL_FROST] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_frost;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_RESISTANT;
af.modifier = RIS_COLD;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
update_pos(victim);
send_to_char( "You are protected from cold.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You protect $N from cold.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N is protected from cold.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] < 50) {
ch_trick(victim, type);
return;
}
victim->mental_state = 0;
act( AT_MAGIC, "You balance $N's mind.", ch, NULL, victim, TO_CHAR);
act( AT_MAGIC, "Your mind is balanced.", ch, NULL, victim, TO_VICT);
break;
case MAG_ACID:
if (ch->curr_talent[TAL_HEALING] < 20
&& ch->curr_talent[TAL_WATER] < 20) {
ch_trick(victim, type);
return;
}
if ( victim->pcdata && victim->pcdata->condition[COND_DRUNK] <= 0 ) {
ch_trick(victim, type);
return;
}
if ( victim->pcdata )
victim->pcdata->condition[COND_DRUNK] = 0;
act(AT_MAGIC, "You purge the alcohol from $N's system.",
ch, NULL, victim, TO_CHAR );
act(AT_MAGIC, "$n purges the alcohol from your system.",
ch, NULL, victim, TO_VICT );
break;
case MAG_TELEKINETIC:
if (ch->curr_talent[TAL_HEALING] < 10) {
ch_trick(victim, type);
return;
}
if (victim->move >= victim->max_move) {
ch_trick(victim, type);
return;
}
victim->move = UMAX(victim->move + power, victim->max_move);
update_pos(victim);
send_to_char( "Vitality and stamina return to you.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You let vitality flow into $N's body.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N's body seems to grow less exhausted.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_BLUNT:
if (ch->curr_talent[TAL_EARTH] < 30) {
ch_trick(victim, type);
return;
}
if (IS_NPC(victim) || victim->pcdata->condition[COND_FULL] < 0) {
ch_trick(victim, type);
return;
}
victim->pcdata->condition[COND_FULL] += 20;
send_to_char("You are satiated.", victim);
if (ch != victim) {
act(AT_MAGIC, "You fill $N's stomach.",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_HEALING] < 30) {
ch_trick(victim, type);
return;
}
if (!is_affected(victim, gsn_curse)) {
ch_trick(victim, type);
return;
}
affect_strip(victim, gsn_curse);
send_to_char("The weight of your curse is lifted.\n\r", victim);
if (ch != victim) {
act(AT_MAGIC, "You dispel the curse afflicting $N.",
ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "$n's dispels the curse afflicting $N.",
ch, NULL, victim, TO_NOTVICT);
}
break;
case MAG_WATER:
if (ch->curr_talent[TAL_WATER] < 50) {
ch_trick(victim, type);
return;
}
if (IS_NPC(victim) || victim->pcdata->condition[COND_THIRST] < 0) {
ch_trick(victim, type);
return;
}
victim->pcdata->condition[COND_THIRST] += 10;
act( AT_MAGIC, "You feel bloated.", ch, NULL, victim, TO_VICT);
act( AT_MAGIC, "You fill $N up with water.", ch, NULL, victim, TO_CHAR);
break;
}
}
void obj_hinder(CHAR_DATA *ch, OBJ_DATA *obj, int type) {
bool found;
AFFECT_DATA *paf;
found = FALSE;
switch (type) {
default:
obj_trick(ch, obj, type);
return;
case MAG_HOLY:
if (obj->item_type != ITEM_ARMOR) {
obj_trick(ch, obj, type);
break;
}
if (TALENT(ch, TAL_SECURITY) / 10
> (obj->pIndexData->value[0] - obj->value[0])) {
act(AT_WHITE, "You reduce the protective ability of $p.", ch, obj, NULL, TO_CHAR);
obj->value[0]--;
} else {
obj_trick(ch, obj, type);
return;
}
break;
case MAG_EARTH:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_CON && !found) {
if (TALENT(ch, TAL_EARTH) / 10 > -1 * paf->modifier) {
act(AT_GREEN, "You hinder $p with the strength of the Earth.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_CON;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_GREEN, "You hinder $p with the strength of the Earth.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_COLD:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_LCK && !found) {
if (TALENT(ch, TAL_FROST) / 10 > -1 * paf->modifier) {
act(AT_FROST, "You hinder $p with the strength of the Ice.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_LCK;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_FROST, "You hinder $p with the strength of the Ice.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_FIRE:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_STR && !found) {
if (TALENT(ch, TAL_FIRE) / 10 > -1 * paf->modifier) {
act(AT_FIRE, "You hinder $p with the strength of the Flames.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_STR;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_FIRE, "You hinder $p with the strength of the Flames.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_SEEK:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_CHA && !found) {
if (TALENT(ch, TAL_SEEKING) / 10 > -1 * paf->modifier) {
act(AT_GREEN, "You hinder $p with the power of Seeking.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_CHA;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_GREEN, "You hinder $p with the power of Seeking.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_WIND:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_DEX && !found) {
if (TALENT(ch, TAL_WIND) / 10 > -1 * paf->modifier) {
act(AT_CYAN, "You hinder $p with the speed of the Wind.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_DEX;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_CYAN, "You hinder $p with the speed of the Wind.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_WATER:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_WIS && !found) {
if (TALENT(ch, TAL_WATER) / 10 > -1 * paf->modifier) {
act(AT_BLUE, "You hinder $p with the power of Water.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_WIS;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_BLUE, "You hinder $p with the power of Water.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_PSIONIC:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_INT && !found) {
if (TALENT(ch, TAL_MIND) / 10 > -1 * paf->modifier) {
act(AT_PURPLE, "You hinder $p with the power of the Mind.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_INT;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_PURPLE, "You hinder $p with the power of the Mind.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_ELECTRICITY:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_DAMROLL && !found) {
if (TALENT(ch, TAL_LIGHTNING) / 10 > -1 * paf->modifier) {
act(AT_YELLOW, "You hinder $p with the strength of the Storm.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_YELLOW, "You hinder $p with the strength of the Storm.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_TELEKINETIC:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_HITROLL && !found) {
if (TALENT(ch, TAL_MOTION) / 10 > -1 * paf->modifier) {
act(AT_YELLOW, "You hinder $p with the speed of Motion.",
ch, obj, NULL, TO_CHAR);
paf->modifier--;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = -1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_YELLOW, "You hinder $p with the speed of Motion.",
ch, obj, NULL, TO_CHAR);
}
break;
}
WAIT_STATE(ch, PULSE_VIOLENCE*2);
obj->mana += 50;
obj->cost -= 50000;
}
void ch_hinder(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) {
AFFECT_DATA af;
int sn;
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_EARTH:
if (ch->in_room->curr_vegetation <
100 - ch->curr_talent[TAL_EARTH]) {
ch_trick(victim, type);
return;
}
if (ch->curr_talent[TAL_EARTH] > number_range(10,50)) {
act(AT_GREEN, "You are entangled in vines!",
ch, NULL, victim, TO_VICT);
act(AT_GREEN, "$N is entangled in vines!",
ch, NULL, victim, TO_NOTVICT);
act(AT_GREEN, "You entangle $N in vines!",
ch, NULL, victim, TO_CHAR);
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_HOLD);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD);
} else {
act(AT_GREEN, "Vines grab for you but fail to hold you!",
ch, NULL, victim, TO_VICT);
act(AT_GREEN, "Your vines fail to hold $N!",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_COLD:
if (ch->in_room->area->weather->temp >
ch->curr_talent[TAL_FROST]*10 - 400) {
ch_trick(victim, type);
return;
}
if (ch->curr_talent[TAL_FROST] > number_range(10,50)) {
act(AT_FROST, "Ice forms around you, holding you in place!",
ch, NULL, victim, TO_VICT);
act(AT_FROST, "Ice forms around $N!",
ch, NULL, victim, TO_NOTVICT);
act(AT_FROST, "You hold $N in ice!",
ch, NULL, victim, TO_CHAR);
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_HOLD);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD);
} else {
act(AT_FROST, "Ice forms around you but fails to hold you!",
ch, NULL, victim, TO_VICT);
act(AT_FROST, "Your ice fails to hold $N!",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_WATER:
if (!IS_UNDERWATER(victim)) {
if (ch->curr_talent[TAL_WATER] < 60) {
ch_trick(victim, type);
return;
}
if (IS_NPC(victim) || victim->pcdata->condition[COND_THIRST] < 0) {
ch_trick(victim, type);
return;
}
victim->pcdata->condition[COND_THIRST] = 0;
act( AT_MAGIC, "You are DYING of THIRST!",
ch, NULL, victim, TO_VICT);
act( AT_MAGIC, "You drain all the water from $N's body.",
ch, NULL, victim, TO_CHAR);
break;
}
if (ch->curr_talent[TAL_WATER] > number_range(10,50)) {
act(AT_MAGIC, "A whirlpool spins around you, holding you in place!",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "$N is held in a whirlpool!",
ch, NULL, victim, TO_NOTVICT);
act(AT_MAGIC, "You hold $N in a whirlpool!",
ch, NULL, victim, TO_CHAR);
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_HOLD);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD);
} else {
act(AT_MAGIC, "A whirlpool spins near you, but you swim away!",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "Your whirlpool fails to hold $N!",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_TIME:
if (ch->curr_talent[TAL_TIME] > number_range(10,50)) {
act(AT_MAGIC, "You are held in place!",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "$N's feet are held to the floor!",
ch, NULL, victim, TO_NOTVICT);
act(AT_MAGIC, "You hold $N in place!",
ch, NULL, victim, TO_CHAR);
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_HOLD);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD);
} else {
act(AT_MAGIC, "Something grabs at you, but fails to hold you!",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "Your magic fails to hold $N!",
ch, NULL, victim, TO_CHAR);
}
break;
case MAG_ANTIMAGIC:
if (victim != ch
&& ch->curr_talent[TAL_VOID] < 30) {
ch_trick(victim, type);
return;
}
if (TALENT(victim, TAL_SECURITY) > TALENT(ch, TAL_VOID)
&& ch != victim && !IS_CONSENTING(victim, ch)) {
act(AT_MAGIC, "$N's magic wavers but holds.", ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "Your magic wavers but holds.", ch, NULL, victim, TO_VICT);
learn_talent(victim, TAL_SECURITY);
return;
}
if ( victim->first_affect ) {
send_to_char ( "Your enchantments are stripped away by powerful magic.\n\r",
victim);
if (ch != victim) {
act(AT_MAGIC, "You strip away $N's enchantments.", ch, NULL, victim, TO_CHAR);
}
while ( victim->first_affect )
affect_remove ( victim, victim->first_affect );
WAIT_STATE(ch, PULSE_VIOLENCE);
} else {
ch_trick(victim, type);
return;
}
break;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 30) {
ch_trick(victim, type);
return;
}
sn = gsn_sticky_flame;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
if (IS_SET(victim->immune, RIS_FIRE)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power/10;
af.location = APPLY_DAMROLL;
af.modifier = TALENT(ch, TAL_FIRE)/40;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_FLAMING);
affect_join( victim, &af );
send_to_char ("Sticky flames cover your body!\n\r", victim);
if (ch != victim)
act(AT_FIRE, "You cover $N in sticky fire!", ch, NULL, victim, TO_CHAR);
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_ILLUSION] < 30) {
ch_trick(victim, type);
return;
}
sn = gsn_blindness;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
if (IS_AFFECTED(victim, AFF_TRUESIGHT)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power/10;
af.location = APPLY_HITROLL;
af.modifier = -1 * TALENT(ch, TAL_ILLUSION)/20;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_BLIND);
affect_join( victim, &af );
send_to_char ("You are blinded by a flash of light!\n\r", victim);
if (ch != victim)
act(AT_YELLOW, "You blind $N with a flash of light!", ch, NULL, victim, TO_CHAR);
break;
case MAG_POISON:
if (ch->curr_talent[TAL_DEATH] < 30) {
ch_trick(victim, type);
return;
}
sn = gsn_poison;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
if (IS_SET(victim->immune, RIS_POISON)
|| IS_AFFECTED(victim, AFF_NONLIVING)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power/10;
af.location = APPLY_STR;
af.modifier = -1 * TALENT(ch, TAL_DEATH)/40;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_POISON);
affect_join( victim, &af );
victim->mental_state = URANGE( 10, victim->mental_state + 10, 100 );
send_to_char ("You feel very sick.\n\r", victim);
if (ch != victim)
act(AT_DGREEN, "You spread poison into $N's body.", ch, NULL, victim, TO_CHAR);
act(AT_DGREEN, "$N begins to look very sick.", ch, NULL, victim, TO_ROOM);
break;
case MAG_DRAIN:
if (ch->curr_talent[TAL_DEATH] < 60) {
ch_trick(victim, type);
return;
}
sn = gsn_mummy_rot;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
if (IS_SET(victim->immune, RIS_DRAIN)
|| IS_AFFECTED(victim, AFF_NONLIVING)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_CON;
af.modifier = -1 * TALENT(ch, TAL_DEATH)/50;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_ROTTING);
affect_join( victim, &af );
send_to_char ("Your flesh begins to rot away.\n\r", victim);
if (ch != victim)
act(AT_DGREY, "You make $N's flesh begin to rot away.", ch, NULL, victim, TO_CHAR);
act(AT_DGREY, "$N's flesh begins to rot away.", ch, NULL, victim, TO_ROOM);
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 40) {
ch_trick(victim, type);
return;
}
sn = gsn_curse;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_HITROLL;
af.modifier = -1 * TALENT(ch, TAL_DEATH)/50;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_CURSE);
affect_join( victim, &af );
send_to_char ("You feel unlucky.\n\r", victim);
if (ch != victim)
act(AT_DGREY, "You inflict a curse upon $N.", ch, NULL, victim, TO_CHAR);
act(AT_DGREY, "A malignant aura surrounds $N for a moment.", ch, NULL, victim, TO_ROOM);
break;
case MAG_DREAM:
sn = gsn_sleep;
if (ch->curr_talent[TAL_DREAM] < 30) {
ch_trick(victim, type);
return;
}
if (!IS_NPC(victim) && IS_FIGHTING(victim)) {
ch_trick(victim, type);
return;
}
if (IS_SET( victim->immune, RIS_SLEEP)) {
ch_trick(victim, type);
return;
}
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
if (number_range(1, get_curr_wil(ch))
< number_range(1, get_curr_wil(victim) + TALENT(victim, TAL_SECURITY))) {
ch_trick(victim, type);
return;
}
if (!IS_FIGHTING(victim)) {
victim->last_hit = ch;
ch->last_hit = victim;
} else {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power/20;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = meb(AFF_SLEEP);
affect_join(victim, &af);
if (!IS_NPC(victim)) {
sprintf(log_buf, "%s has cast sleep on %s.", ch->name, victim->name);
to_channel(log_buf, "Spell", PERMIT_SECURITY);
}
if (IS_AWAKE(victim)) {
act(AT_MAGIC, "You feel very sleepy ..... zzzzzz.", victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n goes to sleep.", victim, NULL, NULL, TO_ROOM);
victim->position = POS_SLEEPING;
}
if (IS_NPC(victim))
start_hating(victim, ch);
break;
case MAG_BLUNT:
if (ch->curr_talent[TAL_EARTH] < 60) {
ch_trick(victim, type);
return;
}
if (IS_NPC(victim) || victim->pcdata->condition[COND_FULL] < 0) {
ch_trick(victim, type);
return;
}
victim->pcdata->condition[COND_FULL] = 0;
act( AT_HUNGRY, "You are STARVING!", ch, NULL, victim, TO_VICT);
act( AT_MAGIC, "You reach out your hand, and $N's body shrivels.",
ch, NULL, victim, TO_CHAR);
act( AT_MAGIC, "$n reaches out $s hand, and $N's body shrivels.",
ch, NULL, victim, TO_NOTVICT);
break;
case MAG_SOUND:
if (ch->curr_talent[TAL_SPEECH] < 60) {
ch_trick(victim, type);
return;
}
stop_fighting(ch, TRUE);
act(AT_SAY, "You hum a tranquil melody to $N.",
ch, NULL, victim, TO_CHAR);
act(AT_SAY, "$n hums a tranquil melody to $N.",
ch, NULL, victim, TO_NOTVICT);
act(AT_SAY, "$n hums a tranquil melody, and you feel at peace.",
ch, NULL, victim, TO_VICT);
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_mind;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_MENTALSTATE;
af.modifier = ch->curr_talent[TAL_MIND];
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
send_to_char ("Suddenly the world seems strange to you as you begin to hallucinate...\n\r", victim);
if (ch != victim)
act(AT_DGREY, "You fill $N's mind with rampant hallucinations.",
ch, NULL, victim, TO_CHAR);
act(AT_DGREY, "$N's eyes grow wide and $E starts hallucinating.",
ch, NULL, victim, TO_ROOM);
break;
case MAG_HOLY:
if (ch->curr_talent[TAL_SECURITY] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_security;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_AC;
af.modifier = -1 * TALENT(ch, TAL_SECURITY) / 10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
send_to_char ("You feel vulnerable.\n\r", victim);
if (ch != victim)
act(AT_DGREY, "You make $N vulnerable.",
ch, NULL, victim, TO_CHAR);
act(AT_DGREY, "$N seems naked for a moment as $E becomes vulnerable.",
ch, NULL, victim, TO_ROOM);
break;
}
}
void room_hinder(CHAR_DATA *ch, ROOM_INDEX_DATA *room, int type, int power, char *argument) {
EXIT_DATA *pexit;
switch (type) {
default:
ch_trick(ch, type);
break;
case MAG_EARTH:
if (ch->curr_talent[TAL_DEATH] < 20) {
ch_trick(ch, type);
return;
}
if (ch->in_room->curr_vegetation <= 0) {
ch_trick(ch, type);
return;
}
ch->in_room->curr_vegetation -= 10;
act( AT_HUNGRY, "You touch the plants in the room, and they begin to wither.",
ch, NULL, NULL, TO_CHAR);
act( AT_HUNGRY, "The vegetation in the room withers.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_WATER:
if (ch->curr_talent[TAL_FIRE] < 20) {
ch_trick(ch, type);
return;
}
if(ch->in_room->curr_water <= 0) {
ch_trick(ch, type);
return;
}
ch->in_room->curr_water -= 10;
act( AT_THIRSTY, "Water drains out of the room.",
ch, NULL, NULL, TO_CHAR);
act( AT_THIRSTY, "Water begins to drain out of the room.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 60) {
ch_trick(ch, type);
return;
}
if (ch->in_room->curr_vegetation < 10) {
ch_trick(ch, type);
return;
}
if (ch->in_room->curr_water > 30) {
ch_trick(ch, type);
return;
}
act(AT_FIRE, "You set fire to the room!", ch, NULL, NULL, TO_CHAR);
act(AT_FIRE, "$n sets fire to the room!", ch, NULL, NULL, TO_ROOM);
SET_BIT(ch->in_room->room_flags, ROOM_BURNING);
break;
case MAG_HOLY:
if (!(pexit=find_door(ch, argument, FALSE))
|| !IS_SET(pexit->exit_info, EX_CLOSED)
|| !IS_SET(pexit->exit_info, EX_LOCKED)
|| IS_SET(pexit->exit_info, EX_PICKPROOF)) {
ch_trick(ch, type);
return;
}
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
send_to_char( "*Click*\n\r", ch );
if ( pexit->rexit && pexit->rexit->to_room == ch->in_room )
REMOVE_BIT( pexit->rexit->exit_info, EX_LOCKED );
check_room_for_traps( ch, TRAP_UNLOCK | trap_door[pexit->vdir] );
break;
}
}
void void_create(CHAR_DATA *ch, int power, char *argument) {
MATERIAL_DATA *material_lookup( int number );
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
OBJ_DATA *obj = NULL;
extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *area;
int lo_vnum=2;
int hi_vnum=2;
MATERIAL_DATA *material;
int hash;
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
AFFECT_DATA *paf;
extern int top_affect;
if (ch->curr_talent[TAL_VOID] < 100) {
huh(ch);
return;
}
if (argument == NULL) {
ch_trick(ch, MAG_ETHER);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
material=material_lookup(116); /* Ether material */
if (!(material)) {
send_to_char("You can't seem to reach the Ether for some reason.\n\r", ch);
bug("Cannot find Ether material for Void Create!", 0);
return;
}
if (!stockobj)
for (area=first_area; area; area=area->next) {
if (!str_cmp( area->filename, "stockobj.are" )) {
stockobj = area;
lo_vnum=area->low_o_vnum;
hi_vnum=area->hi_o_vnum;
break;
} else {
lo_vnum=2;
hi_vnum=2;
}
} else {
area = stockobj;
lo_vnum=area->low_o_vnum;
hi_vnum=area->hi_o_vnum;
}
if (lo_vnum==hi_vnum) {
send_to_char("You cannot figure out how to create anything right now.\n\r", ch);
return;
}
for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) {
for ( pObjIndex = obj_index_hash[hash]; pObjIndex; pObjIndex = pObjIndex->next) {
if (pObjIndex == NULL) {
bug("NULL pObjIndex on void_create!");
send_to_char("Your mind is a blank.\n\r", ch);
return;
}
if ( nifty_is_name( arg1, pObjIndex->name )
&& pObjIndex->vnum >= lo_vnum
&& pObjIndex->vnum <= hi_vnum) {
if (pObjIndex->tech > ch->pcdata->noncombat[SK_SMITH]
+ ch->curr_talent[TAL_VOID] - 100) {
ch_trick(ch, MAG_ETHER);
return;
}
if (pObjIndex->weight * 10 > power
&& !IS_AFFECTED(ch, AFF_VOID)) {
ch_trick(ch, MAG_ETHER);
return;
}
obj = create_object( pObjIndex, 0 );
if (!obj) {
ch_trick(ch, MAG_ETHER);
return;
}
break;
}
}
if (obj) break;
}
if (obj == NULL) {
ch_trick(ch, MAG_ETHER);
return;
}
strcpy(buf, material->name);
sprintf(arg, obj->short_descr, buf);
one_argument(arg, buf);
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(arg);
strcpy(buf, material->name);
sprintf(arg, obj->description, buf);
STRFREE(obj->description);
obj->description = STRALLOC(capitalize(arg));
strcpy(buf, obj->name);
strcat(buf, " ");
strcat(buf, material->name);
STRFREE(obj->name);
obj->name=STRALLOC(buf);
if (obj->item_type == ITEM_WEAPON
|| obj->item_type == ITEM_MISSILE_WEAPON)
obj->value[2] = TALENT(ch, TAL_VOID);
/* This is important so that Void mages cannot create
* infinite free items and sell them.
* Enchanting them will still add value, however,
* but that requires actual work, so lets let them... -keo
*/
obj->cost = 0;
for (paf = material->first_affect; paf; paf = paf->next) {
AFFECT_DATA *naf;
CREATE(naf, AFFECT_DATA, 1);
naf->type = paf->type;
naf->duration = paf->duration;
naf->location = paf->location;
naf->modifier = paf->modifier;
naf->bitvector = paf->bitvector;
top_affect++;
LINK(naf, obj->first_affect, obj->last_affect, next, prev);
}
obj->size = ch->height;
obj->material=material;
obj->obj_by = STRALLOC(ch->name);
obj = obj_to_char(obj, ch);
act( AT_MAGIC, "You weave $p from ether.", ch, obj, NULL, TO_CHAR);
act( AT_MAGIC, "$n weaves $p from ether.", ch, obj, NULL, TO_ROOM);
}
void dream_create(CHAR_DATA *ch, int power, char *arg1, char *arg2) {
MATERIAL_DATA *material_lookup( int number );
OBJ_DATA *obj = NULL;
extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *area;
int lo_vnum=2;
int hi_vnum=2;
MATERIAL_DATA *material;
int hash;
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
AFFECT_DATA *paf;
extern int top_affect;
if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) {
ch_trick(ch, MAG_DREAM);
return;
}
if (arg1 == NULL || arg2 == NULL) {
ch_trick(ch, MAG_DREAM);
return;
}
material=first_material;
while (material) {
if (!str_prefix(material->name, arg2))
break;
material=material->next;
}
if (!(material)) {
ch_trick(ch, MAG_DREAM);
return;
}
if (!stockobj)
for (area=first_area; area; area=area->next) {
if (!str_cmp( area->filename, "stockobj.are" )) {
stockobj = area;
lo_vnum=area->low_o_vnum;
hi_vnum=area->hi_o_vnum;
break;
} else {
lo_vnum=2;
hi_vnum=2;
}
} else {
area = stockobj;
lo_vnum=area->low_o_vnum;
hi_vnum=area->hi_o_vnum;
}
if (lo_vnum==hi_vnum) {
ch_trick(ch, MAG_DREAM);
return;
}
for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) {
for ( pObjIndex = obj_index_hash[hash]; pObjIndex;
pObjIndex = pObjIndex->next) {
if (pObjIndex == NULL) {
bug("NULL pObjIndex on spell_imagine!");
send_to_char("Your mind is a blank.\n\r", ch);
return;
}
if ( nifty_is_name( arg1, pObjIndex->name )
&& pObjIndex->vnum >= lo_vnum
&& pObjIndex->vnum <= hi_vnum) {
obj = create_object( pObjIndex, 0 );
if (!obj) {
ch_trick(ch, MAG_DREAM);
return;
}
break;
}
}
if (obj) break;
}
if (obj == NULL) {
ch_trick(ch, MAG_DREAM);
return;
}
strcpy(buf, material->name);
sprintf(arg, obj->short_descr, buf);
one_argument(arg, buf);
if (strcmp(buf, "some"))
strcpy(arg, aoran(arg));
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(arg);
strcpy(buf, material->name);
sprintf(arg, obj->description, buf);
if (strcmp(buf, "some"))
strcpy(arg, aoran(arg));
STRFREE(obj->description);
obj->description = STRALLOC(capitalize(arg));
strcpy(buf, obj->name);
strcat(buf, " ");
strcat(buf, material->name);
STRFREE(obj->name);
obj->name=STRALLOC(buf);
obj->cost += number_fuzzy(obj->cost);
for (paf = material->first_affect; paf; paf = paf->next) {
AFFECT_DATA *naf;
CREATE(naf, AFFECT_DATA, 1);
naf->type = paf->type;
naf->duration = paf->duration;
naf->location = paf->location;
naf->modifier = paf->modifier;
naf->bitvector = paf->bitvector;
top_affect++;
LINK(naf, obj->first_affect, obj->last_affect, next, prev);
}
obj->material=material;
obj->size = ch->height;
obj->obj_by = STRALLOC(ch->name);
obj = obj_to_char(obj, ch);
act( AT_MAGIC, "You imagine $p.", ch, obj, NULL, TO_CHAR);
act( AT_MAGIC, "$n concentrates, and $p appears in $s hands.", ch, obj, NULL, TO_ROOM);
xSET_BIT(obj->extra_flags, ITEM_DREAMWORLD);
}
void obj_create(CHAR_DATA *ch, int type, int power, char *argument) {
int create, x, y;
OBJ_DATA *obj;
MATERIAL_DATA *material;
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
material=material_lookup(116); /* Ether material */
if (!(material)) {
send_to_char("You can't seem to reach the Ether for some reason.\n\r", ch);
bug("Cannot find Ether material for Void Create!", 0);
return;
}
switch (type) {
default:
ch_trick(ch, type);
return;
case MAG_FIRE:
if (IS_UNDERWATER(ch)
|| ch->curr_talent[TAL_FIRE] < 10) {
ch_trick(ch, MAG_WATER);
return;
}
act(AT_FIRE, "You make a burst of mystic flame burn before you.",
ch, NULL, NULL, TO_CHAR);
act(AT_FIRE, "$n makes a burst of mystic flame burn before $m.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_FIRE;
break;
case MAG_WATER:
if (IS_UNDERWATER(ch)
|| ch->curr_talent[TAL_WATER] < 10) {
ch_trick(ch, type);
return;
}
act(AT_BLUE, "A spring of clear water gushes forth in midair.",
ch, NULL, NULL, TO_CHAR);
act(AT_BLUE, "A spring of clear water gushes forth in midair.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_SPRING;
break;
case MAG_ACID:
if (ch->curr_talent[TAL_WATER] < 20) {
ch_trick(ch, type);
return;
}
act(AT_BLUE, "You conjure a hot cup of tea.",
ch, NULL, NULL, TO_CHAR);
act(AT_BLUE, "$n conjures a hot cup of tea.",
ch, NULL, NULL, TO_ROOM);
create = 54;
break;
case MAG_BLUNT:
if (ch->curr_talent[TAL_EARTH] < 10) {
ch_trick(ch, type);
return;
}
act(AT_HUNGRY, "You conjure a loaf of bread.",
ch, NULL, NULL, TO_CHAR);
act(AT_HUNGRY, "$n conjures a loaf of bread.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_MUSHROOM;
break;
case MAG_EARTH:
if (ch->curr_talent[TAL_EARTH] < 10 ) {
ch_trick(ch, type);
return;
}
act(AT_RED, "You open your hand and a beautiful red rose grows and opens.",
ch, NULL, NULL, TO_CHAR);
act(AT_RED, "$n opens $s hand and a beautiful red rose grows and opens.",
ch, NULL, NULL, TO_ROOM);
create = 53;
break;
case MAG_DRAIN:
if (ch->curr_talent[TAL_MOTION] < 10 ) {
ch_trick(ch, type);
return;
}
act(AT_PURPLE, "You conjure a mystic shovel.",
ch, NULL, NULL, TO_CHAR);
act(AT_PURPLE, "$n conjures a mystic shovel.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_MYSTIC_SHOVEL;
break;
case MAG_ANTIMATTER:
if (ch->curr_talent[TAL_VOID] < 30) {
ch_trick(ch, type);
return;
}
act(AT_MAGIC, "You weave a bag of holding from the Void.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n weaves a bag of holding from the Void.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_BAG_OF_HOLDING;
break;
case MAG_LIGHT:
if (ch->curr_talent[TAL_ILLUSION] < 10) {
ch_trick(ch, type);
return;
}
act(AT_YELLOW, "You conjure a globe of light.",
ch, NULL, NULL, TO_CHAR);
act(AT_YELLOW, "$n conjures a globe of light.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_LIGHT_BALL;
break;
case MAG_POISON:
case MAG_CHANGE:
if (ch->curr_talent[TAL_DEATH] < 10) {
ch_trick(ch, type);
return;
}
act(AT_CHAOS, "You conjure a piece of chaos cheese.",
ch, NULL, NULL, TO_CHAR);
act(AT_CHAOS, "$n conjures a piece of chaos cheese.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_CHAOS_CHEESE;
break;
case MAG_SOUND:
if (ch->curr_talent[TAL_SPEECH] < 10) {
ch_trick(ch, type);
return;
}
act(AT_MAGIC, "You conjure a magic marker.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n conjures a magic marker.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_MAGIC_MARKER;
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 10) {
ch_trick(ch, type);
return;
}
act(AT_DGREY, "You conjure a globe of darkness.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREY, "$n conjures a globe of darkness.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_BALL_DARK;
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] < 20) {
ch_trick(ch, type);
return;
}
act(AT_BLUE, "You conjure a bottle of wine.",
ch, NULL, NULL, TO_CHAR);
act(AT_BLUE, "$n conjures a bottle of wine.",
ch, NULL, NULL, TO_ROOM);
create = OBJ_VNUM_WINE;
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_SEEKING] < 100) {
ch_trick(ch, type);
return;
}
act(AT_BLUE, "You conjure a reflecting pool.",
ch, NULL, NULL, TO_CHAR);
act(AT_BLUE, "$n conjures a reflecting pool.",
ch, NULL, NULL, TO_ROOM);
create = 9006;
break;
case MAG_SLASH:
if (ch->curr_talent[TAL_CATALYSM] < 30) {
ch_trick(ch, type);
return;
}
act(AT_YELLOW, "You draw pure energy together to form a gleaming mageblade.",
ch, NULL, NULL, TO_CHAR);
act(AT_YELLOW, "$n draws $s hands together and forges a mageblade of raw energy.",
ch, NULL, NULL, TO_ROOM);
create = 98;
break;
case MAG_TELEKINETIC:
if (ch->curr_talent[TAL_MOTION] < 40) {
ch_trick(ch, type);
return;
}
if (IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS)) {
ch_trick(ch, type);
return;
}
victim = generate_mob_nation(argument);
if (!victim) {
send_to_char("You cannot find anything like that.\n\r",ch);
return;
}
act(AT_MAGIC, "You open a swirling rift and pull $N through.",
ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "$n opens a swirling rift and pulls $N through.",
ch, NULL, victim, TO_ROOM);
char_to_room( victim, ch->in_room );
do_look( victim, "auto" );
WAIT_STATE(ch, PULSE_VIOLENCE);
return;
}
if (!get_obj_index(create)) {
bug("obj_create: vnum %d not found!", create);
send_to_char("At the last minute, you lose your train of thought!\n\r", ch);
return;
}
obj = create_object(get_obj_index(create), 0);
if (!IS_OBJ_STAT(obj, ITEM_NO_TAKE)) {
obj = obj_to_char(obj, ch);
} else {
obj = obj_to_room(obj, ch->in_room);
}
obj->cost = 0;
obj->obj_by = STRALLOC(ch->name);
obj->timer = power / 10;
obj->material = material;
/* Random mageblade appearances */
if (type == MAG_ALL) {
x = number_range(1,11);
y = number_range(1,12);
sprintf(buf, "%s %s %s",
x == 1 ? "gleaming" :
x == 2 ? "shining" :
x == 3 ? "blazing" :
x == 4 ? "crackling" :
x == 5 ? "sparkling" :
x == 6 ? "fiery" :
x == 7 ? "glimmering" :
x == 8 ? "glistening" :
x == 9 ? "glinting" :
x == 10 ? "mystic" :
"shimmering",
y == 1 ? "&Rred" :
y == 2 ? "&Wwhite" :
y == 3 ? "&wsilver" :
y == 4 ? "&Bblue" :
y == 5 ? "&Ggreen" :
y == 6 ? "&Pviolet" :
y == 7 ? "&ppurple" :
y == 8 ? "&Ppink" :
y == 9 ? "&Ccyan" :
y == 10 ? "&Rmu&Ylti-&Gco&Clo&Pred" :
"&Ygolden",
obj->short_descr);
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(buf);
STRFREE(obj->name);
obj->name = STRALLOC(buf);
}
WAIT_STATE(ch, PULSE_VIOLENCE);
}
void obj_find(CHAR_DATA *ch, OBJ_DATA *obj, int type) {
AFFECT_DATA *paf;
SKILLTYPE *sktmp;
MATERIAL_DATA *mat;
int gp;
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_ALL:
case MAG_ENERGY:
if (ch->curr_talent[TAL_SEEKING] < 15) {
obj_trick(ch, obj, type);
return;
}
if (obj->first_affect || obj->pIndexData->first_affect)
ch_printf(ch, "The %s has the following affects:\n\r", myobj(obj));
else
ch_printf(ch, "The %s has no inherent affects.\n\r", myobj(obj));
for ( paf = obj->pIndexData->first_affect; paf; paf = paf->next )
showaffect( ch, paf );
for ( paf = obj->first_affect; paf; paf = paf->next )
showaffect( ch, paf );
if (obj->gem) {
ch_printf(ch, "%s has been affixed to this item.\n\r",
aoran(myobj(obj->gem)));
for ( paf = obj->gem->first_affect; paf; paf = paf->next )
showaffect( ch, paf );
}
break;
case MAG_SEEK:
ch_printf(ch, "\n\rThe %s is %s", myobj(obj), aoran(item_type_name(obj)));
if (!xIS_EMPTY(obj->parts) )
ch_printf(ch, ", worn on: %s\n\r", ext_flag_string(&obj->parts, bp_flags));
else
send_to_char( ".\n\r", ch );
if (ch->curr_talent[TAL_SEEKING] >= 10) ch_printf( ch,
"Special properties: %s\n\rIts weight is %d.\r\n",
extra_bit_name(&obj->extra_flags), obj->weight);
if (obj->cost > 0) {
gp = obj->cost;
ch_printf( ch, "&wIt is worth &C%d mithril, ", (int)gp/1000000);
gp = gp % 1000000;
ch_printf( ch, "&Y%d gold, ", (int)gp/10000 );
gp = gp % 10000;
ch_printf( ch, "&W%d silver, ", (int)gp/100 );
gp = gp % 100;
ch_printf( ch, "&Oand %d copper coins&C.\n\r", gp);
}
if (ch->curr_talent[TAL_SEEKING] >= 5) ch_printf(ch,
"It appears to have been made for someone %d inches tall.\n\r", obj->size );
if (ch->curr_talent[TAL_SEEKING] >= 10 && obj->material) ch_printf(ch,
"It appears to be made of %s.\r\n", obj->material->name);
if (ch->curr_talent[TAL_SEEKING] >= 25) {
if (obj->timer == 0) ch_printf(ch, "It will not decay.\n\r");
else ch_printf(ch, "It will last another %d hours.\n\r", obj->timer);
}
if (obj->obj_by && ch->curr_talent[TAL_SEEKING] >= 50) ch_printf( ch,
"It was created by %s.\n\r",
obj->obj_by);
if (obj->raw_mana && ch->curr_talent[TAL_SEEKING] >= 5) ch_printf(ch,
"This item %s with raw mana.\n\r",
obj->raw_mana > 2000 ? "vibrates violently" :
obj->raw_mana > 1500 ? "radiates brightly" :
obj->raw_mana > 1000 ? "shines" :
obj->raw_mana > 500 ? "vibrates" : "tingles");
if (obj->mana && ch->curr_talent[TAL_SEEKING] >= 40) ch_printf(ch,
"%d points of energy have been absorbed into this item.\n\r", obj->mana);
switch (obj->item_type) {
case ITEM_CONTAINER:
ch_printf( ch, "%s appears to be %s.\n\r", capitalize(obj->short_descr),
obj->value[0] < 76 ? "of a small capacity" :
obj->value[0] < 150 ? "of a small to medium capacity" :
obj->value[0] < 300 ? "of a medium capacity" :
obj->value[0] < 550 ? "of a medium to large capacity" :
obj->value[0] < 751 ? "of a large capacity" :
"of a giant capacity" );
break;
case ITEM_PILL:
case ITEM_SCROLL:
case ITEM_POTION:
if (ch->curr_talent[TAL_SEEKING] >= 20) {
ch_printf( ch, "Casts:" );
if (obj->value[1] >= 0 && (sktmp=get_skilltype(obj->value[1])) != NULL) {
send_to_char( " '", ch );
send_to_char( sktmp->name, ch );
send_to_char( "'", ch );
}
if (obj->value[2] >= 0 && (sktmp=get_skilltype(obj->value[2])) != NULL) {
send_to_char( " '", ch );
send_to_char( sktmp->name, ch );
send_to_char( "'", ch );
}
if (obj->value[3] >= 0 && (sktmp=get_skilltype(obj->value[3])) != NULL) {
send_to_char( " '", ch );
send_to_char( sktmp->name, ch );
send_to_char( "'", ch );
}
send_to_char( ".\n\r", ch );
}
break;
case ITEM_SALVE:
ch_printf( ch, "Has %d out of %d applications left",
obj->value[1], obj->value[2]);
if (ch->curr_talent[TAL_SEEKING] >= 20) {
ch_printf(ch, " of ");
if (obj->value[4] >= 0 && (sktmp=get_skilltype(obj->value[4])) != NULL) {
send_to_char( " '", ch );
send_to_char( sktmp->name, ch );
send_to_char( "'", ch );
}
if (obj->value[5] >= 0 && (sktmp=get_skilltype(obj->value[5])) != NULL) {
send_to_char( " '", ch );
send_to_char( sktmp->name, ch );
send_to_char( "'", ch );
}
}
send_to_char( ".\n\r", ch );
break;
case ITEM_WEAPON:
if (obj->value[4] && obj->value[4] < 14) ch_printf(ch,
"This is a magically %s&z&Bweapon.\n\r", weapon_brand[obj->value[4]] );
ch_printf(ch, "This weapon falls into the '%s' category.\n\r",
weapon_skill[obj->value[5]]);
if (ch->curr_talent[TAL_SEEKING] >= 40 && obj->value[0]) {
if (ch->curr_talent[TAL_SEEKING] >= 70) {
if (obj->value[0] <= 17)
ch_printf( ch,
"This weapon will inflict %d extra damage against all %s.\n\r",
obj->value[6] / 10, weapon_bane[obj->value[0]]);
} else {
ch_printf( ch,
"This weapon is the bane of all %s.\n\r",
weapon_bane[obj->value[0]]);
}
}
ch_printf(ch, "Damage bonus is %d.\n\r", (obj->value[2]) / 2);
break;
case ITEM_ARMOR:
ch_printf( ch, "Armor class is %d.\n\r", obj->value[0] );
break;
case ITEM_MISSILE_WEAPON:
if (obj->value[4] && obj->value[4] < 13) ch_printf( ch,
"This is a magically %s&z&Bweapon.\n\r", weapon_brand[obj->value[4]] );
ch_printf(ch, "This weapon falls into the '%s' category.\n\r",
weapon_skill[obj->value[5]]);
ch_printf(ch, "Damage bonus is %d.\n\r", obj->value[2]);
if (obj->value[5] != SK_WAND) {
if (obj->value[0] == 0) {
ch_printf(ch, "It is empty.\n\r");
} else {
ch_printf(ch,
"%d shots have been loaded into this weapon.\n\r",
obj->value[0]);
}
break;
case ITEM_SCANNER:
case ITEM_RADIO:
ch_printf( ch, "The volume is set at %d.\n\r", obj->value[0]);
ch_printf( ch, "The frequency is set at %d.\n\r", obj->value[1]);
break;
}
}
break;
case MAG_EARTH:
case MAG_BLUNT:
if (!obj->material) {
obj_trick(ch, obj, type);
return;
}
mat = obj->material;
ch_printf(ch, "The %s is made of %s.\n\r", myobj(obj), mat->name);
ch_printf(ch, "%s has a cost of %d.\n\r", capitalize(mat->name), mat->cost);
if (!xIS_EMPTY(obj->extra_flags) && ch->curr_talent[TAL_EARTH] >= 20)
ch_printf(ch, "It has the properties of %s.\n\r",
extra_bit_name(&mat->extra_flags));
if (ch->curr_talent[TAL_CATALYSM] >= 40)
ch_printf( ch, "%s is a%s magical ore.\n\r", capitalize(mat->name),
mat->magic <= 10 ? "n incredibly" :
mat->magic <= 25 ? "n extremely" :
mat->magic <= 50 ? " highly" :
mat->magic <= 70 ? " very" :
mat->magic <= 80 ? " rather" :
mat->magic <= 90 ? " fairly" :
mat->magic <= 100 ? " somewhat" :
mat->magic <= 120 ? " poorly" :
" non" );
if (ch->curr_talent[TAL_SEEKING] >= 15)
for (paf = mat->first_affect; paf; paf = paf->next)
showaffect(ch, paf);
break;
case MAG_WATER:
if (obj->item_type != ITEM_DRINK_CON
&& obj->item_type != ITEM_FOUNTAIN) {
obj_trick(ch, obj, type);
return;
}
if (obj->value[2] >= LIQ_MAX) {
bug( "Do_drink: bad liquid number %d.", obj->value[2] );
obj->value[2] = 0;
}
if (obj->value[1] <= 0) {
ch_printf(ch, "The %s is empty.\n\r", myobj(obj));
break;
}
if (ch->curr_talent[TAL_WATER] >= 10)
ch_printf(ch, "The %s is %s full of %s.\n\r", myobj(obj),
obj->value[1] < obj->value[0] / 4
? "less than" :
obj->value[1] < 3 * obj->value[0] / 4
? "about" : "more than",
liq_table[obj->value[2]].liq_name);
else
ch_printf(ch, "The %s is %s full of a %s liquid.\n\r", myobj(obj),
obj->value[1] < obj->value[0] / 4
? "less than" :
obj->value[1] < 3 * obj->value[0] / 4
? "about" : "more than",
liq_table[obj->value[2]].liq_color);
if (ch->curr_talent[TAL_WATER] >= 40)
ch_printf(ch, "It will make you %s, %s, %s.\n\r",
liq_table[obj->value[2]].liq_affect[COND_THIRST] > 0 ? "less thirsty" :
liq_table[obj->value[2]].liq_affect[COND_THIRST] < 0 ? "more thirsty" :
"no less thirsty",
liq_table[obj->value[2]].liq_affect[COND_FULL] > 0 ? "less hungry" :
liq_table[obj->value[2]].liq_affect[COND_FULL] < 0 ? "more hungry" :
"no less hungry",
liq_table[obj->value[2]].liq_affect[COND_DRUNK] > 0 ? "and drunk" :
"but not drunk");
if (obj->value[3] && ch->curr_talent[TAL_WATER] > 20)
ch_printf(ch, "The %s is poisoned.\n\r", myobj(obj));
break;
case MAG_POISON:
if ( obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD
|| obj->item_type == ITEM_COOK) {
if ( obj->item_type == ITEM_COOK && obj->value[2] == 0 )
send_to_char( "It looks undercooked.\n\r", ch );
else if ( obj->value[3] != 0 )
send_to_char( "You smell poisonous fumes.\n\r", ch );
else
send_to_char( "It looks very delicious.\n\r", ch );
} else {
send_to_char( "It doesn't look poisoned.\n\r", ch );
}
break;
}
}
void ch_find(CHAR_DATA *victim, CHAR_DATA *ch, int type) {
char *name;
DEITY_DATA *talent;
AFFECT_DATA *paf;
SKILLTYPE *sktmp;
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_ALL:
if ( IS_NPC(victim) )
name = capitalize(victim->short_descr);
else
name = victim->name;
ch_printf(ch,"%s looks like %s.\n\r",
name, victim->nation ? aoran(victim->nation->name)
: get_race(victim));
if (ch->curr_talent[TAL_SEEKING] >= 30) {
if (TALENT(ch, TAL_SEEKING) > TALENT(victim, TAL_SECURITY) ) {
ch_printf(ch, "%s's current stats: %-2d str, %-2d wil, %-2d int, %-2d dex, %2d con, %-2d per, %-2d end.\r\n",
victim->name,
get_curr_str(victim), get_curr_wil(victim), get_curr_int(victim),
get_curr_dex(victim), get_curr_con(victim), get_curr_per(victim),
get_curr_lck(victim) );
}
}
if (ch->curr_talent[TAL_SEEKING] >= 40) {
if ( (chance(ch, 50) && get_curr_wil(ch) >= get_curr_wil(victim) + 10 )) {
ch_printf(ch, "%s appears to be affected by: ", name);
if (!victim->first_affect) {
send_to_char( "nothing.\n\r", ch );
} else {
for ( paf = victim->first_affect; paf; paf = paf->next ) {
if (victim->first_affect != victim->last_affect) {
if( paf != victim->last_affect &&
(sktmp=get_skilltype(paf->type)) != NULL)
ch_printf( ch, "%s, ", sktmp->name );
if( paf == victim->last_affect &&
(sktmp=get_skilltype(paf->type)) != NULL) {
ch_printf( ch, "and %s.\n\r", sktmp->name );
}
} else {
if ( (sktmp=get_skilltype(paf->type)) != NULL )
ch_printf( ch, "%s.\n\r", sktmp->name );
else
send_to_char( "\n\r", ch );
}
}
}
}
}
if (IS_NPC(victim)) return;
ch_printf(ch, "%s's aura:\n\r", PERS(victim, ch));
if (IS_SET(victim->pcdata->flags, PCFLAG_MASK)
&& TALENT(ch, TAL_SEEKING) > TALENT(victim, TAL_SEEKING)) {
send_to_char("You sense only a distorted fog.\n\r", ch);
return;
}
for (talent = first_deity; talent; talent = talent->next) {
if (victim->pcdata->inborn == talent->index) {
if (victim->talent[talent->index] >= 150)
ch_printf(ch, "predominately radiant %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 100)
ch_printf(ch, "primarily brilliant %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 50)
ch_printf(ch, "mainly bright %s\n\r", talent->color);
else
ch_printf(ch, "mostly pale %s\n\r", talent->color);
}
else if (victim->talent[talent->index] >= 200)
ch_printf(ch, "blindingly brilliant %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 160
&& ch->curr_talent[TAL_SEEKING] >= 10)
ch_printf(ch, "awash with a cascade of %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 130
&& ch->curr_talent[TAL_SEEKING] >= 20)
ch_printf(ch, "raging torrents of brilliant %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 100
&& ch->curr_talent[TAL_SEEKING] >= 30)
ch_printf(ch, "radiating %s brightly\n\r", talent->color);
else if (victim->talent[talent->index] >= 85
&& ch->curr_talent[TAL_SEEKING] >= 40)
ch_printf(ch, "shimmering rays of %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 70
&& ch->curr_talent[TAL_SEEKING] >= 50)
ch_printf(ch, "bright streaks of %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 50
&& ch->curr_talent[TAL_SEEKING] >= 80)
ch_printf(ch, "shining %s sparkles\n\r", talent->color);
else if (victim->talent[talent->index] >= 30
&& ch->curr_talent[TAL_SEEKING] >= 120)
ch_printf(ch, "traces of glittering %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 10
&& ch->curr_talent[TAL_SEEKING] >= 150)
ch_printf(ch, "pale flecks of %s\n\r", talent->color);
else if (victim->talent[talent->index] >= 1
&& ch->curr_talent[TAL_SEEKING] >= 200)
ch_printf(ch, "faint tinge of %s barely visible\n\r", talent->color);
}
break;
}
} /* ch_find */
void seek_find(CHAR_DATA *ch, int type, char *argument) {
OBJ_DATA *obj;
OBJ_DATA *in_obj;
CHAR_DATA *victim;
DESCRIPTOR_DATA *d;
char *str;
char buf[MAX_STRING_LENGTH];
char name[MAX_INPUT_LENGTH];
int found, temp;
struct stat fst;
switch (type) {
default:
ch_trick(ch, type);
break;
case MAG_TELEKINETIC:
if (ch->curr_talent[TAL_SEEKING] < 20) {
ch_trick(ch, type);
break;
}
found = FALSE;
if (TALENT(ch, TAL_SEEKING) < 50)
for (victim = first_char; victim; victim = victim->next) {
if (victim->in_room
&& can_see(ch, victim)
&& nifty_is_name( argument, victim->name)) {
found++;
pager_printf( ch, "%s is in %s\n\r",
PERS(victim, ch),
victim->in_room->name );
}
} else
for (victim = first_char; victim; victim = victim->next) {
if (victim->in_room
&& can_see(ch, victim)
&& nifty_is_name( argument, victim->name)) {
found++;
pager_printf( ch, "%s is in %s, in %s\n\r",
PERS(victim, ch),
victim->in_room->name,
victim->in_room->area->name );
}
}
for (obj = first_object; obj; obj = obj->next) {
if (!can_see_obj(ch, obj) ||
!nifty_is_name(argument, obj->name))
continue;
if (IS_OBJ_STAT(obj, ITEM_PROTOTYPE) ||
IS_OBJ_STAT(obj, ITEM_NOLOCATE) ||
IS_OBJ_STAT(obj, ITEM_ARTIFACT) ||
IS_OBJ_STAT(obj, ITEM_GEM) ||
number_percent() > TALENT(ch, TAL_SEEKING))
continue;
found++;
for (temp = 0, in_obj = obj;
in_obj->in_obj && temp < 100;
in_obj = in_obj->in_obj, ++temp);
if (temp >= MAX_NEST) {
sprintf(buf, "seek_object: object [%d] %s is nested more than %d times!",
obj->pIndexData->vnum, obj->short_descr, MAX_NEST);
bug(buf, 0);
continue;
}
if ( in_obj->carried_by ) {
if (TALENT(ch, TAL_SEEKING) < 30)
sprintf( buf, "%s is carried by %s.\n\r",
obj_short(obj), PERS(in_obj->carried_by, ch) );
else if (TALENT(ch, TAL_SEEKING) < 60)
sprintf( buf, "%s is carried by %s, in %s.\n\r",
obj_short(obj), PERS(in_obj->carried_by, ch),
in_obj->carried_by->in_room->name);
else
sprintf( buf, "%s is carried by %s, in %s in %s.\n\r",
obj_short(obj), PERS(in_obj->carried_by, ch),
in_obj->carried_by->in_room->name,
in_obj->carried_by->in_room->area->name);
} else {
if (in_obj->in_room == NULL)
sprintf( buf, "%s is somewhere\n\r", obj_short(obj));
else if (TALENT(ch, TAL_SEEKING) < 50)
sprintf( buf, "%s is in %s.\n\r",
obj_short(obj), in_obj->in_room->name );
else
sprintf( buf, "%s is in %s, in %s.\n\r",
obj_short(obj),
in_obj->in_room->name, in_obj->in_room->area->name );
}
buf[0] = UPPER(buf[0]);
send_to_char(buf, ch);
}
if (!found) {
send_to_char("You were unable to locate anything like that.\n\r", ch);
}
break;
case MAG_EARTH:
case MAG_BLUNT:
if (ch->curr_talent[TAL_SEEKING]
+ ch->curr_talent[TAL_EARTH] < 20) {
ch_trick(ch, type);
return;
}
ch_printf(ch, "You are in %s in %s, on the world of %s.\n\r",
ch->in_room->name, ch->in_room->area->name, ch->in_room->area->resetmsg);
switch( ch->in_room->sector_type ) {
default: str = "somewhere strange"; break;
case SECT_INSIDE: str = "inside"; break;
case SECT_CITY: str = "a city street"; break;
case SECT_FIELD: str = "a field"; break;
case SECT_FOREST: str = "a forest"; break;
case SECT_HILLS: str = "in the hills"; break;
case SECT_MOUNTAIN: str = "in the mountains"; break;
case SECT_WATER_SWIM: str = "swallow water"; break;
case SECT_WATER_NOSWIM: str = "deep water"; break;
case SECT_UNDERWATER: str = "underwater"; break;
case SECT_AIR: str = "in the air"; break;
case SECT_DESERT: str = "in the desert"; break;
case SECT_OCEANFLOOR: str = "on the oceanfloor"; break;
case SECT_UNDERGROUND: str = "underground"; break;
case SECT_LAVA: str = "molten lava"; break;
case SECT_SWAMP: str = "in the swamps"; break;
case SECT_BEACH: str = "on a beach"; break;
case SECT_ICE: str = "on ice"; break;
}
ch_printf(ch, "It appears to be %s.\n\r", str);
if (ch->in_room->room_flags)
ch_printf(ch, "It seems to be %s.\n\r",
flag_string(ch->in_room->room_flags, r_flags) );
temp = ch->in_room->curr_water;
ch_printf(ch, "%s, and ", temp >= 100 ?
"The room is completely underwater" : temp > 50 ?
"The water is deep" : temp > 0 ? "The water is muddy and shallow"
: "The room is dry");
temp = ch->in_room->curr_vegetation;
ch_printf(ch, "%s vegetation grows.\n\r", temp >= 66 ?
"thick" : temp > 33 ? "some" : "no");
temp = ch->in_room->curr_resources;
ch_printf(ch, "There is a %s concentration of resources here.\n\r", temp >= 66 ?
"high" : temp > 33 ? "moderate" : "low");
if (ch->in_room->runes)
ch_printf( ch, "Runes of %s line the walls.\n\r",
ch->curr_talent[TAL_CATALYSM] < 20 ? "some sort" :
flag_string(ch->in_room->runes, rune_flags) );
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_SEEKING] < 200) {
ch_trick(ch, type);
break;
}
if ((victim = get_char_world( ch, argument)) == NULL) {
ch_trick(ch, type);
break;
}
if (!victim->desc) {
ch_trick(ch, type);
break;
}
if (victim == ch) {
for ( d = first_descriptor; d; d = d->next )
if ( d->snoop_by == ch->desc )
d->snoop_by = NULL;
send_to_char("You break your mental connections watching over people.\n\r", ch);
return;
}
if (victim->desc->snoop_by) {
for ( d = first_descriptor; d; d = d->next )
if ( d->snoop_by == ch->desc )
d->snoop_by = NULL;
send_to_char("Your mental links become tangled and sever themselves.\n\r", ch);
return;
}
for (d = ch->desc->snoop_by; d; d = d->snoop_by)
if (d->character == victim || d->original == victim) {
send_to_char("Your target's mind gets in the way.\n\r", ch);
return;
}
if (IS_SET(ch->pcdata->flags, PCFLAG_SHIELD)
|| (IS_SET(victim->pcdata->flags, PCFLAG_SHIELD)
&& TALENT(ch, TAL_MIND) < TALENT(victim, TAL_MIND))) {
send_to_char("A shield blocks you from connecting.\n\r", ch);
return;
}
if (victim->curr_talent[TAL_SEEKING]
+ victim->curr_talent[TAL_MIND] >= 110)
send_to_char("You feel like someone is watching your every move...\n\r", victim);
victim->desc->snoop_by = ch->desc;
send_to_char("You establish a connection to watch over them.\n\r", ch);
break;
case MAG_TIME:
send_to_char("You direct your thoughts backward along the paths of Time...\n\r", ch);
strcpy(name, capitalize(argument));
sprintf(buf, "%s%c/%s", PLAYER_DIR, tolower(argument[0]), name);
if ( stat( buf, &fst ) != -1 )
sprintf(buf, "%s last entered the Planes on %s\r", name, ctime(&fst.st_mtime));
else
sprintf(buf, "You could not find %s's thread within the Planes.\n\r", name);
send_to_char(buf, ch);
break;
}
} /* seek_find */
void ch_focus(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) {
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_ANTIMAGIC:
if (!victim->shield) {
ch_trick(victim, type);
return;
}
if (victim == ch) {
act(AT_MAGIC, "You lower your magical shield.", ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n lowers $s magical shield.",ch, NULL, NULL, TO_ROOM);
} else {
if (ch->curr_talent[TAL_VOID] < 50) {
ch_trick(victim, type);
return;
}
act(AT_MAGIC, "You disrupt $N's magical shield!", ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "$n disrupts $N's magical shield!", ch, NULL, victim, TO_ROOM);
act(AT_MAGIC, "$n disrupts your magical shield!", ch, NULL, victim, TO_VICT);
}
victim->shield = MAG_NONE;
return;
case MAG_ACID:
if (ch->curr_talent[TAL_WATER] < 30
|| ch->curr_talent[TAL_EARTH] < 10) {
ch_trick(victim, type);
return;
}
act(AT_GREEN, "A glistening bubble of acid encompasses you.",
ch, NULL, NULL, TO_CHAR);
act(AT_GREEN, "A glistening bubble of acid encompasses $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_DREAM:
if (ch->curr_talent[TAL_DREAM] < 40) {
ch_trick(victim, type);
return;
}
act(AT_PINK, "Wispy dreams and whispered thoughts surround you.",
ch, NULL, NULL, TO_CHAR);
act(AT_PINK, "Wispy dreams and whispered thoughts surround $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_ENERGY:
if (ch->curr_talent[TAL_CATALYSM] < 40) {
ch_trick(victim, type);
return;
}
act(AT_PURPLE, "A rippling shield of energy surrounds you.",
ch, NULL, NULL, TO_CHAR);
act(AT_PURPLE, "A rippling shield of energy surrounds $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 40) {
ch_trick(victim, type);
return;
}
act(AT_FIRE, "Mystical flames rise to enshroud you.",
ch, NULL, NULL, TO_CHAR);
act(AT_FIRE, "Mystical flames rise to enshroud $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_COLD:
if (ch->curr_talent[TAL_FROST] < 40) {
ch_trick(victim, type);
return;
}
act(AT_FROST, "A glistening hail of ice encompasses you.",
ch, NULL, NULL, TO_CHAR);
act(AT_FROST, "A glistening hail of ice encompasses $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_LIGHT:
if (ch->curr_talent[TAL_ILLUSION] < 40) {
ch_trick(victim, type);
return;
}
act(AT_WHITE, "Searing light radiates from you.",
ch, NULL, NULL, TO_CHAR);
act(AT_WHITE, "Searing light radiates from $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_ALL:
if (victim == ch) {
if (ch->curr_talent[TAL_CATALYSM] < 60) {
ch_trick(victim, type);
return;
}
act(AT_PURPLE, "A field of prismatic mana surrounds you.",
ch, NULL, NULL, TO_CHAR);
act(AT_PURPLE, "A field of prismatic mana surrounds $n.",
ch, NULL, NULL, TO_ROOM);
} else {
if (ch->curr_talent[TAL_CATALYSM] < 30) {
ch_trick(victim, type);
return;
}
WAIT_STATE(ch, PULSE_VIOLENCE);
if (victim->shield == MAG_ALL
|| IS_SET(ch->pcdata->flags, PCFLAG_CHEAT)) {
act(AT_PURPLE, "Your mana bounces off $N's shield!",
ch, NULL, victim, TO_CHAR);
act(AT_PURPLE, "$n's mana bounces off your shield!",
ch, NULL, victim, TO_VICT);
act(AT_PURPLE, "$n's mana bounces off $N's shield!",
ch, NULL, victim, TO_NOTVICT);
ch->mana = ch->max_mana + power;
return;
}
act(AT_PURPLE, "You funnel your magic into $N's body!",
ch, NULL, victim, TO_CHAR);
act(AT_PURPLE, "$n glows brightly, funneling $s magic into you!",
ch, NULL, victim, TO_VICT);
act(AT_PURPLE, "$n glows brightly, funneling $s magic into $N!",
ch, NULL, victim, TO_NOTVICT);
ch->mana -= power;
victim->mana += power;
}
break;
case MAG_POISON:
if (ch->curr_talent[TAL_DEATH] < 40) {
ch_trick(victim, type);
return;
}
act(AT_DGREEN, "Deadly venom oozes from your skin.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREEN, "Deadly venom oozes from $n's skin.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_ELECTRICITY:
if (ch->curr_talent[TAL_LIGHTNING] < 40) {
ch_trick(victim, type);
return;
}
act(AT_YELLOW, "Torrents of cascading energy form around you.",
ch, NULL, NULL, TO_CHAR);
act(AT_YELLOW, "Torrents of cascading energy form around $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_SOUND:
if (ch->curr_talent[TAL_LIGHTNING] < 40) {
ch_trick(victim, type);
return;
}
act(AT_PINK, "A discordant wail of deafening sound surrounds you.",
ch, NULL, NULL, TO_CHAR);
act(AT_PINK, "A discordant wail of deafening sound surrounds $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_BLUNT:
if (ch->curr_talent[TAL_EARTH] < 40) {
ch_trick(victim, type);
return;
}
act(AT_DGREY, "A hail of stones rotates around you.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREY, "A hail of stones rotates around $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] < 40) {
ch_trick(victim, type);
return;
}
act(AT_PURPLE, "You concentrate, forming a mental barrier.",
ch, NULL, NULL, TO_CHAR);
act(AT_PURPLE, "$n concentrates, forming a mental barrier.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_EARTH:
if (ch->curr_talent[TAL_EARTH] < 40) {
ch_trick(victim, type);
return;
}
act(AT_GREEN, "An array of thorny vines surrounds you.",
ch, NULL, NULL, TO_CHAR);
act(AT_GREEN, "An array of thorny vines surrounds $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_CHANGE:
if (ch->curr_talent[TAL_CHANGE] < 40) {
ch_trick(victim, type);
return;
}
act(AT_DBLUE, "The air warps and distorts around you.",
ch, NULL, NULL, TO_CHAR);
act(AT_DBLUE, "The air warps and distorts around $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_WATER:
if (ch->curr_talent[TAL_WATER] < 40) {
ch_trick(victim, type);
return;
}
act(AT_BLUE, "Foaming waves rise to encompass you.",
ch, NULL, NULL, TO_CHAR);
act(AT_BLUE, "Foaming waves rise to encompass $n.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_WIND:
if (ch->curr_talent[TAL_WIND] < 40) {
ch_trick(victim, type);
return;
}
act(AT_CYAN, "Swirling gusts of wind blow around you.",
ch, NULL, NULL, TO_CHAR);
act(AT_CYAN, "Swirling gusts of wind blow around $n.",
ch, NULL, NULL, TO_ROOM);
break;
}
ch->shield = type;
} /* ch_focus */
void obj_focus(CHAR_DATA *ch, OBJ_DATA *obj, int type) {
char buf[MAX_STRING_LENGTH];
if (obj->item_type != ITEM_WEAPON
&& obj->item_type != ITEM_MISSILE_WEAPON) {
obj_trick(ch, obj, type);
return;
}
if (obj->value[4]
&& type != MAG_HOLY
&& type != MAG_ANTIMAGIC) {
obj_trick(ch, obj, type);
return;
}
if (obj->mana < 500
&& type != MAG_ANTIMAGIC) {
obj_trick(ch, obj, type);
return;
}
WAIT_STATE(ch, PULSE_VIOLENCE);
switch (type) {
default:
obj_trick(ch, obj, type);
return;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_FIRE, "$p bursts into flame!", ch, obj, NULL, TO_CHAR );
act( AT_FIRE, "$n's $p bursts into flame!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_FLAMING;
break;
case MAG_COLD:
if (ch->curr_talent[TAL_FROST] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_FROST, "$p shimmers with cold!", ch, obj, NULL, TO_CHAR );
act( AT_FROST, "$n's $p shimmers with cold!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_FROZEN;
break;
case MAG_ELECTRICITY:
if (ch->curr_talent[TAL_LIGHTNING] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_YELLOW, "$p crackles with electricity!", ch, obj, NULL, TO_CHAR);
act( AT_YELLOW, "$n's $p crackles with electricity!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_ELEC;
break;
case MAG_ACID:
if (ch->curr_talent[TAL_WATER] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_YELLOW, "$p hisses with acid!", ch, obj, NULL, TO_CHAR);
act( AT_YELLOW, "$n's $p hisses with acid!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_ACID;
break;
case MAG_ANTIMATTER:
if (ch->curr_talent[TAL_VOID] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_DGREY, "Black lightning erupts from $p!", ch, obj, NULL, TO_CHAR);
act( AT_DGREY, "Black lightning erupts from $n's $p!", ch, obj, NULL, TO_ROOM);
xREMOVE_BIT(obj->extra_flags, ITEM_GLOW);
xSET_BIT(obj->extra_flags, ITEM_DARK);
obj->value[4] = BRAND_ANTI_MATTER;
break;
case MAG_SOUND:
if (ch->curr_talent[TAL_SPEECH] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_GREEN, "$p emits a sonic hum!", ch, obj, NULL, TO_CHAR );
act( AT_GREEN, "$n's $p emits a sonic hum!", ch, obj, NULL, TO_ROOM);
xSET_BIT(obj->extra_flags, ITEM_HUM);
obj->value[4] = BRAND_SONIC;
break;
case MAG_CHANGE:
if (ch->curr_talent[TAL_CHANGE] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_DBLUE, "The air warps and twists into $p!", ch, obj, NULL, TO_CHAR );
act( AT_DBLUE, "The air warps and twists into $n's $p!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_DISTORT;
break;
case MAG_POISON:
if (ch->curr_talent[TAL_DEATH] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_GREEN, "$p drips with venom!", ch, obj, NULL, TO_CHAR );
act( AT_GREEN, "$n's $p drips with venom!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_POISON;
break;
case MAG_SLASH:
if (ch->curr_talent[TAL_CATALYSM] < 50) {
obj_trick(ch, obj, type);
return;
}
if (obj->value[5] != SK_SWORD
&& obj->value[5] != SK_DAGGER
&& obj->value[5] != SK_AXE
&& obj->value[5] != SK_HALBERD
&& obj->value[5] != SK_SPEAR
&& obj->value[5] != SK_POLEARM
&& obj->value[5] != SK_CLAW) {
obj_trick(ch, obj, type);
return;
}
act( AT_WHITE, "$p glints razor-sharp!", ch, obj, NULL, TO_CHAR );
act( AT_WHITE, "$n's $p glints razor-sharp!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_VORPAL;
break;
case MAG_WIND:
if (ch->curr_talent[TAL_WIND] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_CYAN, "Stormy winds swirl about $p!", ch, obj, NULL, TO_CHAR );
act( AT_CYAN, "Stormy winds swirl about $n's $p!", ch, obj, NULL, TO_ROOM );
obj->value[4] = BRAND_STORM;
break;
case MAG_LIGHT:
if (ch->curr_talent[TAL_ILLUSION] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_YELLOW, "$p glows with a blinding radiance!", ch, obj, NULL, TO_CHAR);
act( AT_YELLOW, "$n's $p glows with a blinding radiance!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_RADIANT;
xREMOVE_BIT(obj->extra_flags, ITEM_DARK);
xSET_BIT(obj->extra_flags, ITEM_GLOW);
break;
case MAG_BLUNT:
if (ch->curr_talent[TAL_EARTH] < 50) {
obj_trick(ch, obj, type);
return;
}
if (obj->value[5] != SK_MACE
&& obj->value[5] != SK_STAFF
&& obj->value[5] != SK_WHIP) {
obj_trick(ch, obj, type);
return;
}
act( AT_DGREY, "$p becomes harder than rock!", ch, obj, NULL, TO_CHAR );
act( AT_DGREY, "$n's $p becomes harder than rock!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_CRUSH;
break;
case MAG_DRAIN:
if (ch->curr_talent[TAL_DEATH] < 60) {
obj_trick(ch, obj, type);
return;
}
act( AT_DGREY, "$p thirsts for blood!", ch, obj, NULL, TO_CHAR);
act( AT_DGREY, "$n's $p thirsts for blood!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_DRAIN;
break;
case MAG_PSIONIC:
if (ch->curr_talent[TAL_MIND] < 50) {
obj_trick(ch, obj, type);
return;
}
act( AT_PURPLE, "A strange humming sound emanates from $p!", ch, obj, NULL, TO_CHAR);
act( AT_PURPLE, "A strange humming sound emanates from $n's $p!", ch, obj, NULL, TO_ROOM);
obj->value[4] = BRAND_PSIONIC;
xSET_BIT(obj->extra_flags, ITEM_HUM);
break;
case MAG_HOLY:
if (ch->curr_talent[TAL_SECURITY] < 50) {
obj_trick(ch, obj, type);
return;
}
if (IS_OBJ_STAT(obj, ITEM_LOYAL)
|| IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
return;
}
if (obj->mana < 500) {
obj_trick(ch, obj, type);
return;
}
obj->mana -= 500;
obj->cost += 500000;
xSET_BIT(obj->extra_flags, ITEM_LOYAL);
act(AT_WHITE, "You bind $p with a wash of white light.", ch, obj, NULL, TO_CHAR);
act(AT_WHITE, "White light washes over $n's $p.", ch, obj, NULL, TO_ROOM);
return;
case MAG_ANTIMAGIC:
if (!IS_OBJ_STAT(obj, ITEM_MAGIC)) {
obj_trick(ch, obj, type);
return;
}
if (ch->curr_talent[TAL_VOID] < 30) {
obj_trick(ch, obj, type);
return;
}
act(AT_DGREY, "You strip $p of its magical properties.", ch, obj, NULL, TO_CHAR);
act(AT_DGREY, "Antimagic violently rips at $n's $p.", ch, NULL, NULL, TO_ROOM);
xREMOVE_BIT(obj->extra_flags, ITEM_MAGIC);
xREMOVE_BIT(obj->extra_flags, ITEM_HUM);
xREMOVE_BIT(obj->extra_flags, ITEM_DARK);
xREMOVE_BIT(obj->extra_flags, ITEM_GLOW);
obj->cost -= 50000;
if (obj->value[4]) {
obj->value[4] = 0;
obj->cost -= 500000;
}
obj->value[0] = 0;
obj->value[7] = 0;
obj->mana = 0;
obj->raw_mana = 0;
return;
}
obj->mana -= 500;
obj->cost += 500000;
sprintf(buf, "%s%s", weapon_brand[obj->value[4]],myobj(obj));
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(buf);
} /* obj_focus */
void obj_move(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power, char *argument) {
CHAR_DATA *victim;
CHAR_DATA *target;
ROOM_INDEX_DATA *location;
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_TELEKINETIC:
if ((target = get_char_world(ch, argument)) == NULL
|| !can_travel(90, ch, target)
|| (TALENT(target, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) {
act( AT_MAGIC, "You are unable to locate $t.",
ch, argument, NULL, TO_CHAR);
return;
}
if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD) /* Thanks Smokey */
|| IS_OBJ_STAT(obj, ITEM_ARTIFACT) /* Thanks Waffle */
|| victim->carry_weight + get_obj_weight(obj) > can_carry_w(target)) {
obj_trick(ch, obj, type);
break;
}
separate_obj(obj);
act( AT_MAGIC, "$p slowly dematerializes from your hands.", ch, obj, NULL, TO_CHAR);
act( AT_MAGIC, "$p slowly dematerializes from $n's hands.", ch, obj, NULL, TO_ROOM);
obj_from_char( obj );
if (!IS_AFFECTED(target, AFF_ETHEREAL)) {
obj_to_char( obj, target );
act( AT_MAGIC, "$p slowly materializes in your hands, sent by $N.",
target, obj, ch, TO_CHAR);
act( AT_MAGIC, "$p slowly materializes in $n's hands.",
target, obj, NULL, TO_ROOM);
} else {
obj_to_room( obj, target->in_room );
act( AT_MAGIC, "$p slowly materializes beside you and drops to the ground.",
target, obj, ch, TO_CHAR);
act( AT_MAGIC, "$p slowly materializes beside $n and drops to the ground.",
target, obj, NULL, TO_ROOM);
}
save_char_obj(ch);
save_char_obj(target);
WAIT_STATE(ch, PULSE_VIOLENCE);
break;
case MAG_CHANGE:
for ( ; ; ) {
location = get_room_index( number_range( 0, 32000 ) );
if ( location )
if ( !IS_SET(location->room_flags, ROOM_PRIVATE)
&& !IS_SET(location->room_flags, ROOM_SOLITARY)
&& !IS_SET(location->room_flags, ROOM_NO_ASTRAL)
&& !IS_SET(location->room_flags, ROOM_PROTOTYPE) )
break;
}
act( AT_MAGIC, "You throw $p high into the air where it vanishes.",
ch, obj, NULL, TO_CHAR);
act( AT_MAGIC, "$n throws $p high into the air where it vanishes.",
ch, obj, NULL, TO_ROOM);
obj_from_char(obj);
obj_to_room(obj, location);
break;
case MAG_WIND:
if (obj->weight*10 > power
|| !obj->in_room) {
act(AT_MAGIC, "$p shakes a little.",
ch, obj, NULL, TO_ROOM);
act(AT_MAGIC, "$p shakes a little.",
ch, obj, NULL, TO_CHAR);
return;
}
act(AT_MAGIC, "$p suddenly lifts off the ground and flies through the air toward $n.",
ch, obj, NULL, TO_ROOM);
act(AT_MAGIC, "You lift $p with your magic and bring it toward you.",
ch, obj, NULL, TO_CHAR);
if (ch->curr_talent[TAL_MOTION] < number_range(1,30)) {
act(AT_MAGIC, "$p flies past $n and falls to the ground.",
ch, obj, NULL, TO_ROOM);
act(AT_MAGIC, "$p flies past you and falls to the ground.",
ch, obj, NULL, TO_CHAR);
return;
}
if (ch->curr_talent[TAL_MOTION] < number_range(1,50)) {
act(AT_MAGIC, "$p smacks into $n, but $e catches it.",
ch, obj, NULL, TO_ROOM);
act(AT_MAGIC, "$p smacks into you, but you catch it.",
ch, obj, NULL, TO_CHAR);
lose_hp(ch, obj->weight);
}
separate_obj(obj);
obj_from_room(obj);
obj_to_char(obj, ch);
if ( obj->item_type == ITEM_MONEY ) {
int gp;
gp = obj->value[0];
ch_printf( ch, "There were &C%d mithril, ", (int)gp/1000000 );
gp = gp % 1000000;
ch_printf( ch, "&Y%d gold, ", (int)gp/10000 );
gp = gp % 10000;
ch_printf( ch, "&W%d silver, ", (int)gp/100 );
gp = gp % 100;
ch_printf( ch, "and &O%d copper coins.\n\r", gp);
ch->gold += obj->value[0];
extract_obj( obj );
}
break;
}
} /* obj_move */
void ch_move(CHAR_DATA *victim, CHAR_DATA *ch, int type, char *arg1, char *arg2) {
int slot, mem;
ROOM_INDEX_DATA *location;
CHAR_DATA *target;
char buf[MAX_STRING_LENGTH];
location = NULL;
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_TELEKINETIC:
if ( (target = get_char_world(ch, arg2)) == NULL
|| !can_travel(90, ch, target)
|| (TALENT(target, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) {
act( AT_MAGIC, "You are unable to locate $t.",
ch, arg1, NULL, TO_CHAR);
return;
}
if (target == ch || victim == target) {
ch_trick(victim, type);
break;
}
if (victim != ch
&& ch->curr_talent[TAL_MOTION] < 90) {
ch_trick(victim, type);
break;
}
if (!IS_NPC(victim)) {
sprintf( buf, "%s sent %s to %s (%d).", ch->name,
victim->name, target->in_room->name, target->in_room->vnum );
to_channel( buf, "Spell", PERMIT_SECURITY);
}
act( AT_MAGIC, "You send $N across the astral planes.",
ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "$n sends you across the astral planes.",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "$n sends $N across the astral planes.",
ch, NULL, victim, TO_ROOM);
char_from_room( victim );
victim->in_obj = NULL;
char_to_room( victim, target->in_room );
if (victim->mount) {
char_from_room(victim->mount);
char_to_room(victim->mount, target->in_room);
}
act( AT_MAGIC, "A rift in the sky opens, and $n falls out.",
victim, NULL, NULL, TO_ROOM);
do_look( victim, "auto" );
break;
case MAG_CHANGE:
if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
&& ch->curr_talent[TAL_MOTION] < 80) {
send_to_char("For some reason, nothing happens.\n\r", ch);
return;
}
for ( ;; ) {
location = get_room_index( number_range( 0, 32000 ) );
if ( location )
if ( !IS_SET(location->room_flags, ROOM_PRIVATE)
&& !IS_SET(location->room_flags, ROOM_SOLITARY)
&& !IS_SET(location->room_flags, ROOM_NO_ASTRAL)
&& !IS_SET(location->area->flags, AFLAG_NOTELEPORT)
&& !IS_SET(location->room_flags, ROOM_PROTOTYPE)
&& !IS_SET(location->room_flags, ROOM_NO_RECALL) )
break;
}
act( AT_MAGIC, "Reality seems to twist for a moment, and your surroundings warp and change.", victim, NULL, NULL, TO_CHAR);
act( AT_MAGIC, "Reality seems to twist for a moment, and $n vanishes.",
victim, NULL, NULL, TO_ROOM);
char_from_room( victim );
victim->in_obj = NULL;
char_to_room( victim, location );
if (victim->mount) {
char_from_room(victim->mount);
char_to_room(victim->mount, location);
}
act( AT_MAGIC, "Reality ripples for a moment, and $n suddenly appears.",
ch, NULL, NULL, TO_ROOM);
do_look( victim, "auto" );
break;
case MAG_PSIONIC:
if (!arg2 || arg2[0] == '\0')
slot = 0;
else
slot = atoi(arg2);
if (!str_cmp(arg2, "nexus")) {
if (IS_SET(ch->in_room->area->flags, AFLAG_FREEKILL))
location = get_room_index(ROOM_VNUM_PKILL);
else
location = get_room_index(ROOM_VNUM_NEXUS);
} else if (!str_cmp(arg2, "area")) {
location = get_room_index(ch->in_room->area->hi_soft_range);
} else {
mem = (ch->curr_talent[TAL_MOTION] -20) / 10;
if (mem > 7) mem = 7;
if (mem < 0 && ch->curr_talent[TAL_MOTION] > 0)
mem = 0;
if (slot > mem) {
send_to_char("You cannot recall the details of that location.\n\r", ch);
return;
}
if (IS_NPC(ch)) {
if (IS_AFFECTED(ch, AFF_CHARM) && ch->master && !IS_NPC(ch->master)) {
location = get_room_index( ch->master->pcdata->memorize[slot] );
} else {
return;
}
} else {
location = get_room_index( ch->pcdata->memorize[slot] );
}
}
if ( !location )
location = get_room_index( ROOM_VNUM_NEXUS );
if ( !location ) {
send_to_char( "You are completely lost.\n\r", ch );
return;
}
if ( ch->in_room == location ) {
send_to_char("You are already here!\n\r", ch);
return;
}
if ( IS_AFFECTED(ch, AFF_DREAMWORLD)
&& IS_SET(location->room_flags, ROOM_NO_DREAM)) {
send_to_char("A mysterious shield prevents you from recalling.\n\r", ch);
return;
}
if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
&& ch->curr_talent[TAL_MOTION] < 80) {
send_to_char( "For some strange reason... nothing happens.\n\r", ch);
return;
}
if (IS_AFFECTED(ch, AFF_CURSE)
&& ch->curr_talent[TAL_MOTION] < 70) {
send_to_char("You are cursed and cannot recall!\n\r", ch);
return;
}
if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) {
send_to_char("You cannot recall from combat!\r\n", ch);
return;
}
act( AT_ACTION, "$n disappears in a swirl of mist.",
ch, NULL, NULL, TO_ROOM);
char_from_room(ch);
ch->in_obj = NULL;
char_to_room(ch, location);
if (ch->mount) {
char_from_room(ch->mount);
char_to_room(ch->mount, location);
do_look(ch->mount, "auto");
}
act( AT_ACTION, "$n appears in the room, a ring of mist dissipating around $m.",
ch, NULL, NULL, TO_ROOM );
do_look(ch, "auto");
break;
case MAG_DREAM:
if (victim == ch) {
if ( IS_AFFECTED (ch, AFF_DREAMWORLD ) ) {
if ( !IS_AFFECTED(ch, AFF_SLEEP) ) {
act( AT_MAGIC, "You step out of the world of dreams.",
ch, NULL, NULL, TO_CHAR);
act( AT_MAGIC, "$n slowly fades out of the dream.",
ch, NULL, NULL, TO_ROOM);
drop_dream_items(ch, ch->last_carrying);
if (IS_NPC(ch))
xREMOVE_BIT(ch->affected_by, AFF_DREAMWORLD);
else
xREMOVE_BIT(ch->pcdata->perm_aff, AFF_DREAMWORLD);
act( AT_MAGIC, "$n slowly fades into the waking world.",
ch, NULL, NULL, TO_ROOM);
return;
} else {
send_to_char("You can't seem to wake up!\n\r", ch);
return;
}
}
if (IS_AFFECTED(ch, AFF_VOID)) {
send_to_char("The dream twists your mind!\n\r", ch);
ch->mental_state = 100;
return;
}
if (IS_SET(ch->in_room->room_flags, ROOM_NO_DREAM)
&& (ch->curr_talent[TAL_DREAM] < 100
|| (IS_SET(ch->in_room->runes, RUNE_WARD)
&& ch->curr_talent[TAL_DREAM] < 200))) {
ch_trick(ch, type);
break;
}
act( AT_MAGIC, "You step into the world of dreams.", ch, NULL, NULL, TO_CHAR);
act( AT_MAGIC, "$n slowly fades out of the waking world.", ch, NULL, NULL, TO_ROOM);
xSET_BIT(ch->pcdata->perm_aff, AFF_DREAMWORLD);
ch->position = POS_STANDING;
act( AT_MAGIC, "$n slowly fades into the dream.", ch, NULL, NULL, TO_ROOM);
break;
} else {
if (ch->curr_talent[TAL_DREAM] < 50) {
ch_trick(ch, type);
break;
}
if (!IS_AFFECTED(victim, AFF_DREAMWORLD)) {
if (IS_AFFECTED(victim, AFF_VOID)) {
ch_trick(ch, type);
break;
}
if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) {
ch_trick(ch, type);
break;
}
act( AT_MAGIC, "You pull $N into the dream!", ch, NULL, victim, TO_CHAR);
victim->position = POS_STANDING;
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_DREAMWORLD);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_DREAMWORLD);
act( AT_MAGIC, "The waking world seems to fade away.",
ch, NULL, victim, TO_VICT);
do_look(victim, "auto");
break;
}
act( AT_PURPLE, "You extract $N from the dream!", ch, NULL, victim, TO_CHAR);
victim->position = POS_STANDING;
if (IS_NPC(victim))
xREMOVE_BIT(victim->affected_by, AFF_DREAMWORLD);
else
xREMOVE_BIT(victim->pcdata->perm_aff, AFF_DREAMWORLD);
act( AT_PURPLE, "The dream vanishes and waking world fades into view.",
ch, NULL, victim, TO_VICT);
do_look(victim, "auto");
break;
}
case MAG_ANTIMATTER:
if (number_range(1, ch->curr_talent[TAL_VOID]) < 20) {
ch_trick(ch, type);
break;
}
if (victim == ch) {
if (!IS_AFFECTED(ch, AFF_VOID)) {
if (IS_AFFECTED(ch, AFF_DREAMWORLD)) {
ch_trick(ch, type);
break;
}
act(AT_DGREY, "You enter the Void.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREY, "$n steps out of reality.",
ch, NULL, NULL, TO_ROOM);
xSET_BIT(ch->pcdata->perm_aff, AFF_VOID);
act(AT_DGREY, "$n steps into the Void.",
ch, NULL, NULL, TO_ROOM);
break;
}
act(AT_DGREY, "You step out of the Void.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREY, "$n steps out of the Void.",
ch, NULL, NULL, TO_ROOM);
xREMOVE_BIT(ch->pcdata->perm_aff, AFF_VOID);
act(AT_DGREY, "$n steps into reality.",
ch, NULL, NULL, TO_ROOM);
break;
} else {
if (ch->curr_talent[TAL_VOID] < 40) {
ch_trick(ch, type);
break;
}
if (!IS_AFFECTED(victim, AFF_VOID)) {
if (IS_AFFECTED(victim, AFF_DREAMWORLD)) {
ch_trick(ch, type);
break;
}
if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) {
ch_trick(ch, type);
break;
}
act( AT_MAGIC, "You pull $N into the Void!", ch, NULL, victim, TO_CHAR);
victim->position = POS_STANDING;
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_VOID);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_VOID);
act( AT_MAGIC, "Reality seems to fade away into nothingness.",
ch, NULL, victim, TO_VICT);
do_look(victim, "auto");
break;
}
act( AT_DGREY, "You extract $N from the Void!", ch, NULL, victim, TO_CHAR);
victim->position = POS_STANDING;
if (IS_NPC(victim))
xREMOVE_BIT(victim->affected_by, AFF_VOID);
else
xREMOVE_BIT(victim->pcdata->perm_aff, AFF_VOID);
act( AT_DGREY, "The Void vanishes and reality fades into view.",
ch, NULL, victim, TO_VICT);
do_look(victim, "auto");
break;
}
break;
case MAG_WIND:
if (IS_AFFECTED(victim, AFF_FLYING)) {
if (ch->curr_talent[TAL_WIND] < 20
&& ch->curr_talent[TAL_MOTION] < 50) {
act(AT_CYAN, "You go plummeting toward the ground.",
victim, NULL, NULL, TO_CHAR);
act(AT_CYAN, "$n goes plummeting toward the ground.",
victim, NULL, NULL, TO_ROOM);
lose_hp(victim, victim->weight/10);
} else {
act(AT_CYAN, "You settle gracefully to the ground.",
victim, NULL, NULL, TO_CHAR);
act(AT_CYAN, "$n settles gracefully to the ground.",
victim, NULL, NULL, TO_ROOM);
}
if (IS_NPC(victim))
xREMOVE_BIT(victim->affected_by, AFF_FLYING);
else
xREMOVE_BIT(victim->pcdata->perm_aff, AFF_FLYING);
break;
}
if (ch->curr_talent[TAL_WIND] < 30
&& ch->curr_talent[TAL_MOTION] < 75) {
ch_trick(victim, type);
break;
}
act(AT_MAGIC, "Mystic winds carry you off the ground.",
victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "Mystic winds carry $n off the ground.",
victim, NULL, NULL, TO_ROOM);
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_FLYING);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_FLYING);
break;
}
} /* ch_move */
void summon_move(CHAR_DATA *ch, int type, int power, char *argument) {
int i, vnum;
ROOM_INDEX_DATA *location;
char buf[MAX_STRING_LENGTH];
AREA_DATA *pArea;
EXPLORED_AREA *xarea;
DEITY_DATA *talent;
CHAR_DATA *victim;
CHAR_DATA *next_vict;
bool found;
OBJ_DATA *obj;
location = NULL;
switch (type) {
default:
ch_trick(ch, type);
break;
case MAG_TELEKINETIC:
if (ch->curr_talent[TAL_MOTION] < 20) {
ch_trick(ch, type);
break;
}
if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) {
send_to_char("You can't travel in combat!\n\r", ch);
return;
}
if (!can_travel(90, ch, ch)) {
send_to_char("You feel trapped in this place.\n\r",ch);
return;
}
/* Start travel to location */
for(pArea = first_area; pArea; pArea = pArea->next) {
if (nifty_is_name_prefix(argument, pArea->name)) {
/* Only allow you to target areas you've been to already */
xarea = ch->pcdata->first_explored;
while (xarea) {
if (xarea->index == pArea->low_soft_range) {
ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r",
pArea->name);
break;
}
xarea = xarea->next;
}
if (!xarea) {
send_to_char("&BYou don't know what that area looks like yet.\n\r", ch);
return;
}
if (IS_SET(pArea->flags, AFLAG_NOTRAVEL)) {
send_to_char("&BStrong wards surround the area, blocking your magic.\n\r",
ch);
return;
}
for (i = 0;i <= 20;i++) {
if (i == 20) {
send_to_char("&BYou fail to penetrate the wards surrounding that area.\n\r", ch);
return;
}
vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum);
if ((location = get_room_index(vnum)) == NULL)
continue;
if (IS_SET(location->room_flags, ROOM_NO_ASTRAL)) {
if (IS_SET(location->runes, RUNE_WARD))
continue;
if (IS_SET(pArea->flags, AFLAG_NOBYPASS))
continue;
if (TALENT(ch, TAL_MOTION) < 100)
continue;
}
break;
}
if (!location) {
send_to_char("You can't find a place to land.\n\r", ch);
return;
}
if (ch->pcdata->inborn == -1)
talent = get_talent_by_index(TAL_MOTION);
else
talent = get_talent_by_index(ch->pcdata->inborn);
act(AT_MAGIC, "$T the room, and $n is gone.",
ch, NULL, talent->message, TO_ROOM);
act(AT_MAGIC, "$T the room, and you travel.",
ch, NULL, talent->message, TO_CHAR);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, location);
if (ch->mount) {
char_from_room(ch->mount);
char_to_room(ch->mount, location);
do_look(ch->mount, "auto");
}
act( AT_MAGIC, "$T the room, and $n appears.",
ch, NULL, talent->message, TO_ROOM);
do_look( ch, "auto" );
learn_talent(ch, TAL_MOTION);
WAIT_STATE(ch, PULSE_VIOLENCE*2 - ch->curr_talent[TAL_MOTION]/5);
return;
} /* end travel to location */
}
if (ch->curr_talent[TAL_MOTION] < 50) {
act( AT_MAGIC, "You are unable to locate anyplace like that.",
ch, NULL, NULL, TO_CHAR);
return;
}
/* start travel to person */
if ( (victim = get_char_world(ch, argument)) == NULL
|| !can_travel(90, ch, victim)
|| (TALENT(victim, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) {
send_to_char("&BYou are unable to locate anyplace or anyone like that.\n\r", ch);
return;
}
if (victim == ch) {
send_to_char("That was a short trip!\n\r", ch);
return;
}
if (victim == ch->mount) {
send_to_char("You are riding them already!\n\r", ch);
return;
}
if (ch->pcdata->inborn == -1)
talent = get_talent_by_index(TAL_MOTION);
else
talent = get_talent_by_index(ch->pcdata->inborn);
act(AT_MAGIC, "$T the room, and $n is gone.",
ch, NULL, talent->message, TO_ROOM);
act(AT_MAGIC, "$T the room, and you travel.",
ch, NULL, talent->message, TO_CHAR);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, victim->in_room );
if (ch->mount) {
char_from_room(ch->mount);
char_to_room(ch->mount, victim->in_room);
do_look(ch->mount, "auto");
}
act( AT_MAGIC, "$T the room, and $n appears.",
ch, NULL, talent->message, TO_ROOM);
do_look( ch, "auto" );
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_MOTION] < 40) {
ch_trick(ch, type);
break;
}
if (IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS)) {
ch_trick(ch, type);
break;
}
if (IS_AFFECTED(ch, AFF_VOID)) {
ch_trick(ch, type);
break;
}
victim = get_char_world(ch, argument);
if (!victim) {
send_to_char("You cannot find anything like that.\n\r",ch);
return;
}
if (victim == ch) {
ch_trick(ch, type);
break;
}
if (victim->in_room && !can_travel(100, ch, victim)) {
send_to_char("Something prevents you from opening a rift.\n\r", ch);
return;
}
if (!IS_NPC(victim)) {
sprintf( buf, "%s summoned %s to %s (%d).", ch->name,
victim->name, ch->in_room->name, ch->in_room->vnum );
to_channel( buf, "Spell", PERMIT_SECURITY);
}
act( AT_MAGIC, "A swirling rift opens for a moment, sucking $n through.",
victim, NULL, ch, TO_ROOM);
act(AT_MAGIC, "A swirling rift opens suddenly, and $n pulls you through!",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "You open a swirling rift and pull $N through.",
ch, NULL, victim, TO_CHAR);
act(AT_MAGIC, "$n opens a swirling rift and pulls $N through.",
ch, NULL, victim, TO_ROOM);
char_from_room(victim);
victim->in_obj = NULL;
char_to_room( victim, ch->in_room );
do_look( victim, "auto" );
WAIT_STATE(ch, PULSE_VIOLENCE);
break;
case MAG_DREAM:
if (ch->curr_talent[TAL_DREAM] < 30) {
ch_trick(ch, type);
break;
}
if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) {
ch_trick(ch, type);
break;
}
victim = get_char_world(ch, argument);
if (!victim) {
/* Start travel to location */
for (pArea = first_area; pArea; pArea = pArea->next) {
if ((argument[0] == '\0' ||
nifty_is_name_prefix(argument, pArea->name))
&& !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) {
/* Only allow you to target areas you've been to already */
xarea = ch->pcdata->first_explored;
while (xarea) {
if (xarea->index == pArea->low_soft_range) {
ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r",
pArea->name);
break;
}
xarea = xarea->next;
}
if (!xarea) {
send_to_char("&BYou don't know what that area looks like yet.\n\r", ch);
return;
}
for (i = 0;i < 20;i++) {
vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum);
if ((location = get_room_index(vnum)) == NULL)
continue;
if (IS_SET(location->room_flags, ROOM_NO_DREAM))
continue;
break;
}
if (!location) {
ch_trick(ch, type);
break;
}
act( AT_MAGIC, "You shift into another dream.",
ch, NULL, NULL, TO_CHAR);
act( AT_MAGIC, "$n fades out of existance.",
ch, NULL, NULL, TO_ROOM);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, location );
act( AT_MAGIC, "$n slows fades into view.",
ch, NULL, NULL, TO_ROOM);
do_look( ch, "auto" );
return;
}
}
send_to_char("You can't find anyplace like that.\n\r",ch);
return;
}
if (victim == ch) {
send_to_char("That was a short trip!\n\r", ch);
return;
}
if (IS_SET(victim->in_room->room_flags, ROOM_NO_DREAM)
&& (ch->curr_talent[TAL_DREAM] < 100
|| (IS_SET(victim->in_room->runes, RUNE_WARD)
&& ch->curr_talent[TAL_DREAM] < 200))) {
act( AT_MAGIC, "You are unable to locate anyone like that.",
ch, NULL, NULL, TO_CHAR);
return;
}
act( AT_MAGIC, "You shift into another dream.", ch, NULL, NULL, TO_CHAR);
act( AT_MAGIC, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, victim->in_room );
act( AT_MAGIC, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM);
do_look( ch, "auto" );
break;
case MAG_UNHOLY:
if ( ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_MOTION] < 95 ) {
ch_trick(ch, type);
break;
}
victim = get_char_world(ch, argument);
if (!victim) {
ch_trick(ch, type);
break;
}
if (victim != ch && !IS_CONSENTING(victim, ch)) {
send_to_char("You can't retrieve their corpse without their consent.\n\r" ,ch);
return;
}
found = FALSE;
for ( obj = first_object; obj; obj = obj->next ) {
if ( obj->in_room
&& nifty_is_name( victim->name, obj->name )
&& (obj->pIndexData->vnum == 11 ) ) {
found = TRUE;
if (obj->timer > 38) {
act( AT_MAGIC, "The image of your corpse appears, but wavers away.",
victim, NULL, NULL, TO_CHAR );
act( AT_MAGIC, "The image of $n's corpse appears, but wavers away.",
victim, NULL, NULL, TO_ROOM );
return;
}
if (IS_SET( obj->in_room->room_flags, ROOM_NOSUPPLICATE )
&& ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_MOTION] < 200) {
act( AT_MAGIC, "Only silence answers from that forsaken place.",
ch, NULL, NULL, TO_CHAR);
return;
}
act( AT_MAGIC, "Your corpse appears suddenly, surrounded by a misty aura...",
victim, NULL, NULL, TO_CHAR );
act( AT_MAGIC, "$n's corpse appears suddenly, surrounded by a misty aura...",
victim, NULL, NULL, TO_ROOM );
obj_from_room(obj);
obj = obj_to_room(obj, ch->in_room);
}
}
if ( !found ) {
send_to_char( "No corpse of that sort litters the world...\n\r", ch );
return;
}
WAIT_STATE(ch, PULSE_VIOLENCE*2);
break;
case MAG_PSIONIC:
if (!argument || argument[0] == '\0')
vnum = 0;
else
vnum = atoi(argument);
if (!str_cmp(argument, "nexus")) {
if (IS_SET(ch->in_room->area->flags, AFLAG_FREEKILL))
location = get_room_index(ROOM_VNUM_PKILL);
else
location = get_room_index(ROOM_VNUM_NEXUS);
} else if (!str_cmp(argument, "area")) {
location = get_room_index(ch->in_room->area->hi_soft_range);
} else {
i = (ch->curr_talent[TAL_MOTION] -20) / 10;
if (i > 7) i = 7;
if (i < 0 && ch->curr_talent[TAL_MOTION] > 0)
i = 0;
if (vnum > i) {
send_to_char("You cannot recall the details of that location.\n\r", ch);
return;
}
if (IS_NPC(ch)) {
if (IS_AFFECTED(ch, AFF_CHARM) && ch->master && !IS_NPC(ch->master)) {
location = get_room_index( ch->master->pcdata->memorize[vnum] );
} else {
return;
}
} else {
location = get_room_index( ch->pcdata->memorize[vnum] );
}
}
if ( !location )
location = get_room_index( ROOM_VNUM_NEXUS );
if ( !location ) {
send_to_char( "You are completely lost.\n\r", ch );
return;
}
if ( ch->in_room == location ) {
send_to_char("You are already here!\n\r", ch);
return;
}
if ( IS_AFFECTED(ch, AFF_DREAMWORLD)
&& IS_SET(location->room_flags, ROOM_NO_DREAM)) {
ch_trick(ch, type);
break;
}
if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
&& ch->curr_talent[TAL_MOTION] < 80) {
ch_trick(ch, type);
break;
}
if (IS_AFFECTED(ch, AFF_CURSE)
&& ch->curr_talent[TAL_MOTION] < 70) {
ch_trick(ch, type);
break;
}
if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) {
ch_trick(ch, type);
break;
}
act( AT_ACTION, "$n disappears in a swirl of mist.",
ch, NULL, NULL, TO_ROOM);
char_from_room(ch);
ch->in_obj = NULL;
char_to_room(ch, location);
if (ch->mount) {
char_from_room(ch->mount);
char_to_room(ch->mount, location);
do_look(ch->mount, "auto");
}
act( AT_ACTION, "$n appears in the room, a ring of mist dissipating around $m.",
ch, NULL, NULL, TO_ROOM );
do_look(ch, "auto");
break;
case MAG_ANTIMATTER:
if ( !IS_AFFECTED(ch, AFF_VOID) ) {
ch_trick(ch, type);
break;
}
victim = get_char_world(ch, argument);
if (!victim) {
/* Start travel to location */
for(pArea = first_area; pArea; pArea = pArea->next) {
if((argument[0] == '\0' ||
nifty_is_name_prefix(argument, pArea->name))
&& !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) {
/* Only allow you to target areas you've been to already */
xarea = ch->pcdata->first_explored;
while (xarea) {
if (xarea->index == pArea->low_soft_range) {
ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r",
pArea->name);
break;
}
xarea = xarea->next;
}
if (!xarea) {
send_to_char("&BYou don't know what that area looks like yet.\n\r", ch);
return;
}
for (i = 0;i < 20;i++) {
vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum);
if ((location = get_room_index(vnum)) == NULL)
continue;
break;
}
if (!location) {
ch_trick(ch, type);
break;
}
act( AT_DGREY, "You shift into another part of the Void.",
ch, NULL, NULL, TO_CHAR);
act( AT_DGREY, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, location );
act( AT_DGREY, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM);
do_look( ch, "auto" );
}
}
ch_trick(ch, type);
break;
}
if (victim == ch) {
ch_trick(ch, type);
break;
}
act( AT_DGREY, "You shift into another part of the Void.", ch, NULL, NULL, TO_CHAR);
act( AT_DGREY, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM);
char_from_room( ch );
ch->in_obj = NULL;
char_to_room( ch, victim->in_room );
act( AT_DGREY, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM);
do_look( ch, "auto" );
break;
case MAG_ETHER:
if (ch->curr_talent[TAL_VOID] < 80) {
ch_trick(ch, type);
break;
}
if (!IS_AFFECTED(ch, AFF_VOID)) {
ch_trick(ch, type);
break;
}
victim = get_char_world(ch, argument);
if (!victim
|| (IS_NPC(victim) && !xIS_SET(victim->act, ACT_NAMED)))
victim = generate_mob_nation(argument);
if (!victim) {
ch_trick(ch, type);
break;
}
if (victim == ch) {
ch_trick(ch, type);
break;
}
if (victim->in_room) {
act( AT_DGREY, "$n tears a rift in reality and pulls you through!",
ch, NULL, victim, TO_VICT);
act( AT_DGREY, "$n is ripped through a rift in reality!",
victim, NULL, NULL, TO_ROOM);
char_from_room( victim );
}
victim->in_obj = NULL;
char_to_room( victim, ch->in_room );
if (IS_NPC(victim))
xSET_BIT(victim->affected_by, AFF_VOID);
else
xSET_BIT(victim->pcdata->perm_aff, AFF_VOID);
act( AT_DGREY, "$n is pulled into the Void!", victim, NULL, NULL, TO_ROOM);
do_look( victim, "auto" );
break;
case MAG_BLUNT:
if ((ch->curr_talent[TAL_EARTH] < 20 && !IS_NPC(ch))
|| IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR)) {
ch_trick(ch, type);
break;
}
act(AT_HUNGRY, "The earth trembles beneath you!",
ch, NULL, NULL, TO_CHAR);
act(AT_HUNGRY, "The ground begins to tremble and shake!",
ch, NULL, NULL, TO_ROOM);
for ( victim = ch->in_room->first_person; victim; victim = next_vict ) {
next_vict = victim->next_in_room;
if (IS_AFFECTED(victim, AFF_FLYING)
&& !IS_SET(ch->in_room->room_flags, ROOM_INDOORS))
continue;
ch_harm(victim, ch, power, MAG_BLUNT, FALSE);
if (char_died(ch))
return;
}
break;
}
} /* summon_move */
void obj_change(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power, char *argument) {
CHAR_DATA *mob;
OBJ_DATA *obj1;
OBJ_DATA *obj_next;
MOB_INDEX_DATA *pMobIndex;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
DESCRIPTOR_DATA *d;
PART_DATA *part;
int amt;
bool found;
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 30) {
obj_trick(ch, obj, type);
break;
}
if (obj->item_type == ITEM_CORPSE_PC &&
ch->curr_talent[TAL_DEATH] >= 50) {
for (d = first_descriptor; d; d = d->next) {
if (d->connected == CON_PLAYING) {
if (nifty_is_name(d->character->name, obj->name)) {
victim = d->character;
break;
}
}
}
if (!victim) {
obj_trick(ch, obj, type);
break;
}
if (!IS_CONSENTING(victim, ch)) {
send_to_char("You cannot reanimate them without their consent.\n\r", ch);
return;
}
if (power < victim->perm_con*10) {
obj_trick(ch, obj, type);
break;
}
if (!IS_AFFECTED(victim, AFF_ETHEREAL)) {
send_to_char("You cannot reanimate them when they are not ethereal.\n\r", ch);
return;
}
while ((obj = victim->first_carrying)) {
obj_from_char(obj);
obj_to_room(obj, victim->in_room);
}
while (victim->first_affect)
affect_remove ( victim, victim->first_affect );
act(AT_DGREY, "$n screams in agony as $e is drawn back into $s body.",
victim, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You scream in agony as you are drawn back into your body.",
victim, NULL, NULL, TO_CHAR);
if (victim->in_room != ch->in_room) {
char_from_room(victim);
victim->in_obj = NULL;
char_to_room(victim, ch->in_room);
}
part = victim->first_part;
while (part) {
part->cond = PART_WELL;
part->flags = PART_WELL;
part = part->next;
}
victim->exp += obj->cost;
if ( get_timer( victim, TIMER_PKILLED ) > 0 )
remove_timer( victim, TIMER_PKILLED );
victim->weight = obj->weight;
act(AT_DGREY, "An unholy black aura surrounds the corpse of $n.",
victim, NULL, NULL, TO_ROOM);
while ((obj1 = obj->first_content)) {
obj_from_obj(obj1);
if ( obj1->item_type == ITEM_MONEY ) {
amt = obj1->value[0];
ch->gold += amt;
extract_obj(obj1);
} else {
obj_to_char(obj1, victim);
}
}
separate_obj(obj);
extract_obj(obj);
fix_char(victim);
victim->position = POS_RESTING;
xCLEAR_BITS(victim->pcdata->perm_aff);
xSET_BIT(victim->pcdata->perm_aff, AFF_UNDEAD);
found = TRUE;
if (!str_cmp(argument, "lich")
&& ch->curr_talent[TAL_DEATH] >= 150) {
xSET_BIT(victim->pcdata->perm_aff, AFF_FEAR);
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
} else if (!str_cmp(argument, "vampire")
&& ch->curr_talent[TAL_DEATH] >= 100) {
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
SET_BIT(victim->pcdata->flags, PCFLAG_VAMPIRE);
} else if (!str_cmp(argument, "skeleton")
&& ch->curr_talent[TAL_DEATH] >= 70) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
xSET_BIT(victim->pcdata->perm_aff, AFF_CONSTRUCT);
} else if (!str_cmp(argument, "ghoul")
&& ch->curr_talent[TAL_DEATH] >= 60) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
} else if (!str_cmp(argument, "wraith")
&& ch->curr_talent[TAL_DEATH] >= 110) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE);
xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR);
} else if (!str_cmp(argument, "shadow")
&& ch->curr_talent[TAL_DEATH] >= 130) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE);
xSET_BIT(victim->pcdata->perm_aff, AFF_DARK);
xSET_BIT(victim->pcdata->perm_aff, AFF_UNHOLY);
xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR);
} else if (!str_cmp(argument, "ghost")
&& ch->curr_talent[TAL_DEATH] >= 80) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE);
xSET_BIT(victim->pcdata->perm_aff, AFF_CURSE);
xSET_BIT(victim->pcdata->perm_aff, AFF_FLOATING);
xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR);
} else if (!str_cmp(argument, "banshee")
&& ch->curr_talent[TAL_DEATH] >= 140) {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE);
xSET_BIT(victim->pcdata->perm_aff, AFF_FEAR);
xSET_BIT(victim->pcdata->perm_aff, AFF_FLOATING);
xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR);
} else {
xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED);
xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING);
xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH);
found = FALSE;
}
STRFREE(victim->pcdata->type);
if (found)
victim->pcdata->type = STRALLOC(argument);
else
victim->pcdata->type = STRALLOC("zombie");
act(AT_DGREY, "$n's eyes snap open, glowing with a faint reddish glow.",
victim, NULL, NULL, TO_ROOM);
act(AT_DGREY, "Your eyes snap open, and you look on the world with the sight of unlife.",
victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "You feel drained and exhausted from the reanimation.",
ch, NULL, NULL, TO_CHAR);
ch->mental_state = -100;
STRFREE(ch->last_taken);
sprintf(buf, "reanimating %s", victim->name);
ch->last_taken = STRALLOC(buf);
WAIT_STATE(ch, PULSE_VIOLENCE*10);
STRFREE(victim->last_taken);
ch->last_taken = STRALLOC("being reanimated");
WAIT_STATE(victim, PULSE_VIOLENCE*10);
return;
}
/* end player reanimate */
if (get_mob_index(MOB_VNUM_ANIMATED_CORPSE) == NULL) {
bug("Vnum 5 not found for do_reanimate!", 0);
return;
}
if ((pMobIndex = get_mob_index((sh_int) abs(obj->cost))) == NULL ) {
bug("Can not find mob for cost of corpse, do_reanimate", 0);
return;
}
if (xIS_SET(pMobIndex->affected_by, AFF_NONLIVING)) {
obj_trick(ch, obj, type);
break;
}
if (power - (pMobIndex->perm_con*4) < 0) {
obj_trick(ch, obj, type);
break;
}
if (chance(ch, 75)
&& pMobIndex->perm_con - ch->curr_talent[TAL_DEATH] < 10) {
mob = create_mobile(get_mob_index(MOB_VNUM_ANIMATED_CORPSE));
char_to_room(mob, ch->in_room);
mob->race = pMobIndex->race;
xSET_BIT(mob->affected_by, AFF_UNDEAD);
xSET_BIT(mob->affected_by, AFF_NONLIVING);
xSET_BIT(mob->affected_by, AFF_TRUESIGHT);
/* Fix so mobs wont have 0 hps and crash mud - Scryn 2/20/96 */
if (!pMobIndex->hitnodice)
mob->max_hit = (pMobIndex->perm_con *
TALENT(ch, TAL_DEATH)) / 10;
else
mob->max_hit = UMAX(URANGE(mob->max_hit / 4,
(mob->max_hit * obj->value[3]) / 10,
ch->curr_talent[TAL_DEATH] * dice(20,10)), 1);
xSET_BIT(mob->affected_by, AFF_INFRARED);
mob->hit = mob->max_hit;
mob->damroll = TALENT(ch, TAL_DEATH) / 3;
mob->hitroll = TALENT(ch, TAL_DEATH) / 2;
mob->perm_str = obj->value[0];
mob->perm_int = obj->value[1];
mob->perm_wis = obj->value[2];
mob->perm_dex = obj->value[3];
mob->perm_con = obj->value[4];
mob->perm_cha = obj->value[5];
mob->perm_lck = obj->value[6];
act(AT_MAGIC, "$n makes $N rise from the grave!", ch, NULL, mob, TO_ROOM);
act(AT_MAGIC, "You make $N rise from the grave!", ch, NULL, mob, TO_CHAR);
sprintf(buf, "animated %s", obj->name);
STRFREE(mob->name);
mob->name = STRALLOC(buf);
sprintf(buf, "animated %s", obj->short_descr);
STRFREE(mob->short_descr);
mob->short_descr = STRALLOC(buf);
add_follower( mob, ch );
if (obj->timer > 0) {
af.type = -1;
af.duration = (number_fuzzy( obj->timer ) * DUR_CONV);
af.location = 0;
af.modifier = 0;
af.bitvector = meb(AFF_CHARM);
affect_to_char( mob, &af );
} else {
xSET_BIT(mob->affected_by, AFF_CHARM);
}
/* run through the part flags on the corpse and give it the
* ones it should have. if a part was severed before, it won't
* have it now. i wish this wasn't necessary, but its needed to
* be able to reattach them properly.
*/
if (xIS_SET(obj->parts, BP_CHEST))
add_part(mob, BP_CHEST, -1);
if (xIS_SET(obj->parts, BP_NECK))
add_part(mob, BP_NECK, BP_CHEST);
if (xIS_SET(obj->parts, BP_HEAD))
add_part(mob, BP_HEAD, BP_NECK);
if (xIS_SET(obj->parts, BP_REAR))
add_part(mob, BP_REAR, BP_HEAD);
if (xIS_SET(obj->parts, BP_LEAR))
add_part(mob, BP_LEAR, BP_HEAD);
if (xIS_SET(obj->parts, BP_NOSE))
add_part(mob, BP_NOSE, BP_HEAD);
if (xIS_SET(obj->parts, BP_REYE))
add_part(mob, BP_REYE, BP_HEAD);
if (xIS_SET(obj->parts, BP_LEYE))
add_part(mob, BP_LEYE, BP_HEAD);
if (xIS_SET(obj->parts, BP_TONGUE))
add_part(mob, BP_TONGUE, BP_HEAD);
if (xIS_SET(obj->parts, BP_RHORN))
add_part(mob, BP_RHORN, BP_HEAD);
if (xIS_SET(obj->parts, BP_LHORN))
add_part(mob, BP_LHORN, BP_HEAD);
if (xIS_SET(obj->parts, BP_RARM))
add_part(mob, BP_RARM, BP_CHEST);
if (xIS_SET(obj->parts, BP_LARM))
add_part(mob, BP_LARM, BP_CHEST);
if (xIS_SET(obj->parts, BP_STOMACH))
add_part(mob, BP_STOMACH, -1);
if (xIS_SET(obj->parts, BP_RHAND))
add_part(mob, BP_RWRIST, BP_RARM);
if (xIS_SET(obj->parts, BP_LHAND))
add_part(mob, BP_LWRIST, BP_LARM);
if (xIS_SET(obj->parts, BP_RHAND))
add_part(mob, BP_RHAND, BP_RWRIST);
if (xIS_SET(obj->parts, BP_LHAND))
add_part(mob, BP_LHAND, BP_LWRIST);
if (xIS_SET(obj->parts, BP_RLEG))
add_part(mob, BP_RLEG, BP_ASS);
if (xIS_SET(obj->parts, BP_LLEG))
add_part(mob, BP_LLEG, BP_ASS);
if (xIS_SET(obj->parts, BP_RFOOT))
add_part(mob, BP_RANKLE, BP_RLEG);
if (xIS_SET(obj->parts, BP_LANKLE))
add_part(mob, BP_LANKLE, BP_LLEG);
if (xIS_SET(obj->parts, BP_RFOOT))
add_part(mob, BP_RFOOT, BP_RANKLE);
if (xIS_SET(obj->parts, BP_LFOOT))
add_part(mob, BP_LFOOT, BP_LANKLE);
if (xIS_SET(obj->parts, BP_ASS))
add_part(mob, BP_ASS, -1);
if (xIS_SET(obj->parts, BP_NOSE))
add_part(mob, BP_BACK, -1);
if (xIS_SET(obj->parts, BP_RWING))
add_part(mob, BP_RWING, BP_BACK);
if (xIS_SET(obj->parts, BP_LWING))
add_part(mob, BP_LWING, BP_BACK);
if (xIS_SET(obj->parts, BP_RPAW))
add_part(mob, BP_RPAW, BP_RANKLE);
if (xIS_SET(obj->parts, BP_LPAW))
add_part(mob, BP_LPAW, BP_LANKLE);
if (xIS_SET(obj->parts, BP_RHOOF))
add_part(mob, BP_RHOOF, BP_RANKLE);
if (xIS_SET(obj->parts, BP_LHOOF))
add_part(mob, BP_LHOOF, BP_LANKLE);
if (xIS_SET(obj->parts, BP_CLAWS))
add_part(mob, BP_CLAWS, BP_RPAW);
if (xIS_SET(obj->parts, BP_TAIL))
add_part(mob, BP_TAIL, BP_ASS);
if (xIS_SET(obj->parts, BP_FANGS))
add_part(mob, BP_FANGS, BP_HEAD);
if (xIS_SET(obj->parts, BP_RFLEG))
add_part(mob, BP_RFLEG, BP_CHEST);
if (xIS_SET(obj->parts, BP_LFLEG))
add_part(mob, BP_LFLEG, BP_CHEST);
if (xIS_SET(obj->parts, BP_RRLEG))
add_part(mob, BP_RRLEG, BP_ASS);
if (xIS_SET(obj->parts, BP_LRLEG))
add_part(mob, BP_LRLEG, BP_ASS);
if (xIS_SET(obj->parts, BP_RFIN))
add_part(mob, BP_RFIN, BP_CHEST);
if (xIS_SET(obj->parts, BP_LFIN))
add_part(mob, BP_LFIN, BP_CHEST);
if (xIS_SET(obj->parts, BP_DFIN))
add_part(mob, BP_DFIN, BP_BACK);
if (obj->first_content)
for( obj1 = obj->first_content; obj1; obj1 = obj_next) {
obj_next = obj1->next_content;
obj_from_obj(obj1);
obj_to_char(obj1, mob);
equip_char(mob, obj1);
}
separate_obj(obj);
extract_obj(obj);
STRFREE(ch->last_taken);
sprintf(buf, "reanimating %s", mob->name);
ch->last_taken = STRALLOC(buf);
WAIT_STATE(ch, PULSE_VIOLENCE*4);
STRFREE(mob->last_taken);
ch->last_taken = STRALLOC("being reanimated");
WAIT_STATE(mob, PULSE_VIOLENCE*4);
return;
} else {
send_to_char("You fail to reanimate the corpse.\n\r", ch);
use_magic(ch, TAL_DEATH, 300 - ch->curr_talent[TAL_DEATH]*2);
STRFREE(ch->last_taken);
ch->last_taken = STRALLOC("trying to reanimate a corpse");
WAIT_STATE(ch, PULSE_VIOLENCE*2);
}
break;
case MAG_HOLY:
if (ch->curr_talent[TAL_HEALING] < 100) {
obj_trick(ch, obj, type);
break;
}
if (obj->item_type != ITEM_CORPSE_PC) {
obj_trick(ch, obj, type);
break;
}
for ( d = first_descriptor; d; d = d->next ) {
if (d->connected == CON_PLAYING) {
if (nifty_is_name(d->character->name, obj->name)) {
victim = d->character;
break;
}
}
}
if (!victim) {
obj_trick(ch, obj, type);
break;
}
if (power < victim->perm_con*10) {
obj_trick(ch, obj, type);
break;
}
if (!IS_CONSENTING(victim, ch)) {
send_to_char("You cannot resurrect them without their consent.\n\r", ch);
return;
}
if (!IS_AFFECTED(victim, AFF_ETHEREAL)) {
send_to_char("You cannot resurrect them when they are not ethereal.\n\r", ch);
return;
}
while ((obj1 = victim->first_carrying)) {
obj_from_char(obj);
obj_to_room(obj1, victim->in_room);
}
while (victim->first_affect)
affect_remove ( victim, victim->first_affect );
act(AT_DGREY, "$n screams in agony as $e is drawn back into $s body.",
victim, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You scream in agony as you are drawn back into your body.",
victim, NULL, NULL, TO_CHAR);
if (victim->in_room != ch->in_room) {
char_from_room(victim);
victim->in_obj = NULL;
char_to_room(victim, ch->in_room);
}
part = victim->first_part;
while (part) {
part->cond = PART_WELL;
part->flags = PART_WELL;
part = part->next;
}
victim->exp += obj->cost;
if ( get_timer( victim, TIMER_PKILLED ) > 0 )
remove_timer( victim, TIMER_PKILLED );
act(AT_WHITE, "A radiant white aura surrounds the corpse of $n.",
victim, NULL, NULL, TO_ROOM);
while ((obj1 = obj->first_content)) {
obj_from_obj(obj1);
if ( obj1->item_type == ITEM_MONEY ) {
amt = obj->value[0];
ch->gold += amt;
extract_obj(obj1);
} else {
obj_to_char(obj1, victim);
}
}
separate_obj(obj);
extract_obj(obj);
fix_char(victim);
victim->position = POS_RESTING;
act(AT_WHITE, "$n's eyes flutter open, and $e takes in a deep breath.",
victim, NULL, NULL, TO_ROOM);
act(AT_WHITE, "Your eyes flutter open, and you take in a deep breath.",
victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "You feel drained and exhausted from the resurrection.",
ch, NULL, NULL, TO_CHAR);
ch->mental_state = -100;
STRFREE(ch->last_taken);
sprintf(buf, "resurrecting %s", victim->name);
ch->last_taken = STRALLOC(buf);
WAIT_STATE(ch, PULSE_VIOLENCE*10);
STRFREE(victim->last_taken);
ch->last_taken = STRALLOC("being resurrected");
WAIT_STATE(victim, PULSE_VIOLENCE*10);
/* If they were undead, resurrection will revive them */
if (xIS_SET(victim->pcdata->perm_aff, AFF_UNDEAD)) {
STRFREE(victim->pcdata->type);
victim->pcdata->type = STRALLOC("living");
xCLEAR_BITS(victim->pcdata->perm_aff);
REMOVE_BIT(victim->pcdata->flags, PCFLAG_VAMPIRE);
}
break;
case MAG_LIGHT:
if (ch->curr_talent[TAL_ILLUSION]
+ ch->curr_talent[TAL_CHANGE]
+ ch->curr_talent[TAL_CATALYSM] < 100) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (!argument || argument[0] == '\0') {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) {
obj_trick(ch, obj, type);
break;
}
if (obj->material
&& obj->material->number == 116) { /* ether */
obj_trick(ch, obj, type);
break;
}
separate_obj(obj); /* Thanks Zemus */
act(AT_MAGIC, "Your magic twists around $p, making it look like $T!",
ch, obj, argument, TO_CHAR);
act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!",
ch, obj, argument, TO_ROOM);
STRFREE(obj->name);
STRFREE(obj->short_descr);
STRFREE(obj->description);
obj->name = STRALLOC(munch_colors(argument));
obj->short_descr = STRALLOC(argument);
strcpy(buf, argument);
strcat(buf, " is here.");
obj->description = STRALLOC(buf);
break;
case MAG_ETHER:
if (ch->curr_talent[TAL_VOID] < 30) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (!argument || argument[0] == '\0') {
obj_trick(ch, obj, type);
break;
}
if (!obj->material
|| obj->material->number != 116) { /* ether */
obj_trick(ch, obj, type);
break;
}
separate_obj(obj); /* Thanks Zemus */
act(AT_MAGIC, "Your magic twists around $p, making it look like $T!",
ch, obj, argument, TO_CHAR);
act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!",
ch, obj, argument, TO_ROOM);
STRFREE(obj->name);
STRFREE(obj->short_descr);
STRFREE(obj->description);
obj->name = STRALLOC(munch_colors(argument));
obj->short_descr = STRALLOC(argument);
strcpy(buf, argument);
strcat(buf, " is here.");
obj->description = STRALLOC(buf);
break;
case MAG_DREAM:
if (ch->curr_talent[TAL_DREAM] < 40) {
obj_trick(ch, obj, type);
break;
}
if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) {
obj_trick(ch, obj, type);
break;
}
if (!argument || argument[0] == '\0') {
obj_trick(ch, obj, type);
break;
}
if (!IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) {
obj_trick(ch, obj, type);
break;
}
separate_obj(obj); /* Thanks Zemus */
act(AT_MAGIC, "Your magic twists around $p, making it look like $T!",
ch, obj, argument, TO_CHAR);
act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!",
ch, obj, argument, TO_ROOM);
STRFREE(obj->name);
STRFREE(obj->short_descr);
STRFREE(obj->description);
obj->name = STRALLOC(munch_colors(argument));
obj->short_descr = STRALLOC(argument);
strcpy(buf, argument);
strcat(buf, " is here.");
obj->description = STRALLOC(buf);
break;
}
}
void ch_change(CHAR_DATA *victim, CHAR_DATA *ch, int type, char *argument) {
NATION_DATA *nation;
SPECIES_DATA *species;
OBJ_DATA *obj;
int i;
char arg1[MAX_STRING_LENGTH];
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_CHANGE:
if (!argument || argument[0] == '\0') {
ch_trick(victim, type);
break;
}
if (ch->curr_talent[TAL_CHANGE] < 30) {
ch_trick(victim, type);
break;
}
if (ch->mount) {
send_to_char("And scare your mount?\n\r", ch);
return;
}
if (IS_NPC(victim)) {
ch_trick(victim, type);
break;
}
if (IS_AFFECTED(ch, AFF_MOUNTED))
throw_rider(ch);
if (!str_cmp(argument, "anthro")) {
if (has_bodypart(victim, BP_RHAND)) {
ch_trick(victim, type);
break;
}
if (victim->height > 100) {
ch_trick(victim, type);
break;
}
xSET_BIT(victim->pcdata->perm_aff, AFF_ANTHRO);
check_bodyparts(victim);
if (victim->height < 60)
victim->height = number_range(36,60);
else
victim->height = number_range(60,76);
victim->weight = get_height_weight(victim);
STRFREE(victim->pcdata->type);
victim->pcdata->type = STRALLOC("anthropomorphic");
act(AT_MAGIC, "Your body warps into an anthropomorphic form.",
victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's body warps into an anthropomorphic form.",
ch, NULL, NULL, TO_NOTVICT);
if (victim != ch)
act(AT_MAGIC, "You warp $N's body into an anthropomorphic form.",
ch, NULL, victim, TO_CHAR);
return;
}
if (victim != ch) {
if (TALENT(ch, TAL_CHANGE) < 80) {
ch_trick(victim, type);
break;
}
if (!IS_CONSENTING(victim, ch)
&& TALENT(ch, TAL_CHANGE) < 400) {
send_to_char("You cannot do that without their consent.\n\r", ch);
return;
}
}
nation = find_nation(argument);
if (!nation) {
ch_trick(victim, type);
break;
}
if (str_cmp(nation->species, victim->nation->species)
&& (ch->curr_talent[TAL_CHANGE] < 60)) {
ch_trick(victim, type);
break;
}
de_equip_char(victim);
if (IS_AFFECTED(victim, AFF_FLYING))
do_land(victim, "");
species = find_species(nation->species);
if (!species) {
bug("do_change: cannot find species!");
send_to_char("You suddenly forget what one of those is.",ch);
return;
}
ch_printf(victim, "Your body changes and warps, and you become %s.\n\r",
aoran(nation->name));
act( AT_MAGIC, "$N's body changes and warps, and $E becomes $t.",
ch, aoran(nation->name), victim, TO_NOTVICT);
if (ch != victim) {
act( AT_MAGIC, "You change and warp $N's body into $t.",
ch, aoran(nation->name), victim, TO_CHAR);
}
if (IS_AFFECTED(victim, AFF_ANTHRO)) {
xREMOVE_BIT(victim->pcdata->perm_aff, AFF_ANTHRO);
STRFREE(victim->pcdata->type);
if (IS_AFFECTED(victim, AFF_UNDEAD))
victim->pcdata->type = STRALLOC("undead");
else
victim->pcdata->type = STRALLOC("living");
}
victim->nation = nation;
set_race(victim, FALSE);
if (!IS_SET(nation->parts, PART_HANDS)) {
if (ch->main_hand) {
obj_unaffect_ch(ch, ch->main_hand);
ch->main_hand = NULL;
}
if (ch->off_hand) {
obj_unaffect_ch(ch, ch->off_hand);
ch->off_hand = NULL;
}
}
if (ch->curr_talent[TAL_CHANGE] >= 50) {
for (obj = victim->first_carrying; obj; obj = obj->next_content) {
obj->size = victim->height;
}
}
re_equip_char(victim);
update_aris(victim);
victim->max_hit = UMAX(20, victim->nation->hit *
get_curr_con(victim) + victim->base_hit);
victim->max_mana = UMAX(20, victim->nation->mana *
get_curr_int(victim) + victim->base_mana);
victim->max_move = UMAX(20, 25 * get_curr_end(victim) +
victim->base_move);
victim->mana = UMIN(victim->max_mana, victim->mana);
break;
case MAG_TIME:
if (ch->curr_talent[TAL_TIME] < 30) {
ch_trick(victim, type);
break;
}
if (IS_NPC(victim)) {
ch_trick(victim, type);
break;
}
i = atoi(argument);
if (i < 1 || i > TALENT(ch, TAL_TIME)) {
ch_trick(victim, type);
break;
}
if (!IS_CONSENTING(victim, ch)
&& TALENT(ch, TAL_TIME) < 400) {
send_to_char("You cannot do that without their consent.\n\r", ch);
return;
}
WAIT_STATE(ch, abs(victim->pcdata->age_adjust - i)/10);
if (victim->pcdata->age_adjust == i) {
ch_trick(victim, type);
break;
}
act(AT_BLUE, "$N's body changes as $E becomes $t.",
ch, victim->pcdata->age_adjust < i ? "older" : "younger", victim, TO_NOTVICT);
act(AT_BLUE, "Your body changes as you become $t.",
victim, victim->pcdata->age_adjust < i ? "older" : "younger", NULL, TO_CHAR);
if (ch != victim)
act(AT_BLUE, "You change $N's body to become $t.",
ch, victim->pcdata->age_adjust < i ? "older" : "younger", victim, TO_CHAR);
victim->pcdata->age_adjust = i;
break;
case MAG_SEEK:
if (ch->curr_talent[TAL_CHANGE] < 25) {
ch_trick(victim, type);
break;
}
if (IS_NPC(victim)) {
ch_trick(victim, type);
break;
}
argument = one_argument(argument, arg1);
if (!argument || !arg1) {
ch_trick(victim, type);
break;
}
if (victim != ch) {
if (TALENT(ch, TAL_CHANGE) < 50) {
send_to_char("You are not strong enough to change others yet.\n\r", ch);
return;
}
if (!IS_CONSENTING(victim, ch)
&& TALENT(ch, TAL_CHANGE) < 100) {
send_to_char("You cannot do that without their consent.\n\r", ch);
return;
}
}
if (!str_cmp(arg1, "height")) {
i = atoi(argument);
if (i >= victim->nation->height *
(1 + TALENT(ch, TAL_CHANGE) / 100)) {
send_to_char("You can't make them that tall.\n\r", ch);
return;
}
if (i <= victim->nation->height -
victim->nation->height *
TALENT(ch, TAL_CHANGE) / 100
|| victim->height <= 10) {
send_to_char("You can't make them that short.\n\r", ch);
return;
}
victim->height = i;
if (victim != ch) {
act(AT_MAGIC, "Your height changes.",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "You make $N's height change.",
ch, NULL, victim, TO_CHAR);
} else {
act(AT_MAGIC, "You change your height.",
ch, NULL, NULL, TO_CHAR);
}
act(AT_MAGIC, "$N's height changes.",
ch, NULL, victim, TO_NOTVICT);
} else if (!str_cmp(arg1, "weight")) {
i = atoi(argument);
if (i >= victim->nation->weight *
(1 + TALENT(ch, TAL_CHANGE) / 100)) {
send_to_char("You can't make them that heavy.\n\r", ch);
return;
}
if (i <= victim->nation->weight -
victim->nation->weight *
TALENT(ch, TAL_CHANGE) / 100
|| victim->weight <= 10) {
send_to_char("You can't make them that light.\n\r", ch);
return;
}
victim->weight = i;
if (victim != ch) {
if (victim != ch) {
act(AT_MAGIC, "Your weight changes.",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "You make $N's weight change.",
ch, NULL, victim, TO_CHAR);
} else {
act(AT_MAGIC, "You change your weight.",
ch, NULL, NULL, TO_CHAR);
}
act(AT_MAGIC, "$N's weight changes.",
ch, NULL, victim, TO_NOTVICT);
}
} else if (!str_cmp(arg1, "sex")) {
if (!str_prefix("f", argument)) victim->sex = SEX_FEMALE;
else if (!str_prefix("m", argument)) victim->sex = SEX_MALE;
else if (!str_prefix("n", argument)) victim->sex = SEX_NEUTRAL;
else if (!str_prefix("h", argument)) victim->sex = SEX_HERMAPH;
if (victim != ch) {
act(AT_MAGIC, "You feel something strange change in your crotch.",
ch, NULL, victim, TO_VICT);
act(AT_MAGIC, "You change $N's gender.",
ch, NULL, victim, TO_CHAR);
} else {
act(AT_MAGIC, "You change your own sex.",
ch, NULL, NULL, TO_CHAR);
}
act(AT_MAGIC, "$N's crotch seems to shift a little.",
ch, NULL, victim, TO_NOTVICT);
check_bodyparts(victim);
} else if (victim->pcdata->eyes
&& !str_cmp("eyes", arg1)) {
STRFREE(victim->pcdata->eyes);
victim->pcdata->eyes = STRALLOC(argument);
act(AT_MAGIC, "Your eyes itch.", victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's eyes change to $T.", victim, NULL, argument, TO_ROOM);
} else if (victim->pcdata->hair
&& !str_cmp("hair", arg1)) {
STRFREE(victim->pcdata->hair);
victim->pcdata->hair = STRALLOC(argument);
act(AT_MAGIC, "Your hair shimmers for a moment.", victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's hair changes to $T.", victim, NULL, argument, TO_ROOM);
} else if (victim->pcdata->skin_type
&& !str_cmp(victim->pcdata->skin_type, arg1)) {
STRFREE(victim->pcdata->skin_color);
victim->pcdata->skin_color = STRALLOC(argument);
act(AT_MAGIC, "Your $t shimmers for a moment.",
victim, victim->pcdata->skin_type, NULL, TO_CHAR);
act(AT_MAGIC, "$n's $t changes to $T.",
victim, victim->pcdata->skin_type, argument, TO_ROOM);
} else if (victim->pcdata->extra_type
&& !str_cmp(victim->pcdata->extra_type, arg1)) {
STRFREE(victim->pcdata->extra_color);
victim->pcdata->extra_color = STRALLOC(argument);
act(AT_MAGIC, "Your $t shimmers for a moment.",
victim, victim->pcdata->extra_type, NULL, TO_CHAR);
act(AT_MAGIC, "$n's $t changes to $T.",
victim, victim->pcdata->extra_type, argument, TO_ROOM);
} else {
send_to_char("They don't have that.\n\r", ch);
return;
}
break;
case MAG_LIGHT:
if (!argument || argument[0] == '\0' || argument[0] == ' ') {
STRFREE(ch->pcdata->name_disguise);
act(AT_MAGIC, "Your form flickers as you drop the illusion.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's form flickers for a moment.",
ch, NULL, NULL, TO_ROOM);
break;
}
if (ch->curr_talent[TAL_ILLUSION] < 100) {
ch_trick(victim, type);
break;
}
STRFREE(ch->pcdata->name_disguise);
ch->pcdata->name_disguise = STRALLOC(argument);
act(AT_MAGIC, "Your form shimmers as you raise an illusion.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's form shimmers for a moment.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_ANTIMAGIC:
if (ch->curr_talent[TAL_SEEKING] < 50) {
ch_trick(victim, type);
break;
}
if (IS_NPC(victim) || !victim->pcdata->name_disguise) {
ch_trick(victim, type);
break;
}
STRFREE(victim->pcdata->name_disguise);
act(AT_MAGIC, "Your form flickers as your illusion vanishes.",
victim, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n's form flickers for a moment.",
victim, NULL, NULL, TO_ROOM);
break;
case MAG_HOLY:
if (ch->curr_talent[TAL_HEALING] < 200) {
ch_trick(victim, type);
break;
}
if (IS_AFFECTED(ch, AFF_ANGEL)) {
ch_trick(victim, type);
break;
}
set_char_color(AT_WHITE, ch);
act(AT_WHITE, "A luminous white aura surrounds $n, radiance in holiness...",
ch, NULL, NULL, TO_ROOM);
send_to_char("A cleansing light washes through you, purifying you to the core of your being...\n\r", ch);
STRFREE(ch->pcdata->type);
ch->pcdata->type = STRALLOC("angelic");
act(AT_WHITE, "In a blinding flash of light the luminence fades, leaving $n surrounded in a holy halo.", ch, NULL, NULL, TO_ROOM);
send_to_char("You feel changed, looking on the world in a whole new light.\n\r", ch);
xSET_BIT(ch->pcdata->perm_aff, AFF_ANGEL);
xSET_BIT(ch->pcdata->perm_aff, AFF_HOLY);
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 200) {
ch_trick(victim, type);
break;
}
if (IS_AFFECTED(ch, AFF_DEMON)) {
ch_trick(victim, type);
break;
}
set_char_color(AT_DGREY, ch);
act(AT_DGREY, "Twisting demonic shadows surround $n, writhing and groping at $s body.",
ch, NULL, NULL, TO_ROOM);
send_to_char("You call upon the shadows of the underworld...\n\r", ch);
send_to_char("The shadows surround you, penetrating your body, clutching at your very soul.\n\r", ch);
STRFREE(ch->pcdata->type);
ch->pcdata->type = STRALLOC("demonic");
act(AT_DGREY, "The shadows seem to sink into $n, rooting themselves deeply.",
ch, NULL, NULL, TO_ROOM);
send_to_char("The shadows claim your soul, and leave in its place an unholy aura.\n\r", ch);
xSET_BIT(ch->pcdata->perm_aff, AFF_DEMON);
xSET_BIT(ch->pcdata->perm_aff, AFF_UNHOLY);
break;
case MAG_ALL:
if (ch->curr_talent[TAL_CATALYSM] < 200) {
ch_trick(victim, type);
break;
}
if (IS_AFFECTED(ch, AFF_ETHEREAL)) {
ch_trick(victim, type);
break;
}
set_char_color(AT_PURPLE, ch);
act(AT_MAGIC, "$n glows in a mystical purplish light, brilliant and all-consuming.",
ch, NULL, NULL, TO_ROOM);
send_to_char("You focus yourself, gathering all your magic together in a solid core.\n\r", ch);
STRFREE(ch->pcdata->type);
ch->pcdata->type = STRALLOC("ethereal");
act(AT_MAGIC, "$n seems to transcend $s mortal body, stepping away from it in a magical ethereal form.", ch, NULL, NULL, TO_ROOM);
send_to_char("In a step of tremendous power and will, you step out of your mortal body, leaving it behind.\n\r", ch);
make_corpse(ch);
xCLEAR_BITS(ch->pcdata->perm_aff);
xSET_BIT(ch->pcdata->perm_aff, AFF_ETHEREAL);
xSET_BIT(ch->pcdata->perm_aff, AFF_MAGICAL);
xSET_BIT(ch->pcdata->perm_aff, AFF_NO_CORPSE);
break;
}
}
void draw_rune(CHAR_DATA *ch, ROOM_INDEX_DATA *room, int type) {
OBJ_DATA *obj;
if (IS_SET(ch->in_room->room_flags, ROOM_NO_MAGIC)) {
ch_trick(ch, type);
return;
}
switch (type) {
default:
ch_trick(ch, type);
break;
case MAG_HOLY:
if (ch->curr_talent[TAL_HEALING] < 100) {
ch_trick(ch, type);
break;
}
act(AT_WHITE, "You trace runes of life on the walls.",
ch, NULL, NULL, TO_CHAR);
act(AT_WHITE, "$n traces glowing white runes on the walls.",
ch, NULL, NULL, TO_ROOM);
SET_BIT(room->runes, RUNE_LIFE);
break;
case MAG_DREAM:
if (ch->curr_talent[TAL_DREAM] < 100) {
ch_trick(ch, type);
break;
}
act(AT_PINK, "You trace runes of distraction on the walls.",
ch, NULL, NULL, TO_CHAR);
act(AT_PINK, "$n traces glowing pink runes on the walls.",
ch, NULL, NULL, TO_ROOM);
SET_BIT(room->runes, RUNE_DISTRACT);
break;
case MAG_ENERGY:
if (ch->curr_talent[TAL_SECURITY] < 100) {
ch_trick(ch, type);
break;
}
act(AT_CYAN, "You trace runes of warding on the walls.",
ch, NULL, NULL, TO_CHAR);
act(AT_CYAN, "$n traces glowing cyan runes on the walls.",
ch, NULL, NULL, TO_ROOM);
SET_BIT(room->runes, RUNE_WARD);
break;
case MAG_TELEKINETIC:
if (ch->curr_talent[TAL_MOTION] < 65) {
ch_trick(ch, type);
break;
}
act(AT_YELLOW, "You trace a yellow rune on the floor.",
ch, NULL, NULL, TO_CHAR);
act(AT_YELLOW, "$n traces a yellow rune on the floor.",
ch, NULL, NULL, TO_ROOM);
obj = create_object(get_obj_index(87), 0);
obj = obj_to_room(obj, room);
obj->obj_by = STRALLOC(ch->name);
break;
case MAG_ANTIMAGIC:
if (ch->curr_talent[TAL_VOID] < 50) {
ch_trick(ch, type);
break;
}
act(AT_MAGIC, "You wave your hands, dispelling any enchantments on the room.",
ch, NULL, NULL, TO_CHAR);
act(AT_MAGIC, "$n has dispelled the room!",
ch, NULL, NULL, TO_ROOM);
ch->in_room->runes = 0;
break;
}
}
void obj_enhance(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) {
bool found;
AFFECT_DATA *paf;
int amount;
if (obj->mana < 50) {
obj_trick(ch, obj, type);
return;
}
amount = obj->mana / 50;
amount = UMIN(amount, power / 100);
found = FALSE;
switch (type) {
default:
obj_trick(ch, obj, type);
return;
case MAG_HOLY:
if (obj->item_type != ITEM_ARMOR) {
obj_trick(ch, obj, type);
return;
}
amount = UMIN(amount, TALENT(ch, TAL_SECURITY) / 10
- obj->value[0] + obj->pIndexData->value[0]);
if (amount > 0) {
act(AT_WHITE, "You enhance the protective ability of $p.", ch, obj, NULL, TO_CHAR);
obj->value[0] += amount;
} else {
obj_trick(ch, obj, type);
return;
}
break;
case MAG_EARTH:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_CON && !found) {
amount = UMIN(amount, TALENT(ch, TAL_EARTH) / 10 - paf->modifier);
if (amount > 0) {
act(AT_GREEN, "You enchant $p with the strength of the Earth.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_EARTH) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_CON;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_GREEN, "You enchant $p with the strength of the Earth.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_COLD:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_LCK && !found) {
amount = UMIN(amount, TALENT(ch, TAL_FROST) / 10 - paf->modifier);
if (amount > 0) {
act(AT_FROST, "You enchant $p with the strength of the Ice.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_FROST) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_LCK;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_FROST, "You enchant $p with the strength of the Ice.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_FIRE:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_STR && !found) {
amount = UMIN(amount, TALENT(ch, TAL_FIRE) / 10 - paf->modifier);
if (amount > 0) {
act(AT_FIRE, "You enchant $p with the strength of the Flames.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_FIRE) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_STR;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_FIRE, "You enchant $p with the strength of the Flames.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_SEEK:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_CHA && !found) {
amount = UMIN(amount, TALENT(ch, TAL_SEEKING) / 10 - paf->modifier);
if (amount > 0) {
act(AT_GREEN, "You enchant $p with the power of Seeking.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_SEEKING) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_CHA;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_GREEN, "You enchant $p with the power of Seeking.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_WIND:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_DEX && !found) {
amount = UMIN(amount, TALENT(ch, TAL_WIND) / 10 - paf->modifier);
if (amount > 0) {
act(AT_CYAN, "You enchant $p with the speed of the Wind.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_WIND) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_DEX;
paf->modifier = 1;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_CYAN, "You enchant $p with the speed of the Wind.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_WATER:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_WIS && !found) {
amount = UMIN(amount, TALENT(ch, TAL_WATER) / 10 - paf->modifier);
if (amount > 0) {
act(AT_BLUE, "You enchant $p with the power of Water.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_WATER) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_WIS;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_BLUE, "You enchant $p with the power of Water.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_PSIONIC:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_INT && !found) {
amount = UMIN(amount, TALENT(ch, TAL_MIND) / 10 - paf->modifier);
if (amount > 0) {
act(AT_PURPLE, "You enchant $p with the power of the Mind.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_INT;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_PURPLE, "You enchant $p with the power of the Mind.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_ELECTRICITY:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_DAMROLL && !found) {
amount = UMIN(amount, TALENT(ch, TAL_LIGHTNING) / 10 - paf->modifier);
if (amount > 0) {
act(AT_YELLOW, "You enchant $p with the strength of the Storm.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_LIGHTNING) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_YELLOW, "You enchant $p with the strength of the Storm.",
ch, obj, NULL, TO_CHAR);
}
break;
case MAG_TELEKINETIC:
for (paf = obj->first_affect; paf; paf=paf->next) {
if (paf->location == APPLY_HITROLL && !found) {
amount = UMIN(amount, TALENT(ch, TAL_MOTION) / 10 - paf->modifier);
if (amount > 0) {
act(AT_YELLOW, "You enchant $p with the speed of Motion.",
ch, obj, NULL, TO_CHAR);
paf->modifier += amount;
} else {
obj_trick(ch, obj, type);
return;
return;
}
found=TRUE;
}
}
if (found==FALSE) {
amount = UMIN(amount, TALENT(ch, TAL_MOTION) / 10);
CREATE(paf, AFFECT_DATA, 1);
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = amount;
xCLEAR_BITS(paf->bitvector);
paf->next = NULL;
LINK(paf, obj->first_affect, obj->last_affect, next, prev);
act(AT_YELLOW, "You enchant $p with the speed of Motion.",
ch, obj, NULL, TO_CHAR);
}
break;
}
WAIT_STATE(ch, PULSE_VIOLENCE * amount);
obj->mana -= 50 * amount;
obj->cost += 50000 * amount;
} /* obj_enhance */
void ch_enhance(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) {
AFFECT_DATA af;
SKILLTYPE *skill;
int sn;
switch (type) {
default:
ch_trick(victim, type);
return;
case MAG_FIRE:
sn = gsn_fire;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_STR;
af.modifier = TALENT(ch, TAL_FIRE)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_WATER:
sn = gsn_water;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_WIS;
af.modifier = TALENT(ch, TAL_WATER)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_COLD:
sn = gsn_frost;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_LCK;
af.modifier = TALENT(ch, TAL_FROST)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_EARTH:
sn = gsn_earth;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_CON;
af.modifier = TALENT(ch, TAL_EARTH)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_WIND:
sn = gsn_wind;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_DEX;
af.modifier = TALENT(ch, TAL_WIND)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_PSIONIC:
sn = gsn_mind;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_INT;
af.modifier = TALENT(ch, TAL_MIND)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_SEEK:
sn = gsn_seeking;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_CHA;
af.modifier = TALENT(ch, TAL_SEEKING)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_TELEKINETIC:
sn = gsn_motion;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_HITROLL;
af.modifier = TALENT(ch, TAL_MOTION)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_ELECTRICITY:
sn = gsn_lightning;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_DAMROLL;
af.modifier = TALENT(ch, TAL_LIGHTNING)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_HOLY:
sn = gsn_security;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_AC;
af.modifier = TALENT(ch, TAL_SECURITY)/10;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_DREAM:
if (ch->curr_talent[TAL_DREAM] < 100) {
ch_trick(victim, type);
return;
}
sn = gsn_dream;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_IMMUNE;
af.modifier = RIS_SLEEP;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_POISON:
if (ch->curr_talent[TAL_HEALING] < 100) {
ch_trick(victim, type);
return;
}
sn = gsn_security;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_IMMUNE;
af.modifier = RIS_POISON;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
break;
case MAG_LIGHT:
if (ch->curr_talent[TAL_ILLUSION] < 20) {
ch_trick(victim, type);
return;
}
sn = gsn_illusion;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_AFFECT;
af.modifier = 0;
af.bitvector = meb(AFF_GLOW);
affect_join( victim, &af );
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 20) {
ch_trick(victim, type);
return;
}
sn = gsn_death;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
return;
}
af.type = sn;
af.duration = power*2;
af.location = APPLY_AFFECT;
af.modifier = 0;
af.bitvector = meb(AFF_DARK);
affect_join( victim, &af );
break;
}
skill = get_skilltype(sn);
if (skill->hit_vict && skill->hit_vict[0] != '\0')
act( AT_MAGIC, skill->hit_vict, victim, NULL, ch, TO_CHAR );
if (victim != ch && skill->hit_char && skill->hit_char[0] != '\0')
act( AT_MAGIC, skill->hit_char, ch, NULL, victim, TO_CHAR );
if (skill->hit_room && skill->hit_room[0] != '\0')
act( AT_MAGIC, skill->hit_room, ch, NULL, victim, TO_NOTVICT );
}
void ch_sing(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) {
switch (type) {
default:
ch_trick(ch, type);
break;
}
}
void song_sing(CHAR_DATA *ch, int type, int power, char *argument) {
switch (type) {
default:
ch_trick(ch, type);
break;
}
}
void obj_control(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) {
OBJ_DATA *obj1;
NATION_DATA *nation;
char buf[MAX_STRING_LENGTH];
switch (type) {
default:
obj_trick(ch, obj, type);
break;
case MAG_UNHOLY:
if (ch->curr_talent[TAL_DEATH] < 100) {
obj_trick(ch, obj, type);
break;
}
if (obj->item_type != ITEM_CORPSE_NPC) {
obj_trick(ch, obj, type);
break;
}
if (obj->obj_by == NULL
|| (nation = find_nation(obj->obj_by)) == NULL) {
obj_trick(ch, obj, type);
break;
}
if (!IS_AFFECTED(ch, AFF_ETHEREAL)) {
obj_trick(ch, obj, type);
break;
}
while ((obj1 = obj->first_content)) {
obj_from_obj(obj1);
if ( obj1->item_type == ITEM_MONEY ) {
ch->gold += obj1->value[0];
extract_obj(obj1);
} else {
obj_to_char(obj1, ch);
}
}
STRFREE(ch->last_taken);
sprintf(buf, "possessing the %s", myobj(obj));
ch->last_taken = STRALLOC(buf);
WAIT_STATE(ch, PULSE_VIOLENCE*12);
separate_obj(obj);
extract_obj(obj);
ch->nation = nation;
STRFREE(ch->species);
ch->species = STRALLOC(nation->name);
STRFREE(ch->pcdata->type);
ch->pcdata->type = STRALLOC("living");
fix_char(ch);
check_bodyparts(ch);
xCLEAR_BITS(ch->pcdata->perm_aff);
ch->position = POS_RESTING;
act(AT_DGREY, "You take a deep breath and open your eyes.",
ch, NULL, NULL, TO_CHAR);
act(AT_DGREY, "$n takes a deep breath and opens $s eyes.",
ch, NULL, NULL, TO_ROOM);
if ( get_timer( ch, TIMER_PKILLED ) > 0 )
remove_timer( ch, TIMER_PKILLED );
ch->mental_state = -100;
send_to_char("You feel drained and exhausted by the possession.\n\r", ch);
break;
}
}
void ch_control(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power, char *argument) {
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
int sn;
switch (type) {
default:
ch_trick(victim, type);
break;
case MAG_PSIONIC:
if (!IS_NPC(ch) &&
ch->curr_talent[TAL_MIND]
+ ch->curr_talent[TAL_SPEECH] <
(IS_AFFECTED(ch, AFF_BEAUTY) ? 100 : 200)) {
ch_trick(victim, type);
break;
}
if ( victim == ch ) {
send_to_char( "You like yourself even better!\n\r", ch );
return;
}
if ( IS_SET( victim->immune, RIS_MAGIC )
|| IS_SET( victim->immune, RIS_CHARM )
|| (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) ) {
ch_trick(victim, type);
break;
}
if (!IS_NPC(victim)) {
send_to_char( "I don't think so...\n\r", ch );
send_to_char( "Someone is trying to charm you...\n\r", victim );
return;
}
if ( IS_AFFECTED(victim, AFF_CHARM)
|| IS_AFFECTED(ch, AFF_CHARM)
|| number_range(1, get_curr_wil(ch)) < get_curr_wil(victim)
|| circle_follow( victim, ch ) ) {
act(AT_GREEN, "$N resists your attempts to tame $M.",
ch, NULL, victim, TO_CHAR);
act(AT_GREEN, "$n attempts to tame you, but you resist.",
ch, NULL, victim, TO_VICT);
return;
}
if ( victim->master )
stop_follower( victim );
add_follower( victim, ch );
af.type = -1;
af.duration = number_fuzzy(get_curr_wil(ch));
af.location = 0;
af.modifier = 0;
af.bitvector = meb(AFF_CHARM);
affect_to_char( victim, &af );
act(AT_GREEN, "You charm $N.", ch, NULL, victim, TO_CHAR);
act(AT_GREEN, "You get the sudden urge to follow and obey $n.",
ch, NULL, victim, TO_VICT);
sprintf( buf, "%s has charmed %s.", ch->name, victim->name);
to_channel( buf, "Spell", PERMIT_SECURITY );
break;
case MAG_FIRE:
if (ch->curr_talent[TAL_FIRE] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_fire;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_SUSCEPTIBLE;
af.modifier = RIS_FIRE;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
send_to_char( "You are vulnerable to heat.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You make $N vulnerable to heat.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N is vulnerable to heat.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_COLD:
if (ch->curr_talent[TAL_FROST] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_frost;
if (is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
af.type = sn;
af.duration = power;
af.location = APPLY_SUSCEPTIBLE;
af.modifier = RIS_COLD;
xCLEAR_BITS(af.bitvector);
affect_join( victim, &af );
update_pos(victim);
send_to_char( "You are vulnerable to cold.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You make $N vulnerable to cold.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "$N is vulnerable to cold.", ch, NULL, victim, TO_NOTVICT);
break;
case MAG_WATER:
if (ch->curr_talent[TAL_WATER] < 50) {
ch_trick(victim, type);
return;
}
sn = gsn_sticky_flame;
if (!is_affected(victim, sn)) {
ch_trick(victim, type);
break;
}
affect_strip( victim, gsn_sticky_flame );
send_to_char( "The flames surrounding you are quenched.\n\r", victim );
if ( ch != victim ) {
act( AT_MAGIC, "You quench the flames surrounding $N.", ch, NULL, victim, TO_CHAR);
}
act( AT_MAGIC, "The flames surroudning $N are quenched.", ch, NULL, victim, TO_NOTVICT);
break;
}
}
void room_control(CHAR_DATA *ch, int type, int power, char *argument) {
switch (type) {
default:
ch_trick(ch, type);
break;
case MAG_EARTH:
if (ch->curr_talent[TAL_EARTH] < 20) {
ch_trick(ch, type);
return;
}
if (ch->in_room->curr_vegetation >= 100) {
ch_trick(ch, type);
return;
}
ch->in_room->curr_vegetation += 10;
act( AT_GREEN, "At your command, vegetation flourishes in the room.",
ch, NULL, NULL, TO_CHAR);
act( AT_GREEN, "Vegetation flourishes in the room.",
ch, NULL, NULL, TO_ROOM);
break;
case MAG_WATER:
if (ch->curr_talent[TAL_WATER] < 20) {
ch_trick(ch, type);
return;
}
if(ch->in_room->curr_water >= 100) {
ch_trick(ch, type);
return;
}
ch->in_room->curr_water += 10;
act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_CHAR);
act( AT_BLUE, "Water floods into the room!", ch, NULL, NULL, TO_ROOM);
break;
}
}
/* Check the verb for the spell */
int check_verb(char *argument) {
if ( !str_cmp(argument, "tricks"))
return ACT_TRICKS;
else if ( !str_cmp(argument, "harm")
|| !str_cmp(argument, "hurt")
|| !str_cmp(argument, "damage")
|| !str_cmp(argument, "destroy")
|| !str_cmp(argument, "slay")
|| !str_cmp(argument, "attack")
|| !str_cmp(argument, "kill")
|| !str_cmp(argument, "burn"))
return ACT_HARM;
else if ( !str_cmp(argument, "help")
|| !str_cmp(argument, "assist")
|| !str_cmp(argument, "cure")
|| !str_cmp(argument, "heal")
|| !str_cmp(argument, "aid")
|| !str_cmp(argument, "restore")
|| !str_cmp(argument, "revive"))
return ACT_HELP;
else if ( !str_cmp(argument, "hinder")
|| !str_cmp(argument, "slow")
|| !str_cmp(argument, "stop")
|| !str_cmp(argument, "halt")
|| !str_cmp(argument, "anchor")
|| !str_cmp(argument, "curse")
|| !str_cmp(argument, "reduce")
|| !str_cmp(argument, "immobilize"))
return ACT_HINDER;
else if ( !str_cmp(argument, "create")
|| !str_cmp(argument, "conjure")
|| !str_cmp(argument, "shape")
|| !str_cmp(argument, "form")
|| !str_cmp(argument, "make")
|| !str_cmp(argument, "summon")
|| !str_cmp(argument, "bring")
|| !str_cmp(argument, "fashion"))
return ACT_CREATE;
else if ( !str_cmp(argument, "seek")
|| !str_cmp(argument, "find")
|| !str_cmp(argument, "identify")
|| !str_cmp(argument, "examine")
|| !str_cmp(argument, "locate")
|| !str_cmp(argument, "watch")
|| !str_cmp(argument, "discover"))
return ACT_FIND;
else if ( !str_cmp(argument, "move")
|| !str_cmp(argument, "send")
|| !str_cmp(argument, "transfer")
|| !str_cmp(argument, "shift")
|| !str_cmp(argument, "travel")
|| !str_cmp(argument, "push")
|| !str_cmp(argument, "transport"))
return ACT_MOVE;
else if ( !str_cmp(argument, "change")
|| !str_cmp(argument, "alter")
|| !str_cmp(argument, "transform")
|| !str_cmp(argument, "morph")
|| !str_cmp(argument, "transmute")
|| !str_cmp(argument, "mutate"))
return ACT_CHANGE;
else if ( !str_cmp(argument, "enhance")
|| !str_cmp(argument, "enchant")
|| !str_cmp(argument, "bless")
|| !str_cmp(argument, "improve")
|| !str_cmp(argument, "strengthen")
|| !str_cmp(argument, "imbue"))
return ACT_ENHANCE;
else if ( !str_cmp(argument, "focus")
|| !str_cmp(argument, "brand")
|| !str_cmp(argument, "shield")
|| !str_cmp(argument, "protect")
|| !str_cmp(argument, "bind")
|| !str_cmp(argument, "circle"))
return ACT_FOCUS;
else if ( !str_cmp(argument, "rune")
|| !str_cmp(argument, "area")
|| !str_cmp(argument, "room")
|| !str_cmp(argument, "sigil")
|| !str_cmp(argument, "symbol")
|| !str_cmp(argument, "mark"))
return ACT_RUNE;
else if ( !str_cmp(argument, "sing")
|| !str_cmp(argument, "song")
|| !str_cmp(argument, "music")
|| !str_cmp(argument, "speak")
|| !str_cmp(argument, "play"))
return ACT_SING;
else if ( !str_cmp(argument, "control")
|| !str_cmp(argument, "charm")
|| !str_cmp(argument, "order")
|| !str_cmp(argument, "force")
|| !str_cmp(argument, "compel"))
return ACT_CONTROL;
else
return ACT_TRICKS;
}
/* Check the power on the spell */
int check_power(char *argument) {
if (!str_cmp(argument, "miniscule")) return 10;
else if (!str_cmp(argument, "tiny")) return 20;
else if (!str_cmp(argument, "weak")) return 30;
else if (!str_cmp(argument, "low")) return 50;
else if (!str_cmp(argument, "small")) return 80;
else if (!str_cmp(argument, "medium")) return 100;
else if (!str_cmp(argument, "moderate")) return 200;
else if (!str_cmp(argument, "intermediate")) return 300;
else if (!str_cmp(argument, "high")) return 400;
else if (!str_cmp(argument, "strong")) return 500;
else if (!str_cmp(argument, "great")) return 600;
else if (!str_cmp(argument, "large")) return 700;
else if (!str_cmp(argument, "mighty")) return 800;
else if (!str_cmp(argument, "huge")) return 900;
else if (!str_cmp(argument, "powerful")) return 1000;
else if (!str_cmp(argument, "deadly")) return 1100;
else if (!str_cmp(argument, "massive")) return 1200;
else if (!str_cmp(argument, "enormous")) return 1300;
else if (!str_cmp(argument, "gargantuan")) return 1400;
else if (!str_cmp(argument, "collosal")) return 1500;
else if (!str_cmp(argument, "extreme")) return 1600;
else if (!str_cmp(argument, "amazing")) return 1700;
else if (!str_cmp(argument, "incredible")) return 1800;
else if (!str_cmp(argument, "severe")) return 1900;
else if (!str_cmp(argument, "intense")) return 2000;
else if (!str_cmp(argument, "supreme")) return 2500;
else if (!str_cmp(argument, "ultimate")) return 3000;
else if (!str_cmp(argument, "godlike")) return 3500;
else if (!str_cmp(argument, "omnipotent")) return 3800;
else if (!str_cmp(argument, "godly")) return 4000;
else return -1;
}
/* Return true if they are mentally capable of concentrating */
bool check_concentration(CHAR_DATA *ch, int type, int action, int power) {
AFFECT_DATA af;
int sn;
if (number_percent() - 5 >
ch->pcdata->condition[COND_DRUNK] +
abs(ch->mental_state))
return TRUE;
switch(number_range(1,3)) {
default:
if (type == MAG_FIRE) {
sn = gsn_sticky_flame;
if (is_affected(ch, sn)) {
ch_trick(ch, type);
break;
}
af.type = sn;
af.duration = power/10;
af.location = APPLY_DAMROLL;
af.modifier = TALENT(ch, TAL_FIRE)/40;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_FLAMING);
affect_join(ch, &af);
act(AT_FIRE, "You set yourself on fire!", ch, NULL, NULL, TO_CHAR);
act(AT_FIRE, "$n sets $mself on fire!", ch, NULL, NULL, TO_ROOM);
} else if (type == MAG_LIGHT) {
sn = gsn_blindness;
if (is_affected(ch, sn)) {
ch_trick(ch, type);
break;
}
if (IS_AFFECTED(ch, AFF_TRUESIGHT)) {
ch_trick(ch, type);
break;
}
af.type = sn;
af.duration = power/10;
af.location = APPLY_HITROLL;
af.modifier = -1 * TALENT(ch, TAL_ILLUSION)/20;
xCLEAR_BITS(af.bitvector);
xSET_BIT(af.bitvector, AFF_FLAMING);
affect_join(ch, &af);
act(AT_YELLOW, "You are blinded!", ch, NULL, NULL, TO_CHAR);
act(AT_YELLOW, "$n blinds $mself!", ch, NULL, NULL, TO_ROOM);
} else if (action == ACT_CREATE) {
act(AT_WHITE, "You are covered in confetti.", ch, NULL, NULL, TO_CHAR);
act(AT_WHITE, "$n is covered in confetti.", ch, NULL, NULL, TO_ROOM);
break;
} else {
ch_trick(ch, type);
break;
}
break;
case 1:
huh(ch);
break;
case 2:
ch_trick(ch, type);
break;
}
return FALSE;
}
/* The big magic command and handler. Parses their input,
* tries to figure out what they're trying to do, and
* directs the results to the appropriate function above.
*/
void do_magic(CHAR_DATA *ch, char *argument) {
int talent;
int damage;
int power;
int action;
CHAR_DATA *victim;
CHAR_DATA *next_vict;
OBJ_DATA *obj;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char arg4[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
if (IS_NPC(ch)) return;
if (check_manastorm(ch)) return;
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
argument = one_argument_retain_case(argument, arg3);
argument = one_argument_retain_case(argument, arg4);
talent = TAL_CATALYSM;
damage = MAG_ALL;
power = 1;
action = ACT_TRICKS;
/* First argument, a Talent */
if (!str_cmp(arg1, "fire")
|| !str_cmp(arg1, "flame")
|| !str_cmp(arg1, "flames")) {
act(AT_FIRE, "$n begins to channel Fire Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_FIRE, "You begin to channel Fire Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_FIRE;
damage = MAG_FIRE;
} else if (!str_cmp(arg1, "burn")
|| !str_cmp(arg1, "incinerate")
|| !str_cmp(arg1, "scorch")) {
act(AT_GREEN, "$n begins to channel Fire Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Fire Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_FIRE;
damage = MAG_FIRE;
action = ACT_HARM;
} else if (!str_cmp(arg1, "earth")
|| !str_cmp(arg1, "nature")
|| !str_cmp(arg1, "leaves")) {
act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_EARTH;
damage = MAG_EARTH;
} else if (!str_cmp(arg1, "stone")
|| !str_cmp(arg1, "dirt")
|| !str_cmp(arg1, "soil")
|| !str_cmp(arg1, "rock")) {
act(AT_ORANGE, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_ORANGE, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_EARTH;
damage = MAG_BLUNT;
} else if (!str_cmp(arg1, "crush")) {
act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_EARTH;
damage = MAG_BLUNT;
action = ACT_HARM;
} else if (!str_cmp(arg1, "tangle")
|| !str_cmp(arg1, "entangle")) {
act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_EARTH;
damage = MAG_EARTH;
action = ACT_HINDER;
} else if (!str_cmp(arg1, "lightning")
|| !str_cmp(arg1, "electric")
|| !str_cmp(arg1, "electricity")) {
act(AT_YELLOW, "$n begins to channel Lightning Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Lightning Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_LIGHTNING;
damage = MAG_ELECTRICITY;
} else if (!str_cmp(arg1, "shock")
|| !str_cmp(arg1, "electrocute")
|| !str_cmp(arg1, "zap")) {
act(AT_YELLOW, "$n begins to channel Lightning Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Lightning Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_LIGHTNING;
damage = MAG_ELECTRICITY;
action = ACT_HARM;
} else if (!str_cmp(arg1, "wind")
|| !str_cmp(arg1, "air")
|| !str_cmp(arg1, "storm")
|| !str_cmp(arg1, "storms")) {
act(AT_CYAN, "$n begins to channel Wind Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_CYAN, "You begin to channel Wind Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_WIND;
damage = MAG_WIND;
} else if (!str_cmp(arg1, "frost")
|| !str_cmp(arg1, "ice")
|| !str_cmp(arg1, "cold")
|| !str_cmp(arg1, "snow")) {
act(AT_FROST, "$n begins to channel Frost Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_FROST, "You begin to channel Frost Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_FROST;
damage = MAG_COLD;
} else if (!str_cmp(arg1, "chill")
|| !str_cmp(arg1, "freeze")) {
act(AT_FROST, "$n begins to channel Frost Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_FROST, "You begin to channel Frost Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_FROST;
damage = MAG_COLD;
action = ACT_HARM;
} else if (!str_cmp(arg1, "water")
|| !str_cmp(arg1, "bubbles")
|| !str_cmp(arg1, "sea")
|| !str_cmp(arg1, "ocean")) {
act(AT_BLUE, "$n begins to channel Water Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_BLUE, "You begin to channel Water Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_WATER;
damage = MAG_WATER;
} else if (!str_cmp(arg1, "acid")) {
act(AT_DGREEN, "$n begins to channel Acid Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREEN, "You begin to channel Acid Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_WATER;
damage = MAG_ACID;
} else if (!str_cmp(arg1, "dream")
|| !str_cmp(arg1, "sleep")
|| !str_cmp(arg1, "nightmare")) {
act(AT_PINK, "$n begins to channel Dream Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_PINK, "You begin to channel Dream Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_DREAM;
damage = MAG_DREAM;
} else if (!str_cmp(arg1, "illusion")
|| !str_cmp(arg1, "light")) {
act(AT_YELLOW, "$n begins to channel Light Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Light Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_ILLUSION;
damage = MAG_LIGHT;
} else if (!str_cmp(arg1, "speech")
|| !str_cmp(arg1, "sound")
|| !str_cmp(arg1, "song")
|| !str_cmp(arg1, "sonics")) {
act(AT_PINK, "$n begins to channel Speech Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_PINK, "You begin to channel Speech Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_SPEECH;
damage = MAG_SOUND;
} else if (!str_cmp(arg1, "healing")
|| !str_cmp(arg1, "life")
|| !str_cmp(arg1, "holy")) {
act(AT_WHITE, "$n begins to channel Holy Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_WHITE, "You begin to channel Holy Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_HEALING;
damage = MAG_HOLY;
} else if (!str_cmp(arg1, "heal")
|| !str_cmp(arg1, "cure")) {
act(AT_WHITE, "$n begins to channel Healing Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_WHITE, "You begin to channel Healing Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_HEALING;
damage = MAG_HOLY;
action = ACT_HELP;
} else if (!str_cmp(arg1, "unholy")
|| !str_cmp(arg1, "shadow")) {
act(AT_DGREY, "$n begins to channel Shadow Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to channel Shadow Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_DEATH;
damage = MAG_UNHOLY;
} else if (!str_cmp(arg1, "drain")) {
act(AT_DGREY, "$n begins to channel Death Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to channel Death Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_DEATH;
damage = MAG_DRAIN;
action = ACT_HARM;
} else if (!str_cmp(arg1, "death")) {
act(AT_DGREY, "$n begins to channel Death Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to channel Death Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_DEATH;
damage = MAG_DRAIN;
} else if (!str_cmp(arg1, "venom")
|| !str_cmp(arg1, "poison")) {
act(AT_DGREEN, "$n begins to channel Poison Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREEN, "You begin to channel Poison Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_DEATH;
damage = MAG_POISON;
} else if (!str_cmp(arg1, "changing")
|| !str_cmp(arg1, "chaos")) {
act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CHANGE;
damage = MAG_CHANGE;
} else if (!str_cmp(arg1, "distort")) {
act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CHANGE;
damage = MAG_CHANGE;
action = ACT_HARM;
} else if (!str_cmp(arg1, "change")
|| !str_cmp(arg1, "alter")
|| !str_cmp(arg1, "morph")) {
act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CHANGE;
damage = MAG_CHANGE;
action = ACT_CHANGE;
} else if (!str_cmp(arg1, "time")
|| !str_cmp(arg1, "chronomancy")
|| !str_cmp(arg1, "prophecy")) {
act(AT_DBLUE, "$n begins to channel Time Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_DBLUE, "You begin to channel Time Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_TIME;
damage = MAG_TIME;
} else if (!str_cmp(arg1, "mind")
|| !str_cmp(arg1, "psi")
|| !str_cmp(arg1, "psionics")) {
act(AT_PURPLE, "$n begins to channel Mind Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_PURPLE, "You begin to channel Mind Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_MIND;
damage = MAG_PSIONIC;
} else if (!str_cmp(arg1, "motion")
|| !str_cmp(arg1, "telekinesis")
|| !str_cmp(arg1, "movement")) {
act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_MOTION;
damage = MAG_TELEKINETIC;
} else if (!str_cmp(arg1, "travel")
|| !str_cmp(arg1, "teleport")
|| !str_cmp(arg1, "send")) {
act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_MOTION;
damage = MAG_TELEKINETIC;
action = ACT_MOVE;
} else if (!str_cmp(arg1, "recall")
|| !str_cmp(arg1, "return")
|| !str_cmp(arg1, "nexus")) {
act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_MOTION;
damage = MAG_PSIONIC;
action = ACT_MOVE;
} else if (!str_cmp(arg1, "seeking")
|| !str_cmp(arg1, "finding")
|| !str_cmp(arg1, "divination")) {
act(AT_GREEN, "$n begins to channel Seeking Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Seeking Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_SEEKING;
damage = MAG_SEEK;
} else if (!str_cmp(arg1, "seek")
|| !str_cmp(arg1, "find")
|| !str_cmp(arg1, "divine")
|| !str_cmp(arg1, "locate")) {
act(AT_GREEN, "$n begins to channel Seeking Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_GREEN, "You begin to channel Seeking Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_SEEKING;
damage = MAG_SEEK;
action = ACT_FIND;
} else if (!str_cmp(arg1, "security")
|| !str_cmp(arg1, "binding")
|| !str_cmp(arg1, "protection")) {
act(AT_WHITE, "$n begins to channel Security Magic.", ch, NULL, NULL, TO_ROOM);
act(AT_WHITE, "You begin to channel Security Magic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_SECURITY;
damage = MAG_HOLY;
} else if (!str_cmp(arg1, "void")
|| !str_cmp(arg1, "anti")
|| !str_cmp(arg1, "antimatter")) {
act(AT_DGREY, "$n begins to channel antimatter.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to channel antimatter.", ch, NULL, NULL, TO_CHAR);
talent = TAL_VOID;
damage = MAG_ANTIMATTER;
} else if (!str_cmp(arg1, "ether")) {
act(AT_DGREY, "$n begins to draw upon ether.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to draw upon ether.", ch, NULL, NULL, TO_CHAR);
talent = TAL_VOID;
damage = MAG_ETHER;
} else if (!str_cmp(arg1, "antimagic")
|| !str_cmp(arg1, "dispel")) {
act(AT_DGREY, "$n begins to channel antimagic.", ch, NULL, NULL, TO_ROOM);
act(AT_DGREY, "You begin to channel antimagic.", ch, NULL, NULL, TO_CHAR);
talent = TAL_VOID;
damage = MAG_ANTIMAGIC;
} else if (!str_cmp(arg1, "catalysm")
|| !str_cmp(arg1, "mana")
|| !str_cmp(arg1, "magic")) {
act(AT_PURPLE, "$n begins to channel raw mana.", ch, NULL, NULL, TO_ROOM);
act(AT_PURPLE, "You begin to channel raw mana.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CATALYSM;
damage = MAG_ALL;
} else if (!str_cmp(arg1, "energy")
|| !str_cmp(arg1, "power")
|| !str_cmp(arg1, "force")) {
act(AT_PURPLE, "$n begins to channel raw energy.", ch, NULL, NULL, TO_ROOM);
act(AT_PURPLE, "You begin to channel raw energy.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CATALYSM;
damage = MAG_ENERGY;
} else if (!str_cmp(arg1, "swords")
|| !str_cmp(arg1, "blades")
|| !str_cmp(arg1, "blade")
|| !str_cmp(arg1, "sword")) {
act(AT_PLAIN, "$n begins to dance with magic swords.", ch, NULL, NULL, TO_ROOM);
act(AT_PLAIN, "You begin to dance with magic swords.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CATALYSM;
damage = MAG_SLASH;
} else if (!str_cmp(arg1, "daggers")
|| !str_cmp(arg1, "dagger")
|| !str_cmp(arg1, "knife")
|| !str_cmp(arg1, "knives")) {
act(AT_PLAIN, "$n begins to juggle magic daggers.", ch, NULL, NULL, TO_ROOM);
act(AT_PLAIN, "You begin to juggle magic daggers.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CATALYSM;
damage = MAG_PIERCE;
} else {
act(AT_PURPLE, "$n begins to channel raw mana.", ch, NULL, NULL, TO_ROOM);
act(AT_PURPLE, "You begin to channel raw mana.", ch, NULL, NULL, TO_CHAR);
talent = TAL_CATALYSM;
damage = MAG_ALL;
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
strcpy(arg3,arg2);
strcpy(arg2,arg1);
}
/* Examine the second argument.
* Power and verb are interchangable, so we have to check both.
*/
if (action == ACT_TRICKS) {
if (arg2 && (action = check_verb(arg2)) == ACT_TRICKS) {
if (power < 10) {
if (arg2 && (power = check_power(arg2)) == -1) {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
strcpy(arg3,arg2);
}
} else {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(argument,buf);
strcpy(arg4,arg3);
strcpy(arg3,arg2);
}
}
} else {
if (power < 10) {
if (arg2 && (power = check_power(arg2)) == -1) {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
strcpy(arg3,arg2);
}
} else {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
strcpy(arg3,arg2);
}
}
/* Examine the third argument. Again, power and verb. */
if (power < 10) {
if (arg3 && (power = check_power(arg3)) == -1) {
if (action == ACT_TRICKS) {
if (arg3 && (action = check_verb(arg3)) == ACT_TRICKS) {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
}
} else {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
}
}
} else {
if (action == ACT_TRICKS) {
if (arg3 && (action = check_verb(arg3)) == ACT_TRICKS) {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
}
} else {
if (argument && argument[0] != '\0' && argument[0] != ' ') {
sprintf(buf, "%s %s", arg4, argument);
strcpy(argument,buf);
} else {
strcpy(argument,arg4);
}
strcpy(arg4,arg3);
}
}
if (power < 10) power = 10;
if (!check_concentration(ch, damage, action, power)) return;
if (damage == MAG_SOUND && IS_SILENT(ch)) {
send_to_char("No sound comes out.\n\r", ch);
return;
}
/* Fourth arguemnt, handle and find an appropriate target */
switch (action) {
default:
if (!str_cmp(arg4, "all")) {
for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) {
ch_trick(victim, damage);
}
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_trick(victim, damage);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_trick(ch, obj, damage);
} else {
ch_trick(ch, damage);
}
break;
case ACT_HARM:
if (!str_cmp(arg4, "all")) {
for (victim = ch->in_room->first_person;victim;victim=next_vict) {
next_vict = victim->next_in_room;
if (ch == victim) continue;
ch_harm(victim, ch, power, damage, FALSE);
}
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_harm(victim, ch, power, damage, FALSE);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_harm(ch, obj, damage, power);
} else if (IS_FIGHTING(ch)) {
ch_harm(ch->last_hit, ch, power, damage, FALSE);
} else {
ch_trick(ch, damage);
}
break;
case ACT_HELP:
if (!str_cmp(arg4, "all")) {
for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) {
ch_help(victim, ch, damage, power/2);
}
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_help(victim, ch, damage, power);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_help(ch, obj, damage, power);
} else {
ch_help(ch, ch, damage, power);
}
break;
case ACT_HINDER:
if (!str_cmp(arg4, "all")) {
for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) {
if (ch == victim) continue;
ch_hinder(victim, ch, damage, power/2);
}
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_hinder(victim, ch, damage, power);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_hinder(ch, obj, damage);
} else {
room_hinder(ch, ch->in_room, damage, power, arg4);
}
break;
case ACT_CREATE:
learn_talent(ch, TAL_CATALYSM);
if (damage == MAG_ETHER
&& ch->curr_talent[TAL_VOID] >= 100) {
void_create(ch, power, arg4);
} else if (damage == MAG_DREAM
&& ch->curr_talent[TAL_DREAM] >= 30) {
dream_create(ch, power, arg4, argument);
} else {
obj_create(ch, damage, power, arg4);
}
break;
case ACT_FIND:
learn_talent(ch, TAL_SEEKING);
if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_find(ch, obj, damage);
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_find(victim, ch, damage);
} else {
seek_find(ch, damage, arg4);
}
break;
case ACT_FOCUS:
if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_focus(victim, ch, damage, power);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_focus(ch, obj, damage);
} else {
ch_focus(ch, ch, damage, power);
}
break;
case ACT_MOVE:
learn_talent(ch, TAL_MOTION);
if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_move(ch, obj, damage, power, argument);
} else if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_move(victim, ch, damage, arg4, argument);
} else if (!arg4 || arg4[0] == '\0') {
ch_move(ch, ch, damage, arg4, argument);
} else {
summon_move(ch, damage, power, arg4);
}
break;
case ACT_CHANGE:
if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_change(victim, ch, damage, argument);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_change(ch, obj, damage, power, argument);
} else {
ch_change(ch, ch, damage, argument);
}
break;
case ACT_ENHANCE:
if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_enhance(victim, ch, damage, power);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_enhance(ch, obj, damage, power);
} else {
ch_enhance(ch, ch, damage, power);
}
break;
case ACT_RUNE:
draw_rune(ch, ch->in_room, damage);
break;
case ACT_SING:
if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_sing(victim, ch, damage, power);
} else {
song_sing(ch, damage, power, arg4);
}
break;
case ACT_CONTROL:
if ((victim = get_char_room(ch, arg4)) != NULL) {
ch_control(victim, ch, damage, power, arg4);
} else if ((obj = get_obj_here(ch, arg4)) != NULL) {
obj_control(ch, obj, damage, power);
} else {
room_control(ch, damage, power, arg4);
}
break;
}
if (TALENT(ch, talent) >= 20)
power /= ((TALENT(ch, talent)+100)/100);
use_magic(ch, talent, power);
STRFREE(ch->last_taken);
ch->last_taken = STRALLOC("channeling");
WAIT_STATE(ch, power/100);
}