00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "mech.h"
00012 #include "p.mech.c3.misc.h"
00013 #include "p.mech.c3.h"
00014 #include "p.mech.c3i.h"
00015 #include "p.mech.utils.h"
00016 #include "p.mech.los.h"
00017 #include "p.mech.contacts.h"
00018
00019 #define TARG_LOS_NONE 0
00020 #define TARG_LOS_CLEAR 1
00021 #define TARG_LOS_SOMETHING 2
00022
00023 #define DEBUG_C3 0
00024
00025 MECH *getMechInTempNetwork(int wIdx, dbref * myNetwork, int networkSize)
00026 {
00027 MECH *tempMech;
00028 dbref refOtherMech;
00029
00030 if((wIdx > networkSize) || (wIdx < 0))
00031 return NULL;
00032
00033 refOtherMech = myNetwork[wIdx];
00034
00035 if(refOtherMech > 0) {
00036 tempMech = getMech(refOtherMech);
00037
00038 if(!tempMech)
00039 return NULL;
00040
00041 if(Destroyed(tempMech))
00042 return NULL;
00043
00044 return tempMech;
00045 }
00046
00047 return NULL;
00048 }
00049
00050 MECH *getOtherMechInNetwork(MECH * mech, int wIdx, int tCheckECM,
00051 int tCheckStarted, int tCheckUncon, int tIsC3)
00052 {
00053 MECH *tempMech;
00054 dbref refOtherMech;
00055 int networkSize;
00056
00057 networkSize =
00058 (tIsC3 ? MechC3NetworkSize(mech) : MechC3iNetworkSize(mech));
00059
00060 if((wIdx >= networkSize) || (wIdx < 0))
00061 return NULL;
00062
00063 refOtherMech =
00064 (tIsC3 ? MechC3NetworkElem(mech, wIdx) : MechC3iNetworkElem(mech,
00065 wIdx));
00066
00067 if(refOtherMech > 0) {
00068 tempMech = getMech(refOtherMech);
00069
00070 if(!tempMech)
00071 return NULL;
00072
00073 if(MechTeam(tempMech) != MechTeam(mech))
00074 return NULL;
00075
00076 if(tempMech->mapindex != mech->mapindex)
00077 return NULL;
00078
00079 if(Destroyed(tempMech))
00080 return NULL;
00081
00082 if(tIsC3) {
00083 if(!HasC3(tempMech))
00084 return NULL;
00085
00086 if(C3Destroyed(tempMech))
00087 return NULL;
00088 } else {
00089 if(!HasC3i(tempMech))
00090 return NULL;
00091
00092 if(C3iDestroyed(tempMech))
00093 return NULL;
00094 }
00095
00096 if(tCheckECM)
00097 if(AnyECMDisturbed(tempMech))
00098 return NULL;
00099
00100 if(tCheckStarted)
00101 if(!Started(tempMech))
00102 return NULL;
00103
00104 if(tCheckUncon)
00105 if(Uncon(tempMech))
00106 return NULL;
00107
00108 return tempMech;
00109 }
00110
00111 return NULL;
00112 }
00113
00114 void buildTempNetwork(MECH * mech, dbref * myNetwork, int *networkSize,
00115 int tCheckECM, int tCheckStarted, int tCheckUncon,
00116 int tIsC3)
00117 {
00118 int tempNetworkSize = 0;
00119 int baseNetworkSize;
00120 MECH *otherMech;
00121 dbref myTempNetwork[C3_NETWORK_SIZE];
00122 int i;
00123
00124
00125 for(i = 0; i < C3_NETWORK_SIZE; i++)
00126 myNetwork[i] = -1;
00127
00128 *networkSize = 0;
00129
00130 baseNetworkSize =
00131 (tIsC3 ? MechC3NetworkSize(mech) : MechC3iNetworkSize(mech));
00132
00133 if(baseNetworkSize == 0)
00134 return;
00135
00136
00137
00138
00139 for(i = 0; i < baseNetworkSize; i++) {
00140 otherMech =
00141 getOtherMechInNetwork(mech, i, tCheckECM, tCheckStarted,
00142 tCheckUncon, tIsC3);
00143
00144 if(!otherMech)
00145 continue;
00146
00147 if(!Good_obj(otherMech->mynum))
00148 continue;
00149
00150 myTempNetwork[tempNetworkSize] = otherMech->mynum;
00151 tempNetworkSize++;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 if(tIsC3) {
00162 if(tempNetworkSize > 0)
00163 tempNetworkSize =
00164 trimC3Network(mech, myTempNetwork, tempNetworkSize);
00165 }
00166
00167 for(i = 0; i < tempNetworkSize; i++)
00168 myNetwork[i] = myTempNetwork[i];
00169
00170 *networkSize = tempNetworkSize;
00171 }
00172
00173 void sendNetworkMessage(dbref player, MECH * mech, char *msg, int tIsC3)
00174 {
00175 int i;
00176 MECH *otherMech;
00177 const char *c = GetMechID(mech);
00178 char buf[LBUF_SIZE];
00179 int networkSize;
00180 dbref myNetwork[C3_NETWORK_SIZE];
00181
00182 buildTempNetwork(mech, myNetwork, &networkSize, 1, 1, 1, tIsC3);
00183
00184 for(i = 0; i < networkSize; i++) {
00185 otherMech = getMechInTempNetwork(i, myNetwork, networkSize);
00186
00187 if(!otherMech)
00188 continue;
00189
00190 if(!Good_obj(otherMech->mynum))
00191 continue;
00192
00193 sprintf(buf, "%%ch%s/%s: %s%%cn", (tIsC3 ? "C3" : "C3i"), c, msg);
00194 mech_notify(otherMech, MECHALL, buf);
00195 }
00196
00197 sprintf(buf, "%%ch%s/You: %s%%cn", (tIsC3 ? "C3" : "C3i"), msg);
00198 mech_notify(mech, MECHALL, buf);
00199 }
00200
00201 void showNetworkTargets(dbref player, MECH * mech, int tIsC3)
00202 {
00203 MAP *objMap = getMap(mech->mapindex);
00204 int i, j, wTemp, bearing;
00205 MECH *otherMech;
00206 float realRange, c3Range;
00207 char buff[100];
00208 char *mech_name;
00209 char move_type[30];
00210 char cStatus1, cStatus2, cStatus3, cStatus4, cStatus5;
00211 char weaponarc;
00212 int losFlag;
00213 int arc;
00214 int wSeeTarget = TARG_LOS_NONE;
00215 int wC3SeeTarget = TARG_LOS_NONE;
00216 int tShowStatusInfo = 0;
00217 char bufflist[MAX_MECHS_PER_MAP][120];
00218 float rangelist[MAX_MECHS_PER_MAP];
00219 int buffindex = 0;
00220 int sbuff[MAX_MECHS_PER_MAP];
00221 int networkSize;
00222 dbref myNetwork[C3_NETWORK_SIZE];
00223 dbref c3Ref;
00224
00225 buildTempNetwork(mech, myNetwork, &networkSize, 1, 1, 0, tIsC3);
00226
00227
00228
00229
00230
00231 notify_printf(player, "%s Contacts:", tIsC3 ? "C3" : "C3i");
00232
00233 for(i = 0; i < objMap->first_free; i++) {
00234 if(!(objMap->mechsOnMap[i] != mech->mynum &&
00235 objMap->mechsOnMap[i] != -1))
00236 continue;
00237
00238 otherMech = (MECH *) FindObjectsData(objMap->mechsOnMap[i]);
00239
00240 if(!otherMech)
00241 continue;
00242
00243 if(!Good_obj(otherMech->mynum))
00244 continue;
00245
00246 tShowStatusInfo = 0;
00247 realRange = FlMechRange(objMap, mech, otherMech);
00248 losFlag =
00249 InLineOfSight(mech, otherMech, MechX(otherMech),
00250 MechY(otherMech), realRange);
00251
00252
00253
00254
00255 if(losFlag) {
00256 if(InLineOfSight_NB(mech, otherMech, MechX(otherMech),
00257 MechY(otherMech), 0.0))
00258 wSeeTarget = TARG_LOS_CLEAR;
00259 else
00260 wSeeTarget = TARG_LOS_SOMETHING;
00261 } else
00262 wSeeTarget = TARG_LOS_NONE;
00263
00264
00265
00266
00267 if(wSeeTarget != TARG_LOS_CLEAR)
00268 wC3SeeTarget = mechSeenByNetwork(mech, otherMech, tIsC3);
00269
00270
00271 if(!wSeeTarget && !wC3SeeTarget)
00272 continue;
00273
00274
00275 c3Range =
00276 findC3RangeWithNetwork(mech, otherMech, realRange, myNetwork,
00277 networkSize, &c3Ref);
00278
00279
00280 if((wSeeTarget != TARG_LOS_CLEAR) && (wC3SeeTarget != TARG_LOS_CLEAR)) {
00281 tShowStatusInfo = 0;
00282 mech_name = "something";
00283 } else {
00284 tShowStatusInfo = 1;
00285 mech_name = silly_atr_get(otherMech->mynum, A_MECHNAME);
00286 }
00287
00288 bearing =
00289 FindBearing(MechFX(mech), MechFY(mech), MechFX(otherMech),
00290 MechFY(otherMech));
00291 strcpy(move_type, GetMoveTypeID(MechMove(otherMech)));
00292
00293
00294 arc = InWeaponArc(mech, MechFX(otherMech), MechFY(otherMech));
00295 weaponarc = getWeaponArc(mech, arc);
00296
00297
00298 if(!tShowStatusInfo) {
00299 cStatus1 = ' ';
00300 cStatus2 = ' ';
00301 cStatus3 = ' ';
00302 cStatus4 = ' ';
00303 cStatus5 = ' ';
00304 } else {
00305 cStatus1 = getStatusChar(mech, otherMech, 1);
00306 cStatus2 = getStatusChar(mech, otherMech, 2);
00307 cStatus3 = getStatusChar(mech, otherMech, 3);
00308 cStatus4 = getStatusChar(mech, otherMech, 4);
00309 cStatus5 = getStatusChar(mech, otherMech, 5);
00310 }
00311
00312
00313 sprintf(buff,
00314 "%s%c%c%c[%s]%c %-11.11s x:%3d y:%3d z:%3d r:%4.1f c:%4.1f b:%3d s:%5.1f h:%3d S:%c%c%c%c%c%s",
00315 otherMech->mynum == MechTarget(mech) ? "%ch%cr" :
00316 (tShowStatusInfo &&
00317 !MechSeemsFriend(mech, otherMech)) ? "%ch%cy" : "",
00318 (losFlag & MECHLOSFLAG_SEESP) ? 'P' : ' ',
00319 (losFlag & MECHLOSFLAG_SEESS) ? 'S' : ' ', weaponarc,
00320 MechIDS(otherMech, MechSeemsFriend(mech, otherMech) ||
00321 !tShowStatusInfo), move_type[0], mech_name,
00322 MechX(otherMech), MechY(otherMech), MechZ(otherMech),
00323 realRange, c3Range, bearing, MechSpeed(otherMech),
00324 MechVFacing(otherMech), cStatus1, cStatus2, cStatus3,
00325 cStatus4, cStatus5, (otherMech->mynum == MechTarget(mech)
00326 || !MechSeemsFriend(mech,
00327 otherMech)) ? "%c" :
00328 "");
00329
00330 rangelist[buffindex] = realRange;
00331 rangelist[buffindex] +=
00332 (MechStatus(otherMech) & DESTROYED) ? 10000 : 0;
00333 strcpy(bufflist[buffindex++], buff);
00334 }
00335
00336 for(i = 0; i < buffindex; i++)
00337 sbuff[i] = i;
00338
00339
00340
00341 for(i = 0; i < (buffindex - 1); i++)
00342 for(j = (i + 1); j < buffindex; j++)
00343 if(rangelist[sbuff[j]] > rangelist[sbuff[i]]) {
00344 wTemp = sbuff[i];
00345 sbuff[i] = sbuff[j];
00346 sbuff[j] = wTemp;
00347 }
00348
00349 for(i = 0; i < buffindex; i++)
00350 notify(player, bufflist[sbuff[i]]);
00351
00352 notify_printf(player, "End %s Contact List", tIsC3 ? "C3" : "C3i");
00353 }
00354
00355 void showNetworkData(dbref player, MECH * mech, int tIsC3)
00356 {
00357 int i, bearing;
00358 MECH *otherMech;
00359 float range;
00360 char buff[100];
00361 char *mech_name;
00362 char move_type[30];
00363 int networkSize;
00364 dbref myNetwork[C3_NETWORK_SIZE];
00365
00366 notify_printf(player, "%s Network Status:", tIsC3 ? "C3" : "C3i");
00367
00368 buildTempNetwork(mech, myNetwork, &networkSize, 1, 1, 0, tIsC3);
00369
00370 for(i = 0; i < networkSize; i++) {
00371 otherMech = getMechInTempNetwork(i, myNetwork, networkSize);
00372
00373 if(!otherMech)
00374 continue;
00375
00376 if(!Good_obj(otherMech->mynum))
00377 continue;
00378
00379 range = FlMechRange(objMap, mech, otherMech);
00380 bearing =
00381 FindBearing(MechFX(mech), MechFY(mech), MechFX(otherMech),
00382 MechFY(otherMech));
00383
00384 strcpy(move_type, GetMoveTypeID(MechMove(otherMech)));
00385
00386 mech_name = silly_atr_get(otherMech->mynum, A_MECHNAME);
00387
00388 sprintf(buff,
00389 "%%ch%%cy[%s]%c %-12.12s x:%3d y:%3d z:%3d r:%4.1f b:%3d s:%5.1f h:%3d a: %3d i: %3d%%cn",
00390 MechIDS(otherMech, 1), move_type[0], mech_name,
00391 MechX(otherMech), MechY(otherMech), MechZ(otherMech), range,
00392 bearing, MechSpeed(otherMech), MechVFacing(otherMech),
00393 getRemainingArmorPercent(otherMech),
00394 getRemainingInternalPercent(otherMech));
00395
00396 notify(player, buff);
00397
00398 }
00399
00400 notify_printf(player, "End %s Network Status", tIsC3 ? "C3" : "C3i");
00401 }
00402
00403 int mechSeenByNetwork(MECH * mech, MECH * mechTarget, int tIsC3)
00404 {
00405 int los = TARG_LOS_NONE;
00406 float range = 0.0;
00407 int i;
00408 int networkSize;
00409 dbref myNetwork[C3_NETWORK_SIZE];
00410 MECH *otherMech;
00411
00412 buildTempNetwork(mech, myNetwork, &networkSize, 1, 1, 0, tIsC3);
00413
00414 if(networkSize == 0)
00415 return TARG_LOS_NONE;
00416
00417 for(i = 0; i < networkSize; i++) {
00418 otherMech = getMechInTempNetwork(i, myNetwork, networkSize);
00419
00420 if(!otherMech)
00421 continue;
00422
00423 if(!Good_obj(otherMech->mynum))
00424 continue;
00425
00426 if(otherMech == mechTarget)
00427 continue;
00428
00429 range = FaMechRange(otherMech, mechTarget);
00430 los =
00431 InLineOfSight(otherMech, mechTarget, MechX(mechTarget),
00432 MechY(mechTarget), range);
00433
00434 if(los) {
00435 if(!InLineOfSight_NB(otherMech, mechTarget, MechX(mechTarget),
00436 MechY(mechTarget), range))
00437 los = TARG_LOS_SOMETHING;
00438 else {
00439 los = TARG_LOS_CLEAR;
00440 break;
00441 }
00442 }
00443 }
00444
00445 return los;
00446 }
00447
00448 float findC3Range(MECH * mech, MECH * mechTarget, float realRange,
00449 dbref * c3Ref, int tIsC3)
00450 {
00451 int networkSize;
00452 dbref myNetwork[C3_NETWORK_SIZE];
00453
00454 if(tIsC3) {
00455 if(C3Destroyed(mech)) {
00456 return realRange;
00457 }
00458 } else {
00459 if(C3iDestroyed(mech)) {
00460 validateC3iNetwork(mech);
00461
00462 return realRange;
00463 }
00464 }
00465
00466 if(AnyECMDisturbed(mech))
00467 return realRange;
00468
00469 buildTempNetwork(mech, myNetwork, &networkSize, 1, 1, 0, tIsC3);
00470
00471 return findC3RangeWithNetwork(mech, mechTarget, realRange, myNetwork,
00472 networkSize, c3Ref);
00473 }
00474
00475 float findC3RangeWithNetwork(MECH * mech, MECH * mechTarget,
00476 float realRange, dbref * myNetwork,
00477 int networkSize, dbref * c3Ref)
00478 {
00479 float c3Range = 0.0;
00480 float bestRange = 0.0;
00481 int i;
00482 int inLOS = 0;
00483 int mapX, mapY;
00484 float hexX, hexY, hexZ;
00485 MECH *otherMech;
00486 MAP *map;
00487
00488 bestRange = realRange;
00489 *c3Ref = 0;
00490
00491 if(networkSize == 0)
00492 return realRange;
00493
00494 for(i = 0; i < networkSize; i++) {
00495 otherMech = getMechInTempNetwork(i, myNetwork, networkSize);
00496
00497 if(!otherMech)
00498 continue;
00499
00500 if(!Good_obj(otherMech->mynum))
00501 continue;
00502
00503 if(mechTarget) {
00504 if(otherMech == mechTarget)
00505 continue;
00506
00507 debugC3(tprintf
00508 ("C3RANGE-NETWORK (mech): Finding range from %d to %d.",
00509 mech->mynum, mechTarget->mynum));
00510
00511 c3Range = FaMechRange(otherMech, mechTarget);
00512 inLOS =
00513 InLineOfSight(otherMech, mechTarget, MechX(mechTarget),
00514 MechY(mechTarget), c3Range);
00515 } else if((MechTargX(mech) > 0) && (MechTargY(mech) > 0)) {
00516 mapX = MechTargX(mech);
00517 mapY = MechTargY(mech);
00518 map = getMap(mech->mapindex);
00519
00520 debugC3(tprintf
00521 ("C3RANGE-NETWORK (hex): Finding range from %d to %d %d.",
00522 mech->mynum, mapX, mapY));
00523
00524 MechTargZ(mech) = Elevation(map, mapX, mapY);
00525 hexZ = ZSCALE * MechTargZ(mech);
00526 MapCoordToRealCoord(mapX, mapY, &hexX, &hexY);
00527
00528 c3Range =
00529 FindRange(MechFX(otherMech), MechFY(otherMech),
00530 MechFZ(otherMech), hexX, hexY, hexZ);
00531 inLOS = LOS_NB(otherMech, NULL, mapX, mapY, c3Range);
00532 } else {
00533 continue;
00534 }
00535
00536 if(inLOS && (c3Range < bestRange)) {
00537 bestRange = c3Range;
00538 *c3Ref = otherMech->mynum;
00539 }
00540 }
00541
00542 return bestRange;
00543 }
00544
00545 void debugC3(char *msg)
00546 {
00547 if(DEBUG_C3)
00548 SendDebug(msg);
00549 }