FireballProcess.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2004-2005 The Pentagram team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // p_dynamic_cast stuff
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; // CONSTANT!
00058 }
00059 
00060 bool FireballProcess::run(uint32 /*framenum*/)
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                 // chance of 5% to disappear every frame after 10 seconds
00078                 terminate();
00079                 return false;
00080         }
00081 
00082         // * accelerate a bit towards target
00083         // * try to move
00084         // * if succesful:
00085         //   * move
00086         //   * shift tail, enlarging if smaller than 3 flames
00087         // * if failed
00088         //   * deal damage if hit Actor
00089         //   * turn around if hit non-Actor
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         // limit speed
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         // handle tail
00121         // tail is shape 261, frame 0-7 (0 = to top-right, 7 = to top)
00122         if (tail[2] == 0) {
00123                 // enlarge tail
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                         // hit an actor: deal damage and explode
00142                         hit->receiveHit(0, 8 - targetdir, 5 + (std::rand()%5),
00143                                                         WeaponInfo::DMG_FIRE);
00144                         terminate();
00145                         return true;
00146 
00147                 } else {
00148                         // hit an object: invert direction
00149 
00150                         xspeed = -xspeed;
00151                         yspeed = -yspeed;
00152                 }
00153         }
00154 
00155         return true;
00156 }
00157 
00158 void FireballProcess::terminate()
00159 {
00160         // terminate first to prevent item->destroy() from terminating us again
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 /*argsize*/)
00179 {
00180         ARG_NULL16(); // unknown
00181         ARG_NULL16(); // unknown
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 }

Generated on Fri Jul 27 22:27:14 2007 for pentagram by  doxygen 1.4.7