00001 00007 /* 00008 Copyright (C) 2001 The Exult Team 00009 00010 This program is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU General Public License 00012 as published by the Free Software Foundation; either version 2 00013 of the License, or (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program; if not, write to the Free Software 00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00023 */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include "mappatch.h" 00030 #include "gamewin.h" 00031 #include "objs.h" 00032 #include "vec.h" 00033 00034 /* 00035 * Find (first) matching object. 00036 */ 00037 00038 Game_object *Map_patch::find 00039 ( 00040 ) 00041 { 00042 Game_window *gwin = Game_window::get_instance(); 00043 Game_object_vector vec; // Pass mask=0xb0 to get any object. 00044 Game_object::find_nearby(vec, spec.loc, spec.shapenum, 0, 0xb0, 00045 spec.quality, spec.framenum); 00046 return vec.empty() ? 0 : vec.front(); 00047 } 00048 00049 /* 00050 * Apply by removing object. 00051 * 00052 * Output: false if no object found. 00053 */ 00054 00055 bool Map_patch_remove::apply 00056 ( 00057 ) 00058 { 00059 bool found = false; 00060 Game_object *obj; 00061 while ((obj = find()) != 0) 00062 { 00063 obj->remove_this(); 00064 found = true; 00065 if (!all) // Just one? 00066 return true; 00067 } 00068 return found; 00069 } 00070 00071 /* 00072 * Apply by moving/changing object. 00073 * 00074 * Output: false if no object found. 00075 */ 00076 00077 bool Map_patch_modify::apply 00078 ( 00079 ) 00080 { 00081 Game_object *obj = find(); 00082 if (!obj) 00083 return false; 00084 obj->remove_this(1); // Remove but don't delete. 00085 if (mod.shapenum != c_any_shapenum) 00086 obj->set_shape(mod.shapenum); 00087 if (mod.framenum != c_any_framenum) 00088 obj->set_frame(mod.framenum); 00089 if (mod.quality != c_any_qual) 00090 obj->set_quality(mod.quality); 00091 obj->set_invalid(); // To add it back correctly. 00092 obj->move(mod.loc); 00093 return true; 00094 } 00095 00096 /* 00097 * Delete all the patches. 00098 */ 00099 00100 Map_patch_collection::~Map_patch_collection 00101 ( 00102 ) 00103 { 00104 for (Map_patch_map::iterator it1 = patches.begin(); 00105 it1 != patches.end(); it1++) 00106 { 00107 Map_patch_list& lst = (*it1).second; 00108 while (!lst.empty()) 00109 { 00110 Map_patch *patch = lst.front(); 00111 delete patch; 00112 lst.pop_front(); 00113 } 00114 } 00115 } 00116 00117 /* 00118 * Add a new patch. 00119 */ 00120 00121 void Map_patch_collection::add 00122 ( 00123 Map_patch *p 00124 ) 00125 { 00126 // Get superchunk coords. 00127 int sx = p->spec.loc.tx/c_tiles_per_schunk, 00128 sy = p->spec.loc.ty/c_tiles_per_schunk; 00129 // Get superchunk # (0-143). 00130 int schunk = sy*c_num_schunks + sx; 00131 patches[schunk].push_back(p); 00132 } 00133 00134 /* 00135 * Apply all patches for a superchunk. 00136 */ 00137 00138 void Map_patch_collection::apply 00139 ( 00140 int schunk 00141 ) 00142 { 00143 Map_patch_map::iterator it1 = patches.find(schunk); 00144 if (it1 != patches.end()) // Found list for superchunk? 00145 { 00146 Map_patch_list& lst = (*it1).second; 00147 for (Map_patch_list::const_iterator it2 = lst.begin(); 00148 it2 != lst.end(); it2++) 00149 (*it2)->apply(); // Apply each one in list. 00150 } 00151 }