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 "MissileTracker.h"
00022
00023 #include "CurrentMap.h"
00024 #include "Item.h"
00025 #include "World.h"
00026 #include "getObject.h"
00027
00028 MissileTracker::MissileTracker(Item* item, sint32 sx, sint32 sy, sint32 sz,
00029 sint32 tx, sint32 ty, sint32 tz,
00030 sint32 speed, sint32 gravity_)
00031 {
00032 objid = item->getObjId();
00033 destx = tx;
00034 desty = ty;
00035 destz = tz;
00036 gravity = gravity_;
00037
00038 init(sx, sy, sz, speed);
00039 }
00040
00041 MissileTracker::MissileTracker(Item* item, sint32 tx, sint32 ty, sint32 tz,
00042 sint32 speed, sint32 gravity_)
00043 {
00044 assert(item->getParent() == 0);
00045
00046 objid = item->getObjId();
00047 destx = tx;
00048 desty = ty;
00049 destz = tz;
00050 gravity = gravity_;
00051
00052 sint32 x,y,z;
00053 item->getLocation(x,y,z);
00054
00055 init(x, y, z, speed);
00056 }
00057
00058 void MissileTracker::init(sint32 x, sint32 y, sint32 z, sint32 speed)
00059 {
00060 int range = abs(x - destx) + abs(y - desty);
00061
00062
00063 frames = (range + (speed/2)) / speed;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 if (frames > 0) {
00088 speedz = ((gravity * frames * (frames-1) / 2) + destz - z) / frames;
00089
00090
00091 if (speedz > speed/4) {
00092 if (gravity == 0 || (speed / (4*gravity)) <= frames) {
00093 if (speed >= 4 && (destz-z)/(speed/4) > frames)
00094 frames = (destz-z)/(speed/4);
00095 } else {
00096 frames = speed/(4*gravity);
00097 }
00098 }
00099
00100 speedz = ((gravity * frames * (frames-1) / 2) + destz - z) / frames;
00101
00102
00103 speedx = ((destx - x) + (frames/2)) / frames;
00104 speedy = ((desty - y) + (frames/2)) / frames;
00105
00106 #if 0
00107 pout.printf("MissileTracker: from (%d,%d,%d) to (%d,%d,%d)\n", x, y, z, destx, desty, destz);
00108 pout.printf("speed: %d, gravity: %d, frames: %d\n", speed, gravity, frames);
00109 pout.printf("resulting speed: (%d,%d,%d)\n", speedx, speedy, speedz);
00110 #endif
00111 } else {
00112
00113
00114 if (destz > z)
00115 speedz = speed/4;
00116 else
00117 speedz = -speed/4;
00118
00119 }
00120 }
00121
00122 MissileTracker::~MissileTracker()
00123 {
00124
00125 }
00126
00127 bool MissileTracker::isPathClear()
00128 {
00129 sint32 start[3];
00130 sint32 end[3];
00131 sint32 dims[3];
00132 sint32 sx,sy,sz;
00133
00134 sx = speedx;
00135 sy = speedy;
00136 sz = speedz;
00137
00138 World *world = World::get_instance();
00139 CurrentMap *map = world->getCurrentMap();
00140 Item* item = getItem(objid);
00141
00142 item->getFootpadWorld(dims[0], dims[1], dims[2]);
00143 item->getLocation(start[0], start[1], start[2]);
00144
00145 for (int f = 0; f < frames; ++f) {
00146 end[0] = start[0] + sx;
00147 end[1] = start[1] + sy;
00148 end[2] = start[2] + sz;
00149
00150
00151 std::list<CurrentMap::SweepItem> collisions;
00152 std::list<CurrentMap::SweepItem>::iterator it;
00153 map->sweepTest(start, end, dims, item->getShapeInfo()->flags, objid,
00154 false, &collisions);
00155
00156 sint32 hit = 0x4000;
00157 for (it = collisions.begin(); it != collisions.end(); it++)
00158 {
00159 if (it->blocking && !it->touching) {
00160 hit = it->hit_time;
00161 break;
00162 }
00163 }
00164 if (hit != 0x4000) {
00165
00166 return false;
00167 }
00168
00169 sz -= gravity;
00170 for (int i = 0; i < 3; ++i) start[i] = end[i];
00171 }
00172
00173 return true;
00174 }
00175
00176
00177 void MissileTracker::launchItem()
00178 {
00179 Item* item = getItem(objid);
00180 if (!item) return;
00181
00182 item->hurl(speedx, speedy, speedz, gravity);
00183 }