00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "mech.h"
00012 #include "mech.events.h"
00013 #include "p.mech.c3.h"
00014 #include "p.mech.c3.misc.h"
00015 #include "p.mech.utils.h"
00016 #include "p.mech.los.h"
00017 #include "p.mech.contacts.h"
00018
00019 #define C3_POS_IN_NETWORK -1
00020 #define C3_POS_NO_ROOM -2
00021
00022 #define C3_MASTER_MECH_SIZE 5
00023 #define C3_MASTER_OTHER_SIZE 1
00024
00025 int getC3MasterSize(MECH * mech)
00026 {
00027 if(MechType(mech) == CLASS_MECH)
00028 return C3_MASTER_MECH_SIZE;
00029 else
00030 return C3_MASTER_OTHER_SIZE;
00031 }
00032
00033 int isPartOfWorkingC3Master(MECH * mech, int section, int slot)
00034 {
00035 int x = 0;
00036 int y, t;
00037 int wcWorkingSlots = 0;
00038 int wStartCheck = 0;
00039 int tDoBump;
00040
00041 wStartCheck = MAX(0, slot - (getC3MasterSize(mech) - 1));
00042
00043 while (x < CritsInLoc(mech, section)) {
00044 tDoBump = 0;
00045
00046 if((t = GetPartType(mech, section, x))) {
00047 if(Special2I(t) == C3_MASTER) {
00048 if(x < wStartCheck) {
00049 tDoBump = 1;
00050 } else {
00051
00052 for(y = x; y < (x + getC3MasterSize(mech)); y++) {
00053 if(y != slot) {
00054 if(!PartIsNonfunctional(mech, section, y))
00055 wcWorkingSlots++;
00056 }
00057 }
00058 }
00059 }
00060 }
00061
00062 if(tDoBump)
00063 x += getC3MasterSize(mech);
00064 else
00065 x++;
00066 }
00067
00068 return (wcWorkingSlots == (getC3MasterSize(mech) - 1));
00069 }
00070
00071 int countWorkingC3MastersOnMech(MECH * mech)
00072 {
00073 int x, y, t;
00074 int wcSlots;
00075 int wcWorkingSlots;
00076 int wcMasters = 0;
00077
00078 debugC3(tprintf("Counting working C3 masters for %d", mech->mynum));
00079
00080 for(x = 0; x < NUM_SECTIONS; x++) {
00081 wcSlots = 0;
00082 wcWorkingSlots = 0;
00083
00084 for(y = 0; y < CritsInLoc(mech, x); y++) {
00085 if((t = GetPartType(mech, x, y))) {
00086 if(Special2I(t) == C3_MASTER) {
00087 debugC3(tprintf
00088 ("...found a C3Master slot at section %d, slot %d on %d.",
00089 x, y, mech->mynum));
00090
00091 wcSlots++;
00092
00093 if(!PartIsNonfunctional(mech, x, y)) {
00094 debugC3("......and the slot is functional.");
00095 wcWorkingSlots++;
00096 }
00097 }
00098 }
00099
00100 if(wcSlots == getC3MasterSize(mech)) {
00101 debugC3(tprintf
00102 ("...found enough slots for a C3Master for %d.",
00103 mech->mynum));
00104 wcSlots = 0;
00105
00106 if(wcWorkingSlots == getC3MasterSize(mech)) {
00107 debugC3(tprintf
00108 ("...there is even enough working slots to make the computer work on %d.",
00109 mech->mynum));
00110 wcMasters++;
00111 }
00112 }
00113 }
00114 }
00115
00116 debugC3(tprintf("Found %d working C3 masters on %d", wcMasters,
00117 mech->mynum));
00118
00119 return wcMasters;
00120 }
00121
00122 int countTotalC3MastersOnMech(MECH * mech)
00123 {
00124 int x, y, t;
00125 int wcSlots;
00126 int wcMasters = 0;
00127
00128 debugC3(tprintf("Counting total C3 masters for %d", mech->mynum));
00129
00130 for(x = 0; x < NUM_SECTIONS; x++) {
00131 wcSlots = 0;
00132
00133 for(y = 0; y < CritsInLoc(mech, x); y++) {
00134 if((t = GetPartType(mech, x, y))) {
00135 if(Special2I(t) == C3_MASTER) {
00136 debugC3(tprintf
00137 ("...found a C3Master slot at section %d, slot %d on %d.",
00138 x, y, mech->mynum));
00139
00140 wcSlots++;
00141 }
00142 }
00143
00144 if(wcSlots == getC3MasterSize(mech)) {
00145 debugC3(tprintf
00146 ("...found enough slots for a C3Master for %d.",
00147 mech->mynum));
00148
00149 wcSlots = 0;
00150 wcMasters++;
00151 }
00152 }
00153 }
00154
00155 debugC3(tprintf("Found %d total C3 masters on %d", wcMasters,
00156 mech->mynum));
00157
00158 return wcMasters;
00159 }
00160
00161 int countMaxC3Units(MECH * mech, dbref * myTempNetwork,
00162 int tempNetworkSize, MECH * targMech)
00163 {
00164 dbref otherRef;
00165 MECH *otherMech;
00166 int i;
00167 int wcC3Masters = 0;
00168 int myMasters = 0;
00169 int maxC3Size;
00170
00171 debugC3(tprintf("Counting max C3 units in %d's network", mech->mynum));
00172
00173 if(targMech)
00174 debugC3(tprintf("...using %d as an additional mech",
00175 targMech->mynum));
00176
00177
00178 for(i = 0; i < tempNetworkSize; i++) {
00179 otherRef = myTempNetwork[i];
00180 otherMech = getMech(otherRef);
00181
00182 if(!otherMech)
00183 continue;
00184
00185 wcC3Masters += MechWorkingC3Masters(otherMech);
00186
00187 debugC3(tprintf("...for %d, we add %d masters", otherMech->mynum,
00188 MechWorkingC3Masters(otherMech)));
00189 }
00190
00191
00192 maxC3Size = (wcC3Masters * 4) - wcC3Masters;
00193
00194 debugC3(tprintf("...we now have a max size of %d", maxC3Size));
00195
00196 myMasters = MechWorkingC3Masters(mech);
00197
00198 if(myMasters > 0)
00199 maxC3Size += (myMasters * 4) - myMasters;
00200
00201 debugC3(tprintf
00202 ("...and after adding in my masters, we now have a max size of %d",
00203 maxC3Size));
00204
00205
00206 if(targMech) {
00207 myMasters = MechWorkingC3Masters(targMech);
00208
00209 if(myMasters > 0)
00210 maxC3Size += (myMasters * 4) - myMasters;
00211 }
00212
00213 maxC3Size = MIN(maxC3Size, 11);
00214
00215 debugC3(tprintf("...final max size of %d", maxC3Size));
00216
00217 return maxC3Size;
00218 }
00219
00220 int trimC3Network(MECH * mech, dbref * myTempNetwork, int tempNetworkSize)
00221 {
00222 dbref otherRef;
00223 MECH *otherMech;
00224 int i;
00225 int newNetworkSize;
00226 int maxC3Size = 0;
00227 dbref newNetwork[C3_NETWORK_SIZE];
00228
00229 debugC3(tprintf("C3 TRIM: Trimming %d's C3 network", mech->mynum));
00230
00231
00232 newNetworkSize = tempNetworkSize;
00233
00234 for(i = 0; i < C3_NETWORK_SIZE; i++)
00235 newNetwork[i] = -1;
00236
00237
00238 maxC3Size = countMaxC3Units(mech, myTempNetwork, tempNetworkSize, NULL);
00239
00240 debugC3(tprintf("C3 TRIM: Max C3 size: %d", maxC3Size));
00241 debugC3(tprintf("C3 TRIM: Current C3 size: %d", tempNetworkSize));
00242
00243
00244 if(maxC3Size < tempNetworkSize) {
00245 newNetworkSize = 0;
00246
00247
00248 for(i = 0; i < tempNetworkSize; i++) {
00249 otherRef = myTempNetwork[i];
00250 otherMech = getMech(otherRef);
00251
00252 if(!otherMech)
00253 continue;
00254
00255 if(MechWorkingC3Masters(otherMech) > 0)
00256 newNetwork[newNetworkSize++] = otherRef;
00257 }
00258
00259
00260 if(newNetworkSize < maxC3Size) {
00261 for(i = 0; i < tempNetworkSize; i++) {
00262 otherRef = myTempNetwork[i];
00263 otherMech = getMech(otherRef);
00264
00265 if(!otherMech)
00266 continue;
00267
00268 if(MechWorkingC3Masters(otherMech) == 0)
00269 newNetwork[newNetworkSize++] = otherRef;
00270
00271 if(newNetworkSize >= maxC3Size)
00272 break;
00273 }
00274 }
00275
00276
00277 for(i = 0; i < newNetworkSize; i++)
00278 myTempNetwork[i] = newNetwork[i];
00279 }
00280
00281 return newNetworkSize;
00282 }
00283
00284 int getFreeC3NetworkPos(MECH * mech, MECH * mechToAdd)
00285 {
00286 int i;
00287 dbref otherRef;
00288
00289 validateC3Network(mech);
00290
00291 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00292 otherRef = MechC3NetworkElem(mech, i);
00293
00294 if(otherRef > 0) {
00295 if(otherRef == mechToAdd->mynum)
00296 return C3_POS_IN_NETWORK;
00297 } else
00298 return i;
00299 }
00300
00301 return C3_POS_NO_ROOM;
00302 }
00303
00304 void replicateC3Network(MECH * mechSrc, MECH * mechDest)
00305 {
00306 int i;
00307 dbref otherRef;
00308
00309 debugC3(tprintf("C3 REPLICATE: %d's C3 network to %d",
00310 mechSrc->mynum, mechDest->mynum));
00311
00312 clearC3Network(mechDest, 0);
00313
00314 MechC3NetworkElem(mechDest, 0) = mechSrc->mynum;
00315 MechC3NetworkSize(mechDest) = 1;
00316
00317 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00318 otherRef = MechC3NetworkElem(mechSrc, i);
00319
00320 if(otherRef != mechDest->mynum) {
00321 MechC3NetworkElem(mechDest, MechC3NetworkSize(mechDest)) =
00322 otherRef;
00323 MechC3NetworkSize(mechDest) += 1;
00324 }
00325 }
00326
00327 validateC3Network(mechDest);
00328 }
00329
00330 void addMechToC3Network(MECH * mech, MECH * mechToAdd)
00331 {
00332 MECH *otherMech;
00333 MECH *otherNotifyMech;
00334 dbref otherRef;
00335 int i;
00336 int wPos = -1;
00337
00338 debugC3(tprintf("C3 ADD: %d to the C3 network of %d",
00339 mechToAdd->mynum, mech->mynum));
00340
00341
00342 wPos = getFreeC3NetworkPos(mech, mechToAdd);
00343
00344
00345 if(wPos < 0)
00346 return;
00347
00348
00349 debugC3(tprintf("C3 ADD: Position to add to %d's network is %d",
00350 mech->mynum, wPos));
00351
00352 MechC3NetworkElem(mech, wPos) = mechToAdd->mynum;
00353 MechC3NetworkSize(mech) += 1;
00354
00355 mech_notify(mech, MECHALL,
00356 tprintf("%s connects to your C3 network.",
00357 GetMechToMechID(mech, mechToAdd)));
00358
00359
00360 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00361 otherRef = MechC3NetworkElem(mech, i);
00362
00363 otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 1);
00364
00365 if(!otherMech)
00366 continue;
00367
00368 if(!Good_obj(otherMech->mynum))
00369 continue;
00370
00371 if(otherRef != mechToAdd->mynum) {
00372 otherNotifyMech = getOtherMechInNetwork(mech, i, 1, 1, 1, 1);
00373
00374 if(otherNotifyMech)
00375 mech_notify(otherNotifyMech, MECHALL,
00376 tprintf("%s connects to your C3 network.",
00377 GetMechToMechID(otherNotifyMech,
00378 mechToAdd)));
00379 }
00380
00381 replicateC3Network(mech, otherMech);
00382 }
00383
00384
00385 validateC3Network(mech);
00386 }
00387
00388 void clearMechFromC3Network(dbref refToClear, MECH * mech)
00389 {
00390 int i;
00391
00392 debugC3(tprintf("C3 CLEAR: %d from the C3 network of %d", refToClear,
00393 mech->mynum));
00394
00395 if(!MechC3NetworkSize(mech))
00396 return;
00397
00398 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00399 if(MechC3NetworkElem(mech, i) == refToClear)
00400 MechC3NetworkElem(mech, i) = -1;
00401 }
00402
00403 validateC3Network(mech);
00404 }
00405
00406 void clearC3Network(MECH * mech, int tClearFromOthers)
00407 {
00408 MECH *otherMech;
00409 int i;
00410
00411 debugC3(tprintf("C3 CLEAR: %d's C3 network", mech->mynum));
00412
00413 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00414 otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 1);
00415
00416 MechC3NetworkElem(mech, i) = -1;
00417
00418 if(tClearFromOthers) {
00419 if(!otherMech)
00420 continue;
00421
00422 if(!Good_obj(otherMech->mynum))
00423 continue;
00424
00425 clearMechFromC3Network(mech->mynum, otherMech);
00426 }
00427 }
00428
00429 MechC3NetworkSize(mech) = 0;
00430 }
00431
00432 void validateC3Network(MECH * mech)
00433 {
00434 MECH *otherMech;
00435 dbref myTempNetwork[C3_NETWORK_SIZE];
00436 int i;
00437 int networkSize = 0;
00438
00439 debugC3(tprintf("C3 VALIDATE: %d's C3 network", mech->mynum));
00440
00441 if(!HasC3(mech) || Destroyed(mech) || C3Destroyed(mech)) {
00442 clearC3Network(mech, 1);
00443
00444 return;
00445 }
00446
00447 if(MechC3NetworkSize(mech) < 0) {
00448 clearC3Network(mech, 1);
00449
00450 return;
00451 }
00452
00453 for(i = 0; i < C3_NETWORK_SIZE; i++) {
00454 otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 1);
00455
00456 if(!otherMech)
00457 continue;
00458
00459 if(!Good_obj(otherMech->mynum))
00460 continue;
00461
00462 debugC3(tprintf("C3 VALIDATE INFO: %d is now in %d's C3 network",
00463 otherMech->mynum, mech->mynum));
00464
00465 myTempNetwork[networkSize] = otherMech->mynum;
00466 networkSize++;
00467 }
00468
00469 clearC3Network(mech, 0);
00470
00471 for(i = 0; i < networkSize; i++)
00472 MechC3NetworkElem(mech, i) = myTempNetwork[i];
00473
00474 MechC3NetworkSize(mech) = networkSize;
00475
00476 debugC3(tprintf
00477 ("C3 VALIDATE INFO: (PreTrim) %d's C3 network is %d elements",
00478 mech->mynum, MechC3NetworkSize(mech)));
00479
00480 networkSize = trimC3Network(mech, myTempNetwork, networkSize);
00481
00482 debugC3(tprintf
00483 ("C3 VALIDATE INFO: (PostTrim) %d's C3 network has been trimmed to %d elements",
00484 mech->mynum, networkSize));
00485
00486 if(networkSize != MechC3NetworkSize(mech)) {
00487 clearC3Network(mech, 0);
00488
00489 for(i = 0; i < networkSize; i++)
00490 MechC3NetworkElem(mech, i) = myTempNetwork[i];
00491
00492 MechC3NetworkSize(mech) = networkSize;
00493 }
00494
00495 }
00496
00497 void mech_c3_join_leave(dbref player, void *data, char *buffer)
00498 {
00499 MECH *mech = (MECH *) data, *target;
00500 MAP *objMap;
00501 char *args[2];
00502 dbref refTarget;
00503 int LOS = 1;
00504 float range = 0.0;
00505 int maxC3Size = 0;
00506
00507 cch(MECH_USUALO);
00508
00509 DOCHECK(mech_parseattributes(buffer, args, 2) != 1,
00510 "Invalid number of arguments to function!");
00511
00512 DOCHECK(!HasC3(mech), "This unit is not equipped with C3!");
00513 DOCHECK(C3Destroyed(mech), "Your C3 system is destroyed!");
00514 DOCHECK(AnyECMDisturbed(mech),
00515 "Your C3 system is not currently operational!");
00516
00517 validateC3Network(mech);
00518
00519
00520 if(!strcmp(args[0], "-")) {
00521 if(MechC3NetworkSize(mech) <= 0) {
00522 mech_notify(mech, MECHALL,
00523 "You are not connected to a C3 network!");
00524
00525 return;
00526 }
00527
00528 clearC3Network(mech, 1);
00529
00530 mech_notify(mech, MECHALL, "You disconnect from the C3 network.");
00531
00532 return;
00533 }
00534
00535
00536
00537 DOCHECK(MechC3NetworkSize(mech) > 0, "You are already in a C3 network!");
00538
00539 objMap = getMap(mech->mapindex);
00540
00541
00542 refTarget = FindTargetDBREFFromMapNumber(mech, args[0]);
00543 target = getMech(refTarget);
00544
00545 if(target)
00546 LOS =
00547 InLineOfSight(mech, target, MechX(target), MechY(target), range);
00548 else
00549 refTarget = 0;
00550
00551 DOCHECK((refTarget < 1) ||
00552 !LOS, "That is not a valid targetID. Try again.");
00553 DOCHECK(MechTeam(mech) != MechTeam(target),
00554 "You can't use the C3 network of unfriendly units!");
00555 DOCHECK(mech->mynum == target->mynum, "You can't connect to yourself!");
00556 DOCHECK(Destroyed(target), "That unit is destroyed!");
00557 DOCHECK(!Started(target), "That unit is not started!");
00558 DOCHECK(!HasC3(target),
00559 "That unit does not appear to be equipped with C3!");
00560
00561
00562 validateC3Network(target);
00563
00564
00565 maxC3Size =
00566 countMaxC3Units(mech, MechC3Network(target),
00567 MechC3NetworkSize(target), target);
00568
00569 DOCHECK(maxC3Size < (MechC3NetworkSize(target) + 1),
00570 "That unit's C3 network is operating at maximum capacity!");
00571
00572
00573 mech_notify(mech, MECHALL, tprintf("You connect to %s's C3 network.",
00574 GetMechToMechID(mech, target)));
00575
00576 addMechToC3Network(target, mech);
00577 }
00578
00579 void mech_c3_message(dbref player, MECH * mech, char *buffer)
00580 {
00581 cch(MECH_USUALO);
00582
00583 DOCHECK(!HasC3(mech), "This unit is not equipped with C3!");
00584 DOCHECK(C3Destroyed(mech), "Your C3 system is destroyed!");
00585 DOCHECK(AnyECMDisturbed(mech),
00586 "Your C3 system is not currently operational!");
00587
00588 validateC3Network(mech);
00589
00590 DOCHECK(MechC3NetworkSize(mech) <= 0,
00591 "There are no other units in your C3 network!");
00592
00593 skipws(buffer);
00594 DOCHECK(!*buffer, "What do you want to send on the C3 Network?");
00595
00596 sendNetworkMessage(player, mech, buffer, 1);
00597 }
00598
00599 void mech_c3_targets(dbref player, MECH * mech, char *buffer)
00600 {
00601 cch(MECH_USUALO);
00602
00603 DOCHECK(!HasC3(mech), "This unit is not equipped with C3!");
00604 DOCHECK(C3Destroyed(mech), "Your C3 system is destroyed!");
00605 DOCHECK(AnyECMDisturbed(mech),
00606 "Your C3 system is not currently operational!");
00607
00608 validateC3Network(mech);
00609
00610 DOCHECK(MechC3NetworkSize(mech) <= 0,
00611 "There are no other units in your C3 network!");
00612
00613 showNetworkTargets(player, mech, 1);
00614 }
00615
00616 void mech_c3_network(dbref player, MECH * mech, char *buffer)
00617 {
00618 cch(MECH_USUALO);
00619
00620 DOCHECK(!HasC3(mech), "This unit is not equipped with C3!");
00621 DOCHECK(C3Destroyed(mech), "Your C3 system is destroyed!");
00622 DOCHECK(AnyECMDisturbed(mech),
00623 "Your C3 system is not currently operational!");
00624
00625 validateC3Network(mech);
00626
00627 DOCHECK(MechC3NetworkSize(mech) <= 0,
00628 "There are no other units in your C3 network!");
00629
00630 showNetworkData(player, mech, 1);
00631 }