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 "FireballProcess.h"
00022 #include "Item.h"
00023 #include "CurrentMap.h"
00024 #include "MainActor.h"
00025 #include "Kernel.h"
00026 #include "ItemFactory.h"
00027 #include "Direction.h"
00028 #include "WeaponInfo.h"
00029 #include "getObject.h"
00030
00031 #include "IDataSource.h"
00032 #include "ODataSource.h"
00033
00034
00035 DEFINE_RUNTIME_CLASSTYPE_CODE(FireballProcess,Process);
00036
00037 FireballProcess::FireballProcess()
00038 : Process()
00039 {
00040
00041 }
00042
00043 FireballProcess::FireballProcess(Item* item, Item* target_)
00044 : xspeed(0), yspeed(0), age(0)
00045 {
00046 assert(item);
00047 assert(target_);
00048
00049 tail[0] = 0;
00050 tail[1] = 0;
00051 tail[2] = 0;
00052
00053 item_num = item->getObjId();
00054
00055 target = target_->getObjId();
00056
00057 type = 0x218;
00058 }
00059
00060 bool FireballProcess::run(uint32 )
00061 {
00062 age++;
00063
00064 Item* item = getItem(item_num);
00065 if (!item) {
00066 terminate();
00067 return false;
00068 }
00069
00070 Item* t = getItem(target);
00071 if (!t) {
00072 terminate();
00073 return false;
00074 }
00075
00076 if (age > 300 && (std::rand() % 20 == 0)) {
00077
00078 terminate();
00079 return false;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 sint32 x,y,z;
00092 sint32 tx,ty,tz;
00093 sint32 dx,dy;
00094 item->getLocation(x,y,z);
00095 t->getLocationAbsolute(tx,ty,tz);
00096
00097 dx = tx - x;
00098 dy = ty - y;
00099
00100 int targetdir = item->getDirToItemCentre(*t);
00101
00102 if (xspeed == 0 && yspeed == 0 && dx / 64 == 0 && dy / 64 == 0) {
00103 xspeed += 2 * x_fact[targetdir];
00104 yspeed += 2 * y_fact[targetdir];
00105 } else {
00106 xspeed += (dx / 64);
00107 yspeed += (dy / 64);
00108 }
00109
00110
00111 int speed = static_cast<int>(sqrt(static_cast<float>(xspeed*xspeed + yspeed*yspeed)));
00112 if (speed > 32) {
00113 xspeed = (xspeed * 32) / speed;
00114 yspeed = (yspeed * 32) / speed;
00115 }
00116
00117 ObjId hititem = 0;
00118 item->collideMove(x+xspeed, y+yspeed, z, false, false, &hititem);
00119
00120
00121
00122 if (tail[2] == 0) {
00123
00124 Item* newtail = ItemFactory::createItem(261, 0, 0,
00125 Item::FLG_DISPOSABLE, 0, 0,
00126 Item::EXT_SPRITE, true);
00127 tail[2] = newtail->getObjId();
00128 }
00129
00130 Item* tailitem = getItem(tail[2]);
00131 tailitem->setFrame(Get_WorldDirection(yspeed,xspeed));
00132 tailitem->move(x,y,z);
00133
00134 tail[2] = tail[1];
00135 tail[1] = tail[0];
00136 tail[0] = tailitem->getObjId();
00137
00138 if (hititem) {
00139 Actor* hit = getActor(hititem);
00140 if (hit) {
00141
00142 hit->receiveHit(0, 8 - targetdir, 5 + (std::rand()%5),
00143 WeaponInfo::DMG_FIRE);
00144 terminate();
00145 return true;
00146
00147 } else {
00148
00149
00150 xspeed = -xspeed;
00151 yspeed = -yspeed;
00152 }
00153 }
00154
00155 return true;
00156 }
00157
00158 void FireballProcess::terminate()
00159 {
00160
00161 Process::terminate();
00162
00163 explode();
00164 }
00165
00166 void FireballProcess::explode()
00167 {
00168 Item* item = getItem(item_num);
00169 if (item) item->destroy();
00170
00171 for (unsigned int i = 0; i < 3; ++i) {
00172 item = getItem(tail[i]);
00173 if (item) item->destroy();
00174 }
00175 }
00176
00177 uint32 FireballProcess::I_TonysBalls(const uint8* args,
00178 unsigned int )
00179 {
00180 ARG_NULL16();
00181 ARG_NULL16();
00182 ARG_SINT16(x);
00183 ARG_SINT16(y);
00184 ARG_UINT16(z);
00185
00186 Item* ball = ItemFactory::createItem(260, 4, 0, Item::FLG_FAST_ONLY,
00187 0, 0, 0, true);
00188 if (!ball) {
00189 perr << "I_TonysBalls failed to create item (260, 4)." << std::endl;
00190 return 0;
00191 }
00192 if (!ball->canExistAt(x, y, z)) {
00193 perr << "I_TonysBalls: failed to create fireball." << std::endl;
00194 ball->destroy();
00195 return 0;
00196 }
00197 ball->move(x, y, z);
00198
00199 MainActor* avatar = getMainActor();
00200
00201 FireballProcess* fbp = new FireballProcess(ball, avatar);
00202 Kernel::get_instance()->addProcess(fbp);
00203
00204 return 0;
00205 }
00206
00207 void FireballProcess::saveData(ODataSource* ods)
00208 {
00209 Process::saveData(ods);
00210
00211 ods->write4(static_cast<uint32>(xspeed));
00212 ods->write4(static_cast<uint32>(yspeed));
00213 ods->write2(target);
00214 ods->write2(tail[0]);
00215 ods->write2(tail[1]);
00216 ods->write2(tail[2]);
00217 ods->write2(age);
00218 }
00219
00220 bool FireballProcess::loadData(IDataSource* ids, uint32 version)
00221 {
00222 if (!Process::loadData(ids, version)) return false;
00223
00224 xspeed = static_cast<int>(ids->read4());
00225 yspeed = static_cast<int>(ids->read4());
00226 target = ids->read2();
00227 tail[0] = ids->read2();
00228 tail[1] = ids->read2();
00229 tail[2] = ids->read2();
00230 age = ids->read2();
00231
00232 return true;
00233 }