00001 /* 00002 * gameclk.cc - Keep track of time. 00003 * 00004 * Copyright (C) 2000-2001 The Exult Team 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #ifdef HAVE_CONFIG_H 00022 # include <config.h> 00023 #endif 00024 00025 #include <iostream> /* Debugging. */ 00026 #include "gameclk.h" 00027 #include "gamewin.h" 00028 #include "actors.h" 00029 #include "cheat.h" 00030 #include "game.h" 00031 00032 /* 00033 * Set palette. 00034 */ 00035 00036 void Game_clock::set_time_palette 00037 ( 00038 ) 00039 { 00040 Game_window *gwin = Game_window::get_instance(); 00041 Actor *main_actor = gwin->get_main_actor(); 00042 int new_palette; 00043 if (main_actor && main_actor->get_flag(Obj_flags::invisible)) 00044 { 00045 gwin->get_pal()->set(PALETTE_INVISIBLE); 00046 return; 00047 } 00048 00049 if (cheat.in_infravision()) { 00050 gwin->get_pal()->set(PALETTE_DAY); 00051 return; 00052 } 00053 00054 dungeon = gwin->is_in_dungeon(); 00055 if (dungeon || hour < 5) 00056 new_palette = PALETTE_NIGHT; 00057 else if (hour < 6) 00058 new_palette = PALETTE_DAWN; 00059 else if (hour < 19) 00060 new_palette = storm <= 0 ? PALETTE_DAY : PALETTE_DUSK; 00061 else if (hour < 21) 00062 new_palette = PALETTE_DUSK; 00063 else 00064 new_palette = PALETTE_NIGHT; 00065 if (light_source_level) 00066 { 00067 if (new_palette == PALETTE_NIGHT) 00068 new_palette = light_source_level == 1 ? PALETTE_DUSK 00069 : PALETTE_DAWN; 00070 else if (new_palette == PALETTE_DUSK) 00071 new_palette = PALETTE_DAWN; 00072 } 00073 // Gump mode, or light spell? 00074 if (gwin->is_special_light() && new_palette == PALETTE_NIGHT) 00075 new_palette = PALETTE_DAWN; 00076 gwin->get_pal()->set(new_palette); 00077 } 00078 00079 /* 00080 * Set palette. Used for restoring a game. 00081 */ 00082 00083 void Game_clock::set_palette 00084 ( 00085 ) 00086 { 00087 // Update palette to new time. 00088 set_time_palette(); 00089 } 00090 00091 /* 00092 * Set the palette for a changed light source level. 00093 */ 00094 00095 void Game_clock::set_light_source_level 00096 ( 00097 int lev 00098 ) 00099 { 00100 light_source_level = lev; 00101 set_time_palette(); 00102 } 00103 00104 /* 00105 * Storm ending/starting. 00106 */ 00107 00108 void Game_clock::set_storm 00109 ( 00110 bool onoff 00111 ) 00112 { 00113 storm += (onoff ? 1 : -1); 00114 set_time_palette(); // Update palette. 00115 } 00116 00117 /* 00118 * Decrement food level and check hunger of the party members. 00119 */ 00120 00121 void Game_clock::check_hunger 00122 ( 00123 ) 00124 { 00125 Game_window *gwin = Game_window::get_instance(); 00126 Actor *party[9]; // Get party + Avatar. 00127 int cnt = gwin->get_party(party, 1); 00128 for (int i = 0; i < cnt; i++) 00129 party[i]->use_food(); 00130 } 00131 00132 static void Check_freezing 00133 ( 00134 ) 00135 { 00136 Game_window *gwin = Game_window::get_instance(); 00137 // Avatar's flag applies to party. 00138 bool freeze = gwin->get_main_actor()->get_flag(Obj_flags::freeze)!=false; 00139 Actor *party[9]; // Get party + Avatar. 00140 int cnt = gwin->get_party(party, 1); 00141 for (int i = 0; i < cnt; i++) 00142 party[i]->check_temperature(freeze); 00143 } 00144 00145 /* 00146 * Increment clock. 00147 * 00148 * FOR NOW, skipping call to mend_npcs(). Not sure... 00149 */ 00150 00151 void Game_clock::increment 00152 ( 00153 int num_minutes // # of minutes to increment. 00154 ) 00155 { 00156 Game_window *gwin = Game_window::get_instance(); 00157 int new_3hour, old_3hour, delta_3hour; 00158 long new_min; 00159 00160 old_3hour = hour/3; // Remember current 3-hour period. 00161 num_minutes += time_factor/2; // Round to nearest 15 minutes. 00162 num_minutes -= num_minutes%time_factor; 00163 new_min = minute + num_minutes; 00164 hour += new_min/60; // Update hour. 00165 minute = new_min%60; 00166 day += hour/24; // Update day. 00167 hour %= 24; 00168 00169 // Update palette to new time. 00170 set_time_palette(); 00171 new_3hour = hour/3; // New 3-hour period. 00172 delta_3hour = new_3hour - old_3hour; 00173 if (delta_3hour != 0) // In a new period? 00174 { // Update NPC schedules. 00175 if (Game::get_game_type() == SERPENT_ISLE) 00176 delta_3hour = 8; 00177 gwin->schedule_npcs(new_3hour, (delta_3hour +7)%8); 00178 } 00179 } 00180 00181 /* 00182 * Advance clock. 00183 */ 00184 00185 void Game_clock::handle_event 00186 ( 00187 unsigned long curtime, // Current time of day. 00188 long udata // ->game window. 00189 ) 00190 { 00191 Game_window *gwin = (Game_window *) udata; 00192 00193 int min_old = minute; 00194 int hour_old = hour; 00195 // Time stopped? Don't advance. 00196 if (!gwin->is_time_stopped()) 00197 { 00198 minute += time_rate; 00199 if (Game::get_game_type() == SERPENT_ISLE) 00200 Check_freezing(); 00201 } 00202 00203 while (minute >= 60) // advance to the correct hour (and day) 00204 { 00205 minute -= 60; 00206 if (++hour >= 24) 00207 { 00208 hour -= 24; 00209 day++; 00210 } 00211 set_time_palette(); 00212 gwin->mend_npcs(); // Restore HP's each hour. 00213 check_hunger(); // Use food, and print complaints. 00214 if (hour%3 == 0) // New 3-hour period? 00215 { 00216 // Update NPC schedules. 00217 gwin->schedule_npcs(hour/3); 00218 } 00219 } 00220 if ((hour != hour_old) || (minute/15 != min_old/15)) 00221 COUT("Clock updated to " << hour << ':' << minute); 00222 curtime += 60*1000/time_factor; // 15 changes per minute 00223 tqueue->add(curtime, this, udata); 00224 } 00225 00226 /* 00227 * Fake an update to the next 3-hour period. 00228 */ 00229 00230 void Game_clock::fake_next_period 00231 ( 00232 ) 00233 { 00234 minute = 0; 00235 hour = ((hour/3 + 1)*3); 00236 day += hour/24; // Update day. 00237 hour %= 24; 00238 Game_window *gwin = Game_window::get_instance(); 00239 set_time_palette(); 00240 check_hunger(); 00241 gwin->schedule_npcs(hour/3); 00242 gwin->mend_npcs(); // Just do it once, cheater. 00243 COUT("The hour is now " << hour); 00244 } 00245
1.5.1