Crossfire Server, Branch 1.12
R12190
|
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 }