version 1.97 | | version 1.98 |
---|
| | |
/* | | /* |
* static char *rcsid_spell_effect_c = | | * static char *rcsid_spell_effect_c = |
* "$Id: spell_effect.c,v 1.97 2003/02/21 07:55:38 mwedel Exp $"; | | * "$Id: spell_effect.c,v 1.98 2003/02/22 07:26:56 mwedel Exp $"; |
*/ | | */ |
| | |
| | |
| | |
{ | | { |
#define PORTAL_DESTINATION_NAME "Town portal destination" | | #define PORTAL_DESTINATION_NAME "Town portal destination" |
#define PORTAL_ACTIVE_NAME "Existing town portal" | | #define PORTAL_ACTIVE_NAME "Existing town portal" |
object* dummy; | | |
object* force; | | object *dummy, *force, *old_force, *tmp; |
object* old_force; | | |
object* current_obj; | | |
archetype *perm_portal; | | archetype *perm_portal; |
char portal_name [1024]; | | char portal_name [1024], portal_message [1024]; |
char portal_message [1024]; | | sint16 exitx, exity; |
char *exitpath; | | |
sint16 exitx=15; | | |
sint16 exity=15; | | |
mapstruct *exitmap; | | mapstruct *exitmap; |
int op_level; | | int op_level; |
| | |
/* The first thing to do is to check if we have a marked destination | | /* The first thing to do is to check if we have a marked destination |
* dummy is used to make a check inventory for the force | | * dummy is used to make a check inventory for the force |
*/ | | */ |
if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) | | |
{ | | /* Check to see if the map the player is currently on is a per player unique |
| | * map. This can be determined in that per player unique maps have the |
| | * full pathname listed. |
| | */ |
| | if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) { |
new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n"); | | new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n"); |
return 0; | | return 0; |
} | | } |
dummy=get_archetype("force"); | | |
| | dummy=get_archetype("town_portal"); |
if(dummy == NULL){ | | if(dummy == NULL){ |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name); |
return 0; | | return 0; |
} | | } |
free_string (dummy->name); | | |
dummy->name = add_string (PORTAL_DESTINATION_NAME); | | |
dummy->stats.hp=0; | | |
dummy->slaying = add_string (PORTAL_DESTINATION_NAME); | | |
force=check_inv_recursive (op,dummy); | | force=check_inv_recursive (op,dummy); |
if (force==NULL) | | |
| | if (force==NULL) { |
/* Here we know there is no destination marked up. | | /* Here we know there is no destination marked up. |
* We have 2 things to do: | | * We have 2 things to do: |
* 1. Mark the destination in the player inventory. | | * 1. Mark the destination in the player inventory. |
* 2. Let the player know it worked. | | * 2. Let the player know it worked. |
*/ | | */ |
{ | | |
free_string (dummy->name); | | free_string (dummy->name); |
dummy->name = add_string (op->map->path); | | dummy->name = add_string (op->map->path); |
EXIT_X(dummy)= op->x; | | EXIT_X(dummy)= op->x; |
EXIT_Y(dummy)= op->y; | | EXIT_Y(dummy)= op->y; |
dummy->speed=0.0; | | |
update_ob_speed (dummy); | | |
insert_ob_in_ob (dummy,op); | | insert_ob_in_ob (dummy,op); |
new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere."); | | new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere."); |
return 1; | | return 1; |
} | | } |
free_object (dummy); | | free_object (dummy); |
| | |
/* Here we know where the town portal should go to | | /* Here we know where the town portal should go to |
* We should kill any existing portal associated with the player. | | * We should kill any existing portal associated with the player. |
* Than we should create the 2 portals. | | * Than we should create the 2 portals. |
| | |
* - To mark the position of the portal in the player's inventory | | * - To mark the position of the portal in the player's inventory |
* for easier destruction. ² | | * for easier destruction. ² |
* | | * |
* ² The mark works has follow: | | * The mark works has follow: |
* slaying: Existing town portal | | * slaying: Existing town portal |
* hp, sp : x & y of the associated portal | | * hp, sp : x & y of the associated portal |
* name : name of the portal | | * name : name of the portal |
| | |
*/ | | */ |
| | |
/* First step: killing existing town portals */ | | /* First step: killing existing town portals */ |
dummy=get_archetype("force"); | | dummy=get_archetype("town_portal_active"); |
if(dummy == NULL){ | | if(dummy == NULL){ |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); |
return 0; | | return 0; |
} | | } |
free_string (dummy->name); | | perm_portal = find_archetype ("town_portal_magic"); |
dummy->name = add_string (portal_name); /*Usefull for string comparaison later (add_string)*/ | | |
dummy->stats.hp=0; | | |
dummy->slaying = add_string (PORTAL_ACTIVE_NAME); | | |
perm_portal = find_archetype ("perm_magic_portal"); | | |
while ( (old_force=check_inv_recursive (op,dummy))) | | |
/* To kill a town portal, we go trough the player's inventory, | | /* To kill a town portal, we go trough the player's inventory, |
* for each marked portal in player's inventory, | | * for each marked portal in player's inventory, |
* -We try load the associated map (if impossible, consider the portal destructed) | | * -We try load the associated map (if impossible, consider the portal destructed) |
| | |
* If it has the good name, we destruct it. | | * If it has the good name, we destruct it. |
* -We destruct the force indicating that portal. | | * -We destruct the force indicating that portal. |
*/ | | */ |
{ | | while ( (old_force=check_inv_recursive (op,dummy))) { |
exitpath=add_string (old_force->race); | | |
exitx=EXIT_X(old_force); | | exitx=EXIT_X(old_force); |
exity=EXIT_Y(old_force); | | exity=EXIT_Y(old_force); |
LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",exitpath,exitx,exity); | | LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",old_force->race,exitx,exity); |
if (!strncmp(exitpath, settings.localdir, strlen(settings.localdir))) exitmap = ready_map_name(exitpath, MAP_PLAYER_UNIQUE); | | if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir))) |
else exitmap = ready_map_name(exitpath, 0); | | exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE); |
if (exitmap) | | else exitmap = ready_map_name(old_force->race, 0); |
{ | | |
current_obj=present_arch (perm_portal,exitmap,exitx,exity); | | if (exitmap) { |
while (current_obj) | | tmp=present_arch (perm_portal,exitmap,exitx,exity); |
{ | | while (tmp) { |
if (current_obj->name !=old_force->name) | | if (tmp->name == old_force->name) { |
{ | | remove_ob (tmp); |
current_obj=current_obj->above; | | free_object (tmp); |
continue; | | |
} | | |
remove_ob (current_obj); | | |
free_object (current_obj); | | |
break; | | break; |
} | | } |
} | | } |
| | } |
remove_ob (old_force); | | remove_ob (old_force); |
free_object (old_force); | | free_object (old_force); |
LOG (llevDebug,"\n",old_force->name); | | LOG (llevDebug,"\n",old_force->name); |
free_string (exitpath); | | |
} | | } |
free_object (dummy); | | free_object (dummy); |
| | |
/* Creating the portals. | | /* Creating the portals. |
* The very first thing to do is to ensure | | * The very first thing to do is to ensure |
* access to the destination map. | | * access to the destination map. |
* If we can't, don't fizzle. Simply warn player. | | * If we can't, don't fizzle. Simply warn player. |
* This ensure player pays his mana for the spell | | * This ensure player pays his mana for the spell |
* because HE is responsible of forgotting. | | * because HE is responsible of forgotting. |
| | * 'force' is the destination of the town portal, which we got |
| | * from the players inventory above. |
*/ | | */ |
| | /* Ensure exit map is loaded*/ |
| | if (!strncmp(force->name, settings.localdir, strlen(settings.localdir))) |
| | exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE); |
| | else |
| | exitmap = ready_map_name(force->name, 0); |
| | |
| | /* If we were unable to load (ex. random map deleted), warn player*/ |
| | if (exitmap==NULL) { |
| | new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?"); |
| | return 1; |
| | } |
| | |
op_level =SK_level (op); | | op_level =SK_level (op); |
if (op_level<15) | | if (op_level<15) |
snprintf (portal_message,1024,"\nAir moves around you and\na huge smell of ammoniac\nrounds you as you pass\nthrough %s's portal\nPouah!\n",op->name); | | snprintf (portal_message,1024,"\nAir moves around you and\na huge smell of ammoniac\nrounds you as you pass\nthrough %s's portal\nPouah!\n",op->name); |
| | |
else if (op_level<60) | | else if (op_level<60) |
snprintf (portal_message,1024,"\nA sort of door opens in the air in front of you,\nshowing you the path to somewhere else.\n"); | | snprintf (portal_message,1024,"\nA sort of door opens in the air in front of you,\nshowing you the path to somewhere else.\n"); |
else snprintf (portal_message,1024,"\nAs you walk on %s's portal, flowers comes\nfrom the ground around you.\nYou feel quiet.\n",op->name); | | else snprintf (portal_message,1024,"\nAs you walk on %s's portal, flowers comes\nfrom the ground around you.\nYou feel quiet.\n",op->name); |
exitpath=add_string (force->name); | | |
exitx=EXIT_X(force); | | |
exity=EXIT_Y(force); | | |
remove_ob(force); /*Delete the force inside the player*/ | | |
free_object(force); | | |
if (!strncmp(exitpath, settings.localdir, strlen(settings.localdir))) /*Ensure exit map is loaded*/ | | |
exitmap = ready_map_name(exitpath, MAP_PLAYER_UNIQUE); | | |
else | | |
exitmap = ready_map_name(exitpath, 0); | | |
if (exitmap==NULL) /*If we were unable to load (ex. random map deleted), warn player*/ | | |
{ | | |
new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?"); | | |
free_string (exitpath); | | |
return 1; | | |
} | | |
/* Create a portal in front of player | | /* Create a portal in front of player |
* dummy contain the portal and | | * dummy contain the portal and |
* force contain the track to kill it later | | * force contain the track to kill it later |
*/ | | */ |
snprintf (portal_name,1024,"%s's portal to %s",op->name,exitpath); | | |
dummy=get_archetype ("perm_magic_portal"); /*The portal*/ | | snprintf (portal_name,1024,"%s's portal to %s",op->name,force->name); |
if(dummy == NULL) | | dummy=get_archetype("town_portal_magic"); /*The portal*/ |
{ | | if(dummy == NULL) { |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); |
free_string (exitpath); | | |
return 0; | | return 0; |
} | | } |
dummy->speed = 0.0; | | EXIT_PATH(dummy) = add_string (force->name); |
update_ob_speed (dummy); | | EXIT_X(dummy)=EXIT_X(force); |
free_string (EXIT_PATH(dummy)); | | EXIT_Y(dummy)=EXIT_Y(force); |
EXIT_PATH(dummy) = add_string (exitpath); | | |
EXIT_X(dummy)=exitx; | | |
EXIT_Y(dummy)=exity; | | |
FREE_AND_COPY(dummy->name, portal_name); | | FREE_AND_COPY(dummy->name, portal_name); |
FREE_AND_COPY(dummy->name_pl, portal_name); | | FREE_AND_COPY(dummy->name_pl, portal_name); |
dummy->msg=add_string (portal_message); | | dummy->msg=add_string (portal_message); |
CLEAR_FLAG (dummy,FLAG_WALK_ON); | | |
CLEAR_FLAG (dummy,FLAG_FLY_ON); | | |
dummy->stats.exp=1; /*Set as a 2 ways exit (see manual_apply & is_legal_2ways_exit funcs)*/ | | |
dummy->race=add_string (op->name); /*Save the owner of the portal*/ | | dummy->race=add_string (op->name); /*Save the owner of the portal*/ |
cast_create_obj (op, caster, dummy, 0); | | cast_create_obj (op, caster, dummy, 0); |
force=get_archetype("force"); /*The force*/ | | |
if(force == NULL){ | | /* Now we need to to create a town portal marker inside the player |
| | * object, so on future castings, we can know that he has an active |
| | * town portal. |
| | */ |
| | tmp=get_archetype("town_portal_active"); |
| | if(tmp == NULL){ |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); |
free_string (exitpath); | | |
return 0; | | return 0; |
} | | } |
force->slaying= add_string (PORTAL_ACTIVE_NAME); | | tmp->race=add_string (op->map->path); |
force->race=add_string (op->map->path); | | FREE_AND_COPY(tmp->name, portal_name); |
FREE_AND_COPY(force->name, portal_name); | | EXIT_X(tmp)=dummy->x; |
EXIT_X(force)=dummy->x; | | EXIT_Y(tmp)=dummy->y; |
EXIT_Y(force)=dummy->y; | | insert_ob_in_ob (tmp,op); |
force->speed=0.0; | | |
update_ob_speed (force); | | |
insert_ob_in_ob (force,op); | | |
/* Create a portal in the destination map | | /* Create a portal in the destination map |
* dummy contain the portal and | | * dummy contain the portal and |
* force the track to kill it later | | * force the track to kill it later |
| | * the 'force' variable still contains the 'reminder' of |
| | * where this portal goes to. |
*/ | | */ |
snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path); | | snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path); |
dummy=get_archetype ("perm_magic_portal"); /*The portal*/ | | dummy=get_archetype ("town_portal_magic"); /*The portal*/ |
if(dummy == NULL) | | if(dummy == NULL) { |
{ | | |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); |
free_string (exitpath); | | |
return 0; | | return 0; |
} | | } |
dummy->speed = 0.0; | | |
update_ob_speed (dummy); | | |
free_string (EXIT_PATH(dummy)); | | |
EXIT_PATH(dummy) = add_string (op->map->path); | | EXIT_PATH(dummy) = add_string (op->map->path); |
EXIT_X(dummy)=op->x; | | EXIT_X(dummy)=op->x; |
EXIT_Y(dummy)=op->y; | | EXIT_Y(dummy)=op->y; |
FREE_AND_COPY(dummy->name, portal_name); | | FREE_AND_COPY(dummy->name, portal_name); |
FREE_AND_COPY(dummy->name_pl, portal_name); | | FREE_AND_COPY(dummy->name_pl, portal_name); |
dummy->msg=add_string (portal_message); | | dummy->msg=add_string (portal_message); |
CLEAR_FLAG (dummy,FLAG_WALK_ON); | | dummy->x=EXIT_X(force); |
CLEAR_FLAG (dummy,FLAG_FLY_ON); | | dummy->y=EXIT_Y(force); |
dummy->x=exitx; | | |
dummy->y=exity; | | |
dummy->stats.exp=1; /*Set as a 2 ways exit (see manual_apply & is_legal_2ways_exit funcs)*/ | | |
dummy->race=add_string (op->name); /*Save the owner of the portal*/ | | dummy->race=add_string (op->name); /*Save the owner of the portal*/ |
insert_ob_in_map(dummy,exitmap,op,INS_BELOW_ORIGINATOR); | | insert_ob_in_map(dummy,exitmap,op,0); |
force=get_archetype("force"); /*The force*/ | | |
if(force == NULL){ | | /* Now we create another town portal marker that |
| | * points back to the one we just made |
| | */ |
| | tmp=get_archetype("town_portal_active"); |
| | if(tmp == NULL){ |
new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); | | new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); |
LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); | | LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); |
free_string (exitpath); | | |
return 0; | | return 0; |
} | | } |
force->slaying= add_string (PORTAL_ACTIVE_NAME); | | tmp->race=add_string(force->name); |
force->race=add_string (exitpath); | | FREE_AND_COPY(tmp->name, portal_name); |
FREE_AND_COPY(force->name, portal_name); | | EXIT_X(tmp)=dummy->x; |
EXIT_X(force)=dummy->x; | | EXIT_Y(tmp)=dummy->y; |
EXIT_Y(force)=dummy->y; | | insert_ob_in_ob (tmp,op); |
force->speed=0.0; | | |
update_ob_speed (force); | | |
insert_ob_in_ob (force,op); | | |
/* Describe the player what happened | | /* Describe the player what happened |
*/ | | */ |
new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You see air moving and showing you the way home."); | | new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You see air moving and showing you the way home."); |
free_string (exitpath); | | remove_ob(force); /* Delete the force inside the player*/ |
| | free_object(force); |
return 1; | | return 1; |
#undef PORTAL_DESTINATION_NAME | | |
#undef PORTAL_ACTIVE_NAME | | |
} | | } |
| | |
int cast_destruction(object *op, object *caster, int dam, int attacktype) { | | int cast_destruction(object *op, object *caster, int dam, int attacktype) { |