Crossfire Server, Branch 1.12  R12190
monster.c
Go to the documentation of this file.
00001 /*
00002  * static char *rcsid_monster_c =
00003  *   "$Id: monster.c 11578 2009-02-23 22:02:27Z lalo $";
00004  */
00005 
00006 /*
00007     CrossFire, A Multiplayer game for X-windows
00008 
00009     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
00010     Copyright (C) 1992 Frank Tore Johansen
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025 
00026     The authors can be reached via e-mail at crossfire-devel@real-time.com
00027 */
00028 
00034 #include <global.h>
00035 #include <random_map.h>
00036 #include <rproto.h>
00037 
00049 void  insert_multisquare_ob_in_map(object *new_obj, mapstruct *map) {
00050     int x, y;
00051     archetype *at;
00052     object *old_seg;
00053     object *head;
00054 
00055     /* first insert the head */
00056     insert_ob_in_map(new_obj, map, new_obj, INS_NO_MERGE|INS_NO_WALK_ON);
00057 
00058     x = new_obj->x;
00059     y = new_obj->y;
00060     old_seg = new_obj;
00061     head = new_obj;
00062     for (at = new_obj->arch->more; at != NULL; at = at->more) {
00063         object *new_seg;
00064 
00065         new_seg = arch_to_object(at);
00066         new_seg->x = x+at->clone.x;
00067         new_seg->y = y+at->clone.y;
00068         new_seg->map = old_seg->map;
00069         insert_ob_in_map(new_seg, new_seg->map, new_seg, INS_NO_MERGE|INS_NO_WALK_ON);
00070         new_seg->head = head;
00071         old_seg->more = new_seg;
00072         old_seg = new_seg;
00073     }
00074     old_seg->more = NULL;
00075 }
00076 
00089 void place_monsters(mapstruct *map, char *monsterstyle, int difficulty, RMParms *RP) {
00090     char styledirname[256];
00091     mapstruct *style_map = NULL;
00092     int failed_placements;
00093     sint64 exp_per_sq, total_experience;
00094     int number_monsters = 0;
00095     archetype *at;
00096 
00097     snprintf(styledirname, sizeof(styledirname), "%s", "/styles/monsterstyles");
00098     style_map = find_style(styledirname, monsterstyle, difficulty);
00099     if (style_map == NULL)
00100         return;
00101 
00102     /* fill up the map with random monsters from the monster style*/
00103 
00104     total_experience = 0;
00105     failed_placements = 0;
00106     exp_per_sq = 0;
00107     while (exp_per_sq <= level_exp(difficulty, 1.0)
00108     && failed_placements < 100
00109     && number_monsters < (RP->Xsize*RP->Ysize)/8) {
00110         object *this_monster = pick_random_object(style_map);
00111         int x, y, freeindex;
00112 
00113         if (this_monster == NULL)
00114             return; /* no monster?? */
00115         x = RANDOM()%RP->Xsize;
00116         y = RANDOM()%RP->Ysize;
00117         freeindex = find_first_free_spot(this_monster, map, x, y);
00118         if (freeindex != -1) {
00119             object *new_monster = arch_to_object(this_monster->arch);
00120 
00121             x += freearr_x[freeindex];
00122             y += freearr_y[freeindex];
00123             copy_object_with_inv(this_monster, new_monster);
00124             new_monster->x = x;
00125             new_monster->y = y;
00126             insert_multisquare_ob_in_map(new_monster, map);
00127             total_experience += this_monster->stats.exp;
00128             for (at = new_monster->arch; at != NULL; at = at->more)
00129                 number_monsters++;
00130             RP->total_map_hp += new_monster->stats.hp;  /*  a global count */
00131         } else {
00132             failed_placements++;
00133         }
00134         exp_per_sq = ((double)1000*total_experience)/(MAP_WIDTH(map)*MAP_HEIGHT(map)+1);
00135     }
00136 }