00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024
00025 #ifndef ALPHA_LINUX_CXX
00026 # include <cstdlib>
00027 #endif
00028 #include "npcnear.h"
00029 #include "gamewin.h"
00030 #include "actors.h"
00031 #include "ucmachine.h"
00032 #include "schedule.h"
00033 #include "items.h"
00034 #include "game.h"
00035 #include "cheat.h"
00036
00037 #include "SDL_timer.h"
00038
00039 #ifndef UNDER_CE
00040 using std::rand;
00041 #endif
00042
00043 bool Bg_dont_wake(Game_window *gwin, Actor *npc);
00044
00045
00046
00047
00048
00049 void Npc_proximity_handler::add
00050 (
00051 unsigned long curtime,
00052 Npc_actor *npc,
00053 int additional_secs
00054 )
00055 {
00056 int msecs;
00057 if (npc->get_alignment() >= Npc_actor::hostile)
00058 msecs = rand() % 2000;
00059 else
00060 msecs = (rand() % 4000) + 2000;
00061 unsigned long newtime = curtime + msecs;
00062 newtime += 1000*additional_secs;
00063 gwin->get_tqueue()->add(newtime, this, reinterpret_cast<long>(npc));
00064 }
00065
00066
00067
00068
00069
00070 void Npc_proximity_handler::remove
00071 (
00072 Npc_actor *npc
00073 )
00074 {
00075 npc->clear_nearby();
00076 gwin->get_tqueue()->remove(this, reinterpret_cast<long>(npc));
00077 }
00078
00079
00080
00081
00082
00083 bool Bg_dont_wake
00084 (
00085 Game_window *gwin,
00086 Actor *npc
00087 )
00088 {
00089 int num;
00090 return (Game::get_game_type() == BLACK_GATE &&
00091 (npc->get_info().has_translucency() ||
00092
00093 (num = npc->Actor::get_npc_num()) == 141 || num == 150));
00094 }
00095
00096
00097
00098
00099
00100 void Npc_proximity_handler::handle_event
00101 (
00102 unsigned long curtime,
00103 long udata
00104 )
00105 {
00106 Npc_actor *npc = (Npc_actor *) udata;
00107 int extra_delay = 5;
00108
00109 Rectangle tiles = gwin->get_win_tile_rect().enlarge(10);
00110 Tile_coord t = npc->get_tile();
00111 if (!tiles.has_point(t.tx, t.ty) ||
00112 npc->is_dead())
00113 {
00114 npc->clear_nearby();
00115 return;
00116 }
00117 Schedule::Schedule_types sched = (Schedule::Schedule_types)
00118 npc->get_schedule_type();
00119
00120 if (npc->get_schedule() &&
00121 sched == Schedule::sleep &&
00122
00123 !npc->get_flag(Obj_flags::asleep) &&
00124 gwin->is_main_actor_inside() &&
00125 !Bg_dont_wake(gwin, npc) &&
00126 npc->distance(gwin->get_main_actor()) < 6 && rand()%3 != 0)
00127 {
00128
00129
00130 npc->get_schedule()->ending(Schedule::stand);
00131 npc->say(first_awakened, last_awakened);
00132
00133 npc->start(0, 10000);
00134 extra_delay = 11;
00135 }
00136
00137 else if (!(curtime < wait_until) && !cheat.in_map_editor() &&
00138
00139
00140 (rand()%2 == 1 || npc->get_shapenum() == 811) &&
00141
00142 !npc->is_in_party() &&
00143
00144 sched != Schedule::walk_to_schedule &&
00145
00146
00147 (Game::get_game_type() != SERPENT_ISLE ||
00148 (sched != Schedule::patrol &&
00149 sched != Schedule::wait &&
00150 sched != Schedule::horiz_pace &&
00151 sched != Schedule::vert_pace &&
00152 !npc->is_monster())))
00153
00154 {
00155 int ucfun = npc->get_usecode();
00156 gwin->get_usecode()->call_usecode(ucfun, npc,
00157 Usecode_machine::npc_proximity);
00158 extra_delay += 3;
00159 curtime = Game::get_ticks();
00160 }
00161 add(curtime, npc, extra_delay);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 void Npc_proximity_handler::wait
00171 (
00172 int secs
00173 )
00174 {
00175 wait_until = Game::get_ticks() + 1000*secs;
00176 }
00177
00178
00179
00180
00181
00182 void Npc_proximity_handler::get_all
00183 (
00184 Actor_queue& alist
00185 )
00186 {
00187 Time_queue_iterator next(gwin->get_tqueue(), this);
00188 Time_sensitive *obj;
00189 long data;
00190 while (next(obj, data))
00191 alist.push((Npc_actor *) data);
00192 }