00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "CameraProcess.h"
00022 #include "World.h"
00023 #include "CurrentMap.h"
00024 #include "Item.h"
00025 #include "Actor.h"
00026 #include "UCMachine.h"
00027 #include "ShapeInfo.h"
00028 #include "Kernel.h"
00029 #include "CoreApp.h"
00030 #include "getObject.h"
00031 #include <cstdlib>
00032
00033 #include "IDataSource.h"
00034 #include "ODataSource.h"
00035
00036
00037 DEFINE_RUNTIME_CLASSTYPE_CODE(CameraProcess,Process);
00038
00039
00040
00041
00042 CameraProcess *CameraProcess::camera = 0;
00043 sint32 CameraProcess::earthquake = 0;
00044 sint32 CameraProcess::eq_x = 0;
00045 sint32 CameraProcess::eq_y = 0;
00046
00047 CameraProcess::CameraProcess() : Process()
00048 {
00049
00050 }
00051
00052 CameraProcess::~CameraProcess()
00053 {
00054 if (camera == this)
00055 camera = 0;
00056 }
00057
00058 uint16 CameraProcess::SetCameraProcess(CameraProcess *cam)
00059 {
00060 if (!cam) cam = new CameraProcess(0);
00061 if (camera) camera->terminate();
00062 camera = cam;
00063 return Kernel::get_instance()->addProcess(camera);
00064 }
00065
00066 void CameraProcess::ResetCameraProcess()
00067 {
00068 if (camera) camera->terminate();
00069 camera = 0;
00070 }
00071
00072 void CameraProcess::GetCameraLocation(sint32 &x, sint32 &y, sint32 &z)
00073 {
00074 if (!camera)
00075 {
00076 World *world = World::get_instance();
00077 CurrentMap *map = world->getCurrentMap();
00078 int map_num = map->getNum();
00079 Actor* av = getActor(1);
00080
00081 if (!av || av->getMapNum() != map_num)
00082 {
00083 x = 8192;
00084 y = 8192;
00085 z = 64;
00086 }
00087 else
00088 av->getLocation(x,y,z);
00089
00090 if (earthquake)
00091 {
00092 x += 2*eq_x + 4*eq_y;
00093 y += -2*eq_x + 4*eq_y;
00094 }
00095 }
00096 else
00097 {
00098 camera->GetLerped(x, y, z, 256, true);
00099 }
00100 }
00101
00102
00103
00104
00105
00106
00107 CameraProcess::CameraProcess(uint16 _itemnum) :
00108 time(0), elapsed(0), itemnum(_itemnum), last_framenum(0)
00109 {
00110 GetCameraLocation(sx,sy,sz);
00111
00112 if (itemnum)
00113 {
00114 Item *item = getItem(itemnum);
00115
00116
00117 if (item)
00118 {
00119 item->setExtFlag(Item::EXT_CAMERA);
00120 item->getLocation(ex,ey,ez);
00121 ez += 20;
00122 }
00123 return;
00124 }
00125
00126
00127 itemnum = 0;
00128 ex = sx; ey = sy; ez = sz;
00129 }
00130
00131
00132 CameraProcess::CameraProcess(sint32 _x, sint32 _y, sint32 _z) :
00133 ex(_x), ey(_y), ez(_z), time(0), elapsed(0), itemnum(0), last_framenum(0)
00134 {
00135 GetCameraLocation(sx,sy,sz);
00136 }
00137
00138
00139 CameraProcess::CameraProcess(sint32 _x, sint32 _y, sint32 _z, sint32 _time) :
00140 ex(_x), ey(_y), ez(_z), time(_time), elapsed(0), itemnum(0), last_framenum(0)
00141 {
00142 GetCameraLocation(sx,sy,sz);
00143
00144
00145 }
00146
00147 void CameraProcess::terminate()
00148 {
00149 if (itemnum)
00150 {
00151 Item *item = getItem(itemnum);
00152 if (item) item->clearExtFlag(Item::EXT_CAMERA);
00153 }
00154
00155 Process::terminate();
00156 }
00157
00158 bool CameraProcess::run(const uint32 )
00159 {
00160 if (earthquake)
00161 {
00162 eq_x = (std::rand()%(earthquake*2+1))-earthquake;
00163 eq_y = (std::rand()%(earthquake*2+1))-earthquake;
00164 }
00165 else
00166 {
00167 eq_x = 0;
00168 eq_y = 0;
00169 }
00170
00171 if (time && elapsed>time)
00172 {
00173 result = 0;
00174 CameraProcess::SetCameraProcess(0);
00175 return false;
00176 }
00177
00178 elapsed++;
00179
00180 return true;
00181 }
00182
00183 void CameraProcess::ItemMoved()
00184 {
00185 if (itemnum)
00186 {
00187 Item *item = getItem(itemnum);
00188
00189
00190 if (item && (item->getExtFlags() & Item::EXT_LERP_NOPREV))
00191 {
00192 item->getLocation(ex,ey,ez);
00193 sx = ex;
00194 sy = ey;
00195 sz = ez += 20;
00196
00197 World::get_instance()->getCurrentMap()->updateFastArea(sx,sy,sz,ex,ey,ez);
00198 }
00199 }
00200 }
00201
00202 void CameraProcess::GetLerped(sint32 &x, sint32 &y, sint32 &z, sint32 factor, bool noupdate)
00203 {
00204 if (time == 0)
00205 {
00206 if (!noupdate) {
00207
00208 bool inBetween = true;
00209
00210 if (last_framenum != elapsed)
00211 {
00212
00213 if ((elapsed-last_framenum)>1) factor = 256;
00214 last_framenum = elapsed;
00215 inBetween = false;
00216 }
00217
00218 if (!inBetween)
00219 {
00220 sx = ex;
00221 sy = ey;
00222 sz = ez;
00223
00224 if (itemnum)
00225 {
00226 Item *item = getItem(itemnum);
00227
00228 if (item)
00229 {
00230 sx = ex;
00231 sy = ey;
00232 sz = ez;
00233 item->getLocation(ex,ey,ez);
00234 ez += 20;
00235 }
00236 }
00237
00238 World::get_instance()->getCurrentMap()->updateFastArea(sx,sy,sz,ex,ey,ez);
00239 }
00240 }
00241
00242 if (factor == 256)
00243 {
00244 x = ex; y = ey; z = ez;
00245 }
00246 else if (factor == 0)
00247 {
00248 x = sx; y = sy; z = sz;
00249 }
00250 else
00251 {
00252
00253 x = ((sx*(256-factor) + ex*factor)>>8);
00254 y = ((sy*(256-factor) + ey*factor)>>8);
00255 z = ((sz*(256-factor) + ez*factor)>>8);
00256 }
00257 }
00258 else
00259 {
00260
00261 sint32 sfactor = elapsed;
00262 sint32 efactor = elapsed+1;
00263
00264 if (sfactor > time) sfactor = time;
00265 if (efactor > time) efactor = time;
00266
00267 sint32 lsx = ((sx*(time-sfactor) + ex*sfactor)/time);
00268 sint32 lsy = ((sy*(time-sfactor) + ey*sfactor)/time);
00269 sint32 lsz = ((sz*(time-sfactor) + ez*sfactor)/time);
00270
00271 sint32 lex = ((sx*(time-efactor) + ex*efactor)/time);
00272 sint32 ley = ((sy*(time-efactor) + ey*efactor)/time);
00273 sint32 lez = ((sz*(time-efactor) + ez*efactor)/time);
00274
00275
00276 if (!noupdate) World::get_instance()->getCurrentMap()->updateFastArea(lsx,lsy,lsz,lex,ley,lez);
00277
00278
00279 x = ((lsx*(256-factor) + lex*factor)>>8);
00280 y = ((lsy*(256-factor) + ley*factor)>>8);
00281 z = ((lsz*(256-factor) + lez*factor)>>8);
00282 }
00283
00284 if (earthquake)
00285 {
00286 x += 2*eq_x + 4*eq_y;
00287 y += -2*eq_x + 4*eq_y;
00288 }
00289 }
00290
00291 uint16 CameraProcess::FindRoof(sint32 factor)
00292 {
00293 sint32 x,y,z;
00294 sint32 earthquake_old = earthquake;
00295 earthquake = 0;
00296 GetLerped(x,y,z,factor);
00297 earthquake = earthquake_old;
00298 Item *avatar = getItem(1);
00299 sint32 dx,dy,dz;
00300 avatar->getFootpadWorld(dx,dy,dz);
00301 uint16 roofid;
00302 World::get_instance()->getCurrentMap()->isValidPosition(x, y, z-10, dx/2, dy/2, dz/2, 0, 1, 0, &roofid);
00303 return roofid;
00304 }
00305
00306 void CameraProcess::saveData(ODataSource* ods)
00307 {
00308 Process::saveData(ods);
00309
00310 ods->write4(static_cast<uint32>(sx));
00311 ods->write4(static_cast<uint32>(sy));
00312 ods->write4(static_cast<uint32>(sz));
00313 ods->write4(static_cast<uint32>(ex));
00314 ods->write4(static_cast<uint32>(ey));
00315 ods->write4(static_cast<uint32>(ez));
00316 ods->write4(static_cast<uint32>(time));
00317 ods->write4(static_cast<uint32>(elapsed));
00318 ods->write2(itemnum);
00319 ods->write4(last_framenum);
00320 ods->write4(static_cast<uint32>(earthquake));
00321 ods->write4(static_cast<uint32>(eq_x));
00322 ods->write4(static_cast<uint32>(eq_y));
00323 }
00324
00325 bool CameraProcess::loadData(IDataSource* ids, uint32 version)
00326 {
00327 if (!Process::loadData(ids, version)) return false;
00328
00329 sx = static_cast<sint32>(ids->read4());
00330 sy = static_cast<sint32>(ids->read4());
00331 sz = static_cast<sint32>(ids->read4());
00332 ex = static_cast<sint32>(ids->read4());
00333 ey = static_cast<sint32>(ids->read4());
00334 ez = static_cast<sint32>(ids->read4());
00335 time = static_cast<sint32>(ids->read4());
00336 elapsed = static_cast<sint32>(ids->read4());
00337 itemnum = ids->read2();
00338 last_framenum = ids->read4();
00339 earthquake = static_cast<sint32>(ids->read4());
00340 eq_x = static_cast<sint32>(ids->read4());
00341 eq_y = static_cast<sint32>(ids->read4());
00342
00343 camera = this;
00344
00345 return true;
00346 }
00347
00348
00349 uint32 CameraProcess::I_move_to(const uint8* args, unsigned int )
00350 {
00351 ARG_UINT16(x);
00352 ARG_UINT16(y);
00353 ARG_UINT8(z);
00354 ARG_SINT16(unk);
00355 CameraProcess::SetCameraProcess(new CameraProcess(x,y,z));
00356 return 0;
00357 }
00358
00359
00360 uint32 CameraProcess::I_setCenterOn(const uint8* args, unsigned int )
00361 {
00362 ARG_OBJID(itemnum);
00363 CameraProcess::SetCameraProcess(new CameraProcess(itemnum));
00364 return 0;
00365 }
00366
00367
00368 uint32 CameraProcess::I_scrollTo(const uint8* args, unsigned int )
00369 {
00370 ARG_UINT16(x);
00371 ARG_UINT16(y);
00372 ARG_UINT8(z);
00373 ARG_SINT16(unk);
00374 return CameraProcess::SetCameraProcess(new CameraProcess(x,y,z, 25));
00375 }
00376
00377
00378 uint32 CameraProcess::I_startQuake(const uint8* args, unsigned int )
00379 {
00380 ARG_UINT16(strength);
00381 SetEarthquake(strength);
00382 return 0;
00383 }
00384
00385
00386 uint32 CameraProcess::I_stopQuake(const uint8* , unsigned int )
00387 {
00388 SetEarthquake(0);
00389 return 0;
00390 }
00391