Paperdoll_gump.cc

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2000 The Exult 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 #ifdef HAVE_CONFIG_H
00020 #  include <config.h>
00021 #endif
00022 
00023 #include "game.h"
00024 #include "gamewin.h"
00025 #include "Gump_button.h"
00026 #include "misc_buttons.h"
00027 #include "Paperdoll_gump.h"
00028 #include "contain.h"
00029 #include "actors.h"
00030 #include "objiter.h"
00031 #include "cheat.h"
00032 
00033 #ifndef ALPHA_LINUX_CXX
00034 #  include <cstdio>
00035 #endif
00036 
00037 using std::cerr;
00038 using std::endl;
00039 using std::size_t;
00040 
00041 //#define SHOW_USECODE_CONTAINER
00042 //#define SHOW_NONREADIED_OBJECTS
00043 
00044 /*
00045  *
00046  *  SERPENT ISLE PAPERDOLL GUMP
00047  *
00048  */
00049 
00050 /*
00051  *  Statics:
00052  */
00053 
00054 // Paperdoll is completely different to Actor
00055 short Paperdoll_gump::diskx = 123, Paperdoll_gump::disky = 137;
00056 short Paperdoll_gump::heartx = 97, Paperdoll_gump::hearty = 137;
00057 short Paperdoll_gump::combatx = 51, Paperdoll_gump::combaty = 142;
00058 short Paperdoll_gump::cstatx = 72, Paperdoll_gump::cstaty = 137;
00059 short Paperdoll_gump::cmodex = 75, Paperdoll_gump::cmodey = 140;
00060 short Paperdoll_gump::halox = 123, Paperdoll_gump::haloy = 120;
00061 
00062 short Paperdoll_gump::coords[36] = {
00063   76, 20,   /* head */  115, 27,  /* back */
00064   105, 65,  /* belt */  38, 55,   /* lhand */
00065   55, 62,   /* lfinger */ 80, 80,   /* legs */
00066   84, 105,  /* feet */  90, 50,   /* rfinger */
00067   117, 55,  /* rhand */ 45, 35,   /* torso */
00068   44, 26,   /* neck */  69, 59,   /* ammo */
00069   59, 19,   /* back2 */ 94, 20,   /* back 3 (shield) */
00070   76, 26,   /* ears */  76, 33,   /* cloak */
00071   73, 53,   /* gloves */  0, 0    /* usecode container */
00072 };
00073 short Paperdoll_gump::coords_blue[36] = {
00074   76, 20,   /* head */  64, 27,   /* back */
00075   54, 56,   /* belt */  30, 58,   /* lhand */
00076   55, 62,   /* lfinger */ 80, 80,   /* legs */
00077   84, 105,  /* feet */  90, 50,   /* rfinger */
00078   68, 50,   /* rhand */ 45, 37,   /* torso */
00079   22, 26,   /* neck */  69, 59,   /* ammo */
00080   59, 19,   /* back2 */ 94, 20,   /* back 3 (shield) */
00081   76, 26,   /* ears */  76, 33,   /* cloak */
00082   73, 53,   /* gloves */  0, 0    /* usecode container */
00083 };
00084 short Paperdoll_gump::shapes_blue[36] = {
00085   54, 0,    /* head */  54, 0,    /* back */
00086   54, 0,    /* belt */  55, 0,    /* lhand */
00087   55, 0,    /* lfinger */ 54, 0,    /* legs */
00088   54, 0,    /* feet */  54, 0,    /* rfinger */
00089   54, 0,    /* rhand */ 55, 0,    /* torso */
00090   54, 0,    /* neck */  54, 0,    /* ammo */
00091   55, 0,    /* back2 */ 54, 0,    /* back 3 (shield) */
00092   54, 0,    /* ears */  54, 0,    /* cloak */
00093   54, 0,    /* gloves */  54, 0   /* usecode container */
00094 };
00095 short Paperdoll_gump::coords_hot[36] = {
00096   76, 20,   /* head */  94, 27,   /* back */
00097   92,  61,  /* belt */  38, 55,   /* lhand */
00098   55, 62,   /* lfinger */ 80, 80,   /* legs */
00099   84, 105,  /* feet */  90, 50,   /* rfinger */
00100   117, 55,  /* rhand */ 83, 43,   /* torso */
00101   76, 41,   /* neck */  69, 59,   /* ammo */
00102   59, 19,   /* back2 */ 94, 20,   /* back 3 (shield) */
00103   76, 26,   /* ears */  76, 33,   /* cloak */
00104   73, 53,   /* gloves */  0, 0    /* usecode container */
00105 };
00106 
00107 
00108 
00109 //
00110 // Paperdoll Coords
00111 //
00112   
00113 short Paperdoll_gump::bodyx = 46, Paperdoll_gump::bodyy = 33;
00114 short Paperdoll_gump::headx = 46, Paperdoll_gump::heady = 22;
00115 
00116 short Paperdoll_gump::beltfx = 58, Paperdoll_gump::beltfy = 52;
00117 short Paperdoll_gump::neckfx = 46, Paperdoll_gump::neckfy = 47;
00118 short Paperdoll_gump::beltmx = 57, Paperdoll_gump::beltmy = 55;
00119 short Paperdoll_gump::neckmx = 46, Paperdoll_gump::neckmy = 44;
00120 
00121 short Paperdoll_gump::legsx = 57, Paperdoll_gump::legsy = 66;
00122 short Paperdoll_gump::feetx = 46, Paperdoll_gump::feety = 99;
00123 
00124 short Paperdoll_gump::handsx = 68, Paperdoll_gump::handsy = 44;
00125 short Paperdoll_gump::rhandx = 68, Paperdoll_gump::rhandy = 44;
00126 short Paperdoll_gump::lhandx = 34, Paperdoll_gump::lhandy = 65;
00127 
00128 short Paperdoll_gump::ahandx = 28, Paperdoll_gump::ahandy = 59;
00129 short Paperdoll_gump::ammox = 28, Paperdoll_gump::ammoy = 59;
00130 
00131 short Paperdoll_gump::backfx = 68, Paperdoll_gump::backfy = 28;
00132 short Paperdoll_gump::back2fx = 34, Paperdoll_gump::back2fy = 22;
00133 short Paperdoll_gump::backmx = 68, Paperdoll_gump::backmy = 22;
00134 short Paperdoll_gump::back2mx = 35, Paperdoll_gump::back2my = 22;
00135 short Paperdoll_gump::shieldfx = 56, Paperdoll_gump::shieldfy = 25;
00136 short Paperdoll_gump::shieldmx = 57, Paperdoll_gump::shieldmy = 22;
00137 
00138 
00139 /*
00140  *  Find the index of the closest 'spot' to a mouse point.
00141  *
00142  *  Output: Index, or -1 if unsuccessful.
00143  */
00144 
00145 int Paperdoll_gump::find_closest
00146   (
00147   int mx, int my,     // Mouse point in window.
00148   int only_empty      // Only allow empty spots.
00149   )
00150 {
00151   mx -= x; my -= y;   // Get point rel. to us.
00152   long closest_squared = 1000000; // Best distance squared.
00153   int closest = -1;   // Best index.
00154   int spot;
00155 
00156   for (size_t i = 0; i < sizeof(coords_hot)/(2*sizeof(coords_hot[0])); i++)
00157   {
00158     if (Game::get_game_type() == BLACK_GATE && i > Actor::shield_spot)
00159       continue;
00160 
00161     spot = i;
00162 
00163     int dx = mx - coords_hot[spot*2], dy = my - coords_hot[spot*2+1];
00164     long dsquared = dx*dx + dy*dy;
00165 
00166     // map some SI spots to the BG belt
00167     if (GAME_BG && i == Actor::shield_spot)
00168       spot = Actor::belt;
00169     else if (GAME_BG && i == Actor::back2h_spot)
00170       spot = Actor::belt;
00171 
00172     // Better than prev and free if required.?
00173     if (dsquared < closest_squared && !(only_empty && container->get_readied(spot)))
00174     {
00175       closest_squared = dsquared;
00176       closest = spot;
00177     }
00178   }
00179 
00180   return (closest);
00181 }
00182 
00183 /*
00184  *  Create the gump display for an actor.
00185  */
00186 
00187 Paperdoll_gump::Paperdoll_gump
00188   (
00189   Container_game_object *cont,  // Container it represents.
00190   int initx, int inity,     // Coords. on screen.
00191   int shnum     // Shape #.
00192   ) : Gump(cont, initx, inity, 123, SF_PAPERDOL_VGA)
00193 {
00194   set_object_area(Rectangle(26, 0, 104, 140), 6, 145);
00195 
00196   // Create Heart button
00197   heart_button = new Heart_button(this, heartx, hearty);
00198   Actor *actor = (Actor *) cont;
00199   // Create Cstats button or Halo and Cmode
00200   if (Game::get_game_type() == BLACK_GATE)
00201   {
00202     if (actor->get_npc_num() == 0)
00203       halo_button = new Halo_button(this, halox, haloy, 
00204                   actor);
00205     else
00206       halo_button = new Halo_button(this, diskx, disky,
00207                   actor);
00208 
00209     cmode_button = new Combat_mode_button(this, cmodex, cmodey, 
00210                   actor);
00211     cstats_button = NULL;
00212   }
00213   else
00214   {
00215     cstats_button = new Cstats_button(this, cstatx, cstaty);
00216     halo_button = NULL;
00217     cmode_button = NULL;
00218   }
00219 
00220 
00221 
00222   // If Avatar create Disk Button
00223   if (actor->get_npc_num() == 0)
00224     disk_button = new Disk_button(this, diskx, disky);
00225   else
00226     disk_button = NULL;
00227     
00228 
00229   // If Avtar create Combat Button
00230   if (actor->get_npc_num() == 0)
00231     combat_button = new Combat_button(this, combatx, combaty);
00232   else
00233     combat_button = NULL;
00234 
00235 
00236   // Put all the objects in the right place
00237   for (size_t i = 0; i < sizeof(coords)/2*sizeof(coords[0]); i++)
00238   {
00239     Game_object *obj = container->get_readied(i);
00240     if (obj)
00241       set_to_spot(obj, i);
00242   }
00243 }
00244 
00245 /*
00246  *  Delete actor display.
00247  */
00248 
00249 Paperdoll_gump::~Paperdoll_gump
00250   (
00251   )
00252 {
00253   if (heart_button) delete heart_button;
00254   if (disk_button) delete disk_button;
00255   if (combat_button) delete combat_button;
00256   if (cstats_button) delete cstats_button;
00257   if (halo_button) delete halo_button;
00258   if (cmode_button) delete cmode_button;
00259 }
00260 
00261 /*
00262  *  Is a given screen point on one of our buttons?
00263  *
00264  *  Output: ->button if so.
00265  */
00266 
00267 Gump_button *Paperdoll_gump::on_button
00268   (
00269   int mx, int my      // Point in window.
00270   )
00271 {
00272   Gump_button *btn = Gump::on_button(mx, my);
00273   if (btn)
00274     return btn;
00275   else if (heart_button && heart_button->on_button(mx, my))
00276     return heart_button;
00277   else if (disk_button && disk_button->on_button(mx, my))
00278     return disk_button;
00279   else if (combat_button && combat_button->on_button(mx, my))
00280     return combat_button;
00281   else if (cstats_button && cstats_button->on_button(mx, my))
00282     return cstats_button;
00283   else if (halo_button && halo_button->on_button(mx, my))
00284     return halo_button;
00285   else if (cmode_button && cmode_button->on_button(mx, my))
00286     return cmode_button;
00287   return 0;
00288 }
00289 
00290 /*
00291  *  Add an object.
00292  *
00293  *  Output: 0 if cannot add it.
00294  */
00295 
00296 int Paperdoll_gump::add
00297   (
00298   Game_object *obj,
00299   int mx, int my,     // Screen location of mouse.
00300   int sx, int sy,     // Screen location of obj's hotspot.
00301   bool dont_check,    // Skip volume check.
00302   bool combine      // True to try to combine obj.  MAY
00303           //   cause obj to be deleted.
00304   )
00305 {
00306   Game_object *cont = find_object(mx, my);
00307   
00308   if (cont && cont->add(obj, false, combine))
00309     return (1);
00310   
00311   int index = find_closest(mx, my, 1);
00312   
00313   if (index != -1 && container->add_readied(obj, index))
00314     return (1);
00315 
00316   if (container->add(obj, dont_check, combine))
00317     return (1);
00318 
00319   return (0);
00320 }
00321 
00322 /*
00323  *  Set object's coords. to given spot.
00324  */
00325 
00326 void Paperdoll_gump::set_to_spot
00327   (
00328   Game_object *obj,
00329   int index     // Spot index.
00330   )
00331 {
00332   
00333   // Get shape.
00334   Shape_frame *shape = obj->get_shape();
00335   //if (!shape)     // Funny?  Try frame 0.
00336   //  shape = gwin->get_shape(obj->get_shapenum(), 0);
00337   if (!shape)
00338     return;
00339 
00340   // Height and width
00341   int w = shape->get_width(), h = shape->get_height();
00342   
00343   // Set object's position.
00344   obj->set_chunk(spotx(index) + shape->get_xleft() - w/2 - object_area.x,
00345     spoty(index) + shape->get_yabove() - h/2 - object_area.y);
00346 }
00347 
00348 /*
00349  *  Paint on screen.
00350  */
00351 
00352 void Paperdoll_gump::paint
00353   (
00354   )
00355 {
00356   Game_object *obj;
00357 
00358   // Paint Objects
00359   Rectangle box = object_area;  // Paint objects inside.
00360   box.shift(x, y);    // Set box to screen location.
00361 
00362   paint_shape(x, y);
00363 
00364   // Paint red "checkmark".
00365   check_button->paint();
00366 
00367   // Get the information required about ourself
00368   Actor *actor = container->as_actor();
00369   Paperdoll_npc *info = GetCharacterInfo (container->get_shapenum());
00370   if (!info) info = GetCharacterInfo (actor->get_sexed_coloured_shape());
00371   if (!info) info = GetCharacterInfo (actor->get_shape_real());
00372   if (!info && Game::get_game_type() != BLACK_GATE) info = Characters;
00373   else if (!info) info = Characters_BG;
00374 
00375   // Spots that are female/male specific
00376   int shieldx, shieldy,
00377     back2x,  back2y,
00378     backx,   backy,
00379     neckx,   necky,
00380     beltx,   belty;
00381 
00382   if (info->is_female)    // Set the female spots
00383   {
00384     shieldx = shieldfx;
00385     shieldy = shieldfy;
00386     back2x = back2fx;
00387     back2y = back2fy;
00388     backx = backfx;
00389     backy = backfy;
00390     neckx = neckfx;
00391     necky = neckfy;
00392     beltx = beltfx;
00393     belty = beltfy;
00394   }
00395   else        // Set the male spots
00396   {
00397     shieldx = shieldmx;
00398     shieldy = shieldmy;
00399     back2x = back2mx;
00400     back2y = back2my;
00401     backx = backmx;
00402     backy = backmy;
00403     neckx = neckmx;
00404     necky = neckmy;
00405     beltx = beltmx;
00406     belty = beltmy;
00407   }
00408   
00409   // Now paint. Order is very specific
00410 
00411 
00412   if (Game::get_game_type() != BLACK_GATE)
00413   {
00414     paint_object      (box, info, Actor::shield_spot,shieldx,shieldy);
00415     paint_object      (box, info, Actor::back2h_spot, back2x, back2y);
00416     paint_object      (box, info, Actor::back,        backx,  backy);
00417     paint_object      (box, info, Actor::cloak_spot,  bodyx,  bodyy);
00418     paint_body        (box, info);
00419     paint_object      (box, info, Actor::legs,        legsx,  legsy);
00420     paint_object      (box, info, Actor::feet,        feetx,  feety);   
00421     paint_object      (box, info, Actor::ammo,        ammox,  ammoy);
00422     paint_object      (box, info, Actor::torso,       bodyx,  bodyy);
00423     paint_belt        (box, info);
00424     paint_head        (box, info);
00425     paint_object      (box, info, Actor::neck,        neckx,  necky);
00426     paint_object      (box, info, Actor::belt,        beltx,  belty);
00427     paint_arms        (box, info);
00428     paint_object_arms (box, info, Actor::torso,       bodyx,  bodyy, 1, Actor::torso);
00429     paint_object      (box, info, Actor::ears_spot,   headx,  heady);
00430     paint_object      (box, info, Actor::head,        headx,  heady);
00431     paint_object      (box, info, Actor::cloak_spot,  bodyx,  bodyy, 0, Actor::special_spot);
00432     paint_object_arms (box, info, Actor::rfinger,     lhandx, lhandy, 0);
00433     paint_object_arms (box, info, Actor::lfinger,     rhandx, rhandy, 0);
00434     paint_object_arms (box, info, Actor::hands2_spot, handsx, handsy, 0);
00435     paint_object      (box, info, Actor::lhand,       lhandx, lhandy);
00436     paint_object      (box, info, Actor::ammo,        ahandx, ahandy, 2, -1, Actor::lhand);
00437     paint_object      (box, info, Actor::rhand,       rhandx, rhandy);
00438 
00439     // if debugging show usecode container
00440 #ifdef SHOW_USECODE_CONTAINER
00441     paint_object      (box, info, Actor::ucont_spot,  20,      20 );
00442 #endif
00443   }
00444   else
00445   {
00446     Paperdoll_item *item1, *item2;
00447 
00448     paint_object      (box, info, Actor::belt,       shieldx,shieldy, 0, Actor::shield_spot);
00449     paint_object      (box, info, Actor::belt,        back2x, back2y, 0, Actor::back2h_spot);
00450     paint_object      (box, info, Actor::back,        backx,  backy);
00451     paint_object      (box, info, Actor::neck,        bodyx,  bodyy,  0, Actor::cloak_spot);
00452     paint_body        (box, info);
00453     paint_object      (box, info, Actor::legs,        legsx,  legsy);
00454     paint_object      (box, info, Actor::feet,        feetx,  feety);   
00455     paint_object      (box, info, Actor::ammo,        ammox,  ammoy);
00456 
00457     paint_object      (box, info, Actor::torso,       bodyx,  bodyy);
00458     paint_belt        (box, info);
00459     paint_head        (box, info);
00460 
00461     obj = container->get_readied(Actor::neck);
00462     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::cloak_spot);
00463     item2 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::special_spot);
00464     if (!item1 && !item2)
00465       paint_object      (box, info, Actor::neck,        neckx,  necky);
00466 
00467     obj = container->get_readied(Actor::belt);
00468     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::shield_spot);
00469     item2 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::back2h_spot);
00470     if (!item1 && !item2)
00471       paint_object      (box, info, Actor::belt,        beltx,  belty);
00472 
00473     paint_arms        (box, info);
00474     paint_object_arms (box, info, Actor::torso,       bodyx,  bodyy, 1, Actor::torso);
00475     paint_object      (box, info, Actor::head,        headx,  heady);
00476     paint_object      (box, info, Actor::neck,        bodyx,  bodyy, 0, Actor::special_spot);
00477     paint_object_arms (box, info, Actor::rfinger,     lhandx, lhandy, 0);
00478 
00479     obj = container->get_readied(Actor::lfinger);
00480     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::hands2_spot);
00481     if (!item1)
00482       paint_object_arms (box, info, Actor::lfinger,     rhandx, rhandy, 0);
00483     else
00484       paint_object_arms (box, info, Actor::lfinger,     handsx, handsy, 0, Actor::hands2_spot);
00485 
00486     paint_object      (box, info, Actor::lhand,       lhandx, lhandy);
00487     paint_object      (box, info, Actor::ammo,        ahandx, ahandy, 2, -1, Actor::lhand);
00488     paint_object      (box, info, Actor::rhand,       rhandx, rhandy);
00489   }
00490   
00491 #ifdef SHOW_NONREADIED_OBJECTS
00492   Object_iterator iter(container->get_objects());
00493   while ((obj = iter.get_next()) != 0)
00494     if (actor->find_readied(obj) == -1)
00495       obj->paint(box.x, box.y);
00496 #endif
00497 
00498 
00499   // Paint buttons.
00500   if (heart_button) heart_button->paint();
00501   if (disk_button) disk_button->paint();
00502   if (combat_button) combat_button->paint();
00503   if (cstats_button) cstats_button->paint();
00504   if (halo_button) halo_button->paint();
00505   if (cmode_button) cmode_button->paint();
00506 
00507           // Show weight.
00508   int max_weight = container->get_max_weight();
00509   int weight = container->get_weight()/10;
00510   char text[20];
00511   snprintf(text, 20, "%d/%d", weight, max_weight);
00512   int twidth = sman->get_text_width(2, text);
00513   const int boxw = 102;
00514   sman->paint_text(2, text, x + 84 - (twidth/2), y + 114);
00515 }
00516 
00517 
00518 /*
00519  *  Paint a generic object on screen
00520  */
00521 
00522 void Paperdoll_gump::paint_object 
00523   (
00524   const Rectangle &box,   // box
00525   Paperdoll_npc *info,    // info
00526   int spot,     // Actor::belt
00527   int sx, int sy,     // back2x, back2y
00528   int frame,      // 0
00529   int itemtype,     // Actor::back2h_spot
00530   int checkspot,      // -1
00531   int checktype     // -1
00532   )
00533 {
00534   Game_object *obj = container->get_readied(spot);
00535   if (!obj) return;
00536 
00537   int old_it = itemtype;
00538   if (itemtype == -1) itemtype = spot;
00539   
00540   Paperdoll_item *item = GetItemInfo (obj->get_shapenum(), obj->get_framenum(), itemtype);
00541   if (!item || item->frame == -1 || item->shape == -1)
00542   {
00543     if ((old_it != -1 && !item)|| checkspot != -1) return;
00544     //if (!obj->get_cx() && !obj->get_cy()) return;
00545 
00546     set_to_spot(obj, spot);
00547   
00548     ShapeID s(shapes_blue[spot*2], shapes_blue[spot*2+1], SF_GUMPS_VGA);
00549 
00550     if (Game::get_game_type() == BLACK_GATE) s.set_file(SF_BG_SIGUMP_FLX);
00551 
00552     s.paint_shape(box.x + coords_blue[spot*2],
00553         box.y + coords_blue[spot*2+1]);
00554     int ox = box.x + obj->get_cx(), oy = box.y + obj->get_cy();
00555     obj->paint_shape(ox, oy);
00556     if (cheat.is_selected(obj))
00557           // Outline selected obj.
00558       obj->ShapeID::paint_outline(ox, oy, HIT_PIXEL);
00559 
00560     return;
00561   }
00562   else if (checkspot != -1)
00563   {
00564     Game_object *check = container->get_readied(checkspot);
00565     if (!check) return;
00566   
00567     if (checktype == -1) checktype = checkspot;
00568   
00569     Paperdoll_item *item_check = GetItemInfo (check->get_shapenum(), check->get_framenum(), checktype);
00570     if (!item_check || item_check->type != item->type)
00571       return;
00572   }
00573 
00574 
00575   int f = item->frame;
00576 
00577   if (frame == 1)
00578     f = item->frame2;
00579   else if (frame == 2)
00580     f = item->frame3;
00581   else if (frame == 3)
00582     f = item->frame4;
00583     
00584   if (item->gender && !info->is_female) f++;
00585  
00586   ShapeID s(item->shape, f, item->file);
00587   s.paint_shape(box.x + sx, box.y + sy, 1);
00588   if (cheat.is_selected(obj)) // Outline selected obj.
00589     s.paint_outline(box.x + sx, box.y + sy, HIT_PIXEL);
00590 }
00591 
00592 /*
00593  *  Paint with arms frame
00594  */
00595 void Paperdoll_gump::paint_object_arms
00596   (
00597   const Rectangle &box,
00598   Paperdoll_npc *info,
00599   int spot,
00600   int sx, int sy,
00601   int start,
00602   int itemtype
00603   )
00604 {
00605   switch (get_arm_type())
00606   {
00607     default:
00608     paint_object (box, info, spot, sx, sy, start, itemtype);
00609     break;
00610     
00611     case OT_Double:
00612     paint_object (box, info, spot, sx, sy, start+1, itemtype);
00613     break;
00614     
00615     case OT_Staff:
00616     paint_object (box, info, spot, sx, sy, start+2, itemtype);
00617     break;
00618   } 
00619 }
00620 
00621 /*
00622  *  Paint the body
00623  */
00624 void Paperdoll_gump::paint_body 
00625   (
00626   const Rectangle &box,
00627   Paperdoll_npc *info
00628   )
00629 {
00630   ShapeID s(info->body_shape, info->body_frame, SF_PAPERDOL_VGA);
00631   s.paint_shape(box.x + bodyx, box.y + bodyy);
00632 }
00633 
00634 /*
00635  *  Paint the belt
00636  */
00637 void Paperdoll_gump::paint_belt 
00638   (
00639   const Rectangle &box,
00640   Paperdoll_npc *info
00641   )
00642 {
00643   ShapeID s(10, 0, SF_PAPERDOL_VGA);
00644   if (!info->is_female) s.set_frame(1);
00645   s.paint_shape (box.x + beltmx, box.y + beltmy);
00646 }
00647 
00648 /*
00649  *  Paint the head
00650  */
00651 void Paperdoll_gump::paint_head 
00652   (
00653   const Rectangle &box,
00654   Paperdoll_npc *info
00655   )
00656 {
00657   Game_object *obj = container->get_readied(Actor::head);
00658 
00659   Paperdoll_item *item = NULL;
00660   if (obj) item = GetItemInfo (obj->get_shapenum(), obj->get_framenum());
00661 
00662   int f = info->head_frame;
00663 
00664   if (item && item->type == OT_Helm)
00665     f = info->head_frame_helm;
00666 
00667   ShapeID s(info->head_shape, f, info->file);
00668   s.paint_shape(box.x + headx, box.y + heady);
00669 }
00670 
00671 /*
00672  *  Paint the arms
00673  */
00674 void Paperdoll_gump::paint_arms 
00675   (
00676   const Rectangle &box,
00677   Paperdoll_npc *info
00678   )
00679 {
00680   Game_object *obj = container->get_readied(Actor::rhand);
00681 
00682   Paperdoll_item *item = NULL;
00683   if (obj) item = GetItemInfo (obj->get_shapenum(), obj->get_framenum());
00684 
00685   ShapeID s(info->arms_shape, info->arms_frame, SF_PAPERDOL_VGA);
00686 
00687   switch (get_arm_type())
00688   {
00689     case OT_Double:
00690     s.set_frame(info->arms_frame_2h);
00691     break;
00692 
00693     case OT_Staff:
00694     s.set_frame(info->arms_frame_staff);
00695     break;
00696 
00697     default:
00698     break;
00699   }
00700 
00701   s.paint_shape (box.x + bodyx, box.y + bodyy);
00702 }
00703 
00704 
00705 /*
00706  *  Gets which arm frame to use
00707  */
00708 
00709 Paperdoll_gump::Object_type Paperdoll_gump::get_arm_type(void)
00710 {
00711   Game_object *obj = container->get_readied(Actor::lhand);
00712   if (!obj) return OT_Normal;
00713   
00714   Paperdoll_item *item = GetItemInfo (obj->get_shapenum(), obj->get_framenum());
00715 
00716   if (item) return item->type;
00717 
00718   return OT_Normal;
00719 }
00720 
00721 
00722 /*
00723  *  Find object a screen point is on.
00724  *
00725  *  Output: Object found, or null.
00726  */
00727 
00728 Game_object * Paperdoll_gump::find_object
00729   (
00730   int mx, int my      // Mouse pos. on screen.
00731   )
00732 {
00733 
00734   
00735   // Check Objects
00736   Rectangle box = object_area;  // Paint objects inside.
00737   box.shift(x, y);    // Set box to screen location.
00738   mx -= box.x;
00739   my -= box.y;
00740 
00741   // Get the information required about ourself
00742   Actor *actor = container->as_actor();
00743   Paperdoll_npc *info = GetCharacterInfo (container->get_shapenum());
00744   if (!info) info = GetCharacterInfo (actor->get_sexed_coloured_shape());
00745   if (!info) info = GetCharacterInfo (actor->get_shape_real());
00746   if (!info && Game::get_game_type() != BLACK_GATE) info = Characters;
00747   else if (!info) info = Characters_BG;
00748 
00749   int shieldx, shieldy,
00750     back2x,  back2y,
00751     backx,   backy,
00752     neckx,   necky,
00753     beltx,   belty;
00754 
00755   if (info->is_female)
00756   {
00757     shieldx = shieldfx;
00758     shieldy = shieldfy;
00759     back2x = back2fx;
00760     back2y = back2fy;
00761     backx = backfx;
00762     backy = backfy;
00763     neckx = neckfx;
00764     necky = neckfy;
00765     beltx = beltfx;
00766     belty = beltfy;
00767   }
00768   else
00769   {
00770     shieldx = shieldmx;
00771     shieldy = shieldmy;
00772     back2x = back2mx;
00773     back2y = back2my;
00774     backx = backmx;
00775     backy = backmy;
00776     neckx = neckmx;
00777     necky = neckmy;
00778     beltx = beltmx;
00779     belty = beltmy;
00780   }
00781 
00782   Game_object *obj;
00783   
00784   
00785   // Must be done in this order (reverse of rendering)
00786   if (Game::get_game_type() != BLACK_GATE)
00787   {
00788     // if debugging show usecode container
00789 #ifdef SHOW_USECODE_CONTAINER
00790     if (obj = check_object      (mx, my, info, Actor::ucont_spot,  20,      20 ))
00791       return obj;
00792 #endif
00793 
00794     if ((obj = check_object      (mx, my, info, Actor::rhand,       rhandx, rhandy)))
00795       return obj;
00796     if ((obj = check_object      (mx, my, info, Actor::ammo,        ahandx, ahandy, 2, -1, Actor::lhand)))
00797       return obj;
00798     if ((obj = check_object      (mx, my, info, Actor::lhand,       lhandx, lhandy)))
00799       return obj;
00800     if ((obj = check_object_arms (mx, my, info, Actor::hands2_spot, handsx, handsy, 0)))
00801       return obj;
00802     if ((obj = check_object_arms (mx, my, info, Actor::rfinger,     lhandx, lhandy, 0)))
00803       return obj;
00804     if ((obj = check_object_arms (mx, my, info, Actor::lfinger,     rhandx, rhandy, 0)))
00805       return obj;
00806     if ((obj = check_object      (mx, my, info, Actor::cloak_spot,  bodyx,  bodyy,  0, Actor::special_spot)))
00807       return obj;
00808     if ((obj = check_object      (mx, my, info, Actor::head,        headx,  heady)))
00809       return obj;
00810     if ((obj = check_object      (mx, my, info, Actor::ears_spot,   headx,  heady)))
00811       return obj;
00812     if ((obj = check_object_arms (mx, my, info, Actor::torso,       bodyx,  bodyy,  1, Actor::torso)))
00813       return obj;
00814     if (check_arms              (mx, my, info))
00815       return NULL;
00816     if ((obj = check_object      (mx, my, info, Actor::belt,        beltx,  belty)))
00817       return obj;
00818     if ((obj = check_object      (mx, my, info, Actor::neck,        neckx,  necky)))
00819       return obj;
00820     if (check_head              (mx, my, info))
00821       return NULL;
00822     if (check_belt              (mx, my, info))
00823       return NULL;
00824     if ((obj = check_object      (mx, my, info, Actor::torso,       bodyx,  bodyy)))
00825       return obj;
00826     if ((obj = check_object      (mx, my, info, Actor::ammo,        ammox,  ammoy)))
00827       return obj;
00828     if ((obj = check_object      (mx, my, info, Actor::feet,        feetx,  feety)))  
00829       return obj;
00830     if ((obj = check_object      (mx, my, info, Actor::legs,        legsx,  legsy)))
00831       return obj;
00832     if (check_body        (mx, my, info))
00833       return NULL;
00834     if ((obj = check_object      (mx, my, info, Actor::cloak_spot,  bodyx,  bodyy)))
00835       return obj;
00836     if ((obj = check_object      (mx, my, info, Actor::back,        backx,  backy)))
00837       return obj;
00838     if ((obj = check_object      (mx, my, info, Actor::back2h_spot, back2x, back2y)))
00839       return obj;
00840     if ((obj = check_object      (mx, my, info, Actor::shield_spot,shieldx,shieldy)))
00841       return obj;
00842   }
00843   else
00844   {
00845     Paperdoll_item *item1, *item2;
00846 
00847     if ((obj = check_object      (mx, my, info, Actor::rhand,       rhandx, rhandy)))
00848       return obj;
00849     if ((obj = check_object      (mx, my, info, Actor::ammo,        ahandx, ahandy, 2, -1, Actor::lhand)))
00850       return obj;
00851     if ((obj = check_object      (mx, my, info, Actor::lhand,       lhandx, lhandy)))
00852       return obj;
00853 
00854     obj = container->get_readied(Actor::lfinger);
00855     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::hands2_spot);
00856     if (!item1 && (obj = check_object_arms (mx, my, info, Actor::lfinger,     rhandx, rhandy, 0)))
00857       return obj;
00858     else if ((obj = check_object_arms (mx, my, info, Actor::lfinger,     rhandx, rhandy, 0, Actor::hands2_spot)))
00859       return obj;
00860 
00861     if ((obj = check_object_arms (mx, my, info, Actor::rfinger,     lhandx, lhandy, 0)))
00862       return obj;
00863     if ((obj = check_object      (mx, my, info, Actor::neck,        bodyx,  bodyy,  0, Actor::special_spot)))
00864       return obj;
00865     if ((obj = check_object      (mx, my, info, Actor::head,        headx,  heady)))
00866       return obj;
00867     if ((obj = check_object_arms (mx, my, info, Actor::torso,       bodyx,  bodyy,  1, Actor::torso)))
00868       return obj;
00869     if (check_arms              (mx, my, info))
00870       return NULL;
00871 
00872     obj = container->get_readied(Actor::belt);
00873     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::shield_spot);
00874     item2 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::back2h_spot);
00875     if (!item1 && !item2 && (obj = check_object      (mx, my, info, Actor::belt,        beltx,  belty)))
00876       return obj;
00877 
00878     obj = container->get_readied(Actor::neck);
00879     item1 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::cloak_spot);
00880     item2 = !obj?NULL:GetItemInfo (obj->get_shapenum(), obj->get_framenum(), Actor::special_spot);
00881     if (!item1 && !item2 && (obj = check_object      (mx, my, info, Actor::neck,        neckx,  necky)))
00882       return obj;
00883 
00884     if (check_head              (mx, my, info))
00885       return NULL;
00886     if (check_belt              (mx, my, info))
00887       return NULL;
00888     if ((obj = check_object      (mx, my, info, Actor::torso,       bodyx,  bodyy)))
00889       return obj;
00890 
00891     if ((obj = check_object      (mx, my, info, Actor::ammo,        ammox,  ammoy)))
00892       return obj;
00893     if ((obj = check_object      (mx, my, info, Actor::feet,        feetx,  feety)))  
00894       return obj;
00895     if ((obj = check_object      (mx, my, info, Actor::legs,        legsx,  legsy)))
00896       return obj;
00897 
00898     if (check_body        (mx, my, info))
00899       return NULL;
00900       
00901     if ((obj = check_object      (mx, my, info, Actor::neck,       bodyx,  bodyy, 0, Actor::cloak_spot)))
00902       return obj;
00903     if ((obj = check_object      (mx, my, info, Actor::back,        backx,  backy)))
00904       return obj;
00905 
00906     if ((obj = check_object      (mx, my, info, Actor::belt,        back2x, back2y, 0, Actor::back2h_spot)))
00907       return obj;
00908     if ((obj = check_object      (mx, my, info, Actor::belt,       shieldx,shieldy, 0, Actor::shield_spot)))
00909       return obj;
00910   }
00911   return NULL;
00912 }
00913 
00914 /*
00915  *  Checks for a generic object on screen
00916  */
00917 
00918 Game_object * Paperdoll_gump::check_object 
00919   (
00920   int mx, int my,
00921   Paperdoll_npc *info,
00922   int spot,
00923   int sx, int sy,
00924   int frame,
00925   int itemtype,
00926   int checkspot,
00927   int checktype
00928   )
00929 {
00930   Game_object *obj = container->get_readied(spot);
00931   if (!obj) return NULL;
00932   
00933   int old_it = itemtype;
00934   if (itemtype == -1) itemtype = spot;
00935   
00936   Paperdoll_item *item = GetItemInfo (obj->get_shapenum(), obj->get_framenum(), itemtype);
00937   if (!item || item->frame == -1 || item->shape == -1)
00938   {
00939     if ((old_it != -1 &&!item) || checkspot != -1) return 0;
00940     
00941     if (!obj->get_cx() && !obj->get_cy()) set_to_spot(obj, spot);
00942     
00943     if (check_shape (mx - obj->get_cx(), my - obj->get_cy(),
00944       obj->get_shapenum(), obj->get_framenum(), obj->get_shapefile()))
00945     {
00946       return obj;
00947     }
00948         
00949     return NULL;
00950   }
00951   else if (checkspot != -1)
00952   {
00953     Game_object *check = container->get_readied(checkspot);
00954     if (!check) return NULL;
00955   
00956     if (checktype == -1) checktype = checkspot;
00957   
00958     Paperdoll_item *item_check = GetItemInfo (check->get_shapenum(), check->get_framenum(), checktype);
00959     if (!item_check || item_check->type != item->type)
00960       return NULL;
00961   }
00962 
00963 
00964   int f = item->frame;
00965 
00966   if (frame == 1)
00967     f = item->frame2;
00968   else if (frame == 2)
00969     f = item->frame3;
00970   else if (frame == 3)
00971     f = item->frame4;
00972     
00973   if (item->gender && !info->is_female) f++;
00974 
00975   if (check_shape (mx - sx, my - sy, item->shape, f, item->file))
00976   {
00977     Shape_frame *shape = obj->get_shape();
00978     int w = shape->get_width(), h = shape->get_height();
00979           // Set object's position.
00980     obj->set_chunk(mx + shape->get_xleft() - w/2, my + shape->get_yabove() - h/2);
00981     
00982     return obj;
00983   }
00984   
00985   return NULL;
00986 }
00987 
00988 /*
00989  *  Checks for object with arms frame
00990  */
00991 Game_object * Paperdoll_gump::check_object_arms
00992   (
00993   int mx, int my,
00994   Paperdoll_npc *info,
00995   int spot,
00996   int sx, int sy,
00997   int start,
00998   int itemtype
00999   )
01000 {
01001   switch (get_arm_type())
01002   {
01003     default:
01004     return check_object (mx, my, info, spot, sx, sy, start, itemtype);
01005     
01006     case OT_Double:
01007     return check_object (mx, my, info, spot, sx, sy, start+1, itemtype);
01008     
01009     case OT_Staff:
01010     return check_object (mx, my, info, spot, sx, sy, start+2, itemtype);
01011   } 
01012   return NULL;
01013 }
01014 
01015 /*
01016  *  Checks for the body
01017  */
01018 bool Paperdoll_gump::check_body 
01019   (
01020   int mx, int my,
01021   Paperdoll_npc *info
01022   )
01023 {
01024   return check_shape (mx - bodyx, my - bodyy, info->body_shape, info->body_frame, SF_PAPERDOL_VGA);
01025 }
01026 
01027 /*
01028  *  Checks for the belt
01029  */
01030 bool Paperdoll_gump::check_belt 
01031   (
01032   int mx, int my,
01033   Paperdoll_npc *info
01034   )
01035 {
01036   if (info->is_female) return check_shape (mx - beltfx, my - beltfy, 10, 0, SF_PAPERDOL_VGA);
01037   else return check_shape (mx - beltmx, my - beltmy, 10, 1, SF_PAPERDOL_VGA);
01038 
01039   return false;
01040 }
01041 
01042 /*
01043  *  Checks for the head
01044  */
01045 bool Paperdoll_gump::check_head 
01046   (
01047   int mx, int my,
01048   Paperdoll_npc *info
01049   )
01050 {
01051   Game_object *obj = container->get_readied(Actor::head);
01052 
01053   Paperdoll_item *item = NULL;
01054   if (obj) item = GetItemInfo (obj->get_shapenum(), obj->get_framenum());
01055 
01056   int f = info->head_frame;
01057 
01058   if (item && item->type == OT_Helm)
01059     f = info->head_frame_helm;
01060 
01061   return check_shape (mx - headx, my - heady, info->head_shape, f, info->file);
01062 }
01063 
01064 /*
01065  *  Checks for the arms
01066  */
01067 bool Paperdoll_gump::check_arms 
01068   (
01069   int mx, int my,
01070   Paperdoll_npc *info
01071   )
01072 {
01073   Game_object *obj = container->get_readied(Actor::rhand);
01074 
01075   Paperdoll_item *item = NULL;
01076   if (obj) item = GetItemInfo (obj->get_shapenum(), obj->get_framenum());
01077 
01078   switch (get_arm_type())
01079   {
01080     default:
01081     return check_shape (mx - bodyx, my - bodyy, info->arms_shape, info->arms_frame, SF_PAPERDOL_VGA);
01082 
01083     case OT_Double:
01084     return check_shape (mx - bodyx, my - bodyy, info->arms_shape, info->arms_frame_2h, SF_PAPERDOL_VGA);
01085 
01086     case OT_Staff:
01087     return check_shape (mx - bodyx, my - bodyy, info->arms_shape, info->arms_frame_staff, SF_PAPERDOL_VGA);
01088   }
01089   return false;
01090 }
01091 
01092 /*
01093  *  Generic Shaper checking
01094  */
01095 bool Paperdoll_gump::check_shape
01096   (
01097   int px, int py,
01098   int shape, int frame,
01099   ShapeFile file
01100   )
01101 {
01102   ShapeID sid(shape, frame, file);
01103   Shape_frame *s = sid.get_shape();
01104   
01105   // If no shape, return
01106   if (!s) return false;
01107 
01108   Rectangle r = gwin->get_shape_rect (s, 0, 0);
01109   
01110   // If point not in rectangle, return
01111   if (!r.has_point (px, py)) return false;
01112   
01113   // If point not in shape, return
01114   if (!s->has_point (px, py)) return false;
01115   
01116   return true;
01117 }
01118 
01119 Container_game_object *Paperdoll_gump::find_actor(int mx, int my)
01120 {
01121   return container;
01122 }

Generated on Mon Jul 9 14:42:46 2007 for ExultEngine by  doxygen 1.5.1