00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define GMOD 1
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
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;
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
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);
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 }