src/hcode/btech/aero.bomb.c

Go to the documentation of this file.
00001 /*
00002  * Author: Markus Stenberg <fingon@iki.fi>
00003  *
00004  *  Copyright (c) 1997 Markus Stenberg
00005  *  Copyright (c) 1998-2002 Thomas Wouters
00006  *  Copyright (c) 2000-2002 Cord Awtry
00007  *       All rights reserved
00008  *
00009  * Created: Mon Jan  6 15:57:35 1997 fingon
00010  * Last modified: Mon Jun  8 19:49:25 1998 fingon
00011  *
00012  */
00013 
00014 #define GMOD 1                                  /* Acceleration / second, in Z hexes */
00015 
00016 #include "mech.h"
00017 #include "aero.bomb.h"
00018 #include "coolmenu.h"
00019 #include "mycool.h"
00020 #include "mech.events.h"
00021 #include "math.h"
00022 #include "create.h"
00023 #include "p.mech.utils.h"
00024 #include "p.artillery.h"
00025 #include "p.econ_cmds.h"
00026 
00027 BOMBINFO bombs[] = {
00028         {"10_Inferno", 10, 1, 30}
00029         ,
00030         {"10_Cluster", 10, 2, 30}
00031         ,
00032         {"10_Standard", 10, 0, 130}
00033         ,
00034         {"50_Inferno", 50, 1, 130}
00035         ,
00036         {"50_Cluster", 50, 2, 130}
00037         ,
00038         {"50_Standard", 50, 0, 130}
00039         ,
00040         {"100_Inferno", 100, 1, 250}
00041         ,
00042         {"100_Cluster", 100, 2, 250}
00043         ,
00044         {"100_Standard", 100, 0, 250}
00045         ,
00046         {NULL, 0, 0, 0}
00047 };
00048 
00049 void DestroyBomb(MECH * mech, int loc)
00050 {
00051 
00052 }
00053 
00054 int BombWeight(int i)
00055 {
00056         return bombs[i].weight;
00057 }
00058 
00059 char *bomb_name(int i)
00060 {
00061         return bombs[i].name;
00062 }
00063 
00064 void bomb_list(MECH * mech, int player)
00065 {
00066         int bc = 0, fb;
00067         int i, j, k;
00068         char location[20];
00069         static char *types[] = {
00070                 "Standard",
00071                 "Inferno",
00072                 "Cluster",
00073                 NULL
00074         };
00075         coolmenu *c = NULL;
00076 
00077         addline();
00078         cent(tprintf("Bomb payload for %s:", GetMechID(mech)));
00079         addline();
00080         for(i = 0; i < NUM_SECTIONS; i++) {
00081                 fb = 1;
00082                 for(j = 0; j < NUM_CRITICALS; j++)
00083                         if(IsBomb((k = GetPartType(mech, i, j)))) {
00084                                 k = Bomb2I(k);
00085                                 if(fb) {
00086                                         ArmorStringFromIndex(i, location, MechType(mech),
00087                                                                                  MechMove(mech));
00088                                         fb = 0;
00089                                 }
00090                                 if(!bc) {
00091                                         vsi(tprintf("#  %-20s %-5s %-5s %s", "Location",
00092                                                                 "Weight", "Power", "Type"));
00093                                 }
00094                                 vsi(tprintf("%-2d %-20s %5d %5d", bc + 1, location,
00095                                                         bombs[k].weight / 10, bombs[k].aff,
00096                                                         types[bombs[k].type]));
00097                                 bc++;
00098                         }
00099         }
00100         if(!bc)
00101                 cent("No bombs installed.");
00102         addline();
00103         ShowCoolMenu(player, c);
00104         KillCoolMenu(c);
00105 }
00106 
00107 float calc_dest(MECH * mech, short *x, short *y)
00108 {
00109         /* Present location */
00110         float fx = MechFX(mech);
00111         float fy = MechFY(mech);
00112         float fz = MechFZ(mech) / ZSCALE;
00113         float zspd = MechStartFZ(mech) / ZSCALE;
00114         float t, ot;
00115 
00116         ot = t = (zspd + sqrt(zspd * zspd + 2 * GMOD * fz)) / GMOD;
00117         t = (float) t / MOVE_TICK;
00118         fx = fx + MechStartFX(mech) * t;
00119         fy = fy + MechStartFY(mech) * t;
00120         RealCoordToMapCoord(x, y, fx, fy);
00121         return ot;
00122 }
00123 
00124 void bomb_aim(MECH * mech, dbref player)
00125 {
00126         float t;                                        /* The time of impact */
00127         char toi[LBUF_SIZE];
00128         short x, y;
00129 
00130         t = calc_dest(mech, &x, &y);
00131         sprintf(toi, "%.1f second%s", t, (t >= 2.0 || t < 1.0) ? "" : "s");
00132         mech_printf(mech, MECHALL,
00133                                 "Estimated bomb flight time %s, estimated landing hex %d,%d.",
00134                                 toi, x, y);
00135 }
00136 
00137 void bomb_hit_hexes(MAP * map, int x, int y, int hitnb, int iscluster,
00138                                         int aff_d, int aff_h, char *tomsg, char *otmsg,
00139                                         char *tomsg1, char *otmsg1)
00140 {
00141         blast_hit_hexes(map, aff_d, iscluster ? 2 : 10, aff_h, x, y, tomsg,
00142                                         otmsg, tomsg1, otmsg1, 0, 4, 1, 1, hitnb);
00143 }
00144 
00145 static void bomb_hit(bomb_shot * s)
00146 {
00147         switch (bombs[s->type].type) {
00148         case 0:
00149                 HexLOSBroadcast(s->map, s->x, s->y,
00150                                                 "A blast rocks the area around $H!");
00151                 bomb_hit_hexes(s->map, s->x, s->y, 1, 0,
00152                                            bombs[s->type].type ==
00153                                            1 ? bombs[s->type].aff / 2 : bombs[s->type].aff,
00154                                            bombs[s->type].type == 1 ? bombs[s->type].aff : 0,
00155                                            "You receive a direct hit!", "receives a direct hit!",
00156                                            "You are hit by shrapnel!", "is hit by shrapnel!");
00157                 break;
00158         case 1:
00159                 HexLOSBroadcast(s->map, s->x, s->y,
00160                                                 "A fiery blast occurs in $H, spraying flaming gel everywhere!");
00161                 bomb_hit_hexes(s->map, s->x, s->y, 1, 0,
00162                                            bombs[s->type].type ==
00163                                            1 ? bombs[s->type].aff / 2 : bombs[s->type].aff,
00164                                            bombs[s->type].type == 1 ? bombs[s->type].aff : 0,
00165                                            "You receive a direct hit!", "receives a direct hit!",
00166                                            "You are hit by the globs of flaming gel!",
00167                                            "is hit by the globs!");
00168                 break;
00169         case 2:
00170                 HexLOSBroadcast(s->map, s->x, s->y,
00171                                                 "A bomb drops rain of small bomblets in $H's surroundings!");
00172                 bomb_hit_hexes(s->map, s->x, s->y, 1, 1,
00173                                            bombs[s->type].type ==
00174                                            1 ? bombs[s->type].aff / 2 : bombs[s->type].aff,
00175                                            bombs[s->type].type == 1 ? bombs[s->type].aff : 0,
00176                                            "You are hit by ton of small munitions!",
00177                                            "is hit by many small munitions!",
00178                                            "You are hit by some of the small munitions!",
00179                                            "is hit by some small munitions!");
00180                 break;
00181         }
00182 }
00183 
00184 static void bomb_hit_event(MUXEVENT * e)
00185 {
00186         bomb_shot *s = (bomb_shot *) e->data;
00187 
00188         bomb_hit(s);
00189         free((void *) s);
00190 }
00191 
00192 void simulate_flight(MECH * mech, MAP * map, short *x, short *y, float t)
00193 {
00194         float fx = MechFX(mech);
00195         float fy = MechFY(mech);
00196         float fz = MechFZ(mech);
00197 
00198 /*   float fs = MechStartFZ(mech); */
00199         float delx, dely;
00200         float dx, dy;
00201         int i;
00202         short tx, ty;
00203 
00204         if(t < 1.0)
00205                 return;
00206         MapCoordToRealCoord(*x, *y, &dx, &dy);
00207         delx = (dx - fx) / t;
00208         dely = (dy - fy) / t;
00209         for(i = 1; i < t; i++) {
00210                 fx = fx + delx;
00211                 fy = fx + dely;
00212                 fz = (float) fz - GMOD;
00213                 RealCoordToMapCoord(&tx, &ty, fx, fy);
00214                 if(tx < 0 || ty < 0 || tx >= map->map_width || ty >= map->map_height)
00215                         continue;
00216                 if(Elevation(map, tx, ty) > (fz / ZSCALE)) {
00217                         *x = tx;
00218                         *y = ty;
00219                 }
00220         }
00221 }
00222 
00223 void bomb_drop(MECH * mech, int player, int bn)
00224 {
00225         int bc = 0;
00226         int i, j, k;
00227         int lloc = 0, lpos = 0;
00228         float t;
00229         short x, y;
00230         int ob;
00231         int di;
00232         float dir;
00233         bomb_shot *s;
00234         MAP *map;
00235 
00236         DOCHECK(bn < 0, "Negative bomb number? Gimme a break.");
00237         bn--;
00238         for(i = 0; i < NUM_SECTIONS; i++)
00239                 for(j = 0; j < NUM_CRITICALS; j++)
00240                         if(IsBomb((k = GetPartType(mech, i, j))) &&
00241                            !PartIsDestroyed(mech, i, j)) {
00242                                 if(bc == bn) {
00243                                         lloc = i;
00244                                         lpos = j;
00245                                 }
00246                                 bc++;
00247                         }
00248         DOCHECK(!bc, "No bombs installed.");
00249         DOCHECK(!(map = getMap(mech->mapindex)), "You're on invalid map!");
00250         DOCHECK(bn < 0 ||
00251                         bn >= bc, "No bomb with such number installed! (See BOMB LIST)");
00252         MechLOSBroadcast(mech,
00253                                          "detaches a small object that starts falling down..");
00254         k = Bomb2I(GetPartType(mech, lloc, lpos));
00255         mech_notify(mech, MECHALL, "The ship trembles as you detach a bomb..");
00256         t = calc_dest(mech, &x, &y);
00257         ob = (int) t / 10;
00258         if(MadePilotSkillRoll(mech, 4 + ob) || t < 2.0)
00259                 mech_notify(mech, MECHALL,
00260                                         "Despite the slight problems, you keep the craft stable enough to drop the bomb right on target..");
00261         else {
00262                 mech_notify(mech, MECHALL,
00263                                         "The ship's lurches slightly, dropping the bomb off target!");
00264                 ob = 6 * (1 + ob);              /* Max distance missed  */
00265                 ob = MAX(1, (Number(1, ob)) / 2);
00266                 di = Number(0, 359);
00267                 dir = di * TWOPIOVER360;
00268                 x = x + ob * cos(dir);
00269                 y = y + ob * sin(dir);
00270         }
00271         simulate_flight(mech, map, &x, &y, t);
00272         if(x < 0 || y < 0 || x >= map->map_width || y >= map->map_height)
00273                 return;
00274         SetPartType(mech, lloc, lpos, 0);
00275         Create(s, bomb_shot, 1);
00276         s->x = x;
00277         s->y = y;
00278         s->type = k;
00279         s->map = map;
00280         SetCargoWeight(mech);
00281         muxevent_add(MAX(1, t), 0, EVENT_DHIT, bomb_hit_event, (void *) s, NULL);
00282 }
00283 
00284 void mech_bomb(dbref player, void *data, char *buffer)
00285 {
00286         MECH *mech = (MECH *) data;
00287         char *args[3];
00288         int argc;
00289         int bn;
00290 
00291         cch(MECH_USUALSO);
00292         DOCHECK(!(argc =
00293                           mech_parseattributes(buffer, args, 3)),
00294                         "(At least) one option required.");
00295         DOCHECK(argc > 2, "Too many arguments!");
00296         if(!strcasecmp(args[0], "list")) {
00297                 bomb_list(mech, player);
00298                 return;
00299         }
00300         DOCHECK(Landed(mech), "The craft is landed!");
00301         if(!strcasecmp(args[0], "aim")) {
00302                 bomb_aim(mech, player);
00303                 return;
00304         }
00305         DOCHECK(strcasecmp(args[0], "drop"), "Invalid argument to BOMB!");
00306         DOCHECK(argc < 2, "The BOMB commands needs to know WHICH bomb to drop!");
00307         DOCHECK(Readnum(bn, args[1]), "Invalid bomb number!");
00308         bomb_drop(mech, player, bn);
00309 }

Generated on Mon May 28 04:25:20 2007 for BattletechMUX by  doxygen 1.4.7