objnames.cc

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2002  The Exult Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (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 <cstdio>
00024 
00025 #include "objs.h"
00026 #include "game.h"
00027 #include "items.h"
00028 #include "gamewin.h"
00029 #include "actors.h"
00030 
00031 using std::string;
00032 #ifndef HAVE_SNPRINTF
00033 extern int snprintf(char *, size_t, const char *, /*args*/ ...);
00034 namespace std {
00035 using ::snprintf;
00036 }
00037 #else
00038 #endif
00039 #ifndef UNDER_CE
00040 using std::strchr;
00041 #endif
00042 
00043 /*
00044  *  For objects that can have a quantity, the name is in the format:
00045  *    %1/%2/%3/%4
00046  *  Where
00047  *    %1 : singular prefix (e.g. "a")
00048  *    %2 : main part of name
00049  *    %3 : singular suffix
00050  *    %4 : plural suffix (e.g. "s")
00051  */
00052 
00053 /*
00054  *  Extracts the first, second and third parts of the name string
00055  */
00056 static void get_singular_name
00057   (
00058   const char *name,   // Raw name string from TEXT.FLX
00059   string& output_name   // Output string
00060   )
00061 {
00062   if(*name != '/')    // Output the first part
00063     {
00064     do
00065       output_name += *name++;
00066     while(*name != '/' && *name != '\0');
00067     if(*name == '\0') // should not happen
00068       {
00069       output_name = "?";
00070       return;
00071       }
00072     // If there is a first part it is followed by a space
00073     output_name += ' ';
00074     }
00075   name++;
00076 
00077           // Output the second part
00078   while(*name != '/' && *name != '\0')
00079     output_name += *name++;
00080   if(*name == '\0')   // should not happen
00081     {
00082     output_name = "?";
00083     return;
00084     }
00085   name++;
00086 
00087           // Output the third part
00088   while(*name != '/' && *name != '\0')
00089     output_name += *name++;
00090   if(*name == '\0')   // should not happen
00091     {
00092     output_name = "?";
00093     return;
00094     }
00095   name++;
00096 }
00097 
00098 /*
00099  *  Extracts the second and fourth parts of the name string
00100  */
00101 static void get_plural_name
00102   (
00103   const char *name,
00104   int quantity,
00105   string& output_name
00106   )
00107 {
00108   char buf[20];
00109 
00110   snprintf(buf, 20, "%d ", quantity); // Output the quantity
00111   output_name = buf;
00112 
00113           // Skip the first part
00114   while(*name != '/' && *name != '\0')
00115     name++;
00116   if(*name == '\0')   // should not happen
00117     {
00118     output_name = "?";
00119     return;
00120     }
00121   name++;
00122           // Output the second part
00123   while(*name != '/' && *name != '\0')
00124     output_name += *name++;
00125   if(*name == '\0')   // should not happen
00126     {
00127     output_name = "?";
00128     return;
00129     }
00130   name++;
00131           // Skip the third part
00132   while(*name != '/' && *name != '\0')
00133     name++;
00134   if(*name == '\0')   // should not happen
00135     {
00136     output_name = "?";
00137     return;
00138     }
00139   name++;
00140   while(*name != '\0')    // Output the last part
00141     output_name += *name++;
00142 }
00143 
00144 /*
00145  *  Returns the string to be displayed when the item is clicked on
00146  */
00147 string Game_object::get_name
00148   (
00149   ) const
00150 {
00151   int quantity;
00152   string display_name;
00153   int shnum = get_shapenum();
00154   int frnum = get_framenum();
00155   int qual = get_quality();
00156   int index = -1;
00157   if (GAME_BG) {
00158     //TODO: yourself 
00159     switch (shnum)      // Some special cases!
00160     {
00161     case 0x34a:     // Reagents
00162       index = 0x500 + frnum;
00163       break;
00164     case 0x3bb:     // Amulets
00165       if (frnum < 3)
00166         index = 0x508 + frnum;
00167       else
00168         index = shnum;
00169       break;
00170     case 0x179:     // Food items
00171       index = 0x50b + frnum;
00172       break;
00173     case 0x28a:     // Sextants
00174       index = 0x52c - frnum;
00175       break;
00176     case 0x2a3:     // Desk items
00177       index = 0x52d + frnum;
00178       break;
00179     case 0x390:         // "Blood"
00180       if (frnum < 4)
00181         index = 0x390;
00182       else
00183         index = -1;
00184       break;
00185     default:
00186       index = shnum;
00187       break;
00188     }
00189 
00190 
00191   } else if (GAME_SI) {
00192     //TODO: yourself, misc. checks/fixes
00193     
00194     switch (shnum)      // More special cases!
00195     {
00196     case 0x097:         // wall
00197       if (frnum == 17)
00198         index = 0x681;  // door
00199       else
00200         index = shnum;
00201       break;
00202     case 0x98:          // wall
00203       if (frnum == 22)
00204         index = 0x681;  // door
00205       else
00206         index = shnum;
00207       break;
00208     case 0x0b2:     // Cloth maps
00209       if (frnum < 5 || GAME_SS)
00210         index = 0x596 + frnum;
00211       else
00212         index = shnum; // only SS has a description for frame 5
00213       break;
00214     case 0x0d1:     // Artifacts
00215       index = 0x5c0 + frnum;
00216       break;
00217     case 0xd2:          // chicken coop
00218       if (frnum == 4)
00219         index = 0x680; // platform
00220       else
00221         index = shnum;
00222       break;
00223     case 0x0e3:      // cloak
00224       if (frnum <= 4)
00225         index = 0x5ff + frnum;
00226       else
00227         index = shnum;
00228       break;
00229     case 0x0f3:      // coffin
00230       if (frnum >= 7)
00231         index = 0x605; // stone bier
00232       else
00233         index = shnum;
00234       break;
00235     case 0x0f4:     // Large skulls
00236       if (frnum < 2)
00237         index = 0x5d8 + frnum;
00238       else
00239         index = shnum;
00240       break;
00241     case 0x106:     // Blackrock Serpents
00242       if (frnum < 4)
00243         index = 0x592 + frnum;
00244       else
00245         index = shnum;
00246       break;
00247     case 0x11a:       // painting
00248       if (frnum >= 6 && frnum <= 10)
00249         index = 0x60c; // ruined painting
00250       else
00251         index = shnum;
00252       break;
00253     case 0x11d:      // brush
00254       if (frnum == 6)
00255         index = 0x5fa;
00256       else
00257         index = shnum;
00258       break;
00259     case 0x11e:      // drum
00260       if (frnum == 1 || frnum == 2)
00261         index = 0x669; // drumsticks
00262       else
00263         index = shnum;
00264       break;
00265     case 0x124:      // seat
00266       if (frnum == 17 || frnum == 18 || frnum == 19 || frnum == 22)
00267         index = 0x5fc;
00268       else
00269         index = shnum;
00270       break;
00271     case 0x128:     // Rings
00272       index = 0x5b8 + frnum;
00273       break;
00274     case 0x12c:         // cooking utensil
00275       if (frnum <= 7)
00276         index = 0x636 + (frnum/2);
00277       else if (frnum >= 8 && frnum <= 23)
00278         index = 0x63a + (frnum%4);
00279       else if (frnum >= 24)
00280         index = 0x63e + (frnum%2);
00281       break;
00282     case 0x12f:
00283       if (frnum >= 10 && frnum <= 14)
00284         index = 0x60b;
00285       else
00286         index = shnum;
00287       break;
00288     case 0x135:        // fallen tree
00289       if (frnum == 2)
00290         index = 0x635; // large skull
00291       else
00292         index = shnum;
00293       break;
00294     case 0x141:         // reeds
00295       if (frnum == 11)
00296         index = 0x61c; // crucifix
00297       else
00298         index = shnum;
00299       break;
00300     case 0x14a:         // serpent rune
00301       if (frnum < 8)
00302         index = 0x607; // stones
00303       else
00304         index = shnum;
00305       break;
00306     case 0x150:         // light source
00307       index = 0x646 + frnum;
00308       break;
00309     case 0x152:         // lit light source
00310       {
00311       if (num_item_names <= 0x657)
00312         break;
00313       string tmp = item_names[0x657]; // lit
00314       tmp += item_names[0x646 + frnum];
00315       return tmp;
00316       }
00317       break;
00318     case 0x172:         // floor
00319       if (frnum == 19)
00320         index = 0x60e; // wall
00321       else
00322         index = shnum;
00323       break;
00324     case 0x179:     // Food items
00325       index = 0x510 + frnum;
00326       break;
00327     case 0x17a:         // fence
00328       if (frnum == 3 || (frnum > 7 && frnum < 12))
00329         index = 0x60e; // wall
00330       else
00331         index = shnum;
00332       break;
00333     case 0x17f:         // magic helm
00334       if (frnum == 1)
00335         index = 0x614; // helm of courage
00336       else
00337         index = shnum;
00338       break;
00339     case 0x194:         // food
00340       index = 0x640 + frnum;
00341       break;
00342     case 0x19f:         // garbage
00343       if (frnum > 20 && frnum < 24)
00344         index = 0x60f; // skull
00345       else
00346         index = shnum;
00347       break;
00348     case 0x1ba:         // fireplace
00349       if (frnum == 2)
00350         index = 0x620; // wooden post
00351       else
00352         index = shnum;
00353       break;
00354     case 0x1bd:     // Soul prisms
00355       index = 0x56b + frnum;
00356       break;
00357     case 0x1c2:     // Orbs
00358       index = 0x585 + frnum;
00359       break;
00360     case 0x1d3:     // Magic plants
00361       index = 0x581 + frnum/2;
00362       break;
00363     case 0x1db:         // wall of lights
00364       if (frnum == 10)
00365         index = 0x683; // wall
00366       else
00367         index = shnum;
00368       break;
00369     case 0x1df:         // claw + gwani amulet
00370       index = 0x5f8 + frnum/2;
00371       break;
00372     case 0x1e3:         // rug
00373       if (frnum >= 2)
00374         index = 0x608; // meditation mat
00375       else
00376         index = shnum;
00377       break;
00378     case 0x1f9:         // magic lens
00379       if (frnum == 2)
00380         index = 0x615; // lens of translating
00381       else
00382         index = shnum;
00383       break;
00384     case 0x201:         // floor
00385       if (frnum == 5)
00386         index = 0x60d; // bookshelf
00387       else
00388         index = shnum;
00389       break;
00390     case 0x206:         // glass counter top
00391       if (frnum == 26)
00392         index = 0x682; // table
00393       else
00394         index = shnum;
00395       break;
00396     case 0x207:         // Moon's Eye
00397       if (frnum == 1)
00398         index = 0x616; // crystal ball
00399       else
00400         index = shnum;
00401       break;
00402     case 0x21a:         // fence
00403       if (frnum == 3 || (frnum > 7 && frnum < 12))
00404         index = 0x60e; // wall
00405       else
00406         index = shnum;
00407       break;
00408     case 0x21e:     // Crested Helmets
00409       index = 0x5a3 + frnum;
00410       break;
00411     case 0x220:         // broken column
00412       if (frnum == 14)
00413         index = 0x611; // pillar of purity
00414       else
00415         index = shnum;
00416       break;
00417     case 0x241:     // Nests
00418       if (frnum < 6)
00419         index = 0x5ab + frnum/3;
00420       else
00421         index = shnum;
00422       break;
00423     case 0x24b:     // Boots
00424       index = 0x59c + frnum;
00425       break;
00426     case 0x268:        // Bottles
00427       switch (frnum) {
00428       case 1:
00429         index = 0x5f2; // wine decanter
00430         break;
00431       case 9:
00432         index = 0x5f3; // fawnish ale
00433         break;
00434       case 16:
00435         index = 0x5f4; // ice wine
00436         break;
00437       case 17:
00438         index = 0x5f5; // vintage wine
00439         break;
00440       case 18:
00441         index = 0x5f6; // wineskin
00442         break;
00443         case 20:
00444         index = 0x5f7; // everlasting goblet
00445         break;
00446       default:
00447         index = shnum;
00448       }
00449       break;
00450     case 0x281:         // key
00451       switch (frnum) {
00452       case 21:
00453         index = 0x630; // key of fire
00454         break;
00455       case 22:
00456         index = 0x631; // key of ice
00457         break;
00458       case 23:
00459         index = 0x62f; // blackrock key
00460         break;
00461       default:
00462         index = shnum;
00463       }
00464       break;
00465     case 0x288:         // sleeping powder
00466       if (frnum >= 2)
00467         index = 0x65c - 2 + frnum;
00468       else
00469         index = shnum;
00470       break;
00471     case 0x289:     // Artifacts
00472       index = 0x573 + frnum;
00473       break;
00474     case 0x28a:     // Sextants
00475       index = 0x531 - frnum;
00476       break;
00477     case 0x290:         // wine press
00478       if (frnum == 1)
00479         index = 0x634; // wine vat
00480       else
00481         index = shnum;
00482       break;
00483     case 0x2a1:         // strange plant
00484       if (frnum > 8)
00485         index = 0x62c; // snowy plant
00486       else
00487         index = shnum;
00488       break;
00489     case 0x2a3:     // Desk items
00490       index = 0x532 + frnum;
00491       break;
00492     case 0x2a5:         // stockings
00493       if (frnum < 2)
00494         index = 0x62a + frnum;
00495       else
00496         index = shnum;
00497       break;
00498     case 0x2af:         // pillar
00499       if (frnum == 11)
00500         index = 0x611; // pillar of purity
00501       else
00502         index = shnum;
00503       break;
00504     case 0x2b0:         // serpent carving
00505       if (frnum > 1)
00506         index = 0x621 - 1 + (frnum/2);
00507       else
00508         index = shnum;
00509       break;
00510     case 0x2b4:     // Lute
00511       if (frnum == 2)
00512         index = 0x5be;
00513       else
00514         index = shnum;
00515       break;
00516     case 0x2b5:        // whistle
00517       if (frnum == 1)
00518         index = 0x617; // whistle
00519       else if (frnum == 4 || frnum == 5)
00520         index = 0x618; // bone flute
00521       else
00522         index = shnum;
00523       break;
00524     case 0x2b8:        // bed
00525       if (frnum == 1)
00526         index = 0x5da; // stone bier
00527       else if (frnum == 2)
00528         index = 0x5db; // cot
00529       else if (frnum == 4)
00530         index = 0x5dc; // pallet
00531       else if (frnum == 5)
00532         index = 0x5dd; // fur pallet
00533       else
00534         index = shnum;
00535       break;
00536     case 0x2cd:        // plate
00537       if (frnum == 9)
00538         index = 0x61a; // platter of replenishment
00539       else
00540         index = shnum;
00541       break;
00542     case 0x2ce:        // pedestal
00543       if (frnum == 8)
00544         index = 0x619; // blackrock obelisk
00545       else
00546         index = shnum;
00547       break;
00548     case 0x2d7:        // Dream Crystal
00549       if (frnum <= 1)
00550         index = 0x659; // dream crystal
00551       else if (frnum == 2)
00552         index = 0x65a; // mirror rock
00553       else if (frnum >= 3)
00554         index = 0x65b; // icy column
00555       break;
00556     case 0x2d8:        // Force_Wall
00557       // TODO: CHECK
00558       if (frnum > 0)
00559         index = 0x683; // wall
00560       else
00561         index = shnum;
00562       break;
00563     case 0x2f4:        // caltrops
00564       if (frnum == 2 || frnum == 3)
00565         index = 0x5fb; // broken glass
00566       else
00567         index = shnum;
00568       break;
00569     case 0x313:        // lever
00570       if (frnum == 8 || frnum == 9)
00571         index = 0x613; // button
00572       else
00573         index = shnum;
00574       break;
00575     case 0x314:        // switch
00576       if (frnum >= 6 && frnum <= 9)
00577         index = 0x613; // button
00578       else
00579         index = shnum;
00580       break;
00581     case 0x31f:        // Body parts
00582       index = 0x5df + frnum;
00583       break;
00584     case 0x320:      // chest
00585       if (frnum == 4 || frnum == 5)
00586         index = 0x5fd;
00587       else if (frnum == 6 || frnum == 7)
00588         index = 0x5fe;
00589       else
00590         index = shnum;
00591       break;
00592     case 0x32a:     // Bucket
00593       if (frnum == 1 && qual >= 10 && qual <= 15)
00594         index = 0x55b + qual;
00595       else if (frnum == 2 && qual == 9)
00596         index = 0x55b + qual;
00597       else
00598         index = 0x55b + frnum;
00599       break;
00600     case 0x347:     // Hourglass
00601       if (frnum == 1)
00602         index = 0x5bf;
00603       else
00604         index = shnum;
00605       break;
00606     case 0x34a:     // Reagents
00607       index = 0x500 + frnum;
00608       break;
00609     case 0x35f:         // kitchen items
00610       index = 0x66b + frnum;
00611       break;
00612     case 0x365:         // wall
00613       if (frnum == 11)
00614         index = 0x610; // spirit wall
00615       else
00616         index = shnum;
00617       break;
00618     case 0x36c:         // sliding door
00619       if (frnum >= 10 && frnum <= 14)
00620         index = 0x60b; // iris door
00621       else
00622         index = shnum;
00623       break;
00624     case 0x377:     // More rings
00625       index = 0x5bc + frnum;
00626       break;
00627     case 0x37a:         // table
00628       if (frnum == 6)
00629         index = 0x62e; // torture table
00630       else
00631         index = shnum;
00632       break;
00633     case 0x390:         // blood
00634       if (frnum == 24)
00635         index = 0x5de; // acid
00636       else if (frnum < 4)
00637         index = 0x390; // blood
00638       else
00639         index = -1;
00640       break;
00641     case 0x392:         // urn
00642       if (frnum <= 1) {
00643         // when frame = 0,1, the quality is an NPC num
00644         // the item name is then the name of that NPC + "'s ashes"
00645         // (quality == 0,255: 'urn of ashes')
00646         Actor* npc = gwin->get_npc(get_quality());
00647         if (get_quality() > 0 && npc && !npc->is_unused()) {
00648           string tmp = npc->get_npc_name();
00649           if (tmp != "" && num_item_names>0x65e) {
00650             tmp += item_names[0x65e]; // 's ashes
00651             return tmp;
00652           }
00653         }
00654         index = 0x632; // urn with ashes
00655       } else if (frnum == 2)
00656         index = 0x633; // pot of unguent
00657       else
00658         index = shnum;
00659       break;
00660     case 0x397:         // bookshelf
00661       if (frnum == 6)
00662         index = 0x60a; // slate mantle
00663       else
00664         index = shnum;
00665       break;
00666     case 0x39f:         // serpent slot
00667       if (frnum >= 4 && frnum <= 7)
00668         index = 0x61e; // slotted serpent
00669       else
00670         index = shnum;
00671       break;
00672     case 0x3a7:         // sliding door
00673       if (frnum == 2)
00674         index = 0x60b; // iris door
00675       else
00676         index = shnum;
00677       break;
00678     case 0x3a8:         // sliding door
00679       if (frnum == 2)
00680         index = 0x60b; // iris door
00681       else
00682         index = shnum;
00683       break;
00684     case 0x3b0:         // pot
00685       if (frnum == 5)
00686         index = 0x61b; // cuspidor
00687       else
00688         index = shnum;
00689       break;
00690     case 0x3bb:     // Amulets
00691       index = 0x5ae + frnum;
00692       break;
00693     case 0x3d1:         // fur pelt
00694       if (frnum == 0 || frnum == 8)
00695         index = 0x61f; // leopard rug
00696       else
00697         index = shnum;
00698       break;
00699     case 0x3e5:         // spent light source
00700       {
00701       if (num_item_names <= 0x658)
00702         break;
00703       string tmp = item_names[0x658]; // spent
00704       tmp += item_names[0x646 + frnum];
00705       return tmp;
00706       }
00707       break;
00708     case 0x3e6:         // statue
00709       if (frnum <= 3)
00710         index = 0x628 + (frnum/2);
00711       else
00712         index = shnum;
00713       break;
00714     case 0x3e7:         // plant
00715       index = 0x65f + frnum;
00716       break;
00717     case 0x3ea:         // table
00718       if (frnum == 1)
00719         index = 0x62d; // embalming table
00720       else
00721         index = shnum;
00722       break;
00723     case 0x3ec:     // Helmets
00724       index = 0x5a6 + frnum;
00725       break;
00726     case 0x3f3:     // Beds
00727       if (frnum == 1)
00728         index = 0x5da; // stone bier
00729       else if (frnum == 2)
00730         index = 0x5db; // cot
00731       else if (frnum == 4)
00732         index = 0x5dc; // pallet
00733       else if (frnum == 5)
00734         index = 0x5dd; // fur pallet
00735       else
00736         index = shnum;
00737       break;
00738     case 0x3f8:         // floor
00739       if (frnum == 20 || frnum == 21)
00740         index = 0x623; // symbol of balance
00741       else if (frnum == 22)
00742         index = 0x624; // symbol of order
00743       else if (frnum == 23)
00744         index = 0x625; // symbol of chaos
00745       else
00746         index = shnum;
00747       break;
00748     default:
00749       index = shnum;
00750       break;
00751     }
00752 
00753     // no Silver Seed?
00754     if (!GAME_SS) {
00755       if (index >= 0x605) {
00756         index -= 11;
00757       } else if (index >= 0x5bc) {
00758         index -= 10;
00759       } else if (index >= 0x5b8) {
00760         index -= 9;
00761       } else if (index >= 0x59c) {
00762         index -= 8;
00763       } else if (index >= 0x592) {
00764         index -= 7;
00765       } else if (index >= 0x581) {
00766         index -= 2;
00767       }
00768     }
00769 
00770   } else {
00771     index = shnum;
00772   }
00773 
00774   const char *name = (index >= 0 && index < num_item_names) ?
00775             item_names[index] : 0;
00776   if(name == 0) {
00777     return "";
00778 //    return "?";
00779   }
00780 
00781     if (ShapeID::get_info(shnum).has_quantity())
00782     quantity = quality & 0x7f;
00783   else
00784     quantity = 1;
00785 
00786   // If there are no slashes then it is simpler
00787   if(strchr(name, '/') == 0)
00788     {
00789     if(quantity <= 1)
00790       display_name = name;
00791     else
00792       {
00793       char buf[50];
00794 
00795       snprintf(buf, 50, "%d %s", quantity, name);
00796       display_name = buf;
00797       }
00798     }
00799   else if(quantity <= 1)    // quantity might be zero?
00800     get_singular_name(name, display_name);
00801   else
00802     get_plural_name(name, quantity, display_name);
00803   return display_name;
00804 }
00805 

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