--- deliantra/server/server/spell_effect.C 2007/04/30 04:25:30 1.49 +++ deliantra/server/server/spell_effect.C 2007/05/22 10:50:01 1.53 @@ -587,16 +587,11 @@ { new_draw_info (NDI_UNIQUE, 0, op, "You have:"); new_draw_info (NDI_UNIQUE, 0, op, cp); - if (tmp != NULL) - { - for (i = 0; i < NUM_STATS; i++) - { - if (get_attr_value (&tmp->stats, i) < 0) - { - new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is depleted by %d", statname[i], -(get_attr_value (&tmp->stats, i))); - } - } - } + + if (tmp) + for (i = 0; i < NUM_STATS; i++) + if (tmp->stats.stat (i) < 0) + new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is depleted by %d", statname[i], -tmp->stats.stat (i)); } if (is_dragon_pl (op)) @@ -620,257 +615,6 @@ return 1; } -/* int cast_create_town_portal (object *op, object *caster, int dir) - * - * This function cast the spell of town portal for op - * - * The spell operates in two passes. During the first one a place - * is marked as a destination for the portal. During the second one, - * 2 portals are created, one in the position the player cast it and - * one in the destination place. The portal are synchronized and 2 forces - * are inserted in the player to destruct the portal next time player - * creates a new portal pair. - * This spell has a side effect that it allows people to meet each other - * in a permanent, private, appartements by making a town portal from it - * to the town or another public place. So, check if the map is unique and if - * so return an error - * - * Code by Tchize (david.delbecq@usa.net) - */ -int -cast_create_town_portal (object *op, object *caster, object *spell, int dir) -{ - object *dummy, *force, *old_force; - archetype *perm_portal; - char portal_name[1024], portal_message[1024]; - maptile *exitmap; - int op_level; - - /* 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)) && settings.create_home_portals != TRUE) - { - new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You can't cast that here.\n"); - return 0; - } - - /* 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 = arch_to_object (spell->other_arch); - if (dummy == NULL) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (force in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - force = check_inv_recursive (op, dummy); - - if (force == NULL) - { - /* Here we know there is no destination marked up. - * We have 2 things to do: - * 1. Mark the destination in the player inventory. - * 2. Let the player know it worked. - */ - dummy->name = op->map->path; - EXIT_X (dummy) = op->x; - EXIT_Y (dummy) = op->y; - 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."); - return 1; - } - - dummy->destroy (); - - /* Here we know where the town portal should go to - * We should kill any existing portal associated with the player. - * Than we should create the 2 portals. - * For each of them, we need: - * - To create the portal with the name of the player+destination map - * - set the owner of the town portal - * - To mark the position of the portal in the player's inventory - * for easier destruction. - * - * The mark works has follow: - * slaying: Existing town portal - * hp, sp : x & y of the associated portal - * name : name of the portal - * race : map the portal is in - */ - - /* First step: killing existing town portals */ - dummy = get_archetype (spell->race); - if (dummy == NULL) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - perm_portal = archetype::find (spell->slaying); - - /* To kill a town portal, we go trough the player's inventory, - * for each marked portal in player's inventory, - * -We try load the associated map (if impossible, consider the portal destructed) - * -We find any portal in the specified location. - * If it has the good name, we destruct it. - * -We destruct the force indicating that portal. - */ - while ((old_force = check_inv_recursive (op, dummy))) - { - exitmap = maptile::find_sync (old_force->race, op->map); - - if (exitmap) - { - exitmap->load_sync (); - - int exitx = EXIT_X (old_force); - int exity = EXIT_Y (old_force); - - for (object *tmp = present_arch (perm_portal, exitmap, exitx, exity); tmp; tmp = tmp->above) - { - if (tmp->name == old_force->name) - { - tmp->destroy (); - break; - } - } - } - - old_force->destroy (); - } - - dummy->destroy (); - - /* Creating the portals. - * The very first thing to do is to ensure - * access to the destination map. - * If we can't, don't fizzle. Simply warn player. - * This ensure player pays his mana for the spell - * 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 */ - exitmap = maptile::find_sync (force->name); - - /* If we were unable to load (ex. random map deleted), warn player */ - if (!exitmap) - { - new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Something strange happens.\nYou can't remember where to go!?"); - force->destroy (); - return 1; - } - - exitmap->load_sync (); - - op_level = caster_level (caster, spell); - if (op_level < 15) - snprintf (portal_message, 1024, - "\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n", - &op->name); - else if (op_level < 30) - snprintf (portal_message, 1024, - "\n%s's portal smells of ozone.\nYou do a lot of movements and finally pass\nthrough the small hole in the air\n", &op->name); - else if (op_level < 60) - snprintf (portal_message, 1024, "\nA shining door opens in the air in front of you,\nshowing you the path to another place.\n"); - else - snprintf (portal_message, 1024, "\nAs you walk through %s's portal, flowers come out\nfrom the ground around you.\nYou feel awed.\n", - &op->name); - - /* Create a portal in front of player - * dummy contain the portal and - * force contain the track to kill it later - */ - snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &force->name); - dummy = get_archetype (spell->slaying); /*The portal */ - if (dummy == NULL) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - EXIT_PATH (dummy) = force->name; - EXIT_X (dummy) = EXIT_X (force); - EXIT_Y (dummy) = EXIT_Y (force); - dummy->name = dummy->name_pl = portal_name; - dummy->msg = portal_message; - dummy->race = op->name; /*Save the owner of the portal */ - cast_create_obj (op, caster, dummy, 0); - - /* 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. - */ - object *tmp = get_archetype (spell->race); - - if (!tmp) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - tmp->race = op->map->path; - tmp->name = portal_name; - EXIT_X (tmp) = dummy->x; - EXIT_Y (tmp) = dummy->y; - op->insert (tmp); - - /* Create a portal in the destination map - * dummy contain the portal and - * 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); - dummy = get_archetype (spell->slaying); /*The portal */ - if (dummy == NULL) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - EXIT_PATH (dummy) = op->map->path; - EXIT_X (dummy) = op->x; - EXIT_Y (dummy) = op->y; - dummy->name = dummy->name_pl = portal_name; - dummy->msg = portal_message; - dummy->race = op->name; /*Save the owner of the portal */ - exitmap->insert (dummy, EXIT_X (force), EXIT_Y (force), op); - - /* Now we create another town portal marker that - * points back to the one we just made - */ - tmp = get_archetype (spell->race); - if (tmp == NULL) - { - new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); - LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name); - return 0; - } - - tmp->race = force->name; - tmp->name = portal_name; - EXIT_X (tmp) = dummy->x; - EXIT_Y (tmp) = dummy->y; - insert_ob_in_ob (tmp, op); - - /* Describe the player what happened - */ - new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You see air moving and showing you the way home."); - force->destroy (); - - return 1; -} - /* This creates magic walls. Really, it can create most any object, * within some reason. */ @@ -1370,21 +1114,17 @@ /* Stat adjustment spells */ for (i = 0; i < NUM_STATS; i++) { - sint8 stat = get_attr_value (&spell_ob->stats, i), k, sm; - - if (stat) + if (sint8 stat = spell_ob->stats.stat (i)) { - sm = 0; - for (k = 0; k < stat; k++) + sint8 sm = 0; + for (sint8 k = 0; k < stat; k++) sm += rndm (1, 3); - if ((get_attr_value (&tmp->stats, i) + sm) > (15 + 5 * stat)) - { - sm = (15 + 5 * stat) - get_attr_value (&tmp->stats, i); - if (sm < 0) - sm = 0; - } - set_attr_value (&force->stats, i, sm); + if (tmp->stats.stat (i) + sm > 15 + 5 * stat) + sm = max (0, (15 + 5 * stat) - tmp->stats.stat (i)); + + force->stats.stat (i) = sm; + if (!sm) new_draw_info (NDI_UNIQUE, 0, op, no_gain_msgs[i]); }