version 1.70 | | version 1.71 |
---|
| | |
/* | | /* |
* static char *rcsid_spell_effect_c = | | * static char *rcsid_spell_effect_c = |
* "$Id: spell_effect.c,v 1.70 2002/06/07 07:00:45 mwedel Exp $"; | | * "$Id: spell_effect.c,v 1.71 2002/07/05 22:22:29 uid39786 Exp $"; |
*/ | | */ |
| | |
| | |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
Copyright (C) 2000 Mark Wedel | | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
Copyright (C) 1992 Frank Tore Johansen | | Copyright (C) 1992 Frank Tore Johansen |
| | |
This program is free software; you can redistribute it and/or modify | | This program is free software; you can redistribute it and/or modify |
| | |
along with this program; if not, write to the Free Software | | along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| | |
The author can be reached via e-mail to mwedel@scruz.net | | The authors can be reached via e-mail at crossfire-devel@real-time.com |
*/ | | */ |
| | |
#include <global.h> | | #include <global.h> |
| | |
} | | } |
| | |
| | |
| | /* this pet monster stuff is total crap! |
| | * We should replace it with: |
| | * struct summoned_mon int foo { |
| | * char * mon_arch; |
| | * int num_summoned; |
| | * } |
| | * struct summoned_mon pets_summoned = { |
| | * { "bird", 5 }, |
| | * { "vampire", 6}, |
| | * { NULL, 0 } -* terminator *- |
| | * } |
| | * |
| | * Or even better, use treasure lists for this, |
| | * eg, mage_pet_monster treasure list, etc. Means |
| | * that these could be changed without recompiling the server. |
| | */ |
| | |
#define MAX_PET_MONSTERS 5 | | #define MAX_PET_MONSTERS 5 |
char mage_pet_monsters [MAX_PET_MONSTERS][16] = | | char mage_pet_monsters [MAX_PET_MONSTERS][16] = |
{"bat","spider","stalker","beholder","dark_elf"}; | | {"bat","spider","stalker","beholder","dark_elf"}; |
| | |
{"bird","pixie","skeleton","skull","vampire"}; | | {"bird","pixie","skeleton","skull","vampire"}; |
int altern_num_called [MAX_PET_MONSTERS] = {1,1,2,1,1}; | | int altern_num_called [MAX_PET_MONSTERS] = {1,1,2,1,1}; |
| | |
/* this pet monster stuff is total crap! | | |
** We should replace it with: | | |
struct summoned_mon int foo { | | |
char * mon_arch; | | |
int num_summoned; | | |
} | | |
struct summoned_mon pets_summoned = { | | |
{ "bird", 5 }, | | |
{ "vampire", 6}, | | |
{ NULL, 0 } -* terminator *- | | |
} | | |
** | | |
*/ | | |
| | |
| | |
int summon_pet(object *op, int dir, SpellTypeFrom item) { | | int summon_pet(object *op, int dir, SpellTypeFrom item) { |
| | |
char *monster; | | char *monster; |
archetype *at; | | archetype *at; |
| | |
/* | | |
level = ((op->head?op->head->level:op->level) / 4); | | |
*/ | | |
level = ((op->head?op->head->level:SK_level(op)) / 4); | | level = ((op->head?op->head->level:SK_level(op)) / 4); |
if (level >= MAX_PET_MONSTERS) | | if (level >= MAX_PET_MONSTERS) |
level = MAX_PET_MONSTERS - 1; | | level = MAX_PET_MONSTERS - 1; |
| | |
switch(rndm(0, 2)) { | | switch(rndm(0, 2)) { |
case 0: | | case 0: |
number = priest_num_called[level]; | | number = priest_num_called[level]; |
| | |
number = mage_num_called[level]; | | number = mage_num_called[level]; |
monster = mage_pet_monsters[level]; | | monster = mage_pet_monsters[level]; |
break; | | break; |
| | |
default: | | default: |
number = altern_num_called[level]; | | number = altern_num_called[level]; |
monster = altern_pet_monsters[level]; | | monster = altern_pet_monsters[level]; |
break; | | break; |
} | | } |
| | |
at = find_archetype(monster); | | at = find_archetype(monster); |
if(at == NULL) { | | if(at == NULL) { |
LOG(llevError,"Unknown archetype in summon pet: %s\n",monster); | | LOG(llevError,"Unknown archetype in summon pet: %s\n",monster); |
| | |
} | | } |
if (!dir) | | if (!dir) |
dir = find_free_spot(at, op->map, op->x, op->y, 1, SIZEOFFREE); | | dir = find_free_spot(at, op->map, op->x, op->y, 1, SIZEOFFREE); |
if((dir==-1) || arch_blocked(at,op->map, op->x + freearr_x[dir], op->y+freearr_y[dir])) | | |
{ | | if((dir==-1) || arch_blocked(at,op->map, op->x + freearr_x[dir], op->y+freearr_y[dir])) { |
new_draw_info(NDI_UNIQUE, 0,op, "There is something in the way."); | | new_draw_info(NDI_UNIQUE, 0,op, "There is something in the way."); |
if(op->type == PLAYER) | | if(op->type == PLAYER) |
op->contr->count_left = 0; | | op->contr->count_left = 0; |
return 0; | | return 0; |
} | | } |
if (item != spellNormal) | | |
/* op->stats.sp -= 5 + 10*level + op->level; */ | | |
op->stats.sp -= 5 + 10*level + SK_level(op); | | |
for (i = 1; i < number + 1; i++) { | | for (i = 1; i < number + 1; i++) { |
archetype *atmp; | | archetype *atmp; |
object *prev = NULL, *head = NULL; /* We want to summon dragons *grin* */ | | object *prev = NULL, *head = NULL; /* We want to summon dragons *grin* */ |
| | |
for(atmp = at; atmp!=NULL; atmp = atmp->more) { | | for(atmp = at; atmp!=NULL; atmp = atmp->more) { |
object *tmp; | | object *tmp; |
tmp = arch_to_object(atmp); | | tmp = arch_to_object(atmp); |
| | |
| | /* if this is the head, set owner/friendly as needed */ |
if (atmp == at) { | | if (atmp == at) { |
set_owner(tmp, op); | | set_owner(tmp, op); |
SET_FLAG(tmp, FLAG_MONSTER); | | SET_FLAG(tmp, FLAG_MONSTER); |
| | |
prev = tmp; | | prev = tmp; |
} | | } |
head->direction = dir; | | head->direction = dir; |
| | |
/* Some monsters are sleeping by default - clear that */ | | /* Some monsters are sleeping by default - clear that */ |
CLEAR_FLAG(head, FLAG_SLEEP); | | CLEAR_FLAG(head, FLAG_SLEEP); |
| | |
head = insert_ob_in_map (head, op->map, op,0); | | head = insert_ob_in_map (head, op->map, op,0); |
if (head != NULL && head->randomitems != NULL) { | | if (head != NULL && head->randomitems != NULL) { |
object *tmp; | | object *tmp; |
| | |
SET_FLAG(tmp, FLAG_NO_DROP); | | SET_FLAG(tmp, FLAG_NO_DROP); |
} | | } |
dir = absdir(dir + 1); | | dir = absdir(dir + 1); |
if (arch_blocked(at,op->map, op->x + freearr_x[dir], | | if (arch_blocked(at,op->map, op->x + freearr_x[dir], op->y + freearr_y[dir])) { |
op->y + freearr_y[dir])) | | |
{ | | |
if (i < number) { | | if (i < number) { |
new_draw_info(NDI_UNIQUE, 0,op, "There is something in the way,"); | | new_draw_info(NDI_UNIQUE, 0,op, "There is something in the way,"); |
new_draw_info(NDI_UNIQUE, 0,op, "no more pets for this casting."); | | new_draw_info(NDI_UNIQUE, 0,op, "no more pets for this casting."); |
if (item != spellNormal) { | | |
/* op->stats.sp += (5 + 12 * level + op->level) / (number - i); */ | | |
op->stats.sp += (5 + 12 * level + SK_level(op)) / (number - i); | | |
if (op->stats.sp < 0) | | |
op->stats.sp = 0; | | |
} | | |
return 1; | | return 1; |
} | | } |
} | | } |
} | | } /* for i < number */ |
if (item != spellNormal && op->stats.sp < 0) | | |
op->stats.sp = 0; | | |
return 1; | | return 1; |
} | | } |
| | |
| | |
| | |
| | |
/* cast_cause_disease: this spell looks along <dir> from the | | /* cast_cause_disease: this spell looks along <dir> from the |
player and infects someone. */ | | * player and infects someone. |
| | * op is the player/monster, caster is the object, dir is the direction |
| | * to cast, disease_arch is the specific disease, and type is the spell number |
| | */ |
| | |
int cast_cause_disease(object *op, object *caster, int dir, archetype *disease_arch, int type) { | | int cast_cause_disease(object *op, object *caster, int dir, archetype *disease_arch, int type) { |
int x,y,i; | | int x,y,i; |
| | |
| | |
x = op->x; y = op->y; | | x = op->x; y = op->y; |
| | |
| | /* If casting from a scroll, no direction will be available, so refer to the |
| | * direction the player is pointing. |
| | */ |
| | if (!dir) dir=op->facing; |
| | if (!dir) return 0; /* won't find anything if casting on ourself, so just return */ |
| | |
/* search in a line for a victim */ | | /* search in a line for a victim */ |
for(i=0;i<5;i++) { | | for(i=0;i<5;i++) { |
x += freearr_x[dir]; y+= freearr_y[dir]; | | x += freearr_x[dir]; y+= freearr_y[dir]; |
if(out_of_map(op->map,x,y)) continue; | | |
| | if(out_of_map(op->map,x,y)) return 0; |
| | |
/* search this square for a victim */ | | /* search this square for a victim */ |
for(walk=get_map_ob(op->map,x,y);walk;walk=walk->above) | | for(walk=get_map_ob(op->map,x,y);walk;walk=walk->above) |
if(QUERY_FLAG(walk,FLAG_MONSTER) | | if (QUERY_FLAG(walk,FLAG_MONSTER) || (walk->type==PLAYER)) { /* found a victim */ |
|| !(walk->type==PLAYER)) { /* found a victim */ | | |
| | |
object *disease = arch_to_object(disease_arch); | | object *disease = arch_to_object(disease_arch); |
| | |
set_owner(disease,op); | | set_owner(disease,op); |
disease->stats.exp = 0; | | disease->stats.exp = 0; |
disease->level = op->level; | | disease->level = op->level; |
| | |
| | |
| | |
if(infect_object(walk,disease,1)) { | | if(infect_object(walk,disease,1)) { |
char buf[128]; | | |
object *flash; /* visual effect for inflicting disease */ | | object *flash; /* visual effect for inflicting disease */ |
sprintf(buf,"You inflict %s on %s!",disease->name,walk->name); | | |
| | new_draw_info_format(NDI_UNIQUE, 0, op, "You inflict %s on %s!",disease->name,walk->name); |
| | |
free_object(disease); /* don't need this one anymore */ | | free_object(disease); /* don't need this one anymore */ |
new_draw_info(NDI_UNIQUE,0,op,buf); | | |
flash=get_archetype("detect_magic"); | | flash=get_archetype("detect_magic"); |
flash->x = x; | | flash->x = x; |
flash->y = y; | | flash->y = y; |